diff --git a/docs/developers/README.md b/docs/developers/README.md index f3aeeda..e2b805b 100644 --- a/docs/developers/README.md +++ b/docs/developers/README.md @@ -1,47 +1,408 @@ --- -sidebar_label: 'Developers' +sidebar_label: 'Quickstart' sidebar_position: 1 --- -# Developers +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -SSV is a permissionless network that enables the distribution of validator operations between non-trusting operators. +# Quickstart -![Get Started](/img/get-started-1.avif) +SSV is a permissionless network that enables the distribution of validator operations between non-trusting operators. If you're new to SSV network, go through [the Learn section](/learn/introduction/) to understand its core concepts first. -## How to integrate with SSV +This guide explains how to generate validator keys, split them into key shares, and register them on the Hoodi testnet via the SSV-SDK. -Eager to jump into action? [Quickstart](/developers/quickstart.md) is a great place to start and automate bulk validator registration using our SDK. +### Introduction -If you're new to ssv network, go through [the Learn section](/learn/introduction/) to understand its core concepts first. +Before getting started, review the following list of essential items for integrating with SSV: +- [Quickstart guide below](#overview) shows how to automate bulk validator registration. +- You can also find several [other Guides](/developers/SSV-SDK/examples/) in the respective section. +- On-chain data is made available via [Subgraph](/developers/tools/ssv-subgraph/) and the [SSV API](/developers/tools/ssv-api) (e.g. operator metadata). +- We recommend integrating with SSV by using [the SDK](/developers/SSV-SDK/). You can better understand how it is structured with [SSV SDK Module Reference](/developers/SSV-SDK/module-reference/). +- Lastly, you can start experimenting by interacting with [our Hoodi Testnet](/developers/testnet) smart contracts, before interacting [with the Mainnet ones](/developers/smart-contracts/README.md). -The best way to get started with SSV is using [the SDK](/developers/SSV-SDK/), which allows developers to perform transactions to the smart contract, and access Subgraph data, via simple, high level functions. [SSV SDK Module Reference](/developers/SSV-SDK/module-reference/) can help you understand how it is structured. It might also be helpful to look at [several examples](/developers/SSV-SDK/examples/) of how to use the SSV SDK. +### Overview -[SSV Network smart contract](./smart-contracts/ssvnetwork.md) allows stakers and operators to coordinate in a permissionless way. +The steps you will need to take: +1. [Installation](#1-installation) +2. [Select operators and collect their data](#2-select-operators-and-collect-their-data) +3. [Split your validator keys to shares](#3-split-validator-keys) +4. [Register your validators to the SSV network](#4-register-validators) -On-chain data generated by the smart contract is made available via [Subgraph](./tools/ssv-subgraph/) and the [SSV API](https://api.ssv.network/documentation/#/v4) (for things like operator metadata). +There is also [Full code example](#full-code-example) by the end of this page. -Lastly, you can start experimenting by interacting with [our Hoodi Testnet](/developers/testnet) smart contracts, before interacting with Mainnet ones. +:::note Prerequisite +This tutorial assumes you already have keystores generated, or will use the [*code illustrated here*](/developers/SSV-SDK/examples/create-validator-keys) to generate them pragmatically. +::: +### **1. Installation** -## Tools and Resources +#### Install +```bash +npm i @ssv-labs/ssv-sdk fs path web3 viem +``` -### [SSV SDK](/developers/SSV-SDK/) +#### Import -A comprehensive, open-source developer toolkit that can be used to programmatically write scripts for tasks such as [operator management](/developers/SSV-SDK/module-reference/operator-module), [keyshare generation](/developers/tools/ssv-dkg-client/generate-key-shares), and [bulk validator registration](/developers/quickstart.md). +```typescript +import { SSVSDK, chains } from '@ssv-labs/ssv-sdk' +import { parseEther, createPublicClient, createWalletClient, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +``` -### [Smart Contracts](smart-contracts/) +#### Instantiation -The SSV Network and SSV Read contract handle all of the on-chain data regarding SSV. +To instantiate the SDK, provide a number of parameters: -### [DKG Client](tools/ssv-dkg-client/) +| Parameter | Description | +| --------------- | --------------------------------------- | +| `public_client` | Public client object created using viem | +| `wallet_client` | Wallet object created using viem | -Securely generate keyshares for a validator and distribute them to operators without the full key ever being stored. +You can use these like so to instantiate the SDK and store it an object: -### [Subgraph](tools/ssv-subgraph/) +```typescript +// Setup viem clients +const chain = chains.hoodi as any // or chains.mainnet +const transport = http() -All data about the SSV Network is stored here, accessible through straightforward and user-friendly API calls. +const publicClient = createPublicClient({ + chain, + transport, +}) as any -### [SSV API](https://api.ssv.network/documentation/#/v4) +const account = privateKeyToAccount('0x...') +const walletClient = createWalletClient({ + account, + chain, + transport, +}) as any -A set of calls to get information about the SSV network. \ No newline at end of file +// Initialize SDK with viem clients +const sdk = new SSVSDK({ + publicClient, + walletClient, +}) +``` + +### **2. Select operators and collect their data** +A cluster can have 4, 7, 10, or 13 operators β€” the bigger your cluster, the higher yearly fee, and the more reliable your validator operations. + +If you already know the operator IDs you can proceed to any of the 3 options below to get their data. + +If you need to choose operators, feel free to browse [SSV Explorer](https://explorer.ssv.network/operators) to find the operators you will add to your cluster. Then proceed to the steps below. Please note, some of the operators are Private and only allow specific whitelisted addresses to onboard validators to them. + + + + To generate keyshares, operator IDs and their public keys are needed. You can collect keys of each operator using [SSV Subgraph](/developers/tools/ssv-subgraph). You will need to create own Graph API key and use endpoint with it. + + Alternatively, you can do it using [The Graph UI](https://thegraph.com/explorer/subgraphs/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh?view=Query&chain=arbitrum-one). + + An example of how Hoodi Subgraph can fetch the operator data is below. The code snippet considers you have environment variables (`SUBGRAPH_API_KEY` and `OPERATOR_IDS`) in an `.env` file: + ```typescript + const operatorIDs = JSON.parse(process.env.OPERATOR_IDS) + const url = "https://gateway.thegraph.com/api/subgraphs/id/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh"; + const query = ` + query ValidatorData($operatorIDs: [Bytes!]) { + operators(where: {id_in: $operatorIDs}) { + id + publicKey + } + }` + + const variables = { operatorIDs: operatorIDs } + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${process.env.SUBGRAPH_API_KEY}` + }, + body: JSON.stringify({ query, variables }) + }); + + const responseData: any = await response.json(); + const web3 = new Web3(); + const operators: { id: string; publicKey: string }[] = responseData.data.operators.map((operator: any) => {return { + id: operator.id, + publicKey: web3.eth.abi.decodeParameter("string", operator.publicKey) + }}) + ``` + + + To generate keyshares, operator IDs and their public keys are needed. This can also be done with [SSV Explorer](https://explorer.ssv.network/operators). + + On each operator's page, there is a πŸ—οΈ sign next to operator's name. Click on the key sign and their public key will be copied. Repeat the process for each operator you chose. + + + Operator public key can be collected using our API once you know the ID. Use [this request type](https://api.ssv.network/documentation/#/Operators/OperatorsV4Controller_getOperator) to get the data. You only need to set the network and operator ID. + +```bash +curl -X 'GET' \ + 'https://api.ssv.network/api/v4/hoodi/operators/1' \ + -H 'accept: */*' +``` + +From the response you will need `id` and `public_key` contents: +```json +{ + "id": 1, + "id_str": "1", + "declared_fee": "0", + "previous_fee": "0", + "fee": "382640000000", + "public_key": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeVpGNUR2M2UwSkEzT25TSGwyQmMKNGFxbmpUTWFrUXNZSkY5eE55M21CVTZSQld1d2xVd1dIelJGWUFvb0FlRER3NlYxL3hRQ0JFaWJwTGx1RVdLTgoxNmRpcU5EVmY5VEZndmZlM2NHc3pNcDZCUE04bWhBdkx0c01DcHlXeDZtTEczVm0zVVRNK3hRdUJwVFZsdHNNCkV6eUZEZzNWTlphOW9hZkswbkVYRHVidlBIbkJCdWhlUW5LZThoUkJnRUo0emIrV3dncjFrM3YyWmkwTEtWNUQKYWd3c2QxK25Lb1grVktjYmJFVFBEdGRPV1AvZlpXM3dBMGp3R1pSdkhwNS8xUjBmZy91N01BUk1KTkRWVFYxQwo0Vlh1eHJkbHZWQ2JiS1pnWUIzY1ROSEMzZkVldit0NFVEeFJuQzdUcUN0WFZSYnpZQ001WHVSeUFRa3BiYU0wCjlRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K", + "owner_address": "0x3187a42658417a4d60866163A4534Ce00D40C0C8", + "address_whitelist": "0x5E33db0b37622F7E6b2f0654aA7B985D854EA9Cb", + "whitelist_addresses": [ + "0x5E33db0b37622F7E6b2f0654aA7B985D854EA9Cb" + ], + "is_private": true, + "whitelisting_contract": "", + "location": "United States of America", + "setup_provider": "AWS", + "eth1_node_client": "Geth", + "eth2_node_client": "Prysm", + "mev_relays": "", + "description": "", + "website_url": "", + "twitter_url": "", + "linkedin_url": "", + "dkg_address": "", + "logo": "https://media-v2.ssv.network/operator_1_v4_mainnet_ssvBlack.png", + "type": "operator", + "name": "SSV Labs", + "performance": { + "24h": 100, + "30d": 99.86798961841079 + }, + "is_valid": true, + "is_deleted": false, + "is_active": 1, + "status": "Active", + "validators_count": 143, + "version": "v4", + "network": "mainnet" +} +``` + + + +Pass the collected operator info into ```generateKeyShares``` function in the code below. + +### **3. Split validator keys** +Use the collected data and your keystore to generate the keyshare transaction payload. + +The code snippet below considers you have environment variables (`KEYSTORE_PASSWORD` and `OWNER_ADDRESS`) in an `.env` file. Also, `nonce` is being handled automatically in the [full code example](#full-code-example): + +```typescript +const keysharesPayload = await sdk.utils.generateKeyShares({ + keystore: keystoreValues, + keystore_password: process.env.KEYSTORE_PASSWORD, + operator_keys: operators.map((operator: { id: string; publicKey: string }) => operator.publicKey), + operator_ids: operators.map((operator: { id: string; publicKey: string }) => Number(operator.id)), + owner_address: process.env.OWNER_ADDRESS, + nonce: nonce, +}) +``` + +### **4. Register validators** +Then finally the `registerValidators` function can be called and return the transaction receipt: + +Register your validators to the SSV network is performed on completion of this function, when the transaction is processed successfully. + +```typescript +const txn_receipt = await sdk.clusters.registerValidators({ + args: { + keyshares: keysharesPayload, + depositAmount: parseEther('30') + }, + }).then(tx => tx.wait()) +console.log("txn_receipt: ", txn_receipt) +``` + +For validator [registration transaction](/developers/smart-contracts/ssvnetwork#bulkregistervalidatorpublickey-operatorids-shares-amount-cluster) you need to provide the cluster’s latest snapshot data and the user nonce. Fortunately, SSV SDK retrieves this data automatically, so you don't have to. + +### Full code example + +This example assumes you already have a number of keystore files and they are stored, under whatever is set for `KEYSTORE_FILE_DIRECTORY` in the `.env` file. + +**`.env` example file for the below script:** + +```sh +PRIVATE_KEY=0xYOUR_PRIVATE_KEY +OWNER_ADDRESS=0xA4831B989972605A62141a667578d742927Cbef9 +KEYSTORE_PASSWORD=test1234 +KEYSTORE_FILE_DIRECTORY=./validator_keys +DEPOSIT_AMOUNT=0.1234 +OPERATOR_IDS='["1", "2", "3", "4"]' +SUBGRAPH_API_KEY=GRAPH_API_KEY +``` + +```typescript +import { SSVSDK, chains } from '@ssv-labs/ssv-sdk' +import { parseEther, createPublicClient, createWalletClient, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import * as dotenv from 'dotenv'; +import * as fs from 'fs'; +import * as path from 'path'; +import Web3 from 'web3'; + +dotenv.config(); + +async function main(): Promise { + + if (!process.env.KEYSTORE_FILE_DIRECTORY || + !process.env.OWNER_ADDRESS || + !process.env.KEYSTORE_PASSWORD || + !process.env.OPERATOR_IDS || + !process.env.SUBGRAPH_API_KEY || + !process.env.DEPOSIT_AMOUNT) { + throw new Error('Required environment variables are not set'); + } + + const private_key: `0x${string}` = process.env.PRIVATE_KEY as `0x${string}`; + + // Setup viem clients + const chain = chains.hoodi as any // or chains.mainnet + const transport = http() + + const publicClient = createPublicClient({ + chain, + transport + }) as any + + const account = privateKeyToAccount(private_key as `0x${string}`) + const walletClient = createWalletClient({ + account, + chain, + transport, + }) as any + + // Initialize SDK with viem clients + const sdk = new SSVSDK({ + publicClient, + walletClient, + }) + + const directoryPath = process.env.KEYSTORE_FILE_DIRECTORY; + let keystoresArray: { name: string; keystore: any }[]; + try { + keystoresArray = await loadKeystores(directoryPath); + console.log('Loaded keystores: Keystore Amount: ', keystoresArray.length); + } catch (error) { + console.error('Failed to load keystores:', error); + throw error; // If keystores can't be loaded the code will exit + } + + // keystoresArray is defined at this point + let nonce = Number(await sdk.api.getOwnerNonce({ owner: process.env.OWNER_ADDRESS })) + console.log("Initial nonce: ", nonce) + + const operatorIDs = JSON.parse(process.env.OPERATOR_IDS) + const url = "https://gateway.thegraph.com/api/subgraphs/id/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh"; + const query = ` + query ValidatorData($operatorIDs: [Bytes!]) { + operators(where: {id_in: $operatorIDs}) { + id + publicKey + } + }` + + const variables = { operatorIDs: operatorIDs } + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${process.env.SUBGRAPH_API_KEY}` + }, + body: JSON.stringify({ query, variables }) + }); + + const responseData: any = await response.json(); + const web3 = new Web3(); + const operators: { id: string; publicKey: string }[] = responseData.data.operators.map((operator: any) => {return { + id: operator.id, + publicKey: web3.eth.abi.decodeParameter("string", operator.publicKey) + }}) + + console.log(operators.map((operator: { id: string; publicKey: string }) => operator.publicKey)) + console.log(operators.map((operator: { id: string; publicKey: string }) => Number(operator.id))) + + const chunkSize = 40; // Number of validators per transaction + for (let i = 0; i < keystoresArray.length; i += chunkSize) { + const chunk = keystoresArray.slice(i, i + chunkSize); + + const keystoreValues = chunk.map(item => item.keystore); + + const keysharesPayload = await sdk.utils.generateKeyShares({ + keystore: keystoreValues, + keystore_password: process.env.KEYSTORE_PASSWORD, + operator_keys: operators.map((operator: { id: string; publicKey: string }) => operator.publicKey), + operator_ids: operators.map((operator: { id: string; publicKey: string }) => Number(operator.id)), + owner_address: process.env.OWNER_ADDRESS, + nonce: nonce, + }) + + nonce = nonce + Number(chunk.length) + console.log("New nonce: ", nonce) + // Optional: to validate generated Keyshares you can use sdk.utils.validateSharesPreRegistration + + let txn_receipt + try { + console.log(`Processing chunk from index ${i} to ${i + chunk.length - 1}`); + txn_receipt = await sdk.clusters.registerValidators({ + args: { + keyshares: keysharesPayload, + depositAmount: parseEther(process.env.DEPOSIT_AMOUNT) + }, + }).then(tx => tx.wait()) + console.log("txn_receipt: ", txn_receipt) + } catch (error) { + logErrorToFile(error); + console.log("Failed to do register: ", error) + } + } +} + +async function loadKeystores(directory: string): Promise<{ name: string; keystore: any }[]> { + const keystoresArray: { name: string; keystore: any }[] = []; + + try { + const files = await fs.promises.readdir(directory); + + for (const file of files) { + if (file.startsWith('keystore-m') && file.endsWith('.json')) { + const filePath = path.join(directory, file); + + const fileContent = await fs.promises.readFile(filePath, 'utf-8'); + const jsonContent = JSON.parse(fileContent); + keystoresArray.push({ name: file, keystore: jsonContent }); + } + } + + return keystoresArray; + } catch (error) { + console.error('Error loading keystores:', error); + throw error; + } +} + +function logErrorToFile(error: unknown): void { + const errorMessage = `Failed to do register: ${error instanceof Error ? error.message : String(error)}\n`; + + // Log the error to the console + console.log(errorMessage); + + // Save the error message to a local file + const filePath = './error-log.txt'; + fs.appendFile(filePath, errorMessage, (err) => { + if (err) { + console.error("Failed to write to file: ", err); + } else { + console.log(`Error saved to file: ${filePath}`); + } + }); +} + +main(); +``` diff --git a/docs/developers/SSV-SDK/README.md b/docs/developers/SSV-SDK/README.md index 08257b8..dcb2c41 100644 --- a/docs/developers/SSV-SDK/README.md +++ b/docs/developers/SSV-SDK/README.md @@ -10,7 +10,7 @@ Development Notice: This SDK is currently under active development and testing. This section and SDK are a work in progress and will be continuously updated as new components of the SDK are released. ::: -The SSV SDK is a comprehensive, open-source developer toolkit written in TypeScript, designed to empower developers to seamlessly interact with the SSV Network programmatically. +The SSV SDK is a comprehensive, open-source developer toolkit written in TypeScript, designed to empower developers to seamlessly interact with the SSV Network programmatically. It consolidates all necessary tooling into a single, cohesive package. diff --git a/docs/developers/SSV-SDK/examples/README.md b/docs/developers/SSV-SDK/examples/README.md index 246bc5a..2bbe466 100644 --- a/docs/developers/SSV-SDK/examples/README.md +++ b/docs/developers/SSV-SDK/examples/README.md @@ -4,6 +4,6 @@ sidebar_position: 2 # Examples -In this examples section we will provide quick snippets of code to do certain actions, we will not show the imports/setup for each as this is covered previously. +In this examples section we will provide quick snippets of code to do certain actions, we will not show the imports/setup for each as this is covered previously. Each example will also be available in an executable typescript file found in the SDK repo. diff --git a/docs/developers/SSV-SDK/examples/api-calls.md b/docs/developers/SSV-SDK/examples/api-calls.md index 698a700..451daff 100644 --- a/docs/developers/SSV-SDK/examples/api-calls.md +++ b/docs/developers/SSV-SDK/examples/api-calls.md @@ -4,11 +4,11 @@ sidebar_position: 2 # API calls -This page will show how to use the API module to do various calls. The API module is used to get data such as the Account Nonce, or Cluster Snapshot, both are covered on this page. +This page will show how to use the API module to do various calls. The API module is used to get data such as the Account Nonce, or Cluster Snapshot, both are covered on this page. For the full list of functions you can check the [API Module Reference](../module-reference/api-module.md). -### Get Nonce +### Get Nonce ``` typescript const ownerNonce = await sdk.api.getOwnerNonce({ diff --git a/docs/developers/SSV-SDK/examples/cluster-balance-script.md b/docs/developers/SSV-SDK/examples/cluster-balance-script.md new file mode 100644 index 0000000..07096c5 --- /dev/null +++ b/docs/developers/SSV-SDK/examples/cluster-balance-script.md @@ -0,0 +1,16 @@ +# Cluster Balance Calculation + +The script below calculates the balance of a cluster on the SSV network. This calculation can be made useful by adding it to cluster balance monitoring tool/automation of your own. + +Details on the formulas used can be found in the documentation page related to [Cluster Balance](/stakers/clusters/cluster-balance). + +The core calculation function that computes and prints the cluster balance: + +```typescript + const balance = sdk.utils.getClusterBalance( + {args: { + operatorIds: [1,2,3,4] + }} + ) + console.log(balance) +``` \ No newline at end of file diff --git a/docs/developers/SSV-SDK/examples/create-validator-keys.md b/docs/developers/SSV-SDK/examples/create-validator-keys.md index 60b85b6..96bfd8f 100644 --- a/docs/developers/SSV-SDK/examples/create-validator-keys.md +++ b/docs/developers/SSV-SDK/examples/create-validator-keys.md @@ -4,7 +4,7 @@ sidebar_position: 3 # Create Validator Keys -The SSV SDK does not natively support programmatically generating keystores out of the box, but a number of external libraries can be used to achieve this. +The SSV SDK does not natively support programmatically generating keystores out of the box, but a number of external libraries can be used to achieve this. If you do not need to do this programmatically, it may be easier to use the [Ethereum Staking Deposit CLI](https://github.com/ethereum/staking-deposit-cli) to generate validator keys. To generate Hoodi validator keys you can use [eth-educators' Staking Deposit CLI fork](https://github.com/eth-educators/ethstaker-deposit-cli). diff --git a/docs/developers/SSV-SDK/examples/deposit-eth.md b/docs/developers/SSV-SDK/examples/deposit-eth.md new file mode 100644 index 0000000..e37dc2b --- /dev/null +++ b/docs/developers/SSV-SDK/examples/deposit-eth.md @@ -0,0 +1,28 @@ +--- +sidebar_position: 8 +--- + +# Deposit ETH + +This page shows how to programmatically deposit ETH to a cluster on the SSV network. This executes the contract call to the smart contract to deposit ETH to the cluster. + +### Deposit ETH + +```typescript +import { parseEther } from 'viem'; + +try { + const txnReceipt = await sdk.clusters.deposit({ + value: parseEther('0.123') + args: { + id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", + }, + }, + ).then(tx => tx.wait()); + + console.log('Transaction receipt:', txnReceipt); +} catch (error) { + console.error('Failed to deposit ETH:', error); +} +``` + diff --git a/docs/developers/SSV-SDK/examples/deposit-ssv.md b/docs/developers/SSV-SDK/examples/deposit-ssv.md deleted file mode 100644 index fafc133..0000000 --- a/docs/developers/SSV-SDK/examples/deposit-ssv.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_position: 8 ---- - -# Deposit SSV - -This page shows how to programmatically deposit SSV to a cluster on the SSV network. This executes the contract call to the SSV smart contract to deposit SSV to the cluster. - -### Deposit SSV - -```typescript -import { parseEther } from 'viem'; - -try { - const txnReceipt = await sdk.clusters.deposit({ - args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - amount: parseEther('30'), - }, - }, { - approve: true, // Automatically triggers token approval transaction if the allowance is lower than the deposit amount - }).then(tx => tx.wait()); - - console.log('Transaction receipt:', txnReceipt); -} catch (error) { - console.error('Failed to deposit SSV:', error); -} -``` - diff --git a/docs/developers/SSV-SDK/examples/register-validator.md b/docs/developers/SSV-SDK/examples/register-validator.md index 4c2e480..e894f3a 100644 --- a/docs/developers/SSV-SDK/examples/register-validator.md +++ b/docs/developers/SSV-SDK/examples/register-validator.md @@ -4,7 +4,7 @@ sidebar_position: 5 # Register Validator -This page shows how to progmatically register a validator to the SSV network. Assuming you already have generated a valid keyshare. +This page shows how to progmatically register a validator to the SSV network. Assuming you already have generated a valid keyshare. ### Register Validator diff --git a/docs/developers/SSV-SDK/examples/withdraw-ssv.md b/docs/developers/SSV-SDK/examples/withdraw-eth.md similarity index 66% rename from docs/developers/SSV-SDK/examples/withdraw-ssv.md rename to docs/developers/SSV-SDK/examples/withdraw-eth.md index 1a14766..e8628b4 100644 --- a/docs/developers/SSV-SDK/examples/withdraw-ssv.md +++ b/docs/developers/SSV-SDK/examples/withdraw-eth.md @@ -2,11 +2,11 @@ sidebar_position: 9 --- -# Withdraw SSV +# Withdraw ETH -This page shows how to programmatically withdraw SSV from a cluster on the SSV network. +This page shows how to programmatically withdraw ETH from a cluster on the SSV network. -### Withdraw SSV +### Withdraw ETH ```typescript import { parseEther } from 'viem'; @@ -15,13 +15,13 @@ try { const txnReceipt = await sdk.clusters.withdraw({ args: { id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - amount: parseEther('30'), + amount: parseEther('0.123'), }, }).then(tx => tx.wait()); console.log('Transaction receipt:', txnReceipt); } catch (error) { - console.error('Failed to withdraw SSV:', error); + console.error('Failed to withdraw ETH:', error); } ``` diff --git a/docs/developers/SSV-SDK/module-reference/api-module.md b/docs/developers/SSV-SDK/module-reference/api-module.md index 3b1a4ef..27d2d30 100644 --- a/docs/developers/SSV-SDK/module-reference/api-module.md +++ b/docs/developers/SSV-SDK/module-reference/api-module.md @@ -14,11 +14,9 @@ sdk.api.getOwnerNonce() Accepts a list of addresses, fetches their nonces using subgraph, returns as a list. -Input parameters: -
Input parameterInput typeDescriptionExample input
account_addressstringAn array of owner addresses.[β€œ0xA4831B989972605A62141a667578d742927Cbef9”]
-Examples input: +#### Example: ```typescript const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9" @@ -35,11 +33,9 @@ Example output: Accepts a list of addresses, fetches cluster snapshots using subgraph, returns as a list. -Input: -
Input parameterInput typeDescriptionExample input
cluster_idstringAn array of cluster IDs in their computed ID form.[β€œ4c0239091131c3e57e9555c540bcfd00bcd2484a9c4048f13411f22329511131”]
-Example: +#### Example: ```typescript const clusterSnapshot = await sdk.api.getClusterSnapshot({id: clusterID}) @@ -61,14 +57,13 @@ Example output: Accepts the owner address and a list of operator IDs, computes and returns the cluster ID hash. -Input: | Input parameter | Input type | Description | Example input | | ----------------- | ---------- | ----------------------------- | -------------------------------------------- | | owner\_address | string | Address of the cluster Owner. | '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494' | | operator\_ids\[] | integer | List of operator IDs. | \[12, 34, 56, 78] | -Example: +#### Example: ```typescript import { createClusterId } from '@ssv-labs/ssv-sdk/utils' @@ -77,7 +72,7 @@ const operatorIds = [242, 686, 707, 736] const clusterID = createClusterId(ownerAddress, operatorIds) ``` -Example output: +Example output: ```bash 1179fed483c8c1b0327c8667521162015fa8cbe1a1b047a26baf0f0971a81929 @@ -87,11 +82,9 @@ Example output: Accepts a cluster id in it's hashed form. Returns details about the cluster. -Input: -
Input parameterInput typeDescriptionExample input
cluster_idstringA cluster ID in it's computed formβ€œ4c0239091131c3e57e9555c540bcfd00bcd2484a9c4048f13411f22329511131”
daoAddressstringAddress of the DAO (chain specific)"0x38A4794cCEd47d3baf7370CcC43B560D3a1beEFA"
operatorIdsstring[]A list of operator Ids[1,2,3,4]
-Example: +#### Example: ```typescript const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9" @@ -116,11 +109,9 @@ Example output: Accepts a cluster id in it's hashed form. Returns details about the cluster. -Input: -
Input parameterInput typeDescriptionExample input
cluster_idstringAn array of cluster IDs in their computed ID form.[β€œ4c0239091131c3e57e9555c540bcfd00bcd2484a9c4048f13411f22329511131”]
-Example: +#### Example: ```typescript const clusterData = await sdk.api.getCluster({id: clusterID}) @@ -141,13 +132,11 @@ Example output: ### `getClusters(owner)` -Accepts an owner address. Returns details about all of the clusters that they own. - -Input: +Accepts an owner address. Returns details about all of the clusters that they own.
Input parameterInput typeDescriptionExample input
ownerstringAn owner address"0xA4831B989972605A62141a667578d742927Cbef9"
-Example: +#### Example: ```typescript const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9" @@ -183,11 +172,9 @@ Example output: Accepts an operator ID and returns details about the operator. -Input: -
Input parameterInput typeDescriptionExample input
idstringA single operator ID"4"
-Example: +#### Example: ```typescript const operatorData = await sdk.api.getOperator({id: "4"}) @@ -210,11 +197,9 @@ Example output: Accepts a list of operator IDs and returns details about them. -Input: -
Input parameterInput typeDescriptionExample input
operatorIdsstring[]A single operator ID["4","5"]
-Example: +#### Example: ```typescript const operatorData = await sdk.api.getOperators({operatorIds: ["4","5"]}) @@ -247,11 +232,9 @@ Example output: Accepts a validator ID and returns details about the validator. -Input: -
Input parameterInput typeDescriptionExample input
idstringA single validator ID0x0c74493afd8082f86485e4172be72678b0feb1494087ee6abe7d7ea7437c2a3fc6c06193040c6e24cdf59c9081d1c7a9
-Example: +#### Example: ```typescript const validatorData = await sdk.api.getValidators({id: "0x0c74493afd8082f86485e4172be72678b0feb1494087ee6abe7d7ea7437c2a3fc6c06193040c6e24cdf59c9081d1c7a9"}) @@ -269,11 +252,9 @@ Example output: Accepts an validator ID and returns details about the validator. -Input: -
Input parameterInput typeDescriptionExample input
idsstring[]An array of validator IDs["0x0c74493afd8082f86485e4172be72678b0feb1494087ee6abe7d7ea7437c2a3fc6c06193040c6e24cdf59c9081d1c7a9", "0x1a85052f3b9d17e73ec76c472220c80ada65a19a0fd177344b1e9f6173d51136c400120989dbd9ff498defc99dfe5181"]
-Example: +#### Example: ```typescript const validatorData = await sdk.api.getValidators({id: ["0x0c74493afd8082f86485e4172be72678b0feb1494087ee6abe7d7ea7437c2a3fc6c06193040c6e24cdf59c9081d1c7a9", "0x1a85052f3b9d17e73ec76c472220c80ada65a19a0fd177344b1e9f6173d51136c400120989dbd9ff498defc99dfe5181"]}) diff --git a/docs/developers/SSV-SDK/module-reference/cluster-module.md b/docs/developers/SSV-SDK/module-reference/cluster-module.md index 1aa6636..ae21791 100644 --- a/docs/developers/SSV-SDK/module-reference/cluster-module.md +++ b/docs/developers/SSV-SDK/module-reference/cluster-module.md @@ -4,7 +4,7 @@ sidebar_position: 1 # Cluster Module -This is a library which contains all the cluster functions you need for working with SSV, such as registering a validator +This is a library which contains all the functions you need for working with Clusters of SSV network, such as registering a validator. After instantiating the SDK, you can call any of the functions in the utils library like so: @@ -14,142 +14,176 @@ sdk.clusters.registerValidators() ## Function List -### `registerValidators()` +### `migrateClusterToETH()` +Converts an SSV-based cluster (legacy) to ETH-based cluster. Accepts cluster ID to migrate to ETH-denominated fees, and the amount of ETH to deposit upon migrating. -Accepts all parameters necessary to compute the keyshares, does this in the background using ssv-keys library, returns the keyshares as an object or saves it to file. +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| `cluster_Id` | string | A `cluster_id` in its computed ID form. | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | +| amount | bigint | Amount of ETH to deposit to fund the cluster | 0.1234 | -Input: +#### Example: + +```typescript +txn_receipt = await sdk.clusters.migrateClusterToETH({ + args: { + cluster_Id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + amount: parseEther('0.1234') + }, +}).then(tx => tx.wait()) +``` + +### `registerValidators()` + +Accepts a number of keyshares to be validated and registered to the network. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| keyshares | KeySharesItem[] \| KeySharesPayload[] | Keyshare or transaction payload | See output of [generateKeyShares()](../../tools/ssv-dkg-client/generate-key-shares.md) | -| depositAmount | bigint | Amount of SSV to deposit to cluster | 4 | +| keyshares | KeySharesItem[] | Keyshares | See [keyshares example with its structure](/developers/keyshares-structure) | +| depositAmount | bigint | Amount of ETH to deposit to cluster | 0.1234 | -Example: +#### Example: ```typescript txn_receipt = await sdk.clusters.registerValidators({ args: { keyshares: keysharesPayload, - depositAmount: parseEther('30') + depositAmount: parseEther('0.1234') }, }).then(tx => tx.wait()) ``` ### `deposit()` -Executes the contract call to the SSV smart contract to deposit SSV to the cluster. - -Input: +Executes the contract call to to deposit ETH to the cluster balance. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| id | string | Cluster ID | ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc | -| amount | bigint | Amount of SSV to deposit to cluster | 4 | -| approve | bool | Whether to execute out the SSV ERC20 approve transaction or not | true | +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | +| amount | bigint | Amount of ETH to deposit to cluster | 0.1234 | -Example: +#### Example: ```typescript import { parseEther } from 'viem' txn_receipt = await sdk.clusters.deposit({ args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - amount: parseEther('30') + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + amount: parseEther('0.1234') }, - { - approve: true, // Automatically triggers token approval transaction if the allowance is lower than the deposit amount - }, }).then(tx => tx.wait()) ``` ### `liquidateCluster()` -Liquidates a cluster sends their balances to the msg.sender (the Liquidator), **will fail** if the cluster is not liquidatable. - -Input: +Liquidates a cluster sends their balance to the msg.sender (the Liquidator). **Will fail** if the cluster is not liquidatable. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| id | string | Cluster ID | ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc | +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | -Example: +#### Example: ```typescript txn_receipt = await sdk.clusters.liquidateCluster({ args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", }, }).then(tx => tx.wait()) ``` +### `liquidateSSV()` + +Liquidates a legacy (SSV-based) cluster sends their balance to the msg.sender (the Liquidator). **Will fail** if the cluster is not liquidatable. + +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | + +#### Example: + +```typescript +txn_receipt = await sdk.clusters.liquidateSSV({ + args: { + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + }, +}).then(tx => tx.wait()) +``` + + ### `withdraw()` -Withdraw a specified amount of SSV from a cluster. +Withdraw a specified amount of ETH from a cluster. -Input: +**Will fail** if: +- the amount to withdraw exceeds the current balance of a cluster; +- msg.sender is not the cluster owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| id | string | Cluster ID | ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc | -| amount | bigint | Amount of SSV to withdraw to cluster | 4 | +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | +| amount | bigint | Amount of ETH to withdraw from the cluster | 0.1234 | -Example: +#### Example: ```typescript import { parseEther } from 'viem' txn_receipt = await sdk.clusters.withdraw({ args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - amount: parseEther('30') + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + amount: parseEther('0.1234') }, }).then(tx => tx.wait()) ``` ### `reactivateCluster()` -Reactivates a liquidated cluster, **will fail** if insufficient SSV tokens to cover the cluster's liquidation collateral have been deposited. +Reactivates a liquidated cluster. -Input: +**Will fail** if: +- the ETH amount to deposit is insufficient to cover the cluster's liquidation collateral; +- msg.sender is not the cluster owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| id | string | Cluster ID | ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc | -| amount | bigint | Amount of SSV to withdraw to cluster | 4 | +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | +| amount | bigint | Amount of ETH to deposit to cluster | 0.1234 | -Example input: +#### Example: ```typescript import { parseEther } from 'viem' txn_receipt = await sdk.clusters.reactivateCluster({ args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - amount: parseEther('30') + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + amount: parseEther('0.1234') }, }).then(tx => tx.wait()) ``` ### `removeValidators()` -Accepts all parameters necessary to compute the keyshares, does this in the background using ssv-keys library, returns the keyshares as an object or saves it to file. +Accepts all parameters necessary to remove the validators. Removes all the validators provided as argument from the SSV network. -Input: +**Will fail** if: +- the provided validator keys are not registered to ssv network; +- msg.sender is not the cluster owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| id | string | Cluster ID | ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc | +| id | string | Cluster ID | 0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8 | | publicKeys | Hex[] | Array of validator public keys to remove | ["0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e86", "0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e87"] | -Example: +#### Example: ```typescript txn_receipt = await sdk.clusters.removeValidators({ args: { - id: "ee8881d3c979203025996773ef8a13cb4aac57076e22638dd6ed9b17adcdabfc", - depositAmount: ["0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e86", "0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e87"], + id: "0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8", + publicKeys: ["0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e86", "0x820fd0519c75f74c8be9f21f185406919721dad0c624464538e2eaa323d77d3eb3ef27a039e8779de6cfa649a5484e87"], }, }).then(tx => tx.wait()) ``` @@ -158,13 +192,11 @@ txn_receipt = await sdk.clusters.removeValidators({ Sets a fee recipient address to receive tips from user transactions (part block proposal rewards). This address will be set for all the account's validators (all clusters). -Input: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | recipient | Address | Valid Ethereum address | 0xA4831B989972605A62141a667578d742927Cbef9 | -Example: +#### Example: ```typescript txn_receipt = await sdk.clusters.setFeeRecipient({ @@ -178,14 +210,16 @@ txn_receipt = await sdk.clusters.setFeeRecipient({ Prompts SSV nodes to sign a voluntary exit of the validator. -Input: +**Will fail** if: +- the provided validator keys are not registered to ssv network; +- msg.sender is not the cluster owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| publicKeys | Hex[] | Public keys of the validators to be exited | ["0xA4831B989972605A62141a667578d742927Cbef9","0xA4831B989972605A62141a667578d742927Cbef8"] | +| publicKeys | Hex[] | Array of public keys of the validators to be exited | ["0xA4831B989972605A62141a667578d742927Cbef9","0xA4831B989972605A62141a667578d742927Cbef8"] | | operatorIds | bigint[] | IDs of the operators | [1,2,3,4] | -Example input: +#### Example: ```typescript txn_receipt = await sdk.clusters.exitValidators({ @@ -198,21 +232,19 @@ txn_receipt = await sdk.clusters.exitValidators({ ### `validateSharesPostRegistration()` -Accepts a transaction hash of the validator registration contract call. - -Input: +Accepts a transaction hash of the validator registration contract call. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | txHash | Hex | Hash of the register validator transaction | "0xd9095893dba18b101c01973069922db2d81c45e814003851ccc586d60ae28e5b" | -Example input: +#### Example: ```typescript -const result = await validateSharesPostRegistration( { txHash: '0x123' as Hex }) +const result = await sdk.clusters.validateSharesPostRegistration( { txHash: '0x123' as Hex }) ``` -Example output: +Output: ```typescript { diff --git a/docs/developers/SSV-SDK/module-reference/operator-module.md b/docs/developers/SSV-SDK/module-reference/operator-module.md index ed1ed5a..ec8a6d4 100644 --- a/docs/developers/SSV-SDK/module-reference/operator-module.md +++ b/docs/developers/SSV-SDK/module-reference/operator-module.md @@ -5,7 +5,7 @@ sidebar_position: 2 # Operator Module -This is a library which contains all the helper functions you need for working with operators on SSV. +This is a library which contains all the helper functions you need for working with operators on SSV network. After instantiating the SDK, you can call any of the functions in the utils library like so: @@ -19,22 +19,22 @@ sdk.operators.registerOperator() Accepts a list of addresses, fetches their nonces using subgraph, returns as a list. -Input parameters: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | isPrivate | bool | true/false flag of whether the operator is private | true | -| yearlyFee | bigint | The operator public key (generated as part of the node setup) | 2000000000000000 | -| publicKey | string | The operator public key (generated as part of the node setup) | "0xA4831B989972605A62141a667578d742927Cbef9" | +| yearlyFee | bigint | Operator yearly fee specified in ETH | 0.1234 | +| publicKey | string | The operator public key (generated as part of the node setup) | "LS0tLS1CRUdJTiBSU0EgUFVCTElDIE..." | -Example: +#### Example: ```typescript +import { parseEther } from 'viem' + const receipt = await sdk.operators .registerOperator({ args: { publicKey: "LS0tLS1CRUdJTiBSU0EgUFVCTElDIE..." - yearlyFee: 100000000000000, + yearlyFee: parseEther('0.1234') isPrivate: true, }, }) @@ -43,15 +43,14 @@ const receipt = await sdk.operators ### `removeOperator()` -Permanently removes the operator from the network (irreversible). +Permanently removes the operator from the network (irreversible). **Will fail if** msg.sender is not the operator owner. -Input parameters: | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | bigint | Operator id | 4 | -Example: +#### Example: ```typescript const receipt = await sdk.operators @@ -65,23 +64,83 @@ const receipt = await sdk.operators ### `withdraw()` -Withdraws an amount of SSV from a specified operator. +Withdraws an amount of ETH from a specified operator. **Will fail if** msg.sender is not the operator owner. + +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| operatorId | string | Operator id | 4 | +| amount | bigint | Withdraws a specified amount of ETH earnings from provided operator balance to msg.sender | 0.1234 | + +#### Example: + +```typescript +import { parseEther } from 'viem' + +const receipt = await sdk.operators.withdraw({ + args: { + operatorId: "4", + amount: parseEther('0.1234'), + }, + }) +.then((tx) => tx.wait()) +``` + +### `withdrawOperatorEarningsSSV()` -Input parameters: +Withdraws an amount of SSV from a specified operator. **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | string | Operator id | 4 | -| amount | bigint | Withdraws all SSV tokens earnings from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner | 1231231231311231 | +| amount | bigint | Withdraws a specified amount of SSV tokens earnings from provided operator balance to msg.sender | 30 | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .withdraw({ +import { parseEther } from 'viem' + +const receipt = await sdk.operators.withdrawOperatorEarningsSSV({ + args: { + operatorId: "4", + amount: parseEther('30'), + }, + }) +.then((tx) => tx.wait()) +``` + +### `withdrawAllOperatorEarningsSSV()` + +Withdraws all of the available SSV from a specified operator's balance. **Will fail if** msg.sender is not the operator owner. + +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| operatorId | string | Operator id | 4 | + +#### Example: + +```typescript +const receipt = await sdk.operators.withdrawAllOperatorEarningsSSV({ + args: { + operatorId: "4", + }, + }) +.then((tx) => tx.wait()) +``` + +### `withdrawAllVersionOperatorEarnings()` + +Withdraws all available SSV tokens *and* ETH from specified operators' balances. **Will fail if** msg.sender is not the operator owner. + +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| operatorId | string | Operator id | 4 | + +#### Example: + +```typescript +const receipt = await sdk.operators.withdrawAllVersionOperatorEarnings({ args: { operatorId: "4", - amount: 1231231231311231, }, }) .then((tx) => tx.wait()) @@ -91,18 +150,15 @@ const receipt = await sdk.operators For a list of operators provided, set a list of whitelisted addresses which can register validators to these operators. -Input parameters: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | -| whitelisted | Hex[] | A list of ETH1 addresses to be whitelisted | ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | +| whitelisted | Hex[] | Array of ETH1 addresses to be whitelisted | ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"] | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .setOperatorWhitelists({ +const receipt = await sdk.operators.setOperatorWhitelists({ args: { operatorId: [1,2,3,4], whitelisted: ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"], @@ -113,20 +169,17 @@ const receipt = await sdk.operators ### `removeOperatorWhitelists()` -For a list of operators provided, remove a list of whitelisted addresses. - -Input parameters: +For a list of operators provided, remove a list of whitelisted addresses. **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | -| whitelisted | Hex[] | A list of ETH1 addresses to be removed from the whitelist | ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | +| whitelisted | Hex[] | Array of ETH1 addresses to be removed from the whitelist | ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"] | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .removeOperatorWhitelists({ +const receipt = await sdk.operators.removeOperatorWhitelists({ args: { operatorId: [1,2,3,4], whitelisted: ["0xA4831B989972605A62141a667578d742927Cbef9", "0xA4831B989972605A62141a667578d742927Cbef8"], @@ -137,19 +190,16 @@ const receipt = await sdk.operators ### `setOperatorsPrivate()` -For a list of operators provided, set their status to private. - -Input parameters: +For a list of operators provided, set their status to private. **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .setOperatorsPrivate({ +const receipt = await sdk.operators.setOperatorsPrivate({ args: { operatorId: [1,2,3,4], }, @@ -159,19 +209,16 @@ const receipt = await sdk.operators ### `setOperatorsPublic()` -For a list of operators provided, set their status to public. - -Input parameters: +For a list of operators provided, set their status to public. **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .setOperatorsPublic({ +const receipt = await sdk.operators.setOperatorsPublic({ args: { operatorId: [1,2,3,4], }, @@ -181,20 +228,17 @@ const receipt = await sdk.operators ### `setOperatorWhitelistingContract()` -For a list of operators provided, set an external whitelisting contract to manage the whitelist for these operators. [Must be a valid whitelisting contract.](https://docs.ssv.network/developers/smart-contracts/external-whitelist-contract-example) - -Input parameters: +For a list of operators provided, set an external whitelisting contract to manage the whitelist for these operators. [Must be a valid whitelisting contract.](https://docs.ssv.network/developers/smart-contracts/external-whitelist-contract-example). **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | | whitelistingContract | string | A valid whitelisting contract address | "0xA4831B989972605A62141a667578d742927Cbef9" | -Example: +#### Example: ```typescript -const receipt = await sdk.operators - .setOperatorWhitelistingContract({ +const receipt = await sdk.operators.setOperatorWhitelistingContract({ args: { operatorId: [1,2,3,4], whitelistingContract: "0xA4831B989972605A62141a667578d742927Cbef9", @@ -205,15 +249,13 @@ const receipt = await sdk.operators ### `removeOperatorWhitelistingContract()` -For a list of operators provided, remove the whitelisting contract stored. - -Input parameters: +For a list of operators provided, remove the whitelisting contract stored. **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| -| operatorId | bigint[] | Operator id array | [1,2,3,4] | +| operatorId | bigint[] | Array of operator ID(s) | [1,2,3,4] | -Example: +#### Example: ```typescript const receipt = await sdk.operators @@ -227,23 +269,23 @@ const receipt = await sdk.operators #### `declareOperatorFee()` -Initiates the first step of the operator fee update cycle - declaration of a new fee. [After specified](https://docs.ssv.network/developers/smart-contracts/ssvnetworkviews#getoperatorfeeperiods) time window operator will be able to change to the new fee with executeOperatorFee(). - -Input parameters: +Initiates the first step of the operator fee update cycle - declaration of a new fee. [After specified](https://docs.ssv.network/developers/smart-contracts/ssvnetworkviews#getoperatorfeeperiods) time window operator will be able to change to the new fee with executeOperatorFee(). **Will fail if** msg.sender is not the operator owner. | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | bigint | Operator id | 4 | -| operatorFee | bigint | New fee (denominated as $SSV tokens per block). ***Amount must be shrinkable (divisible by 10000000)*** | 100000000 | +| fee | bigint | New fee (denominated as ETH per block). ***Amount must be shrinkable (divisible by 10000000)***, for simplicity we use `parseEther` | 0.1234 | -Example: +#### Example: ```typescript +import { parseEther } from 'viem' + const receipt = await sdk.operators .declareOperatorFee({ args: { operatorId: 4, - operatorFee: 100000000, + fee: parseEther('0.1234'), }, }) .then((tx) => tx.wait()) @@ -253,13 +295,11 @@ const receipt = await sdk.operators Activates operator's fee change specified in previously called declareOperatorFee(). This function needs to be called within a [certain time window](https://docs.ssv.network/developers/smart-contracts/ssvnetworkviews#getoperatorfeeperiods) following declareOperatorFee(). -Input parameters: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | bigint | Operator id | 4 | -Example: +#### Example: ```typescript const receipt = await sdk.operators @@ -275,13 +315,11 @@ const receipt = await sdk.operators Cancels operator's fee change requested in previously called declareOperatorFee(). -Input parameters: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | bigint | Operator id | 4 | -Example: +#### Example: ```typescript const receipt = await sdk.operators @@ -297,21 +335,21 @@ const receipt = await sdk.operators Reduce the operator fee, does not abide by the restrictions of fee increase. -Input parameters: - | Input parameter | Input type | Description | Example input | |----------------|------------|-------------|---------------| | operatorId | bigint | Operator id | 4 | -| fee | bigint | New fee (denominated as $SSV tokens per block). ***Amount must be shrinkable (divisible by 10000000)*** | 100000000 | +| fee | bigint | New fee (denominated as ETH per block). ***Amount must be shrinkable (divisible by 10000000)***, for simplicity we use `parseEther` | 0.1234 | -Example: +#### Example: ```typescript +import { parseEther } from 'viem' + const receipt = await sdk.operators .reduceOperatorFee({ args: { operatorId: 4, - fee: 100000000, + fee: parseEther('0.1234'), }, }) .then((tx) => tx.wait()) diff --git a/docs/developers/SSV-SDK/module-reference/utils-module.md b/docs/developers/SSV-SDK/module-reference/utils-module.md index cff2224..a62cf94 100644 --- a/docs/developers/SSV-SDK/module-reference/utils-module.md +++ b/docs/developers/SSV-SDK/module-reference/utils-module.md @@ -14,11 +14,16 @@ sdk.utils.generateKeyShares() Accepts all parameters necessary to compute the keyshares, does this in the background using ssv-keys library, returns the keyshares as an object or saves it to file. -Input: +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| operator_keys | string[] | Array of operator public keys to register the validator to | ["LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi..."] | +| operator_ids | integer[] | Array of operator IDs to register the validator to. | [12, 34, 56, 78] | +| keystore | string | Validator keystore file created when generating the validator. Passed as object programmatically or file path. | β€˜./path-to-keystore.json' | +| keystore_password | string | Password for the attached keystore file. | '1234' | +| owner_address | string | Address of the validator Owner. | '0x81592c3de184a3e2c0dcb5a261bc107bfa91f494' | +| nonce | bigint | Nonce of the owner address | 24 | -
Input parameterInput typeDescriptionExample input
operator_keys[]stringList of operator public keys to register the validator to.["LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi...", "LS0tLS1CRUdJTi..."]
operator_ids[]integerList of operator IDs to register the validator to.[12, 34, 56, 78]
keystorestringValidator keystore file created when generating the validator. Passed as object programmatically or file path.β€˜./path-to-keystore.json'
keystore_passwordstringPassword for the attached keystore file.β€˜123’
owner_addressstringAddress of the validator Owner.'0x81592c3de184a3e2c0dcb5a261bc107bfa91f494'
noncebigintNonce of the owner address24
- -Example: +#### Example: ```typescript const ownerAddress = "0xA4831B989972605A62141a667578d742927Cbef9" @@ -46,22 +51,22 @@ Example output: ### `validateKeysharesJSON()` -Checks a JSON file of keyshares and returns whether it is valid or not. +Checks a JSON file of keyshares and returns whether it is valid or not. -
Input ParameterInput Type Description Example Input
operators'id[]' | 'publicKey[]'Array of operator ids or public keysOperatorArrayObject
keysharesstring | objectGenerated keysharesKeyshares json file
+| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| account | string | Owner address of the validators in keyshares | 0x012f55B6Cc5D57F943F1E79cF00214B652513f88 | +| operators | 'id[]' OR 'publicKey[]' | Array of operator ids or public keys | ['1','2','3','4'] | +| keyshares | string OR object | Generated keyshares | Keyshares json file | -Example: -```typescript -const operatorObjectArray = [{ - publicKey: string - id: string -}] +#### Example: -await sdk.utils.validateKeysharesJSON({ +```typescript +const validatedShares = await sdk.utils.validateKeysharesJSON({ account: '0x012f55B6Cc5D57F943F1E79cF00214B652513f88', - operators: operatorObjectArray, - keyshares: keyshareFile, + operators: ['1','2','3','4'], + keyshares: keysharesJsonFile, }); ``` @@ -98,16 +103,20 @@ Example output: ### `validateSharesPreRegistration()` -Checks keyshares json file and returns whether it is valid or not. +Checks keyshares json file and returns whether it is valid or not. -
Input ParameterInput Type Description Example Input
operatorIds'id[]' | 'publicKey[]'Array of operator ids or public keys['1','2','3','4']
keysharesstring | objectGenerated keysharesKeyshares json file
+| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| operatorIds | string[] | Array of operator ids | ['1','2','3','4'] | +| keyshares | string OR object | Generated keyshares | Keyshares json file | -Example: + +#### Example: ```typescript const validatedShares = await sdk.utils.validateSharesPreRegistration({ + operatorIds: ['1','2','3','4'], keyshares: keysharesJsonFile, - operatorIds: ['242','686','707','736'], }); ``` @@ -144,14 +153,16 @@ Example output: ### `getOperatorCapacity()` -Checks how many validators an operator has registered, compares it with the maximum amount of validators that can be registered, and returns the amount that can be registered. +Checks how many validators an operator has registered, compares it with the maximum amount of validators that can be registered, and returns the amount that can be registered. -
Input ParameterInput Type Description Example Input
idstringOperator ID"1"
+| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| id | string | Operator ID | "1” | -Example: +#### Example: ```typescript -const result = await getOperatorCapacity('1') +const result = await sdk.utils.getOperatorCapacity('1') ``` Example output: @@ -162,21 +173,53 @@ Example output: ### `getClusterBalance()` -Returns the[ balance of a cluster](/stakers/clusters/cluster-balance). +Accepts a cluster ID to identify the cluster, for which the balance needs to be fetched. Returns the[ balance of a cluster](/stakers/clusters/cluster-balance). -
Input ParameterInput Type Description Example Input
operatorIdsnumber[]Operator ID array[1,2,3,4]
+| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| cluster_Id | string | A cluster_id in its computed ID form. | β€œ0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8” | -Example: +#### Example: ```typescript -const result = await getClusterBalance([1,2,3,4]) +const result = await sdk.utils.getClusterBalance(β€œ0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8”) ``` Example output: ```typescript { - balance: 1728318231823, // ssv in wei + balance: 1728318231823, // ETH in gwei operationalRunway: 123, // days left in cluster runway } ``` + +### `calcDepositFromRunway()` + +Accepts a string, and a number. Calculates the ETH needed to be deposited, in order to achieve the specified cluster runway. Returns a success message or relevant error. + +The function fetches the cluster snapshot using the provided ID, calculate the Burn Rate of the cluster, and reverse [the Operational Runway formula](https://docs.ssv.network/stakers/clusters/cluster-balance/#operational-runway) , to explicit the needed Cluster Balance to obtain the specified Runway. + +| Input parameter | Input type | Description | Example input | +|----------------|------------|-------------|---------------| +| cluster_Id | string | A cluster_id in its computed ID form. | β€œ0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8” | +| runway | number | Desired Runway length, measured in number of days. | 45 | + + +#### Example: + +```typescript +const result = await sdk.utils.calcDepositFromRunway({ + cluster_Id: β€œ0xf69A08B652f0CEBb685c2fFE043cfB767b66544A-5-6-7-8”, + runway: 45, + }); +``` + +Example output: + +```typescript +{ + 1728318231823, // ETH in gwei +} +``` + diff --git a/docs/developers/code-examples-and-snippets/README.md b/docs/developers/code-examples-and-snippets/README.md index 79f0af3..0d1337a 100644 --- a/docs/developers/code-examples-and-snippets/README.md +++ b/docs/developers/code-examples-and-snippets/README.md @@ -1,6 +1,7 @@ --- sidebar_label: 'Code examples and snippets' sidebar_position: 6 +unlisted: true --- # Code examples and snippets diff --git a/docs/developers/code-examples-and-snippets/cluster-balance-script.md b/docs/developers/code-examples-and-snippets/cluster-balance-script.md deleted file mode 100644 index b98830b..0000000 --- a/docs/developers/code-examples-and-snippets/cluster-balance-script.md +++ /dev/null @@ -1,352 +0,0 @@ -# Automated Cluster Balance Monitoring - -This script automatically monitors the balance of multiple clusters on the SSV network at regular intervals. It calculates the current balance of each cluster by: - -* Querying the subgraph for the relevant data (see the [Subgraph Examples](../tools/ssv-subgraph/subgraph-examples) page for more information) -* Using these values to compute the current cluster balance for each specified cluster, outputting the amount in SSV - -Details on the formulas used can be found in the documentation page related to [Cluster Balance](../../stakers/clusters/cluster-balance). - -## Cluster Balance Calculation - -The core calculation function that computes the cluster balance: - -```typescript -function calculateClusterBalance(responseData: GraphQLResponse, clusterName: string): ClusterCalculationResult | null { - - // Network Fee Calculation - const networkFee = - parseInt(responseData.data.daovalues.networkFeeIndex) + - (responseData.data._meta.block.number - - parseInt(responseData.data.daovalues.networkFeeIndexBlockNumber)) * - parseInt(responseData.data.daovalues.networkFee) - - responseData.data.cluster.networkFeeIndex * 10000000; - - // Operator Fee Calculation - let operatorFee = -responseData.data.cluster.index * 10000000; - for (let operator of responseData.data.operators) { - operatorFee += - parseInt(operator.feeIndex) + - (responseData.data._meta.block.number - - parseInt(operator.feeIndexBlockNumber)) * - parseInt(operator.fee); - } - - // Cluster Balance Calculation - const clusterBalance = - responseData.data.cluster.balance - - (networkFee + operatorFee) * responseData.data.cluster.validatorCount; - - return { - networkFee, - operatorFee, - clusterBalance, - validatorCount: responseData.data.cluster.validatorCount, - }; -} -``` - -## Full Script - -```typescript -import fetch from "node-fetch"; -import fs from "fs"; -import path from "path"; -import { fileURLToPath } from "url"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); - -interface ClusterConfig { - name: string; - accountAddress: string; - operatorIds: string[]; - clusterId: string; -} - -interface Config { - intervalSeconds: number; - graphqlUrl: string; - subgraphApiKey: string; - clusters: ClusterConfig[]; -} - -let monitoring = true; - -function loadConfig(): Config { - const configPath = path.join(__dirname, "config.json"); - const configData = fs.readFileSync(configPath, "utf-8"); - return JSON.parse(configData); -} - -function buildQuery(cluster: ClusterConfig): string { - const operatorIdsJson = JSON.stringify(cluster.operatorIds); - - return `{ - _meta { - block { - number - } - } - daovalues(id: "${cluster.accountAddress}") { - networkFee - networkFeeIndex - networkFeeIndexBlockNumber - } - operators(where: {id_in: ${operatorIdsJson}}) { - fee - feeIndex - feeIndexBlockNumber - } - cluster(id: "${cluster.clusterId}") { - validatorCount - networkFeeIndex - index - balance - } -}`; -} - -async function fetchClusterData(url: string, query: string, apiKey: string) { - const headers: Record = { - "Content-Type": "application/json", - }; - - if (apiKey) { - headers["Authorization"] = `Bearer ${apiKey}`; - } - - const response = await fetch(url, { - method: "POST", - headers, - body: JSON.stringify({ query }), - }); - - return await response.json(); -} - -function calculateClusterBalance(responseData: any, cluster: ClusterConfig) { - if (responseData.errors) { - console.error(`[${cluster.name}] GraphQL errors:`, responseData.errors); - return null; - } - - if (!responseData.data) { - console.error(`[${cluster.name}] No data in response`); - return null; - } - - if (!responseData.data.daovalues) { - console.error(`[${cluster.name}] daovalues is null`); - return null; - } - - if (!responseData.data.cluster) { - console.error(`[${cluster.name}] cluster is null`); - return null; - } - - if (!responseData.data.operators || responseData.data.operators.length === 0) { - console.error(`[${cluster.name}] operators is null or empty`); - return null; - } - - const networkFee = - parseInt(responseData.data.daovalues.networkFeeIndex) + - (responseData.data._meta.block.number - - parseInt(responseData.data.daovalues.networkFeeIndexBlockNumber)) * - parseInt(responseData.data.daovalues.networkFee) - - responseData.data.cluster.networkFeeIndex * 10000000; - - let operatorFee = -responseData.data.cluster.index * 10000000; - - for (let operator of responseData.data.operators) { - operatorFee += - parseInt(operator.feeIndex) + - (responseData.data._meta.block.number - - parseInt(operator.feeIndexBlockNumber)) * - parseInt(operator.fee); - } - - const clusterBalance = - responseData.data.cluster.balance - - (networkFee + operatorFee) * responseData.data.cluster.validatorCount; - - return { - networkFee, - operatorFee, - clusterBalance, - validatorCount: responseData.data.cluster.validatorCount, - }; -} - -async function monitorClusters() { - const config = loadConfig(); - const timestamp = new Date().toISOString(); - - console.log(`\n${"=".repeat(60)}`); - console.log(`Monitoring at ${timestamp}`); - console.log(`${"=".repeat(60)}\n`); - - for (const cluster of config.clusters) { - try { - const query = buildQuery(cluster); - const responseData = await fetchClusterData(config.graphqlUrl, query, config.subgraphApiKey); - const result = calculateClusterBalance(responseData, cluster); - - if (result) { - console.log(`[${cluster.name}]`); - console.log(` Validators: ${result.validatorCount}`); - console.log(` Network Fee: ${result.networkFee}`); - console.log(` Operator Fee: ${result.operatorFee}`); - console.log(` Cluster Balance: ${result.clusterBalance}`); - console.log(); - } - } catch (error) { - console.error(`[${cluster.name}] Error fetching data:`, error); - } - } -} - -async function startMonitoring() { - const config = loadConfig(); - - console.log(`Starting cluster monitoring...`); - console.log(`Interval: ${config.intervalSeconds} seconds`); - console.log(`Clusters to monitor: ${config.clusters.length}`); - console.log(`Press Ctrl+C to stop\n`); - - await monitorClusters(); - - const intervalId = setInterval(async () => { - if (!monitoring) { - clearInterval(intervalId); - return; - } - - await monitorClusters(); - }, config.intervalSeconds * 1000); - - process.on("SIGINT", () => { - console.log("\n\nStopping monitoring..."); - monitoring = false; - clearInterval(intervalId); - process.exit(0); - }); -} - -startMonitoring(); -``` - -## Configuration File - -Create a `config.json` file in the same directory as your script with the following structure: - -```json -{ - "intervalSeconds": 10, - "graphqlUrl": "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest", - "subgraphApiKey": "YOUR_SUBGRAPH_API_KEY_HERE", - "clusters": [ - { - "name": "Cluster 1", - "accountAddress": "0x58410Bef803ECd7E63B23664C586A6DB72DAf59c", - "operatorIds": ["108", "111", "173", "180"], - "clusterId": "0x0577a0d29662e048aab8d4ff3e8883a10b67a489-108-111-173-180" - }, - { - "name": "Cluster 2", - "accountAddress": "0x58410Bef803ECd7E63B23664C586A6DB72DAf59c", - "operatorIds": ["108", "111", "173", "180"], - "clusterId": "0x0577a0d29662e048aab8d4ff3e8883a10b67a489-108-111-173-180" - } - ] -} -``` - -## Prerequisites - -* [_Node.js_](https://nodejs.org/en) must be installed on the system - -## How to Run - -1. Create a file called `monitor-clusters.js` -2. Copy the script code above into this file -3. Create a `config.json` file in the same directory with your cluster configuration (see example above) -4. Install the required dependencies: - - ```bash - npm i node-fetch - ``` - -5. Run the script with node: - - ```bash - node monitor-clusters.js - ``` - -6. The script will continuously monitor your clusters at the interval specified in `config.json`. Press `Ctrl+C` to stop monitoring. - -## Example Output - -When you run the script, you'll see output similar to the following: - -```bash -$ node monitor-clusters.ts - -Starting cluster monitoring... -Interval: 10 seconds -Clusters to monitor: 2 -Press Ctrl+C to stop - -============================================================ -Monitoring at 2025-11-06T16:13:06.689Z -============================================================ - -[Cluster 1] - Validators: 1 - Network Fee: 5364995440000000 - Operator Fee: 30902704629999870 - Cluster Balance: 29963732299930000000 - -[Cluster 2] - Validators: 1 - Network Fee: 5364995440000000 - Operator Fee: 30902704629999870 - Cluster Balance: 29963732299930000000 - -============================================================ -Monitoring at 2025-11-06T16:13:17.642Z -============================================================ - -[Cluster 1] - Validators: 1 - Network Fee: 5365378080000000 - Operator Fee: 30904908659999360 - Cluster Balance: 29963729713260000000 - -[Cluster 2] - Validators: 1 - Network Fee: 5365378080000000 - Operator Fee: 30904908659999360 - Cluster Balance: 29963729713260000000 -``` - -:::info -If you get a warning, or an error similar to this: - -``` -(node:232985) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. -``` - -Just make sure to edit the `package.json` file and add a line with `"type": "module"` to it, like in the example below: - -```json -{ - "dependencies": { - "node-fetch": "^3.3.2" - }, - "type": "module" -} -``` -::: diff --git a/docs/developers/integration-guides/lido-csm.md b/docs/developers/integration-guides/lido-csm.md index df0f3a0..3cedae1 100644 --- a/docs/developers/integration-guides/lido-csm.md +++ b/docs/developers/integration-guides/lido-csm.md @@ -29,7 +29,7 @@ These two conditions are necessary and cannot be omitted. Changing the fee recipient on SSV applies to **all validators owned by an account**. So if you have registered CSM validators in the past, or intend to register validators that will not be part of CSM in the future, please utilize a different account, or you will be effectively **donating the execution rewards to Lido** instead of keeping them for yourself. -### Prerequisites +### Prerequisites * Over 2 ETH for CSM bonding and gas for transactions. * SSV tokens when registering your validator to the network @@ -59,7 +59,7 @@ To register your validator with SSV you can follow [the related guide in this do You can move onto the next step once your validator is registered to a cluster as shown below. -### 3. Set the Fee Recipient +### 3. Set the Fee Recipient As mentioned at the top of this guide, a requirement from Lido for all the validators registered to the CSM is that the fee recipient is set to the Lido Execution Layer Rewards Vault. @@ -77,7 +77,7 @@ In the following screen, set the address to this value: Enter the address, click update, and sign the transaction with your wallet. -### 4. Deposit bond on Lido CSM +### 4. Deposit bond on Lido CSM The following, and final step is to deposit the 2 ETH bond to Lido along with the validator deposit data to add the validator to the activation queue. Lido will deposit the 32 ETH needed for the activation to happen. @@ -104,4 +104,4 @@ To check your validator you can use this link, making sure to swap ` ``` -Once the validator has been activated, the SSV operators you have chosen in step two will handle the validator duties for you. +Once the validator has been activated, the SSV operators you have chosen in step two will handle the validator duties for you. diff --git a/docs/developers/integration-guides/staking-services.md b/docs/developers/integration-guides/staking-services.md index 80dc5bc..714cfd4 100644 --- a/docs/developers/integration-guides/staking-services.md +++ b/docs/developers/integration-guides/staking-services.md @@ -62,8 +62,8 @@ Required\,Funding =( O1fee+O2_{fee}+ O3_{fee} + O4_{fee}+N_{fee})*LTP + (N_{fee Legend: ``` -* $$O1...4_{fee}$$ - operator fee ($SSV per block) -* $$N_{fee}$$ - [network fee] ($SSV per block)​ +* $$O1...4_{fee}$$ - operator fee (SSV per block) +* $$N_{fee}$$ - [network fee] (SSV per block)​ * $$Period$$ - operation period (blocks) * $$LTP$$ - [liquidation threshold period] ``` @@ -82,7 +82,7 @@ To manage account balance, the staking service can deposit or withdraw funds fro * [Deposit] * [Withdraw] -#### Validator Management +#### Validator Management Validators are fully customizable in the ssv.network, giving service providers more flexibility and control over their operations. Having the ability to update the operator group managing your validators can be useful when you want to spin up an additional operator or use another operator’s services. Additionally, being able to offboard a validator can help if one of your users wants to stop their validator operation or migrate to a different service. diff --git a/docs/developers/quickstart.md b/docs/developers/quickstart.md deleted file mode 100644 index 66dc718..0000000 --- a/docs/developers/quickstart.md +++ /dev/null @@ -1,425 +0,0 @@ ---- -description: Quickstart -sidebar_label: 'Quickstart' -sidebar_position: 2 ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -# Quickstart -This page shows how to register any amount of validators to the SSV network. - -:::note Prerequisite -This tutorial assumes you already have keystores generated, or will use the [*code illustrated here*](/developers/SSV-SDK/examples/create-validator-keys.md) to generate them pragmatically. -::: - - -### Overview - -![Get Started](/img/get-started-2.avif) - -Bulk registration flow is roughly outlined in the schema above. - -**Below are the actual steps you will need to take:** -1. [Installation](#1-installation) -2. [Select operators and collect their data](#2-select-operators-and-collect-their-data) -3. [Split your validator keys to shares](#3-split-validator-keys) -4. [Register your validators to the SSV network](#4-register-validators) - -There is also [Full code example](#full-code-example) by the end of this page. - -### **1. Installation** - -#### Install -```bash -npm i @ssv-labs/ssv-sdk fs path web3 viem -``` - -#### Import - -```typescript -import { SSVSDK, chains } from '@ssv-labs/ssv-sdk' -import { parseEther, createPublicClient, createWalletClient, http } from 'viem' -import { privateKeyToAccount } from 'viem/accounts' -``` - -#### Instantiation - -To instantiate the SDK, provide a number of parameters: - -| Parameter | Description | -| --------------- | --------------------------------------- | -| `public_client` | Public client object created using viem | -| `wallet_client` | Wallet object created using viem | - -You can use these like so to instantiate the SDK and store it an object: - -```typescript -// Setup viem clients -const chain = chains.hoodi as any // or chains.mainnet -const transport = http() - -const publicClient = createPublicClient({ - chain, - transport, -}) as any - -const account = privateKeyToAccount('0x...') -const walletClient = createWalletClient({ - account, - chain, - transport, -}) as any - -// Initialize SDK with viem clients -const sdk = new SSVSDK({ - publicClient, - walletClient, -}) -``` - -### **2. Select operators and collect their data** -A cluster can have 4, 7, 10, or 13 operators β€” the bigger your cluster, the higher yearly fee, and the more reliable your validator operations. - -If you already know the operator IDs you can proceed to any of the 3 options below to get their data. - -If you need to choose operators, feel free to browse [SSV Explorer](https://explorer.ssv.network/operators) to find the operators you will add to your cluster. Then proceed to the steps below. Please note, some of the operators are Private and only allow specific whitelisted addresses to onboard validators to them. - - - - To generate keyshares, operator IDs and their public keys are needed. You can collect keys of each operator using [SSV Subgraph](/developers/tools/ssv-subgraph). You will need to create own Graph API key and use endpoint with it. - - Alternatively, you can do it using [The Graph UI](https://thegraph.com/explorer/subgraphs/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh?view=Query&chain=arbitrum-one). - - An example of how Hoodi Subgraph can fetch the operator data is below. The code snippet considers you have environment variables (`SUBGRAPH_API_KEY` and `OPERATOR_IDS`) in an `.env` file: - ```typescript - const operatorIDs = JSON.parse(process.env.OPERATOR_IDS) - const url = "https://gateway.thegraph.com/api/subgraphs/id/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh"; - const query = ` - query ValidatorData($operatorIDs: [Bytes!]) { - operators(where: {id_in: $operatorIDs}) { - id - publicKey - } - }` - - const variables = { operatorIDs: operatorIDs } - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${process.env.SUBGRAPH_API_KEY}` - }, - body: JSON.stringify({ query, variables }) - }); - - const responseData: any = await response.json(); - const web3 = new Web3(); - const operators: { id: string; publicKey: string }[] = responseData.data.operators.map((operator: any) => {return { - id: operator.id, - publicKey: web3.eth.abi.decodeParameter("string", operator.publicKey) - }}) - ``` - - - To generate keyshares, operator IDs and their public keys are needed. This can also be done with [SSV Explorer](https://explorer.ssv.network/operators). - - On each operator's page, there is a πŸ—οΈ sign next to operator's name. Click on the key sign and their public key will be copied. Repeat the process for each operator you chose. - - - Operator public key can be collected using our API once you know the ID. Use [this request type](https://api.ssv.network/documentation/#/Operators/OperatorsV4Controller_getOperator) to get the data. You only need to set the network and operator ID. - -```bash -curl -X 'GET' \ - 'https://api.ssv.network/api/v4/hoodi/operators/1' \ - -H 'accept: */*' -``` - -From the response you will need `id` and `public_key` contents: -```json -{ - "id": 1, - "id_str": "1", - "declared_fee": "0", - "previous_fee": "0", - "fee": "382640000000", - "public_key": "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBeVpGNUR2M2UwSkEzT25TSGwyQmMKNGFxbmpUTWFrUXNZSkY5eE55M21CVTZSQld1d2xVd1dIelJGWUFvb0FlRER3NlYxL3hRQ0JFaWJwTGx1RVdLTgoxNmRpcU5EVmY5VEZndmZlM2NHc3pNcDZCUE04bWhBdkx0c01DcHlXeDZtTEczVm0zVVRNK3hRdUJwVFZsdHNNCkV6eUZEZzNWTlphOW9hZkswbkVYRHVidlBIbkJCdWhlUW5LZThoUkJnRUo0emIrV3dncjFrM3YyWmkwTEtWNUQKYWd3c2QxK25Lb1grVktjYmJFVFBEdGRPV1AvZlpXM3dBMGp3R1pSdkhwNS8xUjBmZy91N01BUk1KTkRWVFYxQwo0Vlh1eHJkbHZWQ2JiS1pnWUIzY1ROSEMzZkVldit0NFVEeFJuQzdUcUN0WFZSYnpZQ001WHVSeUFRa3BiYU0wCjlRSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K", - "owner_address": "0x3187a42658417a4d60866163A4534Ce00D40C0C8", - "address_whitelist": "0x5E33db0b37622F7E6b2f0654aA7B985D854EA9Cb", - "whitelist_addresses": [ - "0x5E33db0b37622F7E6b2f0654aA7B985D854EA9Cb" - ], - "is_private": true, - "whitelisting_contract": "", - "location": "United States of America", - "setup_provider": "AWS", - "eth1_node_client": "Geth", - "eth2_node_client": "Prysm", - "mev_relays": "", - "description": "", - "website_url": "", - "twitter_url": "", - "linkedin_url": "", - "dkg_address": "", - "logo": "https://media-v2.ssv.network/operator_1_v4_mainnet_ssvBlack.png", - "type": "operator", - "name": "SSV Labs", - "performance": { - "24h": 100, - "30d": 99.86798961841079 - }, - "is_valid": true, - "is_deleted": false, - "is_active": 1, - "status": "Active", - "validators_count": 143, - "version": "v4", - "network": "mainnet" -} -``` - - - -Pass the collected operator info into ```generateKeyShares``` function in the code below. - -### **3. Split validator keys** -Use the collected data and your keystore to generate the keyshare transaction payload. - -The code snippet below considers you have environment variables (`KEYSTORE_PASSWORD` and `OWNER_ADDRESS`) in an `.env` file. Also, `nonce` is being handled automatically in the [full code example](#full-code-example): - -```typescript -const keysharesPayload = await sdk.utils.generateKeyShares({ - keystore: keystoreValues, - keystore_password: process.env.KEYSTORE_PASSWORD, - operator_keys: operators.map((operator: { id: string; publicKey: string }) => operator.publicKey), - operator_ids: operators.map((operator: { id: string; publicKey: string }) => Number(operator.id)), - owner_address: process.env.OWNER_ADDRESS, - nonce: nonce, -}) -``` - -Before doing the registration transaction, the specified amount of SSV needs to be approved: - -```typescript -await sdk.contract.token.write -.approve({ - args: { - spender: sdk.core.contractAddresses.setter, - amount: parseEther('10'), - }, -}) -.then((tx) => tx.wait()) -``` - -### **4. Register validators** -Then finally the `registerValidators` function can be called and return the transaction receipt: - -Register your validators to the SSV network is performed on completion of this function, when the transaction is processed successfully. - -```typescript -const txn_receipt = await sdk.clusters.registerValidators({ - args: { - keyshares: keysharesPayload, - depositAmount: parseEther('30') - }, - }).then(tx => tx.wait()) -console.log("txn_receipt: ", txn_receipt) -``` - -For validator [registration transaction](/developers/smart-contracts/ssvnetwork#bulkregistervalidatorpublickey-operatorids-shares-amount-cluster) you need to provide the cluster’s latest snapshot data and the user nonce. Fortunately, SSV SDK retrieves this data automatically, so you don't have to. - -### Full code example - -This example assumes you already have a number of keystore files and they are stored, under whatever is set for `KEYSTORE_FILE_DIRECTORY` in the `.env` file. - -**`.env` example file for the below script:** - -```sh -PRIVATE_KEY=0xYOUR_PRIVATE_KEY -OWNER_ADDRESS=0xA4831B989972605A62141a667578d742927Cbef9 -KEYSTORE_PASSWORD=test1234 -KEYSTORE_FILE_DIRECTORY=./validator_keys -DEPOSIT_AMOUNT=5 -MINIMUM_RUNWAY_DAYS=30 -OPERATOR_IDS='["1", "2", "3", "4"]' -SUBGRAPH_API_KEY=GRAPH_API_KEY -``` - -```typescript -import { SSVSDK, chains } from '@ssv-labs/ssv-sdk' -import { parseEther, createPublicClient, createWalletClient, http } from 'viem' -import { privateKeyToAccount } from 'viem/accounts' -import * as dotenv from 'dotenv'; -import * as fs from 'fs'; -import * as path from 'path'; -import Web3 from 'web3'; - -dotenv.config(); - -async function main(): Promise { - - if (!process.env.KEYSTORE_FILE_DIRECTORY || - !process.env.OWNER_ADDRESS || - !process.env.KEYSTORE_PASSWORD || - !process.env.OPERATOR_IDS || - !process.env.SUBGRAPH_API_KEY) { - throw new Error('Required environment variables are not set'); - } - - const private_key: `0x${string}` = process.env.PRIVATE_KEY as `0x${string}`; - - // Setup viem clients - const chain = chains.hoodi as any // or chains.mainnet - const transport = http() - - const publicClient = createPublicClient({ - chain, - transport - }) as any - - const account = privateKeyToAccount(private_key as `0x${string}`) - const walletClient = createWalletClient({ - account, - chain, - transport, - }) as any - - // Initialize SDK with viem clients - const sdk = new SSVSDK({ - publicClient, - walletClient, - }) - - const directoryPath = process.env.KEYSTORE_FILE_DIRECTORY; - let keystoresArray: { name: string; keystore: any }[]; - try { - keystoresArray = await loadKeystores(directoryPath); - console.log('Loaded keystores: Keystore Amount: ', keystoresArray.length); - } catch (error) { - console.error('Failed to load keystores:', error); - throw error; // If keystores can't be loaded the code will exit - } - - // keystoresArray is defined at this point - await sdk.contract.token.write - .approve({ - args: { - spender: sdk.config.contractAddresses.setter, - amount: parseEther('10000'), - }, - }) - .then((tx) => tx.wait()) - - let nonce = Number(await sdk.api.getOwnerNonce({ owner: process.env.OWNER_ADDRESS })) - console.log("Initial nonce: ", nonce) - - const operatorIDs = JSON.parse(process.env.OPERATOR_IDS) - const url = "https://gateway.thegraph.com/api/subgraphs/id/F4AU5vPCuKfHvnLsusibxJEiTN7ELCoYTvnzg3YHGYbh"; - const query = ` - query ValidatorData($operatorIDs: [Bytes!]) { - operators(where: {id_in: $operatorIDs}) { - id - publicKey - } - }` - - const variables = { operatorIDs: operatorIDs } - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${process.env.SUBGRAPH_API_KEY}` - }, - body: JSON.stringify({ query, variables }) - }); - - const responseData: any = await response.json(); - const web3 = new Web3(); - const operators: { id: string; publicKey: string }[] = responseData.data.operators.map((operator: any) => {return { - id: operator.id, - publicKey: web3.eth.abi.decodeParameter("string", operator.publicKey) - }}) - - console.log(operators.map((operator: { id: string; publicKey: string }) => operator.publicKey)) - console.log(operators.map((operator: { id: string; publicKey: string }) => Number(operator.id))) - - const chunkSize = 40; // Number of validators per transaction - for (let i = 0; i < keystoresArray.length; i += chunkSize) { - const chunk = keystoresArray.slice(i, i + chunkSize); - - const keystoreValues = chunk.map(item => item.keystore); - - const keysharesPayload = await sdk.utils.generateKeyShares({ - keystore: keystoreValues, - keystore_password: process.env.KEYSTORE_PASSWORD, - operator_keys: operators.map((operator: { id: string; publicKey: string }) => operator.publicKey), - operator_ids: operators.map((operator: { id: string; publicKey: string }) => Number(operator.id)), - owner_address: process.env.OWNER_ADDRESS, - nonce: nonce, - }) - - nonce = nonce + Number(chunk.length) - console.log("New nonce: ", nonce) - - // TODO: validate keysharesPayload - - let txn_receipt - try { - console.log(`Processing chunk from index ${i} to ${i + chunk.length - 1}`); - txn_receipt = await sdk.clusters.registerValidators({ - args: { - keyshares: keysharesPayload, - depositAmount: parseEther('30') - }, - }).then(tx => tx.wait()) - console.log("txn_receipt: ", txn_receipt) - } catch (error) { - logErrorToFile(error); - console.log("Failed to do register: ", error) - } - } -} - -async function loadKeystores(directory: string): Promise<{ name: string; keystore: any }[]> { - const keystoresArray: { name: string; keystore: any }[] = []; - - try { - const files = await fs.promises.readdir(directory); - - for (const file of files) { - if (file.startsWith('keystore-m') && file.endsWith('.json')) { - const filePath = path.join(directory, file); - - const fileContent = await fs.promises.readFile(filePath, 'utf-8'); - const jsonContent = JSON.parse(fileContent); - keystoresArray.push({ name: file, keystore: jsonContent }); - } - } - - return keystoresArray; - } catch (error) { - console.error('Error loading keystores:', error); - throw error; - } -} - -function logErrorToFile(error: unknown): void { - const errorMessage = `Failed to do register: ${error instanceof Error ? error.message : String(error)}\n`; - - // Log the error to the console - console.log(errorMessage); - - // Save the error message to a local file - const filePath = './error-log.txt'; - fs.appendFile(filePath, errorMessage, (err) => { - if (err) { - console.error("Failed to write to file: ", err); - } else { - console.log(`Error saved to file: ${filePath}`); - } - }); -} - -main(); -``` diff --git a/docs/developers/smart-contracts/external-whitelist-contract-example.md b/docs/developers/smart-contracts/external-whitelist-contract-example.md index e6512cd..6476bbc 100644 --- a/docs/developers/smart-contracts/external-whitelist-contract-example.md +++ b/docs/developers/smart-contracts/external-whitelist-contract-example.md @@ -4,9 +4,9 @@ sidebar_position: 4 # External Whitelist Contract example -When [configuring a permissioned Operator](../../operators/operator-management/configuring-a-permissioned-operator), we have the option to set an external whitelising contract to manage this whitelist. To work correctly with the SSV network contract, it must meet certain specifications. +When [configuring a permissioned Operator](../../operators/operator-management/configuring-a-permissioned-operator), we have the option to set an external whitelising contract to manage this whitelist. To work correctly with the SSV network contract, it must meet certain specifications. -### What is a valid Whitelisting Contract? +### What is a valid Whitelisting Contract? The operators can choose to whitelist an external contract with custom logic to manage authorized addresses externally. To be used in SSV contracts, it needs to implement the [ISSVWhitelistingContract](https://github.com/ssvlabs/ssv-network/blob/v1.2.0/contracts/interfaces/external/ISSVWhitelistingContract.sol) interface, that requires to implement the `isWhitelisted(address account, uint256 operatorId)` function. This function is called in the register validator process, that must return `true/false` to indicate if the caller (`msg.sender`) is whitelisted for the operator. diff --git a/docs/developers/smart-contracts/ssvnetwork.md b/docs/developers/smart-contracts/ssvnetwork.md index aa59c21..bcdec9b 100644 --- a/docs/developers/smart-contracts/ssvnetwork.md +++ b/docs/developers/smart-contracts/ssvnetwork.md @@ -17,7 +17,7 @@ Description: Registers a new operator (key) with a set fee, **fails if** fee is | **Parameter** | **Type** | **Description** | | ------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | publicKey | bytes | The operator public key (generated as part of the node setup). | -| operatorFee | uint256(casted to uint64) | The fee charged by the operator (denominated as $SSV tokens per block) | +| operatorFee | uint256(casted to uint64) | The fee charged by the operator (denominated as ETH per block) | | setPrivate | bool | A flag to set the operator to private or public during registration. Calls the [**`setOperatorsPrivateUnchecked`**](ssvnetwork.md#setoperatorsprivateuncheckedoperatorids)function if set to true. | Events: @@ -39,7 +39,7 @@ Events: ### **`withdrawOperatorEarnings(operatorId)`** -Description: Withdraws a specified amount of SSV tokens from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. +Description: Withdraws a specified amount of ETH from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------- | @@ -52,7 +52,7 @@ Events: ### `withdrawAllOperatorEarnings`**`(operatorId)`** -Description: Withdraws all SSV tokens earnings from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. +Description: Withdraws all ETH earnings from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. | **Parameter** | **Type** | **Description** | | ------------- | -------- | --------------- | @@ -62,7 +62,7 @@ Events: * `OperatorWithdrawn(address indexed owner, uint64 indexed operatorId, uint256 value)` -### **`setOperatorWhitelists (operatorIds, whitelisted)`** +### **`setOperatorsWhitelists (operatorIds, whitelisted)`** Description: For a list of operators provided, set a list of whitelisted addresses which can register validators to these operators. @@ -75,7 +75,7 @@ Events: * `OperatorMultipleWhitelistUpdated(uint64[] operatorIds, address[] whitelistAddresses)` -### **`removeOperatorWhitelists (operatorIds, whitelisted)`** +### **`removeOperatorsWhitelists (operatorIds, whitelisted)`** Description: For a list of operators provided, remove a list of whitelisted addresses. @@ -112,7 +112,7 @@ Events: * `OperatorPrivacyStatusUpdated(uint64[] operatorIds, bool toPrivate)` -### **`setOperatorWhitelistingContract(operatorIds, whitelistingContract)`** +### **`setOperatorsWhitelistingContract(operatorIds, whitelistingContract)`** Description: For a list of operators provided, set an external whitelisting contract to manage the whitelist for these operators. [Must be a valid whitelisting contract.](external-whitelist-contract-example.md) @@ -144,7 +144,7 @@ Description: Initiates the first step of the operator fee update cycle - declara | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | ----------------------------------------------- | | operatorId | uint64 | The operator id | -| operatorFee | uint256 (casted to uint64) | New fee (denominated as $SSV tokens per block). | +| operatorFee | uint256 (casted to uint64) | New fee (denominated as ETH per block). | Events: @@ -181,7 +181,7 @@ Description: Reduce the operator fee, does not abide by the restrictions of fee | Parameter | Type | Description | | ---------- | -------------------------- | ----------------------------------------------- | | operatorId | uint64 | The operator id | -| fee | uint256 (casted to uint64) | New fee (denominated as $SSV tokens per block). | +| fee | uint256 (casted to uint64) | New fee (denominated as ETH per block). | Events: @@ -203,15 +203,25 @@ Events: ## Cluster Methods -### **`registerValidator(publicKey, operatorIds, shares, amount, cluster)`** +### `migrateClusterToETH(operatorIds, amount, cluster)` + +| **Parameter** | **Type** | **Description** | +| ------------------- | -------- | ---------------------------------------------------- | +| operatorIds | uint64[] | An array of operator IDs of the cluster. | +| amount | uint256 | Amount of ETH to deposit to cluster's balance after migration. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools | + +Events: -Description: Registers new validator to a cluster of provided operators (ids + shares), **fails if** number of operatorIds is greater than 13. +* `ClusterMigratedToETH(address owner, uint64[] operatorIds, uint256 ethDeposited, uint256 ssvRefunded, uint32 effectiveBalance, Cluster cluster)` -:::info -To deposit the SSV Token, you need to approve the amount of SSV tokens you wish to deposit to the cluster. +### **`registerValidator(publicKey, operatorIds, shares, cluster)`** -The approval transaction must be called on the SSV token contract, with the approval address set to the SSVNetwork contract address. [Both adddresses can be found here.](../smart-contracts) +Registers new validator to a cluster of provided operators (ids + shares), **fails if** number of operatorIds is greater than 13. The ETH amount to deposit must be [supplied via `msg.value`](https://docs.ethers.org/v4/api-contract.html#overrides). + +:::info Breaking Changes +With the [introduction of ETH payments](https://ssv.network/blog/introduction-to-ssv-staking), the smart contract function signature has changed. The `amount` parameter has been removed, and the function is now `payable`. The ETH amount to deposit must be supplied via `msg.value`. Update your integrations accordingly, in line with [the ethers documentation](https://docs.ethers.org/v4/api-contract.html#overrides). ::: | **Parameter** | **Type** | **Description** | @@ -219,21 +229,17 @@ The approval transaction must be called on the SSV token contract, with the appr | publicKey | bytes | The validator’s public key. | | operatorIds | unit64\[] | List of cluster operators Ids. | | sharesData | bytes | String of keyshares - obtained by splitting the validator key using the [SSV-Keys](../tools/ssv-keys) tool. | -| amount | uint256 (casted to uint64) | Amount of SSV token to be deposited as payment (not mandatory). Amount must be shrinkable (divisible by 10000000) | -| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](../tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](../tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | - +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools | Events: * `ValidatorAdded(address indexed owner, uint64[] operatorIds, bytes publicKey, bytes shares, Cluster cluster)` -### **`bulkRegisterValidator(publicKey, operatorIds, shares, amount, cluster)`** - -Description: Registers all the new validators provided as argument to a cluster of provided operators (ids + shares), **fails if** number of operatorIds is greater than 13. +### **`bulkRegisterValidator(publicKey, operatorIds, shares, cluster)`** -:::info -To deposit the SSV Token, you need to approve the amount of SSV tokens you wish to deposit to the cluster. +Description: Registers all the new validators provided as argument to a cluster of provided operators (ids + shares), **fails if** number of operatorIds is greater than 13. The ETH amount to deposit must be [supplied via `msg.value`](https://docs.ethers.org/v4/api-contract.html#overrides). -The approval transaction must be called on the SSV token contract, with the approval address set to the SSVNetwork contract address. [Both adddresses can be found here.](../smart-contracts) +:::info Breaking Changes +With the [introduction of ETH payments](https://ssv.network/blog/introduction-to-ssv-staking), the smart contract function signature has changed. The `amount` parameter has been removed, and the function is now `payable`. The ETH amount to deposit must be supplied via `msg.value`. Update your integrations accordingly, in line with [the ethers documentation](https://docs.ethers.org/v4/api-contract.html#overrides). ::: | **Parameter** | **Type** | **Description** | @@ -241,9 +247,7 @@ The approval transaction must be called on the SSV token contract, with the appr | publicKeys | bytes\[] | An array of validators’ public keys. | | operatorIds | unit64\[] | List of cluster operators Ids. | | sharesData | bytes\[] | An array of strings of keyshares - obtained by splitting the validator key using the [SSV-Keys](../tools/ssv-keys) Each element in this array must relate to a public key in the publicKeys array. | -| amount | uint256 (casted to uint64) | Amount of SSV token to be deposited as payment (not mandatory).Amount must be shrinkable (divisible by 10000000)p> | -| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](../tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](../tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | - +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools | Events: * `ValidatorAdded(address indexed owner, uint64[] operatorIds, bytes publicKey, bytes shares, Cluster cluster)` @@ -322,21 +326,18 @@ The function emits as many `ValidatorExited` events, as is the length of the pro Please note: the number of validators that can be requested to exit from the beacon chain with the`bulkExitValidator` function is limited by the total transaction size to a maximum of **500 validator keys at a time.** -### **`deposit(owner, operatorIds, amount, cluster)`** - -Description: Deposits SSV token into a cluster, **will fail if** not enough tokens are approved. +### **`deposit(owner, operatorIds, cluster)`** -:::info -To deposit the SSV Token, you need to approve the amount of SSV tokens you wish to deposit to the cluster. +The ETH amount to deposit must be [supplied via `msg.value`](https://docs.ethers.org/v4/api-contract.html#overrides). -The approval transaction must be called on the SSV token contract, with the approval address set to the SSVNetwork contract address. [Both adddresses can be found here.](../smart-contracts) +:::info Breaking Changes +With the [introduction of ETH payments](https://ssv.network/blog/introduction-to-ssv-staking), the smart contract function signature has changed. The `amount` parameter has been removed, and the function is now `payable`. The ETH amount to deposit must be supplied via `msg.value`. Update your integrations accordingly, in line with [the ethers documentation](https://docs.ethers.org/v4/api-contract.html#overrides). ::: | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | owner | address | The cluster owner address | | operatorIds | unit64\[] | List of cluster operators Ids. | -| amount | uint256 (casted to uint64) | $SSV amount to be deposited. Amount must be shrinkable (divisible by 10000000) | | cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](../tools/ssv-subgraph/subgraph-examples.md#cluster-snapshot), or [SSV Scanner](../tools/ssv-scanner) tools. | Events: @@ -345,7 +346,7 @@ Events: ### **`withdraw(operatorIds, amount, cluster)`** -Description: Withdraws a specified amount of SSV tokens from cluster of msg.sender, **will fail if** msg.sender tries to withdraw more than the cluster’s liquidation collateral. To withdraw the entire cluster balance and stop its operation use liquidate(). +Description: Withdraws a specified amount of ETH from cluster of msg.sender, **will fail if** msg.sender tries to withdraw more than the cluster’s liquidation collateral. To withdraw the entire cluster balance and stop its operation use liquidate(). | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -357,21 +358,17 @@ Events: * `ClusterWithdrawn(address indexed owner, uint64[] operatorIds, uint256 value, Cluster cluster)` -### **`reactivate(operatorIds, amount, cluster)`** - -Description: Reactivates a liquidated cluster, **will fail** if insufficient SSV tokens to cover the cluster’s liquidation collateral have been deposited. +### **`reactivate(operatorIds, cluster)`** -:::info -To deposit the SSV Token, you need to approve the amount of SSV tokens you wish to deposit to the cluster. +Description: Reactivates a liquidated cluster, **will fail** if insufficient ETH to cover the cluster’s liquidation collateral have been deposited. The ETH amount to deposit must be [supplied via `msg.value`](https://docs.ethers.org/v4/api-contract.html#overrides). -The approval transaction must be called on the SSV token contract, with the approval address set to the SSVNetwork contract address. [Both adddresses can be found here.](../smart-contracts) +:::info Breaking Changes +With the [introduction of ETH payments](https://ssv.network/blog/introduction-to-ssv-staking), the smart contract function signature has changed. The `amount` parameter has been removed, and the function is now `payable`. The ETH amount to deposit must be supplied via `msg.value`. Update your integrations accordingly, in line with [the ethers documentation](https://docs.ethers.org/v4/api-contract.html#overrides). ::: | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| operatorIds | unit64\[] | List of cluster operators Ids. | -| amount | uint256 (casted to uint64) | $SSV amount to be deposited. Amount must be shrinkable (divisible by 10000000) - | +| operatorIds | unit64\[] | List of cluster operators Ids. | | | cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](../tools/ssv-subgraph/subgraph-examples.md#cluster-snapshot), or [SSV Scanner](../tools/ssv-scanner) tools. | Events: @@ -404,7 +401,7 @@ Description: Updates network fee. | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | ------------------------------------------------------------------------------------ | -| networkFee | uint256 (casted to uint64) | The fee charged by the network per validator (denominated as $SSV tokens per block). | +| networkFee | uint256 (casted to uint64) | The fee charged by the network per validator (denominated as ETH per block). | Events: @@ -412,7 +409,7 @@ Events: ### **`withdrawNetworkEarnings(amount)`** -Description: Withdraws accumulated network fees in SSV token to DAO treasury. +Description: Withdraws accumulated network fees in ETH to DAO treasury. | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------- | @@ -436,11 +433,11 @@ Events: ### `updateMaxiumumOperatorFee`**`(maxFee)`** -Description: Updates the maximum fee an operator that uses SSV token can set +Description: Updates the maximum fee an operator that uses ETH can set | **Parameter** | **Type** | **Description** | | ------------- | -------- | -------------------------------------------------------- | -| maxFee | uint64 | Maximum fee (in SSV tokens per year) an operator can set | +| maxFee | uint64 | Maximum fee (in ETH per year) an operator can set | Events: @@ -448,11 +445,11 @@ Events: ### `updateMinimumLiquidationCollateral(amount)` -Description: Sets the minimum collateral (in $SSV) each cluster must keep in his balance. +Description: Sets the minimum collateral (in ETH) each cluster must keep in his balance. | **Parameter** | **Type** | **Description** | | ------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- | -| amount | uint256 (casted to uint64) | Amount of SSV collateral. Amount must be shrinkable (divisible by 10000000) | +| amount | uint256 (casted to uint64) | Amount of ETH collateral. Amount must be shrinkable (divisible by 10000000) | Events: @@ -493,3 +490,107 @@ Description: Sets the time window (in seconds) in which an operator can activate Events: * `ExecuteOperatorFeePeriodUpdated(uint64 value)` + +## Legacy Methods + +All methods that relate to the legacy (SSV-based) clusters. + +### **`withdrawOperatorEarningsSSV(operatorId)`** + +Description: Withdraws a specified amount of SSV tokens from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| operatorId | uint64 | The operator id | +| amount | uint256 (casted to uint64) | Amount must be shrinkable (divisible by 10000000) | + +Events: + +* `OperatorWithdrawn(address indexed owner, uint64 indexed operatorId, uint256 value)` + +### `withdrawAllOperatorEarningsSSV`**`(operatorId)`** + +Description: Withdraws all SSV tokens earnings from provided operator balance to msg.sender, **will fail if** msg.sender is not the operator owner. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------- | +| operatorId | uint64 | The operator id | + +Events: + +* `OperatorWithdrawn(address indexed owner, uint64 indexed operatorId, uint256 value)` + +### **`liquidateSSV(owner, operatorIds, cluster)`** + +Description: Liquidates an SSV-based cluster sends their balances to the msg.sender (the Liquidator), **will fail** if the cluster is not liquidatable (see isLiquidatable()). + +| **Parameter** | **Type** | **Description** | +| ------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| owner | address | The cluster owner address | +| operatorIds | unit64\[] | List of cluster operators Ids. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](../tools/ssv-subgraph/subgraph-examples.md#cluster-snapshot), or [SSV Scanner](../tools/ssv-scanner) tools. | + +Events: + +* `ClusterLiquidatedSSV(address indexed owner, uint64[] operatorIds, Cluster cluster)` + +### **`updateNetworkFeeSSV(networkFee)`** + +Description: Updates network fee. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------------------------- | ------------------------------------------------------------------------------------ | +| networkFee | uint256 (casted to uint64) | The fee charged by the network per validator (denominated as SSV tokens per block). | + +Events: + +* `NetworkFeeUpdatedSSV(uint256 oldFee, uint256 newFee)` + +### **`withdrawNetworkSSVEarnings(amount)`** + +Description: Withdraws accumulated network fees in SSV token to DAO treasury. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| amount | uint256 (casted to uint64) | Amount to be withdrawn. Amount must be shrinkable (divisible by 10000000) | + +Events: + +* `NetworkEarningsWithdrawn(uint256 value, address recipient)` + +### **`updateLiquidationThresholdPeriodSSV(blocks)`** + +Description: Sets the minimum period (in blocks) after which a cluster can be liquidated. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------------------------------------- | +| blocks | uint64 | Duration in blocks to have sufficient balance | + +Events: + +* `LiquidationThresholdPeriodSSVUpdated(uint64 value)` + +### `updateMaxiumumOperatorFeeSSV`**`(maxFee)`** + +Description: Updates the maximum fee an operator that uses SSV token can set + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | -------------------------------------------------------- | +| maxFee | uint64 | Maximum fee (in SSV tokens per year) an operator can set | + +Events: + +* `OperatorMaximumFeeSSVUpdated(uint64 maxFee)` + +### `updateMinimumLiquidationCollateralSSV(amount)` + +Description: Sets the minimum collateral (in SSV token) each cluster must keep in his balance. + +| **Parameter** | **Type** | **Description** | +| ------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- | +| amount | uint256 (casted to uint64) | Amount of SSV token collateral. Amount must be shrinkable (divisible by 10000000) | + +Events: + +* `MinimumLiquidationCollateralSSVUpdated(uint256 value)` + diff --git a/docs/developers/smart-contracts/ssvnetworkviews.md b/docs/developers/smart-contracts/ssvnetworkviews.md index 27f4257..5605230 100644 --- a/docs/developers/smart-contracts/ssvnetworkviews.md +++ b/docs/developers/smart-contracts/ssvnetworkviews.md @@ -8,7 +8,7 @@ The SSVNetworkViews contract is for reading information about the network and it [SSV Views Contracts Repository](https://github.com/ssvlabs/ssv-network/tree/main/contracts) -### General Methods +## General Methods ### **`getNetworkFee ()`** @@ -18,7 +18,7 @@ Return values: | Parameter | Type | Description | |-----------|------|-------------| -| fee | uint256 | The fee charged by the network (denominated as $SSV tokens per block) | +| fee | uint256 | The fee charged by the network (denominated as ETH per block) | ### **`getNetworkEarnings ()`** @@ -48,7 +48,7 @@ Return values | **Parameter** | **Type** | **Description** | | ------------- | -------- | ---------------------------------------------------------------------------------------------------- | -| amount | uint256 | The minimum amount of SSV which a cluster has to have (liquidation collateral) to not be liquidated. | +| amount | uint256 | The minimum amount of ETH which a cluster has to have (liquidation collateral) to not be liquidated. | ### **`getOperatorFeeIncreaseLimit()`** @@ -75,13 +75,13 @@ Return values: ### **`getMaximumOperatorFee()`** -Description: **Gets the operator maximum fee for operators that use SSV token** +Description: **Gets the operator maximum fee for operators that use ETH token** Return values | Parameter | Type | Description | | --------- | ------ | -------------------------------- | -| maxFee | uint64 | The maximum fee value (SSV/year) | +| maxFee | uint64 | The maximum fee value (ETH/year) | ### `getValidatorsPerOperatorLimit()` @@ -93,7 +93,7 @@ Return values | --------------- | -------- | -------------------------------------------- | | Validator limit | uint32 | amount of validators an operator may manage. | -### Operator Methods +## Operator Methods ### **`getOperatorById (operatorId)`** @@ -108,7 +108,7 @@ Return values: | Parameter | Type | Description | |-----------|------|-------------| | owner | address | The operator's admin address (for management purposes) | -| fee | uint64256 | The fee charged by the operator (denominated as $SSV tokens per block) | +| fee | uint64256 | The fee charged by the operator (denominated as ETH per block) | | validatorCount | uint32 | The amount of managed validators | | whitelistedContract | address | The external contract set to manage this operator's whitelisted addresses | | isPrivate | boolean | Indication if operator is permissioned | @@ -126,7 +126,7 @@ Return values | **Parameter** | **Type** | **Description** | | ------------- | -------- | ---------------------------------------------------------------------- | -| declaredFee | uint256 | The fee charged by the operator (denominated as $SSV tokens per block) | +| declaredFee | uint256 | The fee charged by the operator (denominated as ETH per block) | ### **`getOperatorDeclaredFee (operatorId)`** @@ -148,13 +148,13 @@ Return values | **Parameter** | **Type** | **Description** | | ------------- | -------- | ---------------------------------------------- | -| balance | uint256 | Operators outstanding earnings in $SSV tokens. | +| balance | uint256 | Operators outstanding earnings in ETH. | -### Cluster Methods +## Cluster Methods ### **`getBalance (owner, operatorIds, cluster)`** -Description: Returns the outstanding SSV balance of a cluster. +Description: Returns the outstanding ETH balance of a cluster. | Parameter | Type | Description | |-----------|------|-------------| @@ -166,35 +166,35 @@ Return values: | Parameter | Type | Description | |-----------|------|-------------| -| balance | uint256 | Clusters outstanding balance denominated in $SSV tokens | +| balance | uint256 | Clusters outstanding balance denominated in ETH | ### **`getBurnRate (owner, operatorIds, cluster)`** -Description: Returns current ongoing expenses of SSV tokens for a particular SSV cluster balance on per block basis (aggregates all expenses for all the validators in this cluster).\\ +Description: Returns current ongoing expenses of ETH for a particular SSV cluster balance on per block basis (aggregates all expenses for all the validators in this cluster).\\ | **Parameter** | **Type** | **Description** | | ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | | owner | address | The user address | | operatorIds | uint64\[] | List of cluster operators Ids. | -| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Scanner](/developers/tools/ssv-scanner) tool. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | Return values | **Parameter** | **Type** | **Description** | | ------------- | -------- | --------------------------------------------------- | -| burnRate | uint256 | The rate per block in which the account spends SSV. | +| burnRate | uint256 | The rate per block in which the account spends ETH. | -### Liquidator Methods +## Liquidator Methods ### **`isLiquidatable (owner, operatorIds, cluster)`** -Description: Returns true if the specified cluster is under the liquidation threshold and can be liquidated.\\ +Description: Returns true if the specified cluster is under the liquidation threshold and can be liquidated. | **Parameter** | **Type** | **Description** | | ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | | owner | address | The user address | | operatorIds | uint64\[] | List of cluster operators Ids. | -| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Scanner](/developers/tools/ssv-scanner) tool. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | Return values @@ -210,7 +210,7 @@ Description: Returns true if the provided cluster is liquidated. | ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | | owner | address | The user address | | operatorIds | uint64\[] | List of cluster operators Ids. | -| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Scanner](/developers/tools/ssv-scanner) tool. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | Return values @@ -261,4 +261,151 @@ Return values | **Parameter** | **Type** | **Description** | | ------------- | -------- | --------------------------------------------- | -| isWhitelisted | bool | True if address is whitelisted, false if not. | \ No newline at end of file +| isWhitelisted | bool | True if address is whitelisted, false if not. | + +## Legacy Methods + +### **`getBalanceSSV (owner, operatorIds, cluster)`** + +Description: Returns the outstanding SSV balance of a legacy (SSV-based) cluster. + +| Parameter | Type | Description | +|-----------|------|-------------| +| owner | address | The cluster owner address | +| operatorIds | uint64[] | List of cluster operators Ids | +| cluster | tuple[] | Object containing the latest cluster snapshot data - obtained using the [SSV Scanner](/developers/tools/ssv-scanner) tool | + +Return values: + +| Parameter | Type | Description | +|-----------|------|-------------| +| balance | uint256 | Clusters outstanding balance denominated in SSV | + +### **`getBurnRateSSV (owner, operatorIds, cluster)`** + +Description: Returns current ongoing expenses of SSV for a particular SSV cluster balance on per block basis (aggregates all expenses for all the validators in this cluster).\\ + +| **Parameter** | **Type** | **Description** | +| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | +| owner | address | The user address | +| operatorIds | uint64\[] | List of cluster operators Ids. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------------------------------------------- | +| burnRate | uint256 | The rate per block in which the account spends ETH. | + +### **`getNetworkFeeSSV ()`** + +Description: Returns current network fee for legacy (SSV-based) clusters. + +Return values: + +| Parameter | Type | Description | +|-----------|------|-------------| +| fee | uint256 | The fee charged by the network (denominated as SSV per block) | + +### **`getNetworkEarningsSSV ()`** + +Description: Returns accumulated network fees not yet withdrawn from the legacy (SSV-based) clusters. + +Return values: + +| Parameter | Type | Description | +|-----------|------|-------------| +| amount | uint256 | Amount of fees accumulated in the network treasury | + +### **`getLiquidationThresholdPeriodSSV ()`** + +Description: Returns the minimum duration (in blocks) which legacy cluster has to have sufficient balance (liquidation collateral) to not be liquidated. + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------- | +| blocks | uint64 | The minimum duration (blocks) which legacy cluster has to have sufficient balance (liquidation collateral) to not be liquidated. | + +### **`getMinimumLiquidationCollateralSSV()`** + +Description: Returns the minimum amount which legacy cluster has to have sufficient balance (liquidation collateral) to not be liquidated. + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | ---------------------------------------------------------------------------------------------------- | +| amount | uint256 | The minimum amount of SSV which a cluster has to have (liquidation collateral) to not be liquidated. | + +### **`getMaximumOperatorFeeSSV()`** + +Description: **Gets the operator maximum fee for operators that use SSV token** + +Return values + +| Parameter | Type | Description | +| --------- | ------ | -------------------------------- | +| maxFee | uint64 | The maximum fee value (SSV/year) | + +### **`getOperatorByIdSSV (operatorId)`** + +Description: Returns operator's data for operators participating in legacy clusters. + +| Parameter | Type | Description | +|-----------|------|-------------| +| operatorId | uint64 | The operator id | + +Return values: + +| Parameter | Type | Description | +|-----------|------|-------------| +| owner | address | The operator's admin address (for management purposes) | +| fee | uint64256 | The fee charged by the operator (denominated as SSV per block) | +| validatorCount | uint32 | The amount of managed validators | +| whitelistedContract | address | The external contract set to manage this operator's whitelisted addresses | +| isPrivate | boolean | Indication if operator is permissioned | +| active | boolean | Operator network status | + +### **`getOperatorFeeSSV (operatorId)`** + +Description: returns current operator's fee (not declared). + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------- | +| operatorId | uint64 | The operator id | + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | ---------------------------------------------------------------------- | +| declaredFee | uint256 | The fee charged by the operator (denominated as SSV per block) | + +### **getOperatorEarningsSSV (operatorId)** + +Description: Returns the outstanding earnings of an operator participating legacy cluster(s). + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | --------------- | +| operatorId | uint64 | The operator id | + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | ---------------------------------------------- | +| balance | uint256 | Operators outstanding earnings in SSV. | + +### **`isLiquidatableSSV (owner, operatorIds, cluster)`** + +Description: Returns true if the specified legacy cluster is under the liquidation threshold and can be liquidated. + +| **Parameter** | **Type** | **Description** | +| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | +| owner | address | The user address | +| operatorIds | uint64\[] | List of cluster operators Ids. | +| cluster | tuple\[] | Object containing the latest cluster snapshot data - obtained using the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), or [SSV Scanner](/developers/tools/ssv-scanner) tools If this is the 1st validator within a specific cluster (unique set of operators), use - \{0,0,0,true,0\} | + +Return values + +| **Parameter** | **Type** | **Description** | +| ------------- | -------- | ------------------------------------------- | +| isLiquidatable | boolean | Indication if a legacy cluster could be liquidated | \ No newline at end of file diff --git a/docs/developers/tools/ssv-dkg-client/change-operator-set-and-reshare-validator-key-shares.md b/docs/developers/tools/ssv-dkg-client/change-operator-set-and-reshare-validator-key-shares.md index 2d197e4..c8d35cb 100644 --- a/docs/developers/tools/ssv-dkg-client/change-operator-set-and-reshare-validator-key-shares.md +++ b/docs/developers/tools/ssv-dkg-client/change-operator-set-and-reshare-validator-key-shares.md @@ -55,7 +55,7 @@ proofsFilePath: ./output/ceremony-2024-11-18--16-04-55.529/proofs.json newOperatorIDs: [5, 6, 7, 8] ``` -* For more information on the YAML configuration file, and how to provide it to the tool, [please refer to this section (Additional flag for generate-reshare-msg)](/developers/tools/ssv-dkg-client/commands-and-config). Make sure to add the `proofsFilePath` parameter to the YAML configuration file +* For more information on the YAML configuration file, and how to provide it to the tool, [please refer to this section (Additional flag for generate-reshare-msg)](/developers/tools/ssv-dkg-client/commands-and-config). Make sure to add the `proofsFilePath` parameter to the YAML configuration file * Alternatively, the tool can be launched as a binary executable. For more information, please [refer to the appropriate section of this page](/developers/tools/ssv-dkg-client/commands-and-config) * For the reference of command line flags, [please refer to this section (Additional flag for generate-reshare-msg)](/developers/tools/ssv-dkg-client/commands-and-config), instead. Remember to add the `proofsFilePath` flag. @@ -96,7 +96,7 @@ newOperatorIDs: [5, 6, 7, 8] signatures: 111886aa25a07bbd9cb64e50e3237f98a6ecabad6f448bc9c4736ccebcacb45c56ecac273b076a5d0b1f19619bf808741dff2d8019c728e16a953d3a0b5ff4771b ``` -* For more information on the YAML file configuration, and how to provide it to the tool, [please refer to this section (Additional flag for reshare command)](/developers/tools/ssv-dkg-client/commands-and-config). +* For more information on the YAML file configuration, and how to provide it to the tool, [please refer to this section (Additional flag for reshare command)](/developers/tools/ssv-dkg-client/commands-and-config). * Alternatively, the tool can be launched as a binary executable. For more information, please [refer to the appropriate section of this page](/developers/tools/ssv-dkg-client/commands-and-config) * For the reference of command line flags, [please refer to this section (Additional flag for reshare command)](/developers/tools/ssv-dkg-client/commands-and-config), instead. diff --git a/docs/developers/tools/ssv-dkg-client/commands-and-config.md b/docs/developers/tools/ssv-dkg-client/commands-and-config.md index e6e89a6..0cac58f 100644 --- a/docs/developers/tools/ssv-dkg-client/commands-and-config.md +++ b/docs/developers/tools/ssv-dkg-client/commands-and-config.md @@ -27,7 +27,7 @@ In order to provide these features, the following options are available: * `generate-reshare-msg` - generates a message with the content of a `proofs.json` file from a past ceremony, that needs to be signed by the `owner` used in that ceremony, in order for a `reshare` ceremony to take place * `reshare` - initiates a DKG ceremony to re-generate Key Shares involving a different operator set * `generate-resign-msg` - generates a message with the content of a `proofs.json` file from a past ceremony, that needs to be signed by the `owner` used in that ceremony, in order for a `resign`ceremony to take place -* `resign` - initiates a DKG ceremony to re-generate the signature portion of existing Key Shares, providing the ability to generate Key Shares for the same validator public key, for a different `owner`, or adjusting the `nonce` for the same `owner` +* `resign` - initiates a DKG ceremony to re-generate the signature portion of existing Key Shares, providing the ability to generate Key Shares for the same validator public key, for a different `owner`, or adjusting the `nonce` for the same `owner` ### Configuration input As previously mentioned, the user can provide input to the tool either through a config file, or through a a series of command line flags. diff --git a/docs/developers/tools/ssv-subgraph/subgraph-examples.md b/docs/developers/tools/ssv-subgraph/subgraph-examples.md index e10047d..d6f9c5c 100644 --- a/docs/developers/tools/ssv-subgraph/subgraph-examples.md +++ b/docs/developers/tools/ssv-subgraph/subgraph-examples.md @@ -165,7 +165,7 @@ Output ### DAO constants and protocol network fee index -Returns the value of important values set by the DAO (such as Minimum Liquidation Collatera, and Liquidation Threshold Period), as well as the protocol-wide Network Fee Index, needed to calculate the balance of clusters and verify their risk of liquidation. +Returns the value of important values set by the DAO (such as Minimum Liquidation Collatera, and Liquidation Threshold Period), as well as the protocol-wide Network Fee Index, needed to calculate the balance of clusters and verify their risk of liquidation, or the amount of ETH per each share of SSV tokens. :::info Please note The `id` of `daovalues` is the address of the SSVNetwork smart contract deployed on the current chain. So in the case of Hoodi it's ` 0x58410Bef803ECd7E63B23664C586A6DB72DAf59c` @@ -186,6 +186,10 @@ query daoValues { networkFeeIndexBlockNumber operatorFeeIncreaseLimit operatorMaximumFee + quorum + accEthPerShare + latestMerkleRoot + totalEffectiveBalance } } ``` @@ -207,6 +211,10 @@ query daoValues { networkFeeIndexBlockNumber operatorFeeIncreaseLimit operatorMaximumFee + quorum + accEthPerShare + latestMerkleRoot + totalEffectiveBalance } }`; @@ -229,7 +237,7 @@ console.log(responseData); curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \ -H "Content-Type: application/json" \ -d '{ - "query": "query daoValues { daovalues(id: \"0x58410Bef803ECd7E63B23664C586A6DB72DAf59c\") { declareOperatorFeePeriod executeOperatorFeePeriod liquidationThreshold minimumLiquidationCollateral networkFee networkFeeIndex networkFeeIndexBlockNumber operatorFeeIncreaseLimit operatorMaximumFee }}" + "query": "query daoValues { daovalues(id: \"0x58410Bef803ECd7E63B23664C586A6DB72DAf59c\") { declareOperatorFeePeriod executeOperatorFeePeriod liquidationThreshold minimumLiquidationCollateral networkFee networkFeeIndex networkFeeIndexBlockNumber operatorFeeIncreaseLimit operatorMaximumFee quorum accEthPerShare latestMerkleRoot totalEffectiveBalance }}" }' ``` @@ -249,7 +257,11 @@ Output "networkFeeIndex": "215784140000000", "networkFeeIndexBlockNumber": "131572", "operatorFeeIncreaseLimit": "1000", - "operatorMaximumFee": "76528650000000" + "operatorMaximumFee": "76528650000000", + "quorum": "7500", + "accEthPerShare": "74267140000000", + "latestMerkleRoot": "0xad75cf901", + "totalEffectiveBalance": "75631987215784140000000", } } } @@ -579,7 +591,7 @@ Output ### Cluster Data by ID (Balance, Active status and Operator IDs) -Returns balance, active status and operator IDs for a cluster. +Returns active status, effective balance, fee asset type (ETH or SSV), validator count and public key for all its validators. :::info Please note The cluster's `id` is generated by concatenating the owner address and the operator IDs using a dash (`-`) separator. @@ -592,13 +604,12 @@ The cluster's `id` is generated by concatenating the owner address and the opera query ClusterData { cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") { active + effectiveBalance + feeAsset + validatorCount validators { id - owner { - id - } } - validatorCount } } ``` @@ -612,13 +623,12 @@ const query = ` query ClusterData { cluster(id: "0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8") { active + effectiveBalance + feeAsset + validatorCount validators { id - owner { - id - } } - validatorCount } }`; @@ -641,7 +651,7 @@ console.log(responseData); curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \ -H "Content-Type: application/json" \ -d '{ - "query": "query ClusterData { cluster(id: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8\") { active validators { id owner { id } } validatorCount }}" + "query": "query ClusterData { cluster(id: \"0x0f1651507bdd33d3d18a5732c22d4713020cd100-5-6-7-8\") { active effectiveBalance feeAsset validatorCount validators { id } }}" }' ``` @@ -654,6 +664,9 @@ Output: "data": { "cluster": { "active": true, + "effectiveBalance": "110000000000000000000", + "feeAsset": "ETH", + "validatorCount": "3" "validators": [ { "id": "0x82808139fefab04eec339d1e4137b0e7d05eb75ec5eacdfe0b6f8d1cf2151b9f46ff3854e3ac5f44467fdc86bdbca345", @@ -674,7 +687,6 @@ Output: } } ], - "validatorCount": "3" } } } @@ -695,6 +707,7 @@ query ValidatorCountPerOperator { totalWithdrawn isPrivate validatorCount + totalEffectiveBalance whitelisted { id } @@ -715,6 +728,7 @@ query ValidatorCountPerOperator { totalWithdrawn isPrivate validatorCount + totalEffectiveBalance whitelisted { id } @@ -740,7 +754,7 @@ console.log(responseData); curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \ -H "Content-Type: application/json" \ -d '{ - "query": "query ValidatorCountPerOperator { operator(id: \"7\") { fee removed totalWithdrawn validatorCount isPrivate whitelisted { id } }}" + "query": "query ValidatorCountPerOperator { operator(id: \"7\") { fee removed totalWithdrawn validatorCount totalEffectiveBalance isPrivate whitelisted { id } }}" }' ``` @@ -756,6 +770,7 @@ Output: "removed": false, "totalWithdrawn": "0", "validatorCount": "318", + "totalEffectiveBalance": "651264", "isPrivate": false, "whitelisted": [] } @@ -763,6 +778,107 @@ Output: } ``` +### Oracle data by ID (oracle ID, address, total delegated amount and its delegators) + +Returns oracle ID, address, total delegated amount and its delegators of a given Oracle + + + + +```graphql +query OracleData { + operator(id: "1") { + totalDelegatedAmount + oracleId + oracleAddress + id + delegators { + amount + delegator { + id + } + } + } + } +} +``` + + + + +```javascript +const url = "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest"; +const query = ` +query OracleData { + operator(id: "1") { + totalDelegatedAmount + oracleId + oracleAddress + id + delegators { + amount + delegator { + id + } + } + } + } +}`; + +const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ query }) +}); + +const responseData = await response.json(); +console.log(responseData); +``` + + + + +```bash +curl -X POST "https://api.studio.thegraph.com/query/71118/ssv-network-hoodi/version/latest" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "query OracleData { operator(id: \"1\") { totalDelegatedAmount oracleId oracleAddress id delegators { amount delegator { id } } } } }" +}' +``` + + + + +Output: +```json +{ + "data": { + "oracle": { + "totalDelegatedAmount": "5421250000000000000000", + "oracleId": "1", + "oracleAddress": "0x011684890d10ecc4473f2a4a8b0f2cb7f19c66eb", + "id": "1", + "delegators": [ + { + "amount": "7750000000000000000", + "delegator": { + "id": "0x4f0f5ab30f62b62ed0466b697f0ec7b30560ee48" + } + }, + { + "amount": "6250000000000000000", + "delegator": { + "id": "0x599fdcd9b73052226721f093fe7b0bddd393fbdf" + } + } + ] + } + } +} +``` + ### 10 most recent clusters with a validator count of 4 Returns data on the 10 most recent clusters, we get this by the last updated blocks and using `orderBy: lastUpdateBlockNumber`and sort it by descending using `orderDirection: desc` diff --git a/docs/learn/glossary.md b/docs/learn/glossary.md index e74b15a..c030b47 100644 --- a/docs/learn/glossary.md +++ b/docs/learn/glossary.md @@ -13,12 +13,35 @@ The Beacon Chain is a brand-new, proof-of-stake blockchain that stores and manag ### Cluster -The group (usually 4, in compliance with [the fault tolerance rule is accepted](../../../stakers/validators/validator-onboarding)) of non-trusting operators that manage a set (one, or multiple) validator(s). Each operator in the cluster holds a share of the complete validator key, for more information, see [Shamir Secret Sharing](glossary.md#shamir-secret-sharing). +The group (usually 4, in compliance with [the fault tolerance rule is accepted](../../../stakers/validators/validator-onboarding)) of non-trusting operators that manage a set (one, or multiple) validator(s). Each operator in the cluster holds a share of the complete validator key, for more information, see [Shamir Secret Sharing](glossary.md#shamir-secret-sharing). + +Clusters pay fees in ETH, which is the standard payment method. Older clusters may still pay fees in SSV tokens, but can migrate to ETH-based payments via `migrateClusterToETH()`. ### Consensus Client Formerly known as an Eth2 client. Runs the Ethereum PoS (Proof-of-Stake) consensus layer, aka the Beacon Chain, checking the validity of transactions and new blocks. Examples of consensus clients include Prysm, Teku, Lighthouse, Nimbus, and Lodestar. +### Cooldown Period + +The mandatory 7-day waiting period between initiating SSV token unstaking and being able to withdraw your staked SSV. During this cooldown: +- Rewards stop accruing immediately +- Oracle voting weight remains active +- The process cannot be cancelled +- Unclaimed rewards can still be claimed + +The cooldown exists to maintain oracle voting stability and prepare for future governance mechanisms. + +### cSSV (Compound SSV) + +A non-rebasing ERC-20 token received when you stake SSV tokens. Key properties: + +- **Non-rebasing** - Your cSSV balance stays constant; it doesn't auto-increase +- **Transferable** - Can be transferred, traded, or used in DeFi protocols +- **Index-based rewards** - ETH rewards accrue separately via an increasing reward index +- **Initial 1:1 ratio** - When you stake SSV, you initially receive equal amounts of cSSV + +cSSV represents your staked position and determines your share of network fee rewards. When you unstake, cSSV is burned and you receive back your original SSV plus any unclaimed rewards. + ### Custodial Staking Centralized service that manages the entire ETH staking process on behalf of the user and retains custody over user private validator keys and withdrawal keys. Custodial staking risks include: severe slashing penalties, reduced overall rewards and increased likelihood of attack on user keys as they are held in a centralized fashion by the service. @@ -35,6 +58,12 @@ A cryptographic process to generate a shared public and private key set, calcula Distributed Validator Technology is another name for SSV (Secret Shared Validator). SSV can also be referred to as DVT because the validator is distributed over multiple non-trusting nodes. +### Effective Balance (EB) + +The active stake balance of a validator on the Beacon Chain, used to calculate rewards and voting weight. After Ethereum's Pectra upgrade, validators can have variable effective balances from 32 to 2048 ETH (previously fixed at 32 ETH). + +In SSV Network, effective balances are reported by oracles and used to calculate fair fee distribution through vUnits (virtual units). ETH clusters pay fees proportional to their validators' actual effective balances, while legacy SSV clusters use the traditional validator count method. + ### Epochs & Slots An epoch lasts approximately 6.4 minutes, and includes 32 slots. A slot lasts 12 seconds, during and is the time period in which a randomly selected validator proposes a block. @@ -93,6 +122,12 @@ Applying secure Multi-Party Computation (MPC) to secret sharing allows for KeySh A service that provides streamlined Ethereum validator set-up and management, but does not hold user private validator keys AND withdrawal keys. Allowing users to maximize staking returns, mitigate security risks and retain complete control over their assets. +### Oracle (SSV Network) + +In SSV Network, oracles are permissioned entities that report validator effective balances from the Beacon Chain to the smart contracts. In v1, there are 4 oracles that require 75% weight consensus to commit balance updates. + +Oracles are supported by SSV stakers, whose staked weight is automatically delegated across all oracles. This oracle system enables fair fee calculation for variable-balance validators post-Pectra. + ### Operator Individuals or institutions that provide the hardware infrastructure, run the SSV protocol, and manage validator KeyShares on behalf of users (stakers). Operators collect fees from stakers in SSV tokens in return for operating their validator(s) on ssv.network. Each operator is ranked on a scale of 0-100% by the DAO based on the overall quality of service they provide. @@ -128,19 +163,28 @@ The SSV Node software maintain peer-to-peer connections with other Nodes to hand ### SSV Token -ssv.network allows access to a decentralized ETH staking infrastructure with SSV token as the protocol’s native token. It has 3 main purposes: +ssv.network allows access to a decentralized ETH staking infrastructure with SSV token as the protocol's native token. It has 4 main purposes: * **Governance** – Submitting votes and voting on DAO proposals -* **Fees** – Operators receive SSV tokens from Stakers for managing and operating validators on their behalf +* **Payments** – The network receives fees paid in ETH by clusters, and the accrued ETH is converted into value for SSV stakers through the staking mechanism * **Grants** – DAO funding for developers and contributors helping to grow the network +* **Staking** – Stake SSV to support oracle infrastructure + +### SSV Staker + +An SSV token holder who stakes their SSV tokens to contribute voting weight to the network's oracle system, which reports validator effective balances to the blockchain. When staking SSV a holder receives cSSV which also allows to participates in SSV governance. While holding cSSV, ETH rewards accrue to the wallet holding cSSV. ### Staker -Services or individual ETH holders that wish to leverage SSV/DVT technology for optimal liveness, security and decentralization of their validator(s). Stakers put 32 ETH β€œat stake” for each validator they want to run. In the PoS consensus mechanism, validators secure the Ethereum blockchain and earn ETH rewards in return for doing so. +Services or individual ETH holders that wish to leverage SSV/DVT technology for optimal liveness, security and decentralization of their validator(s). Stakers put 32 ETH "at stake" for each validator they want to run. In the PoS consensus mechanism, validators secure the Ethereum blockchain and earn ETH rewards in return for doing so. + +### SSV Staking + +The process of staking SSV tokens to earn ETH rewards from network fees. SSV Staking also contributes to the network's oracle infrastructure by providing voting weight for effective balance reporting. ### Staking -Staking is the contributory action of running a node in a PoS consensus mechanism blockchain. One must β€˜put at stake’ a certain amount of network tokens in order to participate in securing the blockchain by verifying and adding blocks. On Ethereum, the minimum threshold to participate as a validator is 32 ETH. Validators will earn ETH rewards for honestly attesting to and adding blocks. A validator risks decreasing their stake by participating in malicious behaviors or for time spent offline, disconnected from the network. +Staking is the contributory action of running a node in a PoS consensus mechanism blockchain. One must 'put at stake' a certain amount of network tokens in order to participate in securing the blockchain by verifying and adding blocks. On Ethereum, the minimum threshold to participate as a validator is 32 ETH. Validators will earn ETH rewards for honestly attesting to and adding blocks. A validator risks decreasing their stake by participating in malicious behaviors or for time spent offline, disconnected from the network. ### Total Value Locked (TVL) @@ -148,6 +192,23 @@ The total amount of ETH in USD (or other currency) that is β€œlocked-up” by st ### Validator -A validator is responsible for confirming transactions and proposing new blocks on the Ethereum blockchain. In order to run a validator, one must put 32 ETH β€˜at stake’, which is subject to increase (or decrease) as the validator performs its assigned duties. A validator is different from the comparable concept of a miner on the legacy Ethereum chain, as validators are called upon by the PoS protocol to propose and validate emerging blocks rather than compete for their generation. +A validator is responsible for confirming transactions and proposing new blocks on the Ethereum blockchain. In order to run a validator, one must put 32 ETH 'at stake', which is subject to increase (or decrease) as the validator performs its assigned duties. A validator is different from the comparable concept of a miner on the legacy Ethereum chain, as validators are called upon by the PoS protocol to propose and validate emerging blocks rather than compete for their generation. An SSV validator is one that is run on ssv.network and employs SSV technology to split the validator key into 4 KeyShares for the purposes of distributing the validator over multiple nodes for redundancy and fault-tolerance. + +Post-Pectra, validators can have variable effective balances from 32 to 2048 ETH. + +### vUnits (Virtual Units) + +A measurement unit used in ETH clusters to calculate fees proportional to validator effective balance. Calculated as: + +``` +vUnits = (effectiveBalance / 32 ETH) Γ— 100 +``` + +Examples: +- 32 ETH validator = 100 vUnits +- 64 ETH validator = 200 vUnits +- 2048 ETH validator = 6400 vUnits + +This ensures that validators with higher effective balances pay proportionally higher fees, as they generate more rewards. Legacy SSV clusters do not use vUnits and treat all validators equally regardless of effective balance. diff --git a/docs/learn/introduction/governance.md b/docs/learn/introduction/governance.md index 1ccda5b..e5dbd77 100644 --- a/docs/learn/introduction/governance.md +++ b/docs/learn/introduction/governance.md @@ -18,7 +18,7 @@ The ssv.network DAO exercises its mandate by two main mechanisms. The first is b * **Network fees** - To use ssv.network, stakers are required to pay a network fee. The network fee is a fixed cost charged per validator, and it’s determined by the DAO. Network fees flow directly into the DAO treasury and can be used to fund further development of the SSV ecosystem and activities that have passed the DAO voting process. Decisions regarding new fee amounts need to be balanced; high enough to cover DAO expenses; but low enough for the SSV protocol to remain competitive. * **Operator fees -** These fees are set and controlled by the operators themselves, not by the DAO governance. The smart contract does however include guardrails that limit the amount by which operators can increase their fees in each fee change cycle as well as the cycle duration (read more on [Operator fee change guidelines](/operators/operator-onboarding/update-fee)). These parameters are essential to ensure the stability of the network and to protect stakers against sudden operator price hikes. On the other hand, if the rate of fee change was too low or the fee change was too long, it could cause the system to be too rigid and not adaptable to the changing market conditions. Setting these parameters must be done judiciously to match the current market conditions. -* **Liquidation parameters** - DAO governance sets the minimum SSV balance required to cover fees for each validator. If the account balance goes below this liquidation threshold, it will be at risk of liquidation. This parameter is essential to ensure the health of the network, and protects it from becoming insolvent (read more on [Liquidations](../protocol-overview/tokenomics/liquidations.md)) +* **Liquidation parameters** - DAO governance sets the minimum SSV balance required to cover fees for each validator. If the account balance goes below this liquidation threshold, it will be at risk of liquidation. This parameter is essential to ensure the health of the network, and protects it from becoming insolvent (read more on [Liquidations](/learn/tokenomics/liquidations.md)) #### Governance Functions diff --git a/docs/learn/introduction/network-overview.md b/docs/learn/introduction/network-overview.md index 59a0565..a371725 100644 --- a/docs/learn/introduction/network-overview.md +++ b/docs/learn/introduction/network-overview.md @@ -8,15 +8,12 @@ The ssv.network ecosystem is composed of 3 types of actors: stakers, operators a ### [Stakers](../../stakers) -Services or individual ETH holders that leverage SSV/DVT technology for optimal liveness, security, and decentralization of their validator(s). Stakers pay a fee in SSV tokens to operators for managing their validator(s). +Services or individual ETH holders that leverage SSV/DVT technology for optimal liveness, security, and decentralization of their validator(s). Stakers pay a fee in ETH to operators for managing their validator(s). ### [Operators](../../operators) -Operators provide the hardware infrastructure, run the SSV protocol, and are responsible for maintaining validators and the overall health of ssv.network. Operators determine their fees for services in SSV tokens and charge stakers for operating and maintaining their validator(s). +Operators provide the hardware infrastructure, run the SSV protocol, and are responsible for maintaining validators and the overall health of ssv.network. Operators determine their fees for services in ETH and charge stakers for operating and maintaining their validator(s). ### DAO The ssv.network DAO decentralises ownership and governance of the ssv.network protocol and treasury, with SSV being the native token of the network. DAO exercises its mandate by two main mechanisms, executing governance functions and executing snapshot proposals passed by the token holders. For more information read the [governance section](governance.md). - - - diff --git a/docs/learn/introduction/ssv-token.md b/docs/learn/introduction/ssv-token.md index e4b74af..5b969a7 100644 --- a/docs/learn/introduction/ssv-token.md +++ b/docs/learn/introduction/ssv-token.md @@ -4,23 +4,32 @@ sidebar_position: 3 # SSV Token -Secret Shared Validator ($SSV) is the native token of [ssv.network](https://ssv.network/). +Secret Shared Validator (SSV) is the native token of [ssv.network](https://ssv.network/). -$SSV's main use cases are payments and governance. +SSV's main use cases are governance and staking. -* **Payments** - serve as a way for stakers to compensate operators for managing their validators -* **Governance** - a way to participate in ssv.network related decision-making and treasury allocations. +* **Governance** - A way to participate in ssv.network related decision-making and treasury allocations +* **Staking** - Stake SSV tokens to support oracle infrastructure -$SSV is playing a pivotal role in the network’s ability to harness a community and motivate the right stakeholders to meaningfully contribute to the network. +SSV is playing a pivotal role in the network's ability to harness a community and motivate the right stakeholders to meaningfully contribute to the network. -### **Tokenomics** +## SSV token utility + +Staked SSV supports the network's oracle infrastructure by providing voting weight for Effective Balance reporting. + +**Key benefits:** +* Support the network's oracle system for validator balance reporting +* Participate in securing decentralized oracle consensus +* Receive ETH rewards from actual network activity -Stakers using ssv.network will pay operators using $SSV. Each participating operator can determine its own price point and compete with other network operators. A percentage of fees collected by operators will be allocated to the DAO treasury in return the DAO will determine the payment in an open vote. +Learn more in the [SSV Staking Guide](/ssv-staking/). + +### **Tokenomics** -Fundamentally, the more ETH is staked in the network, the more fees will be paid to operators and the DAO’s treasury. The DAO will be able to use its treasury for promoting the network’s growth and development efforts thus creating a positive cycle of ETH inflows and $SSV revenue. +Below is a summary of SSV Tokenomics, you can find more details on the [Tokenomics dedicated docs page](/learn/tokenomics/README.md). -$SSV is designed to exponentially progress the network's core values: +SSV is designed to exponentially progress the network's core values: 1. **Decentralized DAO governance -** no single entity or group should have control over the network. -2. **DAO treasury -** continuously increase the DAO’s treasury value (for-profit DAO)**.** A stable, and well-funded treasury will allow the DAO to expedite development efforts, allocate grants and engage in revenue share schemes for DAO members. -3. **Operator income -** a growing network will affect operator compensation. Higher income will incentivize new operators to join the network and existing ones to improve their service, performance, and competitiveness. +2. **DAO treasury -** continuously increase the DAO’s treasury value (for-profit DAO). A stable, and well-funded treasury will allow the DAO to expedite development efforts, allocate grants and engage in revenue share schemes for DAO members. +3. **Operator income -** a growing network will affect operator compensation. Higher income will incentivize new operators to join the network and existing ones to improve their service, performance, and competitiveness. \ No newline at end of file diff --git a/docs/learn/introduction/tech-overview.md b/docs/learn/introduction/tech-overview.md index 9bbca1c..85abb5a 100644 --- a/docs/learn/introduction/tech-overview.md +++ b/docs/learn/introduction/tech-overview.md @@ -9,13 +9,13 @@ SSV is a sophisticated multi-signature wallet with a consensus layer. It is a mi * **Distributed Key Generation** -This process generates a shared public and private key set calculated by the operators running an SSV instance. Each operator owns a single portion of the private key, ensuring that no single operator can affect or have control over the entire private key and make unilateral decisions. +This process generates a shared public and private key set calculated by the operators running an SSV instance. Each operator owns a single portion of the private key, ensuring that no single operator can affect or have control over the entire private key and make unilateral decisions. * **Shamir Secret Sharing** This mechanism used to reconstruct a validator key using a pre-defined threshold of KeyShares. Individual KeyShares cannot be used to sign a duty, yet not all are needed if some are faulty as described by nβ‰₯3f+1. -SSV.network is able to leverage the BLS signatures - allowing for multiple signatures to be combined to recreate a validator key signature. By combining Shamir and BLS - the keys are 'broken down' to share and regrouped whenever a duty is assigned. +SSV.network is able to leverage the BLS signatures - allowing for multiple signatures to be combined to recreate a validator key signature. By combining Shamir and BLS - the keys are 'broken down' to share and regrouped whenever a duty is assigned. * **Multi-Party Computation** @@ -23,4 +23,4 @@ Applying secure Multi-Party Computation (MPC) to secret sharing allows the KeySh * **Istanbul Byzantine Fault Tolerance Consensus** -Tying it all together, the consensus layer of SSV, based on the Istanbul Byzantine Fault Tolerance (IBFT) algorithm. The algorithm randomly selects a validator node (KeyShare) responsible for block proposal and sharing the information with the other participants. Once the predefined threshold of KeyShares deems the block to be valid, it is added to the chain. As such, consensus can be reached even if some operators (up to the threshold) are faulty or not currently online. +Tying it all together, the consensus layer of SSV, based on the Istanbul Byzantine Fault Tolerance (IBFT) algorithm. The algorithm randomly selects a validator node (KeyShare) responsible for block proposal and sharing the information with the other participants. Once the predefined threshold of KeyShares deems the block to be valid, it is added to the chain. As such, consensus can be reached even if some operators (up to the threshold) are faulty or not currently online. diff --git a/docs/learn/protocol-overview/README.md b/docs/learn/protocol-overview/README.md index d19d29f..67e7df5 100644 --- a/docs/learn/protocol-overview/README.md +++ b/docs/learn/protocol-overview/README.md @@ -1,6 +1,7 @@ --- sidebar_label: 'Protocol Overview' sidebar_position: 2 +unlisted: true --- # Protocol Overview diff --git a/docs/learn/protocol-overview/tokenomics/README.md b/docs/learn/protocol-overview/tokenomics/README.md deleted file mode 100644 index 46c7af1..0000000 --- a/docs/learn/protocol-overview/tokenomics/README.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Understanding SSV Network tokenomics -sidebar_position: 1 ---- - -# Tokenomics - -The ssv.network utilizes its native SSV token to facilitate payments between stakers and SSV node operators to maintain their validators. Operators maintain validators by reaching a consensus with clusters of other operators to perform network duties on the beacon chain, thereby generating Ethereum staking rewards for stakers. - -Operators receive SSV payments and generate ETH rewards for stakers. Stakers pay SSV and receive generated ETH rewards in return. - - -![Operators receive SSV payments and generate ETH rewards for stakers. Stakers pay SSV and receive generated ETH rewards in return.](/img/tokenomics-readme-1.avif) -*Operators receive SSV payments and generate ETH rewards for stakers. Stakers pay SSV and receive generated ETH rewards in return.* \ No newline at end of file diff --git a/docs/learn/tokenomics/README.md b/docs/learn/tokenomics/README.md new file mode 100644 index 0000000..7c5e47d --- /dev/null +++ b/docs/learn/tokenomics/README.md @@ -0,0 +1,49 @@ +--- +description: Understanding SSV Network tokenomics +sidebar_position: 1 +--- + +# Tokenomics + +SSV Network has evolved to include both payment mechanisms and staking utilities, creating a comprehensive economic model that aligns network growth with token holder rewards. + +## Network Payments + +The network uses ETH-based payments for clusters and operators: + +* **Clusters pay in ETH** - Deposit ETH to cover operator and network fees +* **Operators earn in ETH** - Receive ETH payments for managing validators +* **Network fees in ETH** - A portion of fees flows to the protocol + +![Operators receive ETH payments and generate ETH rewards for stakers. Stakers pay ETH and receive generated ETH rewards in return.](/img/tokenomics-readme-1.png) +*Operators receive ETH payments and generate ETH rewards for stakers. Stakers pay ETH and receive generated ETH rewards in return.* + +## SSV token utility + +Staked SSV supports the network's oracle infrastructure by providing voting weight for effective balance reporting. + +Also, when clusters pay fees in ETH, a portion flows into the SSV Staking contract and is distributed proportionally to all token holders. Learn more in the [SSV Staking Guide](/ssv-staking/). + +## Dual Utility Model + +SSV token serves multiple purposes in the ecosystem: + +| Utility | Description | Benefit | +|---------|-------------|---------| +| **Governance** | Vote on protocol decisions and treasury allocation | Decentralized control | +| **Oracle Support** | Staked SSV supports oracle consensus | Network security and accuracy | +| **Legacy Payments** | SSV tokens still used in legacy clusters | Backward compatibility | +| **Staking** | Stake SSV to support the network's oracle infrastructure | Provides voting weight for effective balance reporting | + +## Economic Sustainability + +The new economic model creates sustainable, circular value flow: + +1. **More ETH staked** β†’ More validators using SSV +2. **More validators** β†’ More ETH fees collected +3. **More fees** β†’ Higher rewards for SSV stakers +4. **Higher rewards** β†’ Increased usability for SSV token +5. **More SSV staked** β†’ Stronger oracle infrastructure +6. **Stronger network** β†’ Attracts more ETH validators + +This positive feedback loop ties SSV directly to real network usage and rewards. diff --git a/docs/learn/protocol-overview/tokenomics/fees.md b/docs/learn/tokenomics/fees.md similarity index 57% rename from docs/learn/protocol-overview/tokenomics/fees.md rename to docs/learn/tokenomics/fees.md index 8f825d9..2696a61 100644 --- a/docs/learn/protocol-overview/tokenomics/fees.md +++ b/docs/learn/tokenomics/fees.md @@ -8,18 +8,18 @@ sidebar_position: 1 The ssv.network utilizes a free-market approach such that operators can set their desired fees. This approach drives competition between operators and helps ensure that operator services are provided to stakers at lower costs. -When operators register to the network, they set their fee (denominated in SSV), which is then charged to each validator that selects them as an operator. +When operators register to the network, they set their fee, which is then charged to each validator that selects them as an operator. For simplicity and standardization, fees charged for using the network are normalized as annual payments. Although, in practice, they are paid to operators on an ongoing basis - per each passing block (contrary to a single payment model). -For example, assuming there are 100 blocks per day and an operator has a set fee of 365 SSV per year, then the revenue from each validator would be: +For example, assuming there are 100 blocks per day and an operator has a set fee of 0.365 ETH per year, then the revenue from each validator would be: -365 ssv / 100 blocks per day / 365 days in a year = 0.01 SSV per block +0.365 ETH / 100 blocks per day / 365 days in a year = 0.00001 ETH per block + +You can find more details on the dedicated [Operator Onboarding page](/operators/operator-onboarding/README.md). ### Network Fees In addition to operator fees, stakers are also required to pay a β€˜network fee’ for each validator they run through the network. -The network fee is a fixed cost determined by the DAO that governs the network. Also denominated in SSV and similar to operator fees, they are paid continuously over time to the DAO treasury. - -This capital is used to fund, grow, and develop activities and projects in the ecosystem that have passed the voting process. +The network fee is a fixed cost determined by the DAO that governs the network. It's accessible through the [SSV Network Views smart contract](/developers/smart-contracts/ssvnetworkviews#getnetworkfee-) or via the [Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#dao-constants-and-protocol-network-fee-index). \ No newline at end of file diff --git a/docs/learn/protocol-overview/tokenomics/liquidations.md b/docs/learn/tokenomics/liquidations.md similarity index 68% rename from docs/learn/protocol-overview/tokenomics/liquidations.md rename to docs/learn/tokenomics/liquidations.md index 569fc06..6d72db6 100644 --- a/docs/learn/protocol-overview/tokenomics/liquidations.md +++ b/docs/learn/tokenomics/liquidations.md @@ -7,7 +7,7 @@ sidebar_position: 3 Since the payments between validators and operators are a zero-sum game (revenue of operators is the expenses of validators) and payments are paid as an ongoing process that is calculated in retrospect, there can't be a case where a user has insufficient funds in their balance to cover the validator's operational costs. -To use the ssv.network, stakers are required to deposit a sufficient balance of SSV tokens into their cluster balance proportional to the number of validator in the cluster itself. This balance is known as _Liquidation Collateral_, whereas the exceeding portion is usually referred to as Operational Runway. +To use the ssv.network, stakers are required to deposit a sufficient balance of ETH into their cluster balance proportional to the Effective Balance of their validators. This balance is known as _Liquidation Collateral_, whereas the exceeding portion is usually referred to as Operational Runway. ![Liquidation Collateral](/img/liquidation-1.avif) @@ -15,7 +15,7 @@ To use the ssv.network, stakers are required to deposit a sufficient balance of Since transactions on Ethereum aren't free, and users can't incur additional costs if their account runs out of balance, an incentivization model is required to keep the system solvent. -This requires additional actors called [Liquidators](../../../operators/liquidator-bot/) to work behind the scenes to keep the system functioning by flagging users that have insufficient balances to carry their expenses. +This requires additional actors called [Liquidators](/operators/liquidator-bot/) to work behind the scenes to keep the system functioning by flagging users that have insufficient balances to carry their expenses. The ssv network rewards liquidators for the costs and risks associated with liquidating insolvent clusters. The provided collateral serves as a liquidation penalty for clusters and a reward to liquidators for their efforts. @@ -30,9 +30,9 @@ liquidatable = balanceParameterDescription--node-urlThe Ethereum execution node end-point--private-keyPrivate key of the liquidator's wallet--ssv-token-addressSSV token contract address--ssv-network-addressThe ssv.network contract address--ssv-network-viewsThe ssv.network views contract address--gas-price

Gas price heuristic according to the median gas price suggested by web3 gas price oracle:

  • Low (*0.1)
  • Med (*0.2)
  • High (*0.3)
+| CLI Parameter | .ENV Variable | Description | +| ---------------| ---------- | --------------------------------------- | +| `--node-url` | `NODE_URL` |The Ethereum execution node end-point | +| `--private-key` | `ACCOUNT_PRIVATE_KEY` |Private key of the liquidator's wallet | +| `--liquidator-type` | `LIQUIDATOR_TYPE` |The liquidator type. `eth` `ssv` | +| `--ssv-sync-env` | `SSV_SYNC_ENV` |The SSV sync environment. `prod` (default) or `stage` | +| `--ssv-sync` | `SSV_SYNC` |The SSV contract name. `v4.hoodi` (default) or `v4.mainnet` | +| `--gas-price` | `GAS_PRICE` |Gas price heuristic according to the median gas price suggested by web3 gas price oracle: low (0.1), med (0.2), high (0.3). Default: low | +| `--hide-table` | `HIDE_TABLE` |Hide/show realtime table | +| `--max-visible-blocks` | `MAX_VISIBLE_BLOCKS` |Max block range to display active clusters (optional, by default: `50000`) | + ### Running Options @@ -44,7 +49,7 @@ This installation requires NodeJS on your machine. ```sh -yarn cli --ssv-sync-env= --ssv-sync= --node-url= --private-key= --gas-price=slow --max-visible-blocks= +yarn cli --liquidator-type=eth --ssv-sync-env= --ssv-sync= --node-url= --private-key= --gas-price=low --max-visible-blocks= ``` @@ -53,13 +58,14 @@ yarn cli --ssv-sync-env= --ssv-sync= GAS_PRICE=medium # low | medium | high HIDE_TABLE=false MAX_VISIBLE_BLOCKS=50000 SSV_SYNC_ENV=prod # prod or stage, prod - is default value -SSV_SYNC=v4.prater # v4.holesky | v4.mainnet | v4.prater +SSV_SYNC=v4.mainnet # v4.hoodi - is the default ``` @@ -68,17 +74,15 @@ SSV_SYNC=v4.prater # v4.holesky | v4.mainnet | v4.prater :::warning Make sure that `--ssv-sync` and `--node-url` parameters (or `SSV_SYNC` and `NODE_URL` environment variables) are all relative to the same blockchain. -For example, for Holesky (using a sample QuickNode RPC endpoint), the command should look like this: +For example, for Hoodi (using a sample QuickNode RPC endpoint), the command should look like this: ```sh yarn cli \ --ssv-sync-env=prod \ ---ssv-sync=v4.holesky \ ---node-url=https://red-silent-dawn.ethereum-holesky.quiknode.pro// \ +--ssv-sync=v4.hoodi \ +--node-url=https://red-silent-dawn.ethereum-hoodi.quiknode.pro// \ --private-key= \ --gas-price=slow \ --max-visible-blocks=5000 ``` - -The smart contract addresses were taken [from this page](../../developers/smart-contracts/#holesky-testnet), in this instance. ::: diff --git a/docs/operators/operator-management/registration.md b/docs/operators/operator-management/registration.md index 8f3829e..161eef5 100644 --- a/docs/operators/operator-management/registration.md +++ b/docs/operators/operator-management/registration.md @@ -14,7 +14,7 @@ You can register your operator through the SSV network [web app](https://app.ssv While registering your operator you will need to provide the following parameters: * [Operator public key](/operators/operator-node/node-setup) - Generated in the node installation process (base64 format) -* [Operator fee](../../learn/protocol-overview/tokenomics/fees) - The fee charged by the operator per each managed validator +* [Operator fee](/learn/tokenomics/fees) - The fee charged by the operator per each managed validator :::info The wallet address used to register the operator is the only address that will hold management permissions for it. @@ -52,7 +52,7 @@ Click _Next_ when ready. In the following screen, shown below, you are being asked to set the Operator Fee. -For more information about fees, please [head over to the related page](../../learn/protocol-overview/tokenomics/fees). Just know that it will be possible to update the Operator fees later, [with limitations imposed by the protocol, to protect stakers](/operators/operator-onboarding/update-fee), for a guide on how to do that, head over to [the dedicated page](/operators/operator-management/updating-operator-fees). +For more information about fees, please [head over to the related page](/learn/tokenomics/fees). Just know that it will be possible to update the Operator fees later, [with limitations imposed by the protocol, to protect stakers](/operators/operator-onboarding/update-fee), for a guide on how to do that, head over to [the dedicated page](/operators/operator-management/updating-operator-fees). Enter a number and click _Next_ when ready. diff --git a/docs/operators/operator-node/node-setup/README.md b/docs/operators/operator-node/node-setup/README.md index 992267f..87b573c 100644 --- a/docs/operators/operator-node/node-setup/README.md +++ b/docs/operators/operator-node/node-setup/README.md @@ -23,7 +23,7 @@ At a high level, here is what involved in installing an SSV Node: 3. Adjust your configuration 4. Run it! -Please note the process implies you will setup Execution and Beacon clients on your own, _before_ installing the SSV Node. +Please note the process implies you will setup Execution and Beacon clients on your own, _before_ installing the SSV Node. Once you have your node running you'll be able to participate in multiple validator clusters and earn rewards πŸ₯³ @@ -100,7 +100,7 @@ In order to run the SSV Node, in a server, only Docker engine is necessary, you Git -To install the latest stable version for your release of Debian/Ubuntu run `apt-get install git` in your command line. +To install the latest stable version for your release of Debian/Ubuntu run `apt-get install git` in your command line. If your machine is using another Linux distribution, please use the [official Git documentation](https://git-scm.com/downloads/linux), and find the option that better fits your server configuration. @@ -153,7 +153,7 @@ Example: `BEACON_NODE_ADDR=http://1.2.3.4:5052;http://1.2.3.4:5053` ::: ### Password and private key -On the first start the Node will generate a random `password` and encrypted `private_key` files. You can find the files under `~/ssv-stack/ssv-node-data` directory. +On the first start the Node will generate a random `password` and encrypted `private_key` files. You can find the files under `~/ssv-stack/ssv-node-data` directory. **If you already have encrypted key and password files**: * Copy/move them to `/ssv-stack/ssv-node-data` @@ -172,7 +172,7 @@ Both password and private key are needed to run SSV and DKG Nodes. ### Custom ports -We recommend using the default ports for ease of the setup. +We recommend using the default ports for ease of the setup. If you wish to change any of the ports β€” change them in both `ssv.env` and `docker-compose.yaml`, then get [back to exposing those ports in your firewall](#4-adjust-firewall). @@ -210,7 +210,7 @@ Be sure to implement a robust backup and recovery strategy for your database(s), ## What's next? -* You might want to [configure MEV](/operators/operator-node/setup-sidecars/configuring-mev) to increase your rewards for block proposals. +* You might want to [configure MEV](/operators/operator-node/setup-sidecars/configuring-mev) to increase your rewards for block proposals. * You can [enable DKG node](/operators/operator-node/setup-sidecars/enabling-dkg/) to increase your chances of being included in a cluster. diff --git a/docs/operators/operator-node/setup-sidecars/enabling-dkg/README.md b/docs/operators/operator-node/setup-sidecars/enabling-dkg/README.md index 3518f1e..ae91175 100644 --- a/docs/operators/operator-node/setup-sidecars/enabling-dkg/README.md +++ b/docs/operators/operator-node/setup-sidecars/enabling-dkg/README.md @@ -17,6 +17,6 @@ Also, in order to access logs it is necessary to utilize permanent storage when You can setup your `ssv-dkg` node by following these three pages: -1. [**Prerequisites**](prerequisites.md) -2. [**Start DKG Node**](start-dkg-node/) +1. [**Prerequisites**](prerequisites.md) +2. [**Start DKG Node**](start-dkg-node/) 3. [**Final Steps**](final-steps.md) diff --git a/docs/operators/operator-node/setup-sidecars/enabling-dkg/prerequisites.md b/docs/operators/operator-node/setup-sidecars/enabling-dkg/prerequisites.md index d719979..2dfe3c9 100644 --- a/docs/operators/operator-node/setup-sidecars/enabling-dkg/prerequisites.md +++ b/docs/operators/operator-node/setup-sidecars/enabling-dkg/prerequisites.md @@ -7,7 +7,7 @@ sidebar_position: 1 ## Minimum requirements -The minimum requirement is an AWS `t3.small` or equivalent machine dedicated to run DKG. +The minimum requirement is an AWS `t3.small` or equivalent machine dedicated to run DKG. The recommend requirement is an AWS `t3.medium` or higher tier machine ([https://aws.amazon.com/ec2/instance-types/](https://aws.amazon.com/ec2/instance-types/)). Minimum docker resource allocations: @@ -31,7 +31,7 @@ In order to successfully participate in DKG ceremonies initiated by stakers, you * **Operator ID** - the ID of your operator within the SSV network. * **Operator Key Pair** - * **Public Key** - the public key of the operator + * **Public Key** - the public key of the operator * **Private Key** - the private key of the operator as an password-encrypted file (if you are in possession of raw text private key, follow [this migration guide to encrypt your existing operator keys](/operators/operator-node/maintenance/troubleshooting/#faq)) * **Machine Endpoint** - the endpoint (`protocol:ip:port`, e.g. `https://my-dkg.com:3030`) of the machine intended to run the `ssv-dkg` client (if you have a domain name, instead of an `ip` that works as well) diff --git a/docs/operators/operator-onboarding/README.md b/docs/operators/operator-onboarding/README.md index fb6363e..b09210c 100644 --- a/docs/operators/operator-onboarding/README.md +++ b/docs/operators/operator-onboarding/README.md @@ -14,9 +14,17 @@ This can be done by installing the [node software](/operators/operator-node/) on ### Operator Fee -Operators set their own fees - denominated in SSV tokens - to be charged per each validator that selects them as one of their operators. +:::tip ETH vs SSV fees +**Previously registered operators will have a default ETH fee** which [they can change as usual](/operators/operator-management/updating-operator-fees.md). They will also have 2 separate balances β€” in ETH and SSV token. Once clusters they manage migrate to ETH, the operator will only have ETH balance. -Operator earnings are paid to their account balance, and can be withdrawn to their wallet at any time. +**Newly registered operators** will only have ETH balance, without an option to be paid in SSV token. +::: + +Operators set their own fees denominated in ETH. This fee will be charged per each 32 ETH staked with validators that selects them as one of their operators. + +Fees in SSV (legacy) can not be changed and are charged per each validator, regardless of their effective balance. + +Operator earnings are paid to their account balance(s), and can be withdrawn to their wallet at any time. **Fee Configuration** @@ -24,14 +32,13 @@ Operators initially set their fee when registering an operator to the network. Fees are presented as annual payments, but in practice are paid to operators continuously as an ongoing process - per each passed block. -This means that when setting the operator fee through the smart contract (whether at registration or fee updates), operators should set their preferred fee according to a fee per block format. +Please note, if you set your operator fee through the smart contract (whether at registration or fee updates), the value should be according to a fee per block format. * To calculate fee per block according to a desired annual fee in fiat (USD): -$$ Fee\;per\;block = \dfrac{Annual\;Fee_{usd}}{SSV_{usd}}\;/\;Blocks_{year} $$ - +$$ Fee\;per\;block = \dfrac{Annual\;Fee_{usd}}{ETH_{usd}}\;/\;Blocks_{year} $$ Where: - $\text{Annual Fee}_{usd}$ - desired fee per year in USD -- $SSV_{usd}$ - SSV price in USD +- $ETH_{usd}$ - ETH price in USD - $Blocks_{year}$ - avg. number of blocks per year ([reference](https://ycharts.com/indicators/ethereum_blocks_per_day)) diff --git a/docs/operators/operator-onboarding/offboarding.md b/docs/operators/operator-onboarding/offboarding.md index 0c95d2c..d5df22d 100644 --- a/docs/operators/operator-onboarding/offboarding.md +++ b/docs/operators/operator-onboarding/offboarding.md @@ -12,7 +12,7 @@ An operator can choose to leave the network at any time. Choosing to remove an o * Remove themself from the network and they will no longer be discoverable by other validators. :::warning -Please be aware: this process is irreversible and removed Operators would not be able to reactivate or register this operator back in the future. +Please be aware: this process is **irreversible** and removed Operators would not be able to reactivate or register this operator back in the future. Attempting to register an Operator using the same private key will result in an error. In such a case, Operator registration must be done with with a new key. ::: diff --git a/docs/operators/operator-onboarding/permissioned-operators.md b/docs/operators/operator-onboarding/permissioned-operators.md index d7e0f7e..580f884 100644 --- a/docs/operators/operator-onboarding/permissioned-operators.md +++ b/docs/operators/operator-onboarding/permissioned-operators.md @@ -5,15 +5,23 @@ sidebar_position: 5 # Permissioned Operators -### What are Permissioned Operators? +## What are Permissioned Operators? Permissioned Operators (also known as "Private") are Operators that have selected to authorize only a list of wallet addresses to register validators to them. There are multiple reasons why an Operator would want this, and various reasons why they would **not** want to choose this option, and why this disabled by default. -:::tip New feature -The latest version of the SSVNetworks smart contract adds the ability to set multiple whitelisted addresses to multiple operators in bulk. Information on how to do this via the webapp can be found [here](/operators/operator-management/configuring-a-permissioned-operator). +### How to become a Permissioned Operator? + +The **`setOperatorMultipleWhitelists`** smart contract function allows to whitelist a set of addresses to a number of different with the permission to register validators to the specified operators. + +Conveniently, [the ssv.network WebApp](https://app.ssv.network/) offers a way to interact with the smart contract through a UI, and you can get guidance on the process [on this page in this documentation](/operators/operator-management/configuring-a-permissioned-operator). + +:::info +It's important to note that configuring Permissioned Operator only affects **future validator registrations**. + +If any number of validators have already been registered to various clusters that include a certain Operator, configuring this Operator to become a Permissioned Operator **will not** cause these validators to stop working. ::: -#### How to identify Permissioned Operators +### How to identify Permissioned Operators When an Operator owner chooses to identify their Operator as Permissioned, **any smart contract transaction to register a validator with such Operator will fail**, if the sender of the transaction is not included in the list of whitelisted addresses. @@ -25,13 +33,13 @@ Similarly, the [SSV Explorer](https://explorer.ssv.network/operators/1) also sho ![permissioned-operator](/img/permissioned-operators-2.avif) -#### SSV Subgraph +### SSV Subgraph SSV also provide a subgraph to easily look up information on permissioned Operators, this tracks all the events surrounding whitelisting and means we can check which operators are private, and which addresses are whitelisted per operator. You can find out more details on how to use the subgraph [**here**](../../developers/tools/ssv-subgraph/)**.** One last way to verify this is to use the [SSV Network Views smart contract](../../developers/smart-contracts/ssvnetworkviews.md#getoperatorbyid-operatorid). -#### Use Cases +### Use Cases Since setting an operator as Permissioned Operator has the consequence of renouncing from potentially being chosen by public customers to operate their validators, let's talk about the upsides, and why one would choose to do so. The main use cases for a Permissioned Operator are: @@ -48,14 +56,3 @@ The team could elect to reduce Operator Fees to 0, but this would mean that **ev In practical terms, this means renouncing the potential profits from public customers choosing their Operator and paying Operator fees, but if the team projects that the service fees paid to the Staking Service and the convenience of not paying Operator fees will outweigh the potential missed revenue, then this is the right choice for them. -### How to become a Permissioned Operator? - -The **`setOperatorMultipleWhitelists`** smart contract function allows to whitelist a set of addresses to a number of different with the permission to register validators to the specified operators. - -Conveniently, [the ssv.network WebApp](https://app.ssv.network/) offers a way to interact with the smart contract through a UI, and you can get guidance on the process [on this page in this documentation](/operators/operator-management/configuring-a-permissioned-operator). - -:::info -It's important to note that configuring Permissioned Operator only affects **future validator registrations**. - -If any number of validators have already been registered to various clusters that include a certain Operator, configuring this Operator to become a Permissioned Operator **will not** cause these validators to stop working. -::: diff --git a/docs/operators/operator-onboarding/update-fee.md b/docs/operators/operator-onboarding/update-fee.md index a85d51a..0326f4d 100644 --- a/docs/operators/operator-onboarding/update-fee.md +++ b/docs/operators/operator-onboarding/update-fee.md @@ -9,7 +9,7 @@ On this page you will find educational concepts, to see the actionable steps to Fees are initially set when registering an operator but can be changed at any point in time. -Fee changes are generally initiated to stay competitive with other operators or to align with SSV market price fluctuations. +Fee changes are generally initiated to stay competitive with other operators. ### Fee Increase Process diff --git a/docs/ssv-staking/README.md b/docs/ssv-staking/README.md new file mode 100644 index 0000000..16e2031 --- /dev/null +++ b/docs/ssv-staking/README.md @@ -0,0 +1,129 @@ +--- +sidebar_position: 1 +--- + +# SSV Staking + +SSV Staking enables SSV token holders to support the network's oracle infrastructure and get rewards. When you stake SSV, you receive cSSV (Compound SSV) tokens and can continue to participate in SSV Network governance processes. While you hold cSSV, ETH rewards accrue to the wallet holding cSSV and can be claimed at any time without the need to unstake SSV. + +## Overview + +SSV Network has transitioned to a model where network fees are paid in ETH, creating a sustainable revenue stream that flows directly to SSV stakers. By staking your SSV tokens, you: + +- **Support the network** - Your staked weight contributes to oracle consensus for effective balance reporting +- **Maintain liquidity** - Receive transferable cSSV tokens that represent your staked position +- **Retain flexibility** - Claim rewards anytime and unstake with a 7-day cooldown period + + + +## How It Works + +### The Staking Flow + +``` +Stake SSV β†’ Receive cSSV β†’ Claim Rewards β†’ Unstake (7-day cooldown) +``` + +1. **Stake SSV tokens** - Deposit your SSV tokens into the staking contract +2. **Receive cSSV** - Get cSSV tokens representing your staked position (1:1 initially) +3. **Claim rewards** - Withdraw your accumulated ETH rewards anytime +4. **Unstake** - Initiate unstaking with a 7-day cooldown, then withdraw SSV + remaining rewards + +### ETH Fees Flow + +Network fees flow from clusters to SSV stakers through the following mechanism: + +``` +ETH Clusters pay fees + ↓ +Network fee portion + ↓ +SSV Staking contract + ↓ +Distributed to cSSV holders +``` + +When clusters pay operator fees and network fees in ETH, a portion of these fees flows into the SSV Staking contract. These ETH rewards are distributed proportionally to all cSSV holders based on their share of the total staked SSV. + + + +## cSSV Token Mechanics + +cSSV (Compound SSV) is a **non-rebasing**, **index-based** reward token that represents your staked SSV position. + +### Key Properties + +- **Non-rebasing**: Your cSSV balance stays constant - it doesn't automatically increase +- **Transferable**: cSSV is a standard ERC-20 token that can be transferred or used in DeFi +- **Separate rewards**: ETH rewards accrue separately and can be claimed independently +- **DeFi compatible**: Use cSSV in other protocols while earning staking rewards + +### How Rewards Work + +Unlike rebasing tokens where your balance increases, cSSV uses an **index-based reward model**: + +1. Your cSSV balance remains fixed +2. The reward index increases as network fees flow in +3. Your claimable ETH = (cSSV balance) Γ— (reward index increase) +4. Claim rewards anytime without affecting your cSSV balance + +### Example + +- You stake 1,000 SSV β†’ Receive 1,000 cSSV +- Network earns 10 ETH in fees +- If you hold 1% of total cSSV, you can claim 0.1 ETH +- Your cSSV balance stays at 1,000 +- You can claim rewards multiple times as fees continue to flow in + + + +## Oracle Delegation (v1) + +When you stake SSV, your stake weight automatically contributes to the network's oracle system, which reports validator effective balances to the blockchain. + +### Automatic Delegation + +In v1, your staked weight is **automatically split equally** across all 4 permissioned oracles. This means: + +- No manual delegation required +- All stakers participate in oracle consensus +- 75% quorum required for balance commitments +- Your weight remains active during the unstaking cooldown period + +### Future Versions + +Future versions of SSV Staking will introduce: +- Variable number of oracles +- Staker-chosen delegation +- Performance-based oracle rewards +- Entry/exit queues + +## Unstaking Process + +Unstaking SSV involves a **7-day cooldown period** to maintain protocol stability: + +| Step | Duration | Details | +|------|----------|---------| +| **Initiate Unstake** | Immediate | Call unstake function, cooldown begins | +| **Cooldown Period** | 7 days | Your weight remains active for oracle voting | +| **Rewards Stop** | During cooldown | No new rewards accrue after initiating unstake | +| **Withdraw** | After cooldown | Receive SSV + any unclaimed ETH rewards | + +### Why a Cooldown Period? + +The 7-day cooldown serves several purposes: + +1. **Oracle stability** - Prevents rapid weight changes that could affect consensus +2. **Protocol security** - Maintains voting power during critical oracle reporting periods +3. **Future governance** - Prepares for future governance where staked SSV may serve as protocol backstop + +⚠️ **Important**: Rewards stop accruing immediately when you initiate unstaking, even though your oracle voting weight remains active during the cooldown. + +## Getting Started + +Ready to start staking? Follow these guides: + +- [Stake SSV](stake-ssv.md) - Step-by-step guide to stake your SSV tokens +- [Claim Rewards](claim-rewards.md) - How to claim your accumulated ETH rewards +- [Unstake SSV](unstake-ssv.md) - How to unstake your SSV tokens +- [FAQ](faq.md) - Frequently asked questions diff --git a/docs/ssv-staking/claim-rewards.md b/docs/ssv-staking/claim-rewards.md new file mode 100644 index 0000000..ce102a1 --- /dev/null +++ b/docs/ssv-staking/claim-rewards.md @@ -0,0 +1,107 @@ +--- +sidebar_position: 3 +--- + +# Claim Rewards + +Claim your accumulated ETH rewards from SSV staking anytime without unstaking. + +## Overview + +As an SSV staker, you earn ETH rewards proportional to your share of total staked SSV. These rewards: + +- Accrue continuously as clusters pay network fees +- Are tracked separately from your cSSV balance +- Can be claimed anytime without affecting your staking position +- Do not auto-compound (your cSSV balance stays constant) + +## Claiming Process + +### Step 1: Connect Wallet + +Navigate to the SSV Network webapp and connect your wallet holding cSSV tokens. + + + +### Step 2: View Unclaimed Rewards + +Go to the "Staking" section and locate the "Unclaimed Rewards" panel showing total ETH available, reward history, current APY, and last claim timestamp. + + + +### Step 3: Initiate Claim + +Click "Claim Rewards" and review the claim details (ETH amount, estimated gas fees, destination address). + + + +### Step 4: Confirm Transaction + +Your wallet will prompt for confirmation. Review and confirm the transaction, then wait for blockchain confirmation. + + + +### Step 5: Receive ETH + +Once confirmed, ETH is sent to your wallet. Your "Unclaimed Rewards" counter resets to 0, cSSV balance remains unchanged, and new rewards continue accruing immediately. + + + +## How Rewards Are Calculated + +``` +Your Rewards = (Your cSSV / Total cSSV) Γ— Total Network Fees +``` + +**Example:** +- You hold 1,000 cSSV +- Total cSSV supply: 100,000 +- Network collects 10 ETH in fees +- Your share: (1,000 / 100,000) Γ— 10 ETH = 0.1 ETH + +## Factors Affecting Rewards + +1. **Network usage** - More validators = more fees = more rewards +2. **Your stake size** - Larger cSSV balance = larger reward share +3. **Total staked SSV** - More competition = smaller individual share +4. **Network fee rate** - Set by the DAO +5. **Time elapsed** - Longer between claims = more accumulated + +## After Claiming + +- cSSV balance stays the same +- Oracle voting weight unchanged +- Continue earning new rewards immediately +- Can claim again when rewards accumulate + +## Manual Compounding + +cSSV does not auto-compound. To compound rewards: + +1. Claim ETH rewards +2. Swap ETH for SSV tokens +3. Stake the new SSV tokens +4. Receive additional cSSV +5. Earn rewards on larger cSSV balance + +⚠️ **Note**: Requires manual action and incurs transaction costs. + +## Rewards During Unstaking + +⚠️ **Critical**: Rewards stop accruing the MOMENT you initiate unstaking, not after the 7-day cooldown. + +| Stage | Rewards Accruing? | Can Claim? | +|-------|-------------------|------------| +| **Staked** | βœ… Yes | βœ… Yes | +| **Unstaking initiated** | ❌ No | βœ… Yes | +| **During 7-day cooldown** | ❌ No | βœ… Yes | +| **After cooldown** | ❌ No | βœ… During withdrawal | + +## Transfers and Rewards + +If you transfer cSSV tokens to another wallet: + +- **You keep**: All unclaimed ETH rewards accrued up to the transfer +- **Recipient gets**: The cSSV tokens +- **Recipient earns**: New rewards from the transfer moment onward +- **You can still**: Claim your historical rewards diff --git a/docs/ssv-staking/faq.md b/docs/ssv-staking/faq.md new file mode 100644 index 0000000..562658c --- /dev/null +++ b/docs/ssv-staking/faq.md @@ -0,0 +1,306 @@ +--- +sidebar_position: 5 +--- + +# SSV Staking FAQ + +## General Staking + +### What is SSV Staking? + +SSV Staking allows SSV token holders to support oracle infrastructure. When you stake SSV, you receive cSSV tokens to keep participating in SSV Network governance and earn a proportional share of network fees paid by clusters. While you hold cSSV, ETH rewards accrue to the wallet holding cSSV and can be claimed at any time without the need to unstake SSV + +### How do I start staking? + +1. Connect your wallet to the SSV webapp +2. Navigate to the Staking section +3. Enter the amount of SSV to stake +4. Approve the token (first time only) +5. Confirm the staking transaction + +See the [Stake SSV](stake-ssv.md) guide for detailed steps. + +### What is cSSV? + +cSSV (Compound SSV) is a non-rebasing ERC-20 token you receive when staking SSV. Your cSSV balance stays constant while ETH rewards accrue separately. It's fully transferable and can be used in other DeFi protocols. + +### How much SSV should I stake? + +Consider: +- Keep some SSV unstaked for liquidity needs +- Factor in the 7-day unstaking cooldown +- Larger stakes earn more rewards +- You can always stake more later + +### Is there a minimum staking amount? + +Check the webapp for current minimum requirements. Minimums ensure gas costs are economical relative to potential rewards. + +### Can I stake from multiple wallets? + +Yes! Each wallet can stake independently. Rewards are tracked separately per wallet address. + +## Rewards + +### How are rewards calculated? + +``` +Your Rewards = (Your cSSV / Total cSSV) Γ— Total Network Fees +``` + +### When do rewards start? + +Rewards begin accruing immediately after your staking transaction is confirmed. + +### Do rewards auto-compound? + +No. cSSV is non-rebasing, so rewards don't automatically compound. To compound: +1. Claim ETH rewards +2. Swap ETH for SSV +3. Stake the new SSV +4. Receive additional cSSV + +### Do I need to claim rewards regularly? + +No, rewards can accumulate indefinitely. However, claiming periodically gives you access to ETH and reduces the amount at risk in the contract. + +### Can someone else claim my rewards? + +No. Only the wallet holding the cSSV tokens can claim the associated rewards. + +### Do rewards continue after I claim? + +Yes! Claiming doesn't affect your staking position. Your cSSV balance stays the same and you continue earning immediately. + +### What happens to unclaimed rewards if I never claim? + +They remain in the contract associated with your address indefinitely. You can claim them at any time. + +### Is there a minimum claim amount? + +The contract may have a minimum to prevent spam. Check the webapp for current requirements. + +### Can I claim rewards to a different address? + +Typically, rewards are sent to the wallet holding the cSSV tokens. Check contract documentation for specifics. + +## cSSV Tokens + +### Can I transfer cSSV? + +Yes, cSSV is a standard ERC-20 token and fully transferable. + +### What happens when I transfer cSSV? + +- You keep all unclaimed ETH rewards accrued up to the transfer +- The recipient gets the cSSV tokens +- The recipient starts earning new rewards from that point +- You can still claim your historical rewards + +### Can I use cSSV in other protocols? + +Yes! cSSV has full DeFi composability. You can trade it, use it as collateral, or hold it in any wallet. + +### What happens to cSSV when I unstake? + +The cSSV tokens are burned (permanently destroyed) when you complete the withdrawal. This reduces total cSSV supply. + +## Oracle Delegation + +### What is oracle delegation? + +Your staked SSV weight automatically supports the network's oracle system, which reports validator effective balances to the blockchain. + +### Do I need to choose an oracle? + +No. In v1, your stake weight is automatically split equally across all 4 permissioned oracles. No manual action required. + +### What is the 75% quorum? + +Oracles need 75% of total voting weight to agree before balance updates are accepted. This prevents any single oracle from manipulating data. + +### Will delegation change in the future? + +Yes. Future versions will allow stakers to choose which oracles to delegate to, with performance-based rewards. + +## Unstaking + +### Can I unstake anytime? + +Yes, but there's a mandatory 7-day cooldown period between initiating unstaking and being able to withdraw. + +### Why is there a 7-day cooldown? + +The cooldown maintains: +- Oracle voting stability (prevents rapid weight changes) +- Protocol security (protects against flash-stake attacks) +- Future governance compatibility (prepares for additional use cases) + +### When do rewards stop during unstaking? + +**Critical**: Rewards stop accruing the MOMENT you initiate unstaking, not after the 7-day cooldown. + +### Can I cancel unstaking? + +No. Once you initiate unstaking, the process is irreversible. + +### Can I speed up the cooldown? + +No. The 7-day cooldown is a protocol requirement and cannot be shortened. + +### What happens if I don't withdraw after cooldown ends? + +Nothing urgent. Your SSV remains claimable indefinitely with no deadline. + +### Can I partially unstake? + +Yes! You can unstake a portion of your cSSV while keeping the rest staked and earning rewards. + +### Can I claim rewards during cooldown? + +Yes, you can claim any ETH rewards that accrued before you initiated unstaking. + +### What happens to my oracle weight during cooldown? + +It remains active for the 7-day cooldown period for protocol stability, then is removed upon withdrawal. + +### Can I transfer cSSV during cooldown? + +No. Once unstaking is initiated, the cSSV is locked and cannot be transferred. + +### Can I add more stake during cooldown? + +No. You cannot stake additional SSV while you have an active unstaking cooldown in progress. + +### Do I pay gas twice for unstaking? + +Yes - once to initiate unstaking and once to complete withdrawal after the cooldown period. + +### Can I restake after unstaking? + +Yes! You can restake immediately after withdrawal with no waiting period. However, frequent unstaking and restaking incurs gas costs. + +## Troubleshooting + +### Transaction failed - what should I check? + +1. Sufficient token balance (SSV for staking, ETH for gas) +2. Token approval completed (for first-time staking) +3. Adequate gas limit +4. Contract not paused (rare) +5. No existing unstaking in progress (when trying to unstake) + +### cSSV not showing in wallet + +1. Manually add cSSV token using contract address +2. Check transaction confirmed on block explorer +3. Refresh wallet or try different interface +4. Contact support if issue persists + +### Rewards lower than expected + +- Verify your cSSV balance +- Check total staked SSV (more competition = smaller share) +- Review network usage (fewer validators = lower fees) +- Confirm time since last claim +- Check if DAO fee rate changed + +### Claimed ETH not appearing + +1. Verify transaction confirmed on block explorer +2. Check correct wallet address +3. Refresh wallet interface +4. Allow time for wallet to update +5. Contact support if issue persists + +### Lost wallet access during cooldown + +- Recover wallet using seed phrase +- Import to new wallet software +- Cooldown continues regardless +- Withdrawal still available after 7 days + +## Security + +### How do I verify I'm on the official webapp? + +- Check the URL matches official documentation +- Verify the contract address +- Bookmark the official site +- Never click links from unsolicited messages + +### What should I never share? + +- Private keys +- Seed phrases / recovery phrases +- Never share these with anyone, including "support" + +### Common scam warning signs + +- 🚫 Unsolicited DMs offering staking help +- 🚫 Websites with similar but different URLs +- 🚫 "Instant unstaking" or "cancel cooldown" offers (impossible) +- 🚫 Requests for private keys or seed phrases +- 🚫 Promises of guaranteed or unrealistic returns + +### What should I save for records? + +- Transaction hashes for all operations +- Staking amounts and dates +- Reward claim history +- Unstaking initiation and withdrawal dates + +## Economics + +### Where do staking rewards come from? + +Network fees paid by ETH clusters. A portion of fees flows to the SSV Staking contract and is distributed to cSSV holders. + +### How does network growth affect rewards? + +More validators β†’ More fees collected β†’ Higher total rewards (but distributed among all stakers) + +### What if there are no validators using SSV? + +If no fees are collected, no rewards accrue. Staking rewards depend on actual network usage. + +## Technical + +### What token standard is cSSV? + +cSSV is a standard ERC-20 token with full compatibility. + +### Is cSSV rebasing? + +No. cSSV is non-rebasing. Your balance stays constant while rewards accrue separately via an index-based model. + +### What is the reward model based on? + +The reward mechanism is based on Synthetix's StakingRewards.sol pattern, providing better DeFi composability than rebasing tokens. + +### Can I interact with the contract directly? + +Yes, advanced users can interact with the smart contract directly. However, using the webapp is recommended for most users. + +## Support + +### Where can I get help? + +- Official SSV documentation +- SSV Discord community +- SSV support channels +- GitHub for technical issues + +### Who should I contact for issues? + +Only contact official SSV support channels. Ignore unsolicited DMs offering help - these are scams. + +## Learn More + +- [SSV Staking Overview](README.md) - Complete staking guide +- [Stake SSV](stake-ssv.md) - Step-by-step staking +- [Claim Rewards](claim-rewards.md) - Claiming process +- [Unstake SSV](unstake-ssv.md) - Unstaking guide +- [Tokenomics](/learn/tokenomics/README.md) - Economic model +- [Glossary](/learn/glossary.md) - Key definitions + diff --git a/docs/ssv-staking/stake-ssv.md b/docs/ssv-staking/stake-ssv.md new file mode 100644 index 0000000..977b4c3 --- /dev/null +++ b/docs/ssv-staking/stake-ssv.md @@ -0,0 +1,112 @@ +--- +sidebar_position: 2 +--- + +# Stake SSV + +## Prerequisites + +- SSV tokens in your wallet +- Compatible Web3 wallet (MetaMask, WalletConnect, etc.) +- Sufficient ETH for gas fees +- Access to the SSV Network webapp + +## Staking Process + +### Step 1: Connect Your Wallet + +Navigate to the SSV Network webapp, click "Connect Wallet", and approve the connection. + + + +### Step 2: Navigate to Staking + +Go to the "Staking" section to see the staking dashboard with current statistics (total SSV staked, APY, your balance, rewards distributed). + + + +### Step 3: Enter Staking Amount + +Click "Stake SSV" and enter the amount you wish to stake. Review the details including cSSV you'll receive (1:1 ratio initially), estimated APY, and gas fees. + + + +### Step 4: Approve SSV Token (First Time Only) + +If this is your first time staking, approve the staking contract to access your SSV tokens. Click "Approve SSV" and confirm the transaction. + +⚠️ **Note**: You only need to do this once. + + + +### Step 5: Confirm Staking Transaction + +Click "Stake", review the transaction details in your wallet, and confirm. Wait for blockchain confirmation. + + + +### Step 6: Receive cSSV + +Once confirmed, you'll receive cSSV tokens in your wallet and start earning ETH rewards immediately. + + + +## What Happens When You Stake? + +1. **SSV is locked** in the staking contract +2. **You receive cSSV** at a 1:1 ratio initially +3. **Oracle weight** is automatically delegated equally across all 4 oracles +4. **Rewards start accruing** immediately based on network fees +5. **cSSV stays constant** - your balance doesn't auto-compound + +## Understanding Your Position + +After staking, monitor your position on the dashboard: + +- **Staked SSV**: Total SSV tokens staked +- **cSSV Balance**: Your compound SSV token balance +- **Unclaimed Rewards**: ETH rewards available to claim +- **Oracle Weight**: Your contribution to oracle consensus +- **Estimated APY**: Current annual percentage yield + +## Using cSSV Tokens + +cSSV is a standard ERC-20 token with full DeFi composability: + +- βœ… Transfer to another wallet +- βœ… Trade on DEXs (if liquidity exists) +- βœ… Use as collateral in other protocols +- βœ… Hold in cold storage + +**Important**: +- Transferring cSSV transfers the staked position +- Unclaimed ETH rewards stay with the original holder +- The recipient starts earning new rewards from the transfer +- Only the cSSV holder can unstake + +## Adding More Stake + +You can stake additional SSV anytime. Return to the dashboard, click "Stake SSV" again, enter the amount, and confirm (no need to approve again). + +## Transaction Costs + +- **First-time staking**: 2 transactions (Approve + Stake) +- **Additional staking**: 1 transaction (Stake only) +- **Gas costs vary**: Based on network congestion + +## Next Steps + +After staking: + +1. **Monitor your position** - Check the dashboard regularly +2. **Claim rewards** - See [Claim Rewards](claim-rewards.md) when ETH accumulates +3. **Track performance** - Review APY and total rewards earned +4. **Consider adding more** - Stake additional SSV to increase rewards + +## Learn More + +- [SSV Staking Overview](README.md) - Full staking mechanism +- [Claim Rewards](claim-rewards.md) - How to claim ETH rewards +- [Unstake SSV](unstake-ssv.md) - Unstaking process +- [FAQ](faq.md) - Common questions and answers +- [Glossary](/learn/glossary.md) - Key terms and definitions diff --git a/docs/ssv-staking/unstake-ssv.md b/docs/ssv-staking/unstake-ssv.md new file mode 100644 index 0000000..a8dbfb9 --- /dev/null +++ b/docs/ssv-staking/unstake-ssv.md @@ -0,0 +1,170 @@ +--- +sidebar_position: 4 +--- + +# Unstake SSV + +Unstake your SSV tokens with a mandatory 7-day cooldown period. + +## Overview + +Unstaking SSV withdraws your staked tokens from the staking contract. The process includes: + +- **7-day cooldown period** - Required waiting time after initiating +- **Reward cessation** - Rewards stop accruing immediately +- **Oracle weight retention** - Voting weight remains active during cooldown +- **Full withdrawal** - Receive SSV + any unclaimed ETH after cooldown + +⚠️ **Important**: This process is irreversible. Once initiated, you cannot cancel and rewards stop immediately. + +## Before You Unstake + +### Key Considerations + +| Aspect | Details | +|--------|---------| +| **Cooldown period** | 7 days from initiation to withdrawal | +| **Rewards** | Stop accruing immediately | +| **Oracle weight** | Remains active for voting | +| **Unclaimed ETH** | Should be claimed before or during unstaking | +| **cSSV tokens** | Will be burned upon withdrawal | +| **Irreversible** | Cannot cancel once initiated | + +## Unstaking Process + +### Step 1: Connect Your Wallet + +Navigate to the SSV Network webapp, connect your wallet holding cSSV tokens, and ensure sufficient ETH for gas fees. + + + +### Step 2: Navigate to Unstaking + +Go to the "Staking" section and locate your staking position details (staked SSV, cSSV balance, unclaimed rewards, APY). + + + +### Step 3: Review and Claim Rewards + +Check if you have unclaimed ETH rewards. **Strongly recommended**: Claim them now before proceeding. + +### Step 4: Initiate Unstaking + +Click "Unstake SSV" and choose: +- **Full unstake** (all cSSV) +- **Partial unstake** (specify amount) + +Review the details: SSV amount, cSSV to burn, cooldown end date, and gas fees. + + + +### Step 5: Confirm Transaction + +Read and acknowledge the warnings, click "Confirm Unstake", approve in your wallet, and wait for blockchain confirmation. + + + +### Step 6: Cooldown Period (7 Days) + +Once confirmed: +- Cooldown timer starts +- Rewards stop accruing immediately +- Oracle voting weight remains active +- "Unstaking" status shows on dashboard +- Estimated withdrawal date displayed + + + +### Step 7: Wait for Cooldown + +During the 7-day cooldown: + +- ⏱️ Monitor cooldown timer +- ❌ No new rewards accrue +- βœ… Can still claim previously accumulated rewards +- βœ… Oracle weight still active +- ❌ Cannot cancel unstaking +- ❌ Cannot stake additional SSV + + + +### Step 8: Complete Withdrawal + +After cooldown ends, return to the dashboard, click "Withdraw", review details, and confirm the transaction. + + + +### Step 9: Receive Your SSV + +Once confirmed: +- SSV tokens returned to your wallet +- Any unclaimed ETH rewards sent +- cSSV tokens burned from circulation +- Staking position closed +- Oracle weight removed + + + +## Why 7-Day Cooldown? + +The cooldown period serves three purposes: + +1. **Oracle Stability** - Prevents rapid voting weight changes and maintains consensus reliability +2. **Protocol Security** - Protects against flash-stake attacks and manipulation +3. **Future Governance** - Prepares for governance mechanisms and protocol backstop functionality + +## What Happens During Cooldown + +| Aspect | Status | Details | +|--------|--------|---------| +| **Rewards** | ❌ Stopped | No new ETH rewards accrue | +| **Oracle weight** | βœ… Active | Voting power still counts | +| **Claim rewards** | βœ… Allowed | Can claim accumulated ETH | +| **Transfer cSSV** | ❌ Not allowed | Tokens locked for unstaking | +| **Cancel unstaking** | ❌ Not allowed | Process is irreversible | +| **Add more stake** | ❌ Not allowed | Wait until withdrawal complete | + +## Partial Unstaking + +You can unstake a portion of your cSSV while keeping the rest staked: + +1. Choose partial unstake option +2. Specify amount of cSSV to unstake +3. Remaining cSSV continues earning rewards +4. Only unstaked portion goes through cooldown +5. Can unstake more later if desired + +**Example:** +- You have 1,000 cSSV staked +- Unstake 400 cSSV +- During cooldown: 400 cSSV earns nothing, 600 cSSV still earning +- After cooldown: Withdraw 400 SSV, keep 600 SSV staked + +## Critical: When Rewards Stop + +``` +[Staking] β†’ [Initiate Unstake] β†’ [7-Day Cooldown] β†’ [Withdraw] + βœ… Earning ❌ STOPS HERE ❌ No rewards ❌ No rewards +``` + +⚠️ **Most Important**: Rewards stop the moment you initiate unstaking, NOT after the cooldown period. + +To maximize rewards: +- Let rewards accumulate before unstaking +- Claim all unclaimed ETH +- Consider timing (don't unstake before large fee distributions) +- Remember you lose 7 days of potential rewards + +## After Withdrawal + +Once complete: +- Original SSV tokens returned +- All claimed ETH rewards (if claimed) +- cSSV tokens burned (removed from circulation) +- Oracle weight removed +- Staking position closed + +## Restaking + +You can restake immediately after withdrawal with no waiting period. However, frequent unstaking and restaking incurs gas costs. + diff --git a/docs/stakers/README.md b/docs/stakers/README.md index 076f898..981691c 100644 --- a/docs/stakers/README.md +++ b/docs/stakers/README.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Stakers -Stakers using the ssv network come in various forms: staking services/providers, staking pools, or individual ETH holders that supply the initially required capital to enable validators on the beacon chain. To enable the operation of a distributed validator, stakers must pay a fee in SSV to their chosen operators for them to manage their validator(s). +Stakers using the ssv network come in various forms: staking services/providers, staking pools, or individual ETH holders that supply the initially required capital to enable validators on the beacon chain. To enable the operation of a distributed validator, stakers pay fees in native ETH to their chosen operators for them to manage their validator(s). Users that leverage the SSV network’s DVT technology will promote optimal liveness, security, and decentralization for their validator(s). @@ -19,8 +19,8 @@ If you'd like to start by understanding how Distributed Validators work on ssv n Validators are distributed to several operators, forming a cluster. Each cluster has its balance to pay for network and operator fees, so you might want to [learn about cluster balance](/stakers/clusters/cluster-balance) and its caveats. -Practically speaking, there are several ways to interact with a cluster. For example, [adding more SSV to cluster's balance](/stakers/cluster-management/depositing-ssv/), [adding more validators](/stakers/cluster-management/adding-validator-to-existing-cluster), and other actions listed on [the Cluster Management section](/stakers/cluster-management). +Practically speaking, there are several ways to interact with a cluster. For example, [depositing ETH to fund your cluster](/stakers/cluster-management/depositing-eth/), [adding more validators](/stakers/cluster-management/adding-validator-to-existing-cluster), and other actions listed on [the Cluster Management section](/stakers/cluster-management). -Finally, there is an option to automate the onboarding through a script, if you manage a large number of validators. [Check out the example](/docs/developers/quickstart.md) of how to do it using our SDK is the starting place. +Finally, there is an option to automate the onboarding through a script, if you manage a large number of validators. [Check out the developer Quickstart](/docs/developers/README.md) which shows how to automate validator onboarding using our SDK. We suggest to skim through all of the guides on our documentation, to get familiar with all of the concepts and possible actions. If you still have questions, feel free to ask them on the [official Discord channel](https://discord.gg/5vT22pRBrf). \ No newline at end of file diff --git a/docs/stakers/cluster-management/README.md b/docs/stakers/cluster-management/README.md index fc1e1d0..cf6edfa 100644 --- a/docs/stakers/cluster-management/README.md +++ b/docs/stakers/cluster-management/README.md @@ -5,11 +5,28 @@ sidebar_position: 5 # Cluster Management +All new clusters on SSV Network use **native ETH** for fee payments. + +:::warning Legacy SSV Clusters +Existing SSV-based clusters are treated as legacy. Support for actively operating them under the SSV payment model has been removed. While these clusters may continue running as long as they have sufficient runway, they can no longer be maintained through operational changes. + +**This means:** +- ❌ Adding new validators to SSV clusters is no longer supported +- ❌ Depositing additional SSV to extend runway is no longer supported +- ❌ Removing or exiting validators from SSV clusters is no longer supported + +**The only forward path is [migration to ETH](./migrating-to-eth-clusters.md).** Migration automatically refunds your SSV balance. + +For cluster owners who need more time to migrate, ensure you have deposited sufficient SSV in advance for operational runway until migration can be completed. +::: + + **Follow the guides in this section:** - [**Add validator**](./adding-validator-to-existing-cluster.md) to existing cluster -- [**Deposit SSV**](./depositing-ssv.md) to cluster's balance -- [**Withdraw SSV**](./withdrawing-ssv.md) from cluster's balance -- [**Re-activate a cluster**](./re-activating-a-cluster.md) if your SSV balance went to 0 +- [**Deposit ETH**](./depositing-eth.md) to cluster balance +- [**Withdraw ETH**](./withdrawing-eth.md) from cluster balance +- [**Re-activate a cluster**](./re-activating-a-cluster.md) if your balance went to 0 - [**Update operators**](./update-operators.md) when you need to change one of the operators - [**Exit a validator**](./exiting-a-validator.md) -- [**Remove a validator**](./removing-a-validator.md) \ No newline at end of file +- [**Remove a validator**](./removing-a-validator.md) +- [**Migrate to ETH**](./migrating-to-eth-clusters.md) (for legacy SSV cluster owners) \ No newline at end of file diff --git a/docs/stakers/cluster-management/adding-validator-to-existing-cluster.md b/docs/stakers/cluster-management/adding-validator-to-existing-cluster.md index 0d33e50..a50d4f7 100644 --- a/docs/stakers/cluster-management/adding-validator-to-existing-cluster.md +++ b/docs/stakers/cluster-management/adding-validator-to-existing-cluster.md @@ -5,6 +5,10 @@ sidebar_position: 1 # Adding validator to existing cluster +:::warning Legacy SSV Clusters +Adding validators to legacy SSV clusters is **no longer supported**. If you have a legacy SSV cluster, you must [migrate to ETH](./migrating-to-eth-clusters.md) first before adding new validators. +::: + ### Connect your Web3 wallet to the WebApp Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. @@ -71,17 +75,13 @@ The next screen presents a summary of your validator setup. ![add-validator-to-cluster](/img/add-validator-to-cluster-10.avif) -By clicking on Register validator, you'll be proposed to sign transactions to confirm your choice and transfer the SSV balance necessary to cover for the operational costs. - -:::info -**Note:** If this is the first time you are registering a validator to ssv.network, you will be required to make two transactions - one to approve the SSV smart contract and another one to register the validator. -::: +By clicking on Register validator, you'll be proposed to sign a transaction to confirm your choice and deposit the ETH necessary to cover operational costs (if additional funding is needed). ![add-validator-to-cluster](/img/add-validator-to-cluster-11.webp) -### SSV Balance deposit +### ETH Balance deposit -Now, finalize the validator registration by signing the transaction and adding SSV tokens to your account balance. +Now, finalize the validator registration by signing the transaction and depositing ETH to your cluster balance.
diff --git a/docs/stakers/cluster-management/depositing-eth.md b/docs/stakers/cluster-management/depositing-eth.md new file mode 100644 index 0000000..c254ba8 --- /dev/null +++ b/docs/stakers/cluster-management/depositing-eth.md @@ -0,0 +1,51 @@ +--- +title: Depositing ETH +sidebar_position: 2 +--- + +# Depositing ETH to Cluster + +All clusters on SSV Network use native ETH for fee payments to operators and the network. The cluster balance is necessary to reward operators and pay network fees. + +For more information on cluster balance mechanics, please refer to [the dedicated learning page](/stakers/clusters/cluster-balance). + +:::warning Legacy SSV Clusters +If you have a legacy SSV cluster, you cannot deposit additional SSV. The only way to maintain your cluster is to [migrate to ETH](./migrating-to-eth-clusters.md), which automatically refunds your SSV balance. +::: + +### Connect your Web3 wallet to the WebApp + +Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. + +:::info +**Note:** Your account is associated with your Web3 wallet. +::: + +In the My Account page, select an active cluster and then click on the "Deposit" button. + +ETH_FEES_FILLER_TEXT + +In the next screen, you'll be asked to enter the amount of ETH you want to deposit. + +ETH_FEES_FILLER_TEXT + +Once you enter the amount, click on the _Deposit_ button. + +ETH_FEES_FILLER_TEXT + +The page will submit a transaction to the SSV Network smart contract. The ETH amount will be included as `msg.value` in the transaction. Check your Web3 wallet to confirm. + +ETH_FEES_FILLER_TEXT + +Now, finalize the deposit to the Cluster by signing the transaction. + +ETH_FEES_FILLER_TEXT + +You'll be taken back to the Cluster page, where the balance will be updated with the deposited ETH amount. + +ETH_FEES_FILLER_TEXT + +:::tip Operational Runway +Remember to maintain sufficient ETH balance to cover your cluster's operational costs. Monitor your runway regularly to avoid liquidation. +::: + diff --git a/docs/stakers/cluster-management/depositing-ssv.md b/docs/stakers/cluster-management/depositing-ssv.md deleted file mode 100644 index da19c83..0000000 --- a/docs/stakers/cluster-management/depositing-ssv.md +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: Depositing SSV -sidebar_position: 2 ---- - -### Connect your Web3 wallet to the WebApp - -The SSV token is used as as the payment layer of the network and the cluster balance is necessary to reward its operators. - -For more information on this topic, please refer to [the dedicated learning page](/stakers/clusters/cluster-balance). - -Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. - -:::info -**Note:** Your account is associated with your Web3 wallet. -::: - -In the My Account page, select an active cluster and then click on the "Deposit" button. - -![deposit-ssv](/img/deposit-ssv-1.avif) - -In the next screen, you'll be asked to enter the amount of SSV you want to deposit - -![deposit-ssv](/img/deposit-ssv-2.avif) - -Once you enter the amount, click on the _Deposit_ button - -![deposit-ssv](/img/deposit-ssv-3.avif) - -The page will attempt to submit a transaction to the SSV Network smart contract, check your Web3 wallet. - -![deposit-ssv](/img/deposit-ssv-4.avif) - -Now, finalize the deposit on the Cluster by signing the transaction. - -
- Deposit SSV -
- -You'll be taken back to the Cluster page, where the balance will be updated with the amount of SSV tokens deposited. - -![deposit-ssv](/img/deposit-ssv-6.avif) \ No newline at end of file diff --git a/docs/stakers/cluster-management/exiting-a-validator.md b/docs/stakers/cluster-management/exiting-a-validator.md index 50ba9f6..34727cb 100644 --- a/docs/stakers/cluster-management/exiting-a-validator.md +++ b/docs/stakers/cluster-management/exiting-a-validator.md @@ -5,6 +5,10 @@ sidebar_position: 6 # Exiting a validator +:::info Exiting validators from legacy SSV clusters +You **can** exit validators from legacy SSV clusters. Exiting is one of the few operations still supported for legacy clusters, as it allows you to gracefully withdraw your stake from the beacon chain before letting the cluster liquidate or migrating to ETH. +::: + ### Connect your Web3 wallet to the WebApp Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. diff --git a/docs/stakers/cluster-management/migrating-to-eth-clusters.md b/docs/stakers/cluster-management/migrating-to-eth-clusters.md new file mode 100644 index 0000000..41df067 --- /dev/null +++ b/docs/stakers/cluster-management/migrating-to-eth-clusters.md @@ -0,0 +1,133 @@ +--- +title: Migrating to ETH Clusters +sidebar_position: 8 +--- + +# Migrating to ETH Clusters + +Legacy SSV clusters can be migrated to ETH clusters to continue active operations. Migration is the only path forward for maintaining and modifying SSV-based clusters. + +:::danger One-Way Migration +**Migration from SSV to ETH is permanent and cannot be reverted.** Once you migrate, your cluster will exclusively use ETH for fee payments and cannot return to the SSV payment model. +::: + +## Why Migrate? + +After the network upgrade, legacy SSV clusters have limited functionality: + +**❌ NOT Supported for SSV Clusters:** +- Adding new validators +- Depositing additional SSV +- Removing validators +- Re-activating liquidated clusters +- Updating operators (resharing) + +**βœ… Still Supported for SSV Clusters:** +- Running existing validators (until liquidation) +- Exiting validators + +**βœ… Fully Supported After Migration to ETH:** +- All cluster operations +- Adding/removing validators +- Depositing/withdrawing ETH +- Updating operators +- Re-activating if liquidated + +## What Happens During Migration + +When you migrate your cluster to ETH: + +1. **ETH Deposit**: You deposit ETH to fund your cluster's operational runway +2. **SSV Refund**: Your entire SSV balance is automatically refunded to your wallet +3. **Cluster Conversion**: Your cluster switches to ETH-based fee accounting +4. **Continued Operation**: Your validators continue running without interruption + +:::info Automatic SSV Refund +You do **not** need to manually withdraw SSV before migrating. The migration process automatically returns your full SSV balance to your wallet address. +::: + +## Prerequisites + +Before migrating, ensure you have: + +- Access to the wallet that owns the cluster +- Sufficient ETH to cover: + - Initial cluster funding (operational runway) + - Gas fees for the migration transaction + +:::tip Operational Runway +We recommend depositing enough ETH for at least 90 days of operations to avoid frequent top-ups. +::: + +## Migration Process + +### Via WebApp + +:::info Coming Soon +The SSV WebApp will provide a guided migration flow. +**SCREENSHOTS/gUIDE TO FOLLOW IN ANOTHER PR** +::: + +### Via Smart Contract + +If you prefer to migrate directly via the smart contract, use the `migrateClusterToETH()` function: + +```solidity +function migrateClusterToETH( + bytes calldata publicKey, + uint64[] calldata operatorIds, + Cluster calldata cluster +) external payable +``` + +**Parameters:** +- `publicKey` - Public key of any validator in the cluster +- `operatorIds` - Array of operator IDs managing the cluster +- `cluster` - Current cluster snapshot +- `msg.value` - ETH amount to deposit for operational runway + +**The transaction will:** +1. Validate your cluster snapshot +2. Transfer your SSV balance back to your wallet +3. Accept your ETH deposit +4. Convert the cluster to ETH-based accounting +5. Emit `ClusterMigratedToETH` event + +:::warning Cluster Snapshot Required +You need the current cluster snapshot (balance, index, active status, etc.) to call this function. Retrieve this from the [SSV Subgraph](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot) or [SSV Scanner](/developers/tools/ssv-scanner). +::: + +## After Migration + +Once migration is complete: + +βœ… **Your cluster is now ETH-based** and has full functionality + +βœ… **Your SSV balance has been refunded** to your wallet + +βœ… **You can:** +- Add new validators to the cluster +- Deposit or withdraw ETH as needed +- Update operators (reshare) +- Remove validators +- Perform all standard cluster operations + +## FAQ + +**Q: What happens to my SSV balance?** +A: Your full SSV balance is automatically refunded to your wallet during migration. You don't need to withdraw it first. + +**Q: Can I migrate back to SSV after migrating to ETH?** +A: No. Migration is one-way and permanent. + +**Q: Will my validators experience downtime during migration?** +A: No. Your validators continue running without interruption throughout the migration process. + +**Q: What if I have insufficient SSV runway before I can migrate?** +A: Ensure you deposit sufficient SSV in advance to maintain operations until you complete the migration. If your cluster is liquidated before migration, you'll need to reactivate it with ETH directly. + +**Q: Do I need to inform my operators about migration?** +A: No. Operators can serve both SSV and ETH clusters during the transition. Your migration happens automatically from their perspective. + +**Q: Can I deposit more ETH after migrating?** +A: Yes. After migration, you can [deposit ETH](./depositing-eth.md) at any time to extend your operational runway. \ No newline at end of file diff --git a/docs/stakers/cluster-management/re-activating-a-cluster.md b/docs/stakers/cluster-management/re-activating-a-cluster.md index 7756d8f..2345b91 100644 --- a/docs/stakers/cluster-management/re-activating-a-cluster.md +++ b/docs/stakers/cluster-management/re-activating-a-cluster.md @@ -3,6 +3,12 @@ title: Re-activating a cluster sidebar_position: 4 --- +# Re-activating a cluster + +:::warning Legacy SSV Clusters +Re-activating legacy SSV clusters is **no longer supported**. If your legacy SSV cluster was liquidated, you must [migrate to ETH](./migrating-to-eth-clusters.md) to continue operating on the network. +::: + ### Connect your Web3 wallet to the WebApp Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. @@ -19,7 +25,7 @@ In the Cluster page, click on the **Reactivate Cluster** button ![reactivate-cluster](/img/reactivate-a-cluster-2.avif) -In the next screen, you'll be asked to choose the cluster runway, which will impact the amount of SSV you will have to deposit to reactivate the cluster. +In the next screen, you'll be asked to choose the cluster runway, which will impact the amount of ETH you will have to deposit to reactivate the cluster. ![reactivate-cluster](/img/reactivate-a-cluster-3.avif) @@ -37,6 +43,6 @@ Now, finalize the validator reactivation by signing the transaction. />
-You'll be taken back to the Cluster page, where the balance will be updated with the amount of SSV tokens deposited. +You'll be taken back to the Cluster page, where the balance will be updated with the amount of ETH deposited. ![reactivate-cluster](/img/reactivate-a-cluster-6.avif) \ No newline at end of file diff --git a/docs/stakers/cluster-management/removing-a-validator.md b/docs/stakers/cluster-management/removing-a-validator.md index cf192e2..21c933e 100644 --- a/docs/stakers/cluster-management/removing-a-validator.md +++ b/docs/stakers/cluster-management/removing-a-validator.md @@ -5,6 +5,14 @@ sidebar_position: 7 # Removing a validator +:::warning Legacy SSV Clusters +Removing validators from legacy SSV clusters is **no longer supported**. If you need to remove a validator from a legacy cluster: +1. [Migrate the cluster to ETH](./migrating-to-eth-clusters.md) first +2. Then remove the validator + +Alternatively, you can [exit the validator](./exiting-a-validator.md) and let the cluster liquidate naturally. +::: + ### Connect your Web3 wallet to the WebApp Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. diff --git a/docs/stakers/cluster-management/update-operators.md b/docs/stakers/cluster-management/update-operators.md index f00be9e..cb4dd65 100644 --- a/docs/stakers/cluster-management/update-operators.md +++ b/docs/stakers/cluster-management/update-operators.md @@ -5,6 +5,14 @@ sidebar_position: 5 # Update Operators +:::warning Legacy SSV Clusters +Updating operators (resharing) for validators in legacy SSV clusters is **no longer supported**. If you need to change operators: +1. [Migrate your cluster to ETH](./migrating-to-eth-clusters.md) first +2. Then follow the reshare process + +The reshare functionality only works for clusters using ETH payments. +::: + :::warning Collusion risks Please do not change more than 2 operators in a cluster. Each set of **generated shares will always be valid** when their signing threshold is met (e.g. 3/4). To reduce the risks, it is advised to not change more than 2 of the validator's managing operators when changing its cluster. ::: diff --git a/docs/stakers/cluster-management/withdrawing-eth.md b/docs/stakers/cluster-management/withdrawing-eth.md new file mode 100644 index 0000000..d681794 --- /dev/null +++ b/docs/stakers/cluster-management/withdrawing-eth.md @@ -0,0 +1,51 @@ +--- +title: Withdrawing ETH +sidebar_position: 3 +--- + +# Withdrawing ETH from Cluster + +You can withdraw excess ETH from your cluster balance at any time, as long as you maintain the minimum [liquidation collateral](../clusters/cluster-balance.md) required for your cluster. + +:::info Legacy SSV Clusters & SSV Withdrawal +If you have a legacy SSV cluster and want to recover your SSV balance: +- **To stay in the network:** [Migrate to ETH](./migrating-to-eth-clusters.md) - this automatically refunds your entire SSV balance +- **To leave the network:** Allow your cluster to be liquidated - this also returns your SSV balance +::: + +### Connect your Web3 wallet to the WebApp + +Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. + +:::info +**Note:** Your account is associated with your Web3 wallet. +::: + +In the My Account page, select an active cluster and then click on the "Withdraw" button. + +ETH_FEES_FILLER_TEXT + +In the next screen, you'll be asked to enter the amount of ETH you want to withdraw. The maximum withdrawable amount is your cluster balance minus the required liquidation collateral. + +ETH_FEES_FILLER_TEXT + +Once you enter the amount, click on the _Withdraw_ button. + +ETH_FEES_FILLER_TEXT + +The page will submit a transaction to the SSV Network smart contract. Check your Web3 wallet to confirm. + +ETH_FEES_FILLER_TEXT + +Now, finalize the withdrawal by signing the transaction. + +ETH_FEES_FILLER_TEXT + +You'll be taken back to the Cluster page, where the balance will be updated, and the withdrawn ETH will be sent to your wallet. + +ETH_FEES_FILLER_TEXT + +:::warning Liquidation Risk +Only withdraw excess balance beyond the liquidation collateral. Withdrawing too much may put your cluster at risk of liquidation if fees accumulate faster than expected. +::: + diff --git a/docs/stakers/cluster-management/withdrawing-ssv.md b/docs/stakers/cluster-management/withdrawing-ssv.md deleted file mode 100644 index e3e703d..0000000 --- a/docs/stakers/cluster-management/withdrawing-ssv.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Withdrawing SSV -sidebar_position: 3 ---- - -# Withdrawing SSV - -### Connect your Web3 wallet to the WebApp - -Make sure to connect your Web3 wallet with the WebApp, and that the address corresponds with the one you want to manage your Validators with. - -:::info -**Note:** Your account is associated with your Web3 wallet. -::: - -In the My Account page, select an active cluster and then click on the "Withdraw" button. - -![withdraw-ssv](/img/withdraw-ssv-1.avif) - -In the next screen, you'll be asked to enter the amount of SSV you want to withdraw - -![withdraw-ssv](/img/withdraw-ssv-2.avif) - -Once you enter the amount, click on the Withdraw button. Please take a close look at the updated estimated cluster runway. - -![withdraw-ssv](/img/withdraw-ssv-3.avif) - -The page will attempt to submit a transaction to the SSV Network smart contract, check your Web3 wallet. - -Now, finalize the withdrawal from the Cluster by signing the transaction. - -
- Withdraw SSV -
- -You'll be taken back to the Cluster page, where the balance will be updated with the amount of SSV tokens withdrawn. - -![withdraw-ssv](/img/withdraw-ssv-5.avif) \ No newline at end of file diff --git a/docs/stakers/clusters/README.md b/docs/stakers/clusters/README.md index 11b00b0..aaf2ef6 100644 --- a/docs/stakers/clusters/README.md +++ b/docs/stakers/clusters/README.md @@ -9,6 +9,10 @@ sidebar_position: 4 Distributed Validators are managed within Clusters - the group of operators that were selected to operate them. Clusters are unique to each account and are used for fees payment facilitation and management purposes. +:::tip ETH Clusters +All new clusters use **native ETH** for fee payments. Legacy SSV clusters can [migrate to ETH](../cluster-management/migrating-to-eth-clusters.md) for full functionality. +::: + Example of an account with 2 clusters: - Cluster #1 manages 3 validators and is operated by operators 1,2,3,4,5,6,7 - Cluster #2 manages 1 validator and is operated by operators 1,2,3,4 diff --git a/docs/stakers/clusters/cluster-balance.md b/docs/stakers/clusters/cluster-balance.md index 3565d57..c5706f1 100644 --- a/docs/stakers/clusters/cluster-balance.md +++ b/docs/stakers/clusters/cluster-balance.md @@ -5,39 +5,45 @@ sidebar_position: 2 # Cluster Balance -With the SSV token serving as the payment layer of the network, the cash flow between stakers and operators is facilitated by maintaining an SSV balance in a cluster. The cluster balance needs to be kept in check to ensure the continued operation of its validator(s) and below it is explained how to calculate the balance of a cluster at a specific blockchain block. +:::danger Legacy SSV Clusters +**SSV-based payments are frozen.** Existing SSV clusters cannot be actively maintained under the SSV payment model. The only forward path is to [migrate to ETH](/stakers/cluster-management/migrating-to-eth-clusters.md). + +While this documentation primarily focuses on **ETH clusters** (the current standard), the formulas and concepts also apply to legacy SSV clusters during the transition period. Where payment currency matters, substitute SSV for ETH in legacy clusters. +::: + +The cluster balance needs to be kept in check to ensure the continued operation of its validator(s). This page explains how to calculate cluster balance at a specific blockchain block. It is important to be aware that the cluster balance must **always be higher than the required** collateral for the cluster, so only the portion of the cluster balance exceeding the Liquidation Collateral can be used to calculate the Operational Runway. ![Operational Runway](/img/cluster-balance-1.avif) -Since operator and network fees are dynamic, the required [**Liquidation Collateral**](../../learn/protocol-overview/tokenomics/liquidations.md#liquidation-collateral) could vary between different clusters. To calculate how much funding is needed as collateral for a cluster, please refer to the [Liquidations page](../../learn/protocol-overview/tokenomics/liquidations.md#liquidators). +Since operator and network fees are dynamic, the required [**Liquidation Collateral**](/learn/tokenomics/liquidations.md#liquidation-collateral) could vary between different clusters. To calculate how much funding is needed as collateral for a cluster, please refer to the [Liquidations page](/learn/tokenomics/liquidations.md). ### Cluster Balance Formula -As explained in the documentation page related to [Payments](../../learn/protocol-overview/tokenomics/payments.md), the cluster balance is affected by three factors, mainly: +As explained in the documentation page related to [Payments](/learn/tokenomics/payments.md), cluster balance is affected by three main factors: * Network fee * Operator fees -* Number of validators +* Effective balance -And to keep track of their changes over time, the concept of [Indexes](../../learn/protocol-overview/tokenomics/payments.md#indexes) have been introduced. This, in turn, means that indexes for network fees and operator fees are necessary to calculate the cluster balance, as well as [the "snapshot" of the cluster status](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), taken the last time this was updated (the cluster snapshot is also used in smart contract transactions). +To track changes over time, the concept of [Indexes](/learn/tokenomics/payments.md#indexes) has been introduced. Indexes for network fees and operator fees are necessary to calculate the cluster balance, along with [the "snapshot" of the cluster status](/developers/tools/ssv-subgraph/subgraph-examples#cluster-snapshot), taken the last time it was updated (the cluster snapshot is also used in smart contract transactions). #### Cluster balance To calculate the updated cluster balance, given the cluster balance from most recent snapshot, you can use this formula: $$ -balance_n = balance_{snapshot} - (\Delta_{network\ fee} + \Delta_{operators\ fee}) * v_c +balance_n = balance_{snapshot} - (\Delta_{network\ fee} + \Delta_{operators\ fee}) * eb / 32 $$ Legend: -* $$balance_n$$ - cluster balance at block number `n` +* $$balance_n$$ - cluster balance at block number `n` in ETH * $$\Delta_{network\ fee}$$ - Change in network fees paid since the last snapshot -* $$\Delta_{operators\ fee}$$ - Change in network fees paid since the last snapshot +* $$\Delta_{operators\ fee}$$ - Change in operator fees paid since the last snapshot * $$balance_{snapshot}$$ - value of the cluster balance on its latest snapshot -* $$v_c$$ - Validator Count, the number of validators in the cluster +* $$eb$$ - total effective balance of validators managed by the cluster #### Network fees delta @@ -90,8 +96,8 @@ $$ Legend: -* $$Residual\;Balance$$ - Amount of SSV in the cluster balance, exceeding the Liquidation Collateral -* $$Burn\;Rate_{cluster}$$ - The rate at which a cluster spends (denominated in SSV tokens per block) +* $$Residual\;Balance$$ - Amount of ETH in the cluster balance, exceeding the Liquidation Collateral +* $$Burn\;Rate_{cluster}$$ - The rate at which a cluster spends ETH per block ### Deposits diff --git a/docs/stakers/clusters/effective-balance.md b/docs/stakers/clusters/effective-balance.md new file mode 100644 index 0000000..1e13b82 --- /dev/null +++ b/docs/stakers/clusters/effective-balance.md @@ -0,0 +1,100 @@ +--- +description: Effective Balance Accounting explained +sidebar_position: 3 +--- + +# Effective Balance Accounting + +Effective Balance Accounting was brought together with SSV Staking update. With it in place fees, cluster runway, and liquidations are calculated across the SSV Network by aligning them with validators’ actual effective balance, rather than assuming a fixed 32 ETH per validator. +This change is required to natively support [Ethereum’s post-Pectra validator model](https://consensys.io/blog/ethereum-pectra-upgrade), where a single validator can secure and earn rewards on significantly more than 32 ETH. Historically, this gap was partially addressed through off-chain mechanisms, while Effective Balance Accounting brings this logic fully on-chain and applies it consistently across network fees, operator fees, and cluster payments. + +## Effective Balance Monitoring +Under this new model it is crucial to closely monitor each validator's on-chain effective balance. This is performed by the set of [Oracles](/learn/protocol-overview/oracles), periodically fetching on-chain data. + +However, these oracles only monitor already registered validators. When just registering new validators you will be prompted to fill in the total Effective Balance (EB) of registered validators yourself. This is optional and is done for accurate runway estimation. + +Below is an example of what can happen if a staker fails to provide factual EB when prompted: +1. Register a validator with EB of 2048 ETH +2. Claim its EB as 32 ETH during registration to ssv network +3. See runway estimation as if the validator has EB of 32 ETH +4. Deposit the fees according to the *incorrect* estimations +5. Once oracles get the information that the validator has EB of 2048 ETH, the actual fees will jump by 64 times +6. The cluster's runway becomes 64 times shorter, and is at high risk of liquidation + +## Accounting Changes +Effective Balance Accounting changes how fees are calculated at the cluster level, by replacing validator count as a proxy with the cluster’s effective balance. + +In the ETH-based model, effective balance becomes the billing unit. Fees are defined per 32 ETH of effective balance and scale with a cluster’s total effective balance: + +$$ +(f_o + f_n) * Total Effective Balance / 32 +$$ + +#### Legend: + * $$f_o$$ - operator fees *(per 32 ETH)* - the fees of all operators in the cluster (denominated in _ETH per block_) + * $$f_n$$ - network fees *(per 32 ETH)* - the fees owed to the ssv network (denominated in _ETH per block_) + * $$Total Effective Balance$$ - the cumulative effective balance of all validators belonging to the cluster + +#### Under this model: +- Fees are denominated in ETH +- Fees are proportional to the actual Effective Balance of a cluster they secure +- Validator count does *not* affect the fees. +- Effective balance can be distributed across validator keys in any way. For more details, see [Examples](#examples) below. +- Effective balance-based accounting applies only to ETH-based clusters. + + +### Legacy Clusters (SSV-based) +:::info Legacy Model +SSV-based clusters continue operating under the validator-count model until they migrate. After the migration, **ETH-based model becomes the only accounting model** used by the protocol. +::: + +In the SSV-based model, validators act as a proxy for effective balance. +Each validator is implicitly assumed to represent a fixed 32 ETH of effective balance. Fees therefore scale linearly with the number of validators in the cluster, regardless of how much effective balance those validators actually secure. + +$$ +(f_o + f_n) * Validator Count +$$ + +#### Legend: + * $$f_o$$ - operator fees *(per Validator)* - the fees of all operators in the cluster (denominated in _SSV tokens per block_) + * $$f_n$$ - network fees *(per Validator)* - the fees owed to the ssv network (denominated in _SSV tokens per block_) + +#### Under this model: +- Fees are defined per validator +- Total fees scale with validator count +- Consolidated validators are not fully accounted for + +## Examples + +As mentioned above, the fees will scale proportionally to the Total Effective Balance of a cluster. + +:::tip Validator Count +Please note the Validator Count is completely irrelevant in calculations: + +A cluster of 1 validator with 64 ETH balance (1 \* 64) and 2 validators each with 32 ETH effective balance (2 \* 32) **would have the same** annual fee. +::: + +#### Example Cluster #1 +- Total Effective Balance: 32 +- Operators fees: 0.01 ETH +- Network fee: 0.00928 ETH + +Annual fee for the cluster: +$$(0.01+0.00928)*32/32=0.01928 ETH$$ + + +#### Example Cluster #2 +- Total Effective Balance: 64 +- Operators fees: 0.01 ETH +- Network fee: 0.00928 ETH + +Annual fee for the cluster: +$$(0.01+0.00928)*64/32=0.03856 ETH$$ + +#### Example Cluster #3 +- Total Effective Balance: 2048 +- Operators fees: 0.01 ETH +- Network fee: 0.00928 ETH + +Annual fee for the cluster: +$$(0.01+0.00928)*2048/32=1.23392 ETH$$ diff --git a/docs/stakers/clusters/reactivation.md b/docs/stakers/clusters/reactivation.md index 75d9b78..52e46c1 100644 --- a/docs/stakers/clusters/reactivation.md +++ b/docs/stakers/clusters/reactivation.md @@ -1,15 +1,21 @@ # Reactivation -The following the educational context behind Cluster Reactivation. To see the actionable steps, please follow [this guide instead](../cluster-management/re-activating-a-cluster.md). +The following the educational context behind Cluster Reactivation. To see the actionable steps, please follow [this guide instead](/stakers/cluster-management/re-activating-a-cluster.md). -In order to reactivate a liquidated cluster, the user must supply the liquidation collateral required for their cluster. It is advised to deposit more than the reactivation amount so the cluster will have an operational runway. Users that only deposit the liquidation collateral may be liquidated soon after because they did not compensate for the operational cost of their cluster’s managed validator(s). +:::warning Legacy SSV Clusters +**SSV-based payments are frozen.** Legacy SSV clusters must [migrate to ETH](/stakers/cluster-management/migrating-to-eth-clusters.md) before they can be reactivated. -Once reactivated, the clusters’ validator(s) operation will continue. To calculate how much minimal funding (liquidation collateral) is needed to reactivate a cluster: +This documentation focuses on **ETH clusters** (the current standard), but the formulas also apply to legacy SSV clusters during the transition period. +::: + +In order to reactivate a [liquidated cluster](/learn/tokenomics/liquidations.md), the user must supply the liquidation collateral required for their cluster. It is advised to deposit more than the reactivation amount so the cluster will have an operational runway. Users that only deposit the liquidation collateral may be liquidated soon after because they did not compensate for the operational cost of their cluster's managed validator(s). + +Once reactivated, the clusters' validator(s) operation will continue. To calculate how much minimal funding (liquidation collateral) is needed to reactivate a cluster: $$ reactivation\;Balance > BurnRate_{cluster} * LTP $$ -* Legend - * $$Burn Rate$$ - the rate at which a cluster spends $SSV per block +#### Legend + * $$Burn Rate$$ - the rate at which a cluster spends ETH per block * $$LTP$$ - liquidation threshold period diff --git a/docs/stakers/incentivized-mainnet.md b/docs/stakers/incentivized-mainnet.md new file mode 100755 index 0000000..09e3c49 --- /dev/null +++ b/docs/stakers/incentivized-mainnet.md @@ -0,0 +1,47 @@ +--- +description: Boosted APR +sidebar_position: 2 +--- + +# Boosted APR + +Our tiered incentive program fosters accelerated usage of SSV network via boosted rewards. Each validator staked on SSV Mainnet network is eligible for claiming Incentives, which boosts APR. + +## How to claim rewards +You can find technical details about the program below. If you are aware of the program, feel free to claim the rewards on any of the following pages: +- https://www.ssvrewards.com/ +- https://ssvscan.io/claim/ +- https://monitorssv.xyz/claim + +πŸ“œ **Mainnet Rewards Distributor Contract Address:** +`0xe16d6138B1D2aD4fD6603ACdb329ad1A6cD26D9f` +Refer to the documentation for details: [SSV Smart Contracts Docs](/developers/smart-contracts#ethereum-mainnet) + +## What is Incentivized Mainnet Program + +The Incentivized Mainnet Program (IMP) [is an initiative from SSV Network DAO](https://forum.ssv.network/t/dip-34-incentivized-mainnet-program-revision-3/1908), made available by the SSV Foundation, designed to accelerate the adoption of Distributed Validator Technology (DVT) by rewarding participants with SSV Tokens who operate validators on the SSV Network. Launched in October 2023, the program offers tiered rewards to incentivize early and continued participation. + +You can find more details on [the IMP FAQ page](https://ssv.network/incentivized-mainnet-faq). + +### Reward Tiers +The program tiers and corresponding APR boosts is structured according to the effective balance, as opposed to the number of validators. + +An Online IM reward calculator can be [found on this page](https://ssv.network/incentivized-mainnet). + +| Tier (Effective Balance) | APR Boost | +|---------------------------|-----------| +| 1,440,032 - 3,200,000 ETH | 10% | +| 3,200,032 - 4,000,000 ETH | 7.5% | +| 4,000,032 - 4,800,000 ETH | 6% | +| 4,800,032 - 5,600,000 ETH | 5% | +| 5,600,032 - 6,400,000 ETH | 3.5% | + +### Reward Distribution Flow +This rewards distribution flow is repeated monthly. Usually, the rewards are distributed around the middle of the following month: +1. A snapshot is taken of all active validators on the SSV Network. +2. After the snapshot is finished, calculations are made and published on the SSV governance forum. +3. A merkle root is published on-chain which enables eligible validators to claim their rewards. +4. After the merkle root is updated on-chain, rewards can be claimed. + +Updates are posted every month in this SSV Governance Forum thread: +[Incentivized Mainnet Distribution Details](https://forum.ssv.network/t/incentivized-mainnet-program-distributions/). \ No newline at end of file diff --git a/docs/stakers/quickstart.md b/docs/stakers/quickstart.md index 0afa494..5e58b48 100644 --- a/docs/stakers/quickstart.md +++ b/docs/stakers/quickstart.md @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; # Quickstart The quickest way to engage with ssv network is to distribute and register your validator. Feel free to start with Testnet and then proceed to Mainnet. -In order to run a validator, you'll need to be in possession of its keys, have made the deposit to the Deposit Contract to activate it, and own the necessary amount of SSV tokens to cover operational costs. +In order to run a validator, you'll need to be in possession of its keys, have made the deposit to the Deposit Contract to activate it, and own the necessary amount of ETH to cover operational costs. :::note Don't have validator keys? To learn how to create a new set of validator keys and activate them, [please refer to this guide](/docs/stakers/validator-management/creating-a-new-validator.md). @@ -20,9 +20,9 @@ To learn how to create a new set of validator keys and activate them, [please re At a high level, here is what involved in distributing your validator: 1. [Connect your wallet](#connect-your-web3-wallet-to-webapp) 2. [Select Operators](#select-operators) -3. [Split and register your validator key](#key-splitting) +3. [Split your validator key](#key-splitting) 4. [Set the cluster runway](#validator-operational-runway) -5. [Deposit SSV](#ssv-balance-deposit) +5. [Deposit ETH to finalize](#eth-balance-deposit) ### Connect your Web3 wallet to WebApp @@ -33,15 +33,13 @@ Make sure to connect your Web3 wallet with the WebApp, and that the address corr **Your account is associated with your Web3 wallet**. This wallet will be the owner, so having access to it is vital. It can only be changed by removing validator and register using a new wallet. ::: -When creating a new account, you are presented with the option of _Distribute Validator_ or _Join as an Operator_. +When creating a new account, you can **Create a new cluster** for your validators. -Select _**Distribute a Validator**_. - -![Distribute a validator](/img/distributing-a-val-1.avif) +![Distribute a validator](/img/distributing-a-val-1.png) Accept the disclaimer by clicking _**Next**_ if you have all the pre-requisites. -![Distribute a validator](/img/distributing-a-val-3.avif) +![Distribute a validator](/img/distributing-a-val-3.png) ### Select operators @@ -51,19 +49,15 @@ Now, select four operators to manage your validator. Please note the **Yearly Fe **Important:** [Verified Operators (VOs)](/docs/operators/operator-onboarding/verified-operators.md) are operators that have been granted the **Verified** status by the DAO for completing KYC and providing consistent high-quality service. You can sort the operator list by their daily performance, yearly fee, and # of validators they manage. You can also filter to view only Verified Operators. ::: -![Distribute a validator](/img/distributing-a-val-4.avif) +![Distribute a validator](/img/distributing-a-val-4.png) ### Key splitting The next screen will allow you to generate KeyShares for your validator key. -- On Testnet, this can be done Online, directly on the WebApp, or Offline, on your computer. -- On Mainnet, only the Offline option is available. - -:::success Multiple Keystores -The latest SSV Smart Contract updates added support for [_bulk operations_](/developers/smart-contracts/ssvnetwork#bulkregistervalidatorpublickey-operatorids-shares-amount-cluster), and the latest release of `ssv-keys` has been made compatible with bulk operations. With version 1.1.0 (and above), it is possible to generate keyshares for multiple keystores in a single operation/transaction. -::: +- **On Testnet**, this can be done Online, directly on the WebApp, or Offline, on your computer. +- **On Mainnet, only the Offline** option is available. -![Distribute a validator](/img/distributing-a-val-5.avif) +![Distribute a validator](/img/distributing-a-val-5.png) @@ -79,7 +73,7 @@ The latest SSV Smart Contract updates added support for [_bulk operations_](/dev Once uploaded, if successfully validated, advance to the next screen clicking Next. - ![Distribute a validator](/img/distributing-a-val-10.avif) + ![Distribute a validator](/img/distributing-a-val-10.png) @@ -101,16 +95,22 @@ The latest SSV Smart Contract updates added support for [_bulk operations_](/dev +### Effective Balance input + +For accurate runway estimation, you need to manually input the Effective Balance of your validators. If this won't be done, it will be defaulted to each validator having 32 ETH balance. You can read more about [Effective Balance accounting](/stakers/clusters/effective-balance) for detailed calculations of fees. + +Read the warning on the page, input your Effective Balance and proceed to the next step. + ![Distribute a validator](/img/distributing-a-val-EB.png) ### Validator operational runway -You can select the operational runway period of your validator, in accordance with the **Yearly Fee** of previously selected operators. This will dictate the initial amount of SSV to be deposited in the cluster, but it can always be managed later. +You can select the operational runway period of your validator, in accordance with the **Yearly Fee** of previously selected operators. This will dictate the initial amount of ETH to be deposited in the cluster, but it can always be managed later. -![Distribute a validator](/img/distributing-a-val-11.avif) +![Distribute a validator](/img/distributing-a-val-11.png) -**Please read carefully and understand how fees are managed and the risks of account** [**liquidation**](/docs/learn/glossary.md#liquidation) **if your account balance falls below the** [**Threshold Balance**](/docs/learn/glossary.md#liquidation-collateral)**.** +**Please read carefully and understand how fees are managed and the risks of account** [**liquidation**](/learn/tokenomics/liquidations.md) **if your account balance falls below the** [**Threshold Balance**](/learn/tokenomics/liquidations.md#liquidation-collateral). -![Distribute a validator](/img/distributing-a-val-12.avif) +![Distribute a validator](/img/distributing-a-val-12.png) ### Slashing warning @@ -118,33 +118,31 @@ The following screen alerts you of the potential dangers of registering a valida Please make sure to stop any other running validator setup, if you have any. -![Distribute a validator](/img/distributing-a-val-13.avif) +![Distribute a validator](/img/distributing-a-val-13.png) ### Validator summary The next screen presents a summary of your validator setup. -![Distribute a validator](/img/distributing-a-val-14.avif) - +![Distribute a validator](/img/distributing-a-val-14.png) -By clicking on Register validator(s), you'll be proposed to sign transactions to confirm your choice and transfer the SSV balance necessary to cover for the operational costs. -:::info Two transactions -**Note:** If this is the first time you are registering a validator to ssv.network, you will be required to make two transactions - one to approve the SSV smart contract and another one to register the validator. -::: +By clicking on Register validator(s), you'll be proposed to sign a transaction to confirm your choice and deposit the ETH balance necessary to cover for the operational costs. -### SSV Balance deposit +### ETH Balance deposit -Now, finalize the validator registration by signing the transaction and adding SSV tokens to your account balance. +Now, finalize the validator registration by signing the transaction and adding ETH to your cluster balance.
- Distribute a validator + Distribute a validator
You will need to confirm the transaction in your web3 wallet. -![Distribute a validator](/img/distributing-a-val-16.avif) - Once the transaction has been signed and confirmed by the network, you'll be presented with the summary screen. ![Distribute a validator](/img/distributing-a-val-17.avif) diff --git a/docs/stakers/validator-management/creating-a-new-validator.md b/docs/stakers/validator-management/creating-a-new-validator.md index 6a88a08..de5899e 100644 --- a/docs/stakers/validator-management/creating-a-new-validator.md +++ b/docs/stakers/validator-management/creating-a-new-validator.md @@ -5,6 +5,10 @@ sidebar_position: 1 # Creating a new validator +:::tip ETH Clusters +All new clusters on SSV use **native ETH** for operator fee payments. This guide prepares you for creating the validator keys that will be distributed to operators. +::: + :::info Note: Instead of creating a validator key pair and then distribute that into Key Shares, you can run a Distributed Key Generation ceremony, thanks to the [SSV DKG Client](/developers/tools/ssv-dkg-client/). ::: @@ -30,6 +34,7 @@ For this reason, an alternative and shorter route to the Launchpad is to use the * Confidence using the command line, and command line interfaces * ETH (or Hoodi ETH): 32 + ~0.1 for gas fees to activate the validator keys +* Additional ETH to fund your cluster's operational runway for operator fees ### Generate validator keys diff --git a/docs/stakers/validator-management/distributing-a-validator.md b/docs/stakers/validator-management/distributing-a-validator.md index 5dc31da..6890af5 100644 --- a/docs/stakers/validator-management/distributing-a-validator.md +++ b/docs/stakers/validator-management/distributing-a-validator.md @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; # Migrating a validator -In order to distribute a validator you'll need β€” its keys, have made the deposit to the Deposit Contract to activate it, and own the necessary amount of SSV tokens to cover operational costs. +In order to distribute a validator you'll need β€” its keys, have made the deposit to the Deposit Contract to activate it, and have sufficient ETH to cover operational costs. :::note Don't have validator keys? To learn how to create a new set of validator keys and activate them, [please refer to this guide](creating-a-new-validator.md). @@ -113,7 +113,11 @@ To avoid losing your keystores to an attacker, follow these best practices: ### Validator operational runway -You can select the operational runway period of your validator, in accordance with the **Yearly Fee** of previously selected operators. This will dictate the initial amount of SSV to be deposited in the cluster, but it can always be managed later. +You can select the operational runway period of your validator, in accordance with the **Yearly Fee** of previously selected operators. This will dictate the initial amount of **ETH** to be deposited in the cluster, but it can always be managed later. + +:::tip ETH Payments +New clusters use native ETH for all fee payments. This provides simpler accounting and better alignment with Ethereum economics. +::: ![Distribute a validator](/img/distributing-a-val-11.avif) @@ -138,15 +142,15 @@ The next screen presents a summary of your validator setup. ![Distribute a validator](/img/distributing-a-val-14.avif) -By clicking on Register validator(s), you'll be proposed to sign transactions to confirm your choice and transfer the SSV balance necessary to cover for the operational costs. +By clicking on Register validator(s), you'll be proposed to sign a transaction to confirm your choice and deposit the ETH necessary to cover operational costs. -:::info Two transactions -**Note:** If this is the first time you are registering a validator to ssv.network, you will be required to make two transactions - one to approve the SSV smart contract and another one to register the validator. +:::info ETH Deposit +**Note:** Your transaction will include the ETH amount needed for your selected operational runway. This ETH is deposited into your cluster balance to pay operator and network fees. ::: -### SSV Balance deposit +### ETH Balance deposit -Now, finalize the validator registration by signing the transaction and adding SSV tokens to your account balance. +Now, finalize the validator registration by signing the transaction and depositing ETH to your cluster balance.
Distribute a validator diff --git a/docs/stakers/validators/validator-onboarding.md b/docs/stakers/validators/validator-onboarding.md index 7fb18e6..94850e8 100644 --- a/docs/stakers/validators/validator-onboarding.md +++ b/docs/stakers/validators/validator-onboarding.md @@ -39,38 +39,50 @@ Factors to consider in cluster formation: ### Operational Costs -The associated costs for running validators on the ssv network are determined by **operator fees** and **network fees**. +The associated costs for running validators on the SSV network are determined by **operator fees** and **network fees**, paid in **native ETH**. With the network embracing a free-market approach, where operators set their own fees, the cost for each validator will vary based on its operator setup. -In addition to fees, there’s a minimum balance requirement, known as [liquidation collateral](../clusters/cluster-balance), that has to be deposited for each validator a user runs through the network. +In addition to fees, there's a minimum balance requirement, known as [liquidation collateral](../clusters/cluster-balance), that has to be deposited for each validator a user runs through the network. + +:::tip ETH Clusters +New clusters on SSV Network use ETH for all fee payments. +::: ### Validator Funding -To carry validators operational costs, the validator's cluster must be funded with an appropriate amount of SSV (see [Cluster Balance](../clusters/cluster-balance.md)). +To cover validator operational costs, your cluster must be funded with an appropriate amount of **ETH** (see [Cluster Balance](../clusters/cluster-balance.md)). -Funding can be made at any time to the cluster’s balance (see [Deposits](../clusters/cluster-balance), but in case the first validator is onboarded to a cluster, the initial funding must be carried with its registration. +Funding can be made at any time to the cluster's balance, but when onboarding the first validator to a new cluster, the initial funding must be provided with the registration transaction. -To calculate how much funding is needed to run a validator within its cluster according to a certain **operation period** and the required **liquidation collateral**: +To calculate how much ETH funding is needed to run a validator within its cluster according to a certain **operation period** and the required **liquidation collateral**: $$ -Required\;Funding = (O1_{fee} + O2_{fee} + O3_{fee} + O4_{fee} + N_{fee}) * (Period + LTP) +Required\;Funding_{ETH} = (O1_{fee} + O2_{fee} + O3_{fee} + O4_{fee} + N_{fee}) * (Period + LTP) $$ Legend: -* $$O1_{fee}$$ to $$O4_{fee}$$ - operator fee (SSV per block) -* $$N_{fee}$$ - network fee (SSV per block) +* $$O1_{fee}$$ to $$O4_{fee}$$ - operator fee (ETH per block) +* $$N_{fee}$$ - network fee (ETH per block) * $$Period$$ - desired operation period (blocks) * $$LTP$$ - liquidation threshold period (blocks) -### Single Validator Funding Example +### Single Validator Funding Example (ETH Cluster) -Assuming there are 100 blocks per day, **operators and network fee** of 0.001 SSV (per block) and a **liquidation period** of 1 month, the **required funding** for 1 year of **operation period** would be: +Assuming there are 7,200 blocks per day, **operator fees** of 0.0000001 ETH per block each, and a **network fee** of 0.00000005 ETH per block, with a **liquidation period** of 30 days, the **required funding** for 365 days of **operation period** would be: $$ -197.5 SSV = ((0.001 + 0.001 + 0.001 + 0.001 + 0.001) * 100 * (365+30)) +ETH_{required} = ((4 \times 0.0000001) + 0.00000005) \times 7,200 \times (365 + 30) +$$ + $$ +ETH_{required} \approx 1.278 ETH +$$ + +:::info Operational Runway +Maintaining your cluster's operational runway is essential. You can always deposit more ETH to extend your runway or withdraw excess balance as needed. +::: -:::info -Please note that maintaining your cluster's operational runway is essential and a user could always deposit more balance to their account, or withdraw as they see fit. +:::note Legacy SSV Clusters +If you're operating a legacy SSV cluster (funded with SSV tokens), new validators **cannot** be added to it. They can, however, be added to ETH clusters instead. ::: diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 7517fec..f9dbac1 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -83,6 +83,7 @@ const config: Config = { {to: '/developers/', label: 'Developers', position: 'left'}, {to: '/stakers/', label: 'Stakers', position: 'left'}, {to: '/operators/', label: 'Operators', position: 'left'}, + {to: '/ssv-staking/', label: 'SSV Staking', position: 'left'}, { href: 'https://github.com/ssvlabs', label: 'GitHub', @@ -150,7 +151,9 @@ const config: Config = { const redirectFiles: Record = { '/operators/operator-node/setup-sidecars/configuring-mev': '/operators/operator-node/node-setup/configuring-mev', '/operators/operator-node/setup-sidecars/configuring-primev': '/operators/operator-node/node-setup/configuring-primev', - '/developers/quickstart':'/developers/SSV-SDK/examples/bulk-register-validators' + '/developers/quickstart':'/developers/SSV-SDK/examples/bulk-register-validators', + '/stakers/cluster-management/depositing-ssv': '/stakers/cluster-management/depositing-eth', + '/stakers/cluster-management/withdrawing-ssv': '/stakers/cluster-management/withdrawing-eth' }; for (const [newPath, oldPath] of Object.entries(redirectFolders)) { if (existingPath === newPath || existingPath.startsWith(`${newPath}/`)) { diff --git a/package-lock.json b/package-lock.json index 729edfc..baf667f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -179,7 +179,6 @@ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.45.0.tgz", "integrity": "sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.45.0", "@algolia/requester-browser-xhr": "5.45.0", @@ -305,7 +304,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -2095,7 +2093,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2118,7 +2115,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -2228,7 +2224,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2650,7 +2645,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3608,7 +3602,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/logger": "3.9.2", @@ -4484,7 +4477,6 @@ "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", "license": "MIT", - "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -4788,7 +4780,6 @@ "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -5146,7 +5137,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz", "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -5488,7 +5478,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5553,7 +5542,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -5599,7 +5587,6 @@ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.45.0.tgz", "integrity": "sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA==", "license": "MIT", - "peer": true, "dependencies": { "@algolia/abtesting": "1.11.0", "@algolia/client-abtesting": "5.45.0", @@ -6063,7 +6050,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -7020,7 +7006,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8385,7 +8370,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13036,7 +13020,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13552,7 +13535,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -14456,7 +14438,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -15251,7 +15232,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -15261,7 +15241,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -15299,7 +15278,6 @@ "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" }, @@ -15328,7 +15306,6 @@ "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -17059,7 +17036,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -17252,8 +17228,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/type-fest": { "version": "2.19.0", @@ -17316,7 +17291,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17686,7 +17660,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -17885,7 +17858,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz", "integrity": "sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==", "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.12.1", @@ -18161,7 +18133,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", diff --git a/sidebars.ts b/sidebars.ts index 26cc4f0..cb147c4 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -16,6 +16,7 @@ const sidebars: SidebarsConfig = { developersSidebar: [{type: 'autogenerated', dirName: 'developers'}], operatorsSidebar: [{type: 'autogenerated', dirName: 'operators'}], stakersSidebar: [{type: 'autogenerated', dirName: 'stakers'}], + ssvStakingSidebar: [{type: 'autogenerated', dirName: 'ssv-staking'}], }; export default sidebars; diff --git a/static/img/distributing-a-val-1.png b/static/img/distributing-a-val-1.png new file mode 100644 index 0000000..c78869d Binary files /dev/null and b/static/img/distributing-a-val-1.png differ diff --git a/static/img/distributing-a-val-10.png b/static/img/distributing-a-val-10.png new file mode 100644 index 0000000..50c9e00 Binary files /dev/null and b/static/img/distributing-a-val-10.png differ diff --git a/static/img/distributing-a-val-11.png b/static/img/distributing-a-val-11.png new file mode 100644 index 0000000..e16d045 Binary files /dev/null and b/static/img/distributing-a-val-11.png differ diff --git a/static/img/distributing-a-val-12.png b/static/img/distributing-a-val-12.png new file mode 100644 index 0000000..857cc1e Binary files /dev/null and b/static/img/distributing-a-val-12.png differ diff --git a/static/img/distributing-a-val-13.png b/static/img/distributing-a-val-13.png new file mode 100644 index 0000000..f782ecd Binary files /dev/null and b/static/img/distributing-a-val-13.png differ diff --git a/static/img/distributing-a-val-14.png b/static/img/distributing-a-val-14.png new file mode 100644 index 0000000..fc03879 Binary files /dev/null and b/static/img/distributing-a-val-14.png differ diff --git a/static/img/distributing-a-val-16.png b/static/img/distributing-a-val-16.png new file mode 100644 index 0000000..969d70b Binary files /dev/null and b/static/img/distributing-a-val-16.png differ diff --git a/static/img/distributing-a-val-17.png b/static/img/distributing-a-val-17.png new file mode 100644 index 0000000..9afacc8 Binary files /dev/null and b/static/img/distributing-a-val-17.png differ diff --git a/static/img/distributing-a-val-3.png b/static/img/distributing-a-val-3.png new file mode 100644 index 0000000..3f200c6 Binary files /dev/null and b/static/img/distributing-a-val-3.png differ diff --git a/static/img/distributing-a-val-4.png b/static/img/distributing-a-val-4.png new file mode 100644 index 0000000..e4f5cce Binary files /dev/null and b/static/img/distributing-a-val-4.png differ diff --git a/static/img/distributing-a-val-5.png b/static/img/distributing-a-val-5.png new file mode 100644 index 0000000..5195e61 Binary files /dev/null and b/static/img/distributing-a-val-5.png differ diff --git a/static/img/distributing-a-val-EB.png b/static/img/distributing-a-val-EB.png new file mode 100644 index 0000000..7ef6c5b Binary files /dev/null and b/static/img/distributing-a-val-EB.png differ diff --git a/static/img/tokenomics-readme-1.avif b/static/img/tokenomics-readme-1.avif deleted file mode 100644 index 5913916..0000000 Binary files a/static/img/tokenomics-readme-1.avif and /dev/null differ diff --git a/static/img/tokenomics-readme-1.png b/static/img/tokenomics-readme-1.png new file mode 100644 index 0000000..a0435a2 Binary files /dev/null and b/static/img/tokenomics-readme-1.png differ diff --git a/yarn.lock b/yarn.lock index 0da55c0..6d36743 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,44 +2,9 @@ # yarn lockfile v1 -"@ai-sdk/gateway@2.0.18": - version "2.0.18" - resolved "https://registry.yarnpkg.com/@ai-sdk/gateway/-/gateway-2.0.18.tgz#7e81bdedddb7363af2c38d2cf7f34ac2d5e5eaa7" - integrity sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ== - dependencies: - "@ai-sdk/provider" "2.0.0" - "@ai-sdk/provider-utils" "3.0.18" - "@vercel/oidc" "3.0.5" - -"@ai-sdk/provider-utils@3.0.18": - version "3.0.18" - resolved "https://registry.yarnpkg.com/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz#fc7757ad7eb48a48ce1976da3025f0b9215b1aff" - integrity sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ== - dependencies: - "@ai-sdk/provider" "2.0.0" - "@standard-schema/spec" "^1.0.0" - eventsource-parser "^3.0.6" - -"@ai-sdk/provider@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@ai-sdk/provider/-/provider-2.0.0.tgz#b853c739d523b33675bc74b6c506b2c690bc602b" - integrity sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA== - dependencies: - json-schema "^0.4.0" - -"@ai-sdk/react@^2.0.30": - version "2.0.106" - resolved "https://registry.yarnpkg.com/@ai-sdk/react/-/react-2.0.106.tgz#ba80a5788bdc752dea519ec9d8d774d6706991d7" - integrity sha512-TU8ONNhm64GI7O60UDCcOz9CdyCp3emQwSYrSnq+QWBNgS8vDlRQ3ZwXyPNAJQdXyBTafVS2iyS0kvV+KXaPAQ== - dependencies: - "@ai-sdk/provider-utils" "3.0.18" - ai "5.0.106" - swr "^2.2.5" - throttleit "2.1.0" - "@algolia/abtesting@1.11.0": version "1.11.0" - resolved "https://registry.yarnpkg.com/@algolia/abtesting/-/abtesting-1.11.0.tgz#e6561f2cb17978445eb8b8aff339ee7a2f985daa" + resolved "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.11.0.tgz" integrity sha512-a7oQ8dwiyoyVmzLY0FcuBqyqcNSq78qlcOtHmNBumRlHCSnXDcuoYGBGPN1F6n8JoGhviDDsIaF/oQrzTzs6Lg== dependencies: "@algolia/client-common" "5.45.0" @@ -47,29 +12,36 @@ "@algolia/requester-fetch" "5.45.0" "@algolia/requester-node-http" "5.45.0" -"@algolia/autocomplete-core@1.19.2": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz#702df67a08cb3cfe8c33ee1111ef136ec1a9e232" - integrity sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw== +"@algolia/autocomplete-core@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz" + integrity sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.17.9" + "@algolia/autocomplete-shared" "1.17.9" + +"@algolia/autocomplete-plugin-algolia-insights@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz" + integrity sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ== dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.19.2" - "@algolia/autocomplete-shared" "1.19.2" + "@algolia/autocomplete-shared" "1.17.9" -"@algolia/autocomplete-plugin-algolia-insights@1.19.2": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz#3584b625b9317e333d1ae43664d02358e175c52d" - integrity sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg== +"@algolia/autocomplete-preset-algolia@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz" + integrity sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ== dependencies: - "@algolia/autocomplete-shared" "1.19.2" + "@algolia/autocomplete-shared" "1.17.9" -"@algolia/autocomplete-shared@1.19.2": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz#c0b7b8dc30a5c65b70501640e62b009535e4578f" - integrity sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w== +"@algolia/autocomplete-shared@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz" + integrity sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ== "@algolia/client-abtesting@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.45.0.tgz#7e1984b02d58ce965bf190080b3ffa10c738ddbd" + resolved "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.45.0.tgz" integrity sha512-WTW0VZA8xHMbzuQD5b3f41ovKZ0MNTIXkWfm0F2PU+XGcLxmxX15UqODzF2sWab0vSbi3URM1xLhJx+bXbd1eQ== dependencies: "@algolia/client-common" "5.45.0" @@ -79,7 +51,7 @@ "@algolia/client-analytics@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.45.0.tgz#4f58d6c1c8d43afeedfd8ef7b84b49e3e7cdff14" + resolved "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.45.0.tgz" integrity sha512-I3g7VtvG/QJOH3tQO7E7zWTwBfK/nIQXShFLR8RvPgWburZ626JNj332M3wHCYcaAMivN9WJG66S2JNXhm6+Xg== dependencies: "@algolia/client-common" "5.45.0" @@ -89,12 +61,12 @@ "@algolia/client-common@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.45.0.tgz#c674f7f47a5f0013e3ab717929e51a6109af2dd2" + resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.45.0.tgz" integrity sha512-/nTqm1tLiPtbUr+8kHKyFiCOfhRfgC+JxLvOCq471gFZZOlsh6VtFRiKI60/zGmHTojFC6B0mD80PB7KeK94og== "@algolia/client-insights@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.45.0.tgz#ca7128edec95da8217da76f867b8cd2c2a05f682" + resolved "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.45.0.tgz" integrity sha512-suQTx/1bRL1g/K2hRtbK3ANmbzaZCi13487sxxmqok+alBDKKw0/TI73ZiHjjFXM2NV52inwwcmW4fUR45206Q== dependencies: "@algolia/client-common" "5.45.0" @@ -104,7 +76,7 @@ "@algolia/client-personalization@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.45.0.tgz#e674b76b4dd5a8e89d9f157cbc958d68fbeb1c60" + resolved "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.45.0.tgz" integrity sha512-CId/dbjpzI3eoUhPU6rt/z4GrRsDesqFISEMOwrqWNSrf4FJhiUIzN42Ac+Gzg69uC0RnzRYy60K1y4Na5VSMw== dependencies: "@algolia/client-common" "5.45.0" @@ -114,7 +86,7 @@ "@algolia/client-query-suggestions@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.45.0.tgz#6bad2a7eaa7e1a6ecf1a7960c2056e08ee0302b6" + resolved "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.45.0.tgz" integrity sha512-tjbBKfA8fjAiFtvl9g/MpIPiD6pf3fj7rirVfh1eMIUi8ybHP4ovDzIaE216vHuRXoePQVCkMd2CokKvYq1CLw== dependencies: "@algolia/client-common" "5.45.0" @@ -122,9 +94,9 @@ "@algolia/requester-fetch" "5.45.0" "@algolia/requester-node-http" "5.45.0" -"@algolia/client-search@5.45.0": +"@algolia/client-search@>= 4.9.1 < 6", "@algolia/client-search@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.45.0.tgz#709f5fb2a13487fa6327b31306654a2c694c0fe9" + resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.45.0.tgz" integrity sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA== dependencies: "@algolia/client-common" "5.45.0" @@ -134,12 +106,12 @@ "@algolia/events@^4.0.1": version "4.0.1" - resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" + resolved "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz" integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== "@algolia/ingestion@1.45.0": version "1.45.0" - resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.45.0.tgz#f99eb766a0cff112d65834ee1a43e08d18bc5f2a" + resolved "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.45.0.tgz" integrity sha512-t+1doBzhkQTeOOjLHMlm4slmXBhvgtEGQhOmNpMPTnIgWOyZyESWdm+XD984qM4Ej1i9FRh8VttOGrdGnAjAng== dependencies: "@algolia/client-common" "5.45.0" @@ -149,7 +121,7 @@ "@algolia/monitoring@1.45.0": version "1.45.0" - resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.45.0.tgz#09e7320973741f829badb5fa47c54cbc512bb0bc" + resolved "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.45.0.tgz" integrity sha512-IaX3ZX1A/0wlgWZue+1BNWlq5xtJgsRo7uUk/aSiYD7lPbJ7dFuZ+yTLFLKgbl4O0QcyHTj1/mSBj9ryF1Lizg== dependencies: "@algolia/client-common" "5.45.0" @@ -159,7 +131,7 @@ "@algolia/recommend@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.45.0.tgz#06dc022d85f8a0b6a93dd70c690a236d4ee745a3" + resolved "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.45.0.tgz" integrity sha512-1jeMLoOhkgezCCPsOqkScwYzAAc1Jr5T2hisZl0s32D94ZV7d1OHozBukgOjf8Dw+6Hgi6j52jlAdUWTtkX9Mg== dependencies: "@algolia/client-common" "5.45.0" @@ -169,21 +141,21 @@ "@algolia/requester-browser-xhr@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.45.0.tgz#0cb197014e2344a7f58aef245c10831597d23fdd" + resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.45.0.tgz" integrity sha512-46FIoUkQ9N7wq4/YkHS5/W9Yjm4Ab+q5kfbahdyMpkBPJ7IBlwuNEGnWUZIQ6JfUZuJVojRujPRHMihX4awUMg== dependencies: "@algolia/client-common" "5.45.0" "@algolia/requester-fetch@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.45.0.tgz#df040b30f67e70b074e7a740874befd191bb6067" + resolved "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.45.0.tgz" integrity sha512-XFTSAtCwy4HdBhSReN2rhSyH/nZOM3q3qe5ERG2FLbYId62heIlJBGVyAPRbltRwNlotlydbvSJ+SQ0ruWC2cw== dependencies: "@algolia/client-common" "5.45.0" "@algolia/requester-node-http@5.45.0": version "5.45.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.45.0.tgz#d96196d538d3ad5c25e3e21b469e92b19b442153" + resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.45.0.tgz" integrity sha512-8mTg6lHx5i44raCU52APsu0EqMsdm4+7Hch/e4ZsYZw0hzwkuaMFh826ngnkYf9XOl58nHoou63aZ874m8AbpQ== dependencies: "@algolia/client-common" "5.45.0" @@ -202,7 +174,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz" integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== -"@babel/core@^7.21.3", "@babel/core@^7.25.9": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.21.3", "@babel/core@^7.25.9", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": version "7.28.5" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz" integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== @@ -1465,29 +1437,20 @@ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@docsearch/core@4.3.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@docsearch/core/-/core-4.3.1.tgz#88a97a6fe4d4025269b6dee8b9d070b76758ad82" - integrity sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ== - -"@docsearch/css@4.3.2": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-4.3.2.tgz#d47d25336c9516b419245fa74e8dd5ae84a17492" - integrity sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ== +"@docsearch/css@3.9.0": + version "3.9.0" + resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz" + integrity sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA== "@docsearch/react@^3.9.0 || ^4.1.0": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-4.3.2.tgz#450b8341cb5cca03737a00075d4dfd3a904a3e3e" - integrity sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ== - dependencies: - "@ai-sdk/react" "^2.0.30" - "@algolia/autocomplete-core" "1.19.2" - "@docsearch/core" "4.3.1" - "@docsearch/css" "4.3.2" - ai "^5.0.30" - algoliasearch "^5.28.0" - marked "^16.3.0" - zod "^4.1.8" + version "3.9.0" + resolved "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz" + integrity sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ== + dependencies: + "@algolia/autocomplete-core" "1.17.9" + "@algolia/autocomplete-preset-algolia" "1.17.9" + "@docsearch/css" "3.9.0" + algoliasearch "^5.14.2" "@docusaurus/babel@3.9.2": version "3.9.2" @@ -1600,7 +1563,7 @@ "@docusaurus/logger@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.9.2.tgz#6ec6364b90f5a618a438cc9fd01ac7376869f92a" + resolved "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz" integrity sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA== dependencies: chalk "^4.1.2" @@ -1608,7 +1571,7 @@ "@docusaurus/mdx-loader@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz#78d238de6c6203fa811cc2a7e90b9b79e111408c" + resolved "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz" integrity sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ== dependencies: "@docusaurus/logger" "3.9.2" @@ -1649,9 +1612,9 @@ react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/plugin-client-redirects@^3.9.2": +"@docusaurus/plugin-client-redirects@^3.8.1": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.9.2.tgz#9c27025c72aeeedeb783a94720163911567da0e8" + resolved "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.9.2.tgz" integrity sha512-lUgMArI9vyOYMzLRBUILcg9vcPTCyyI2aiuXq/4npcMVqOr6GfmwtmBYWSbNMlIUM0147smm4WhpXD0KFboffw== dependencies: "@docusaurus/core" "3.9.2" @@ -1688,9 +1651,9 @@ utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.9.2": +"@docusaurus/plugin-content-docs@*", "@docusaurus/plugin-content-docs@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz#cd8f2d1c06e53c3fa3d24bdfcb48d237bf2d6b2e" + resolved "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz" integrity sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg== dependencies: "@docusaurus/core" "3.9.2" @@ -1863,7 +1826,7 @@ "@docusaurus/theme-common@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.9.2.tgz#487172c6fef9815c2746ef62a71e4f5b326f9ba5" + resolved "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz" integrity sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag== dependencies: "@docusaurus/mdx-loader" "3.9.2" @@ -1879,7 +1842,7 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-search-algolia@3.9.2", "@docusaurus/theme-search-algolia@^3.9.2": +"@docusaurus/theme-search-algolia@^3.7.0", "@docusaurus/theme-search-algolia@3.9.2": version "3.9.2" resolved "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz" integrity sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw== @@ -1903,7 +1866,7 @@ "@docusaurus/theme-translations@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz#238cd69c2da92d612be3d3b4f95944c1d0f1e041" + resolved "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz" integrity sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA== dependencies: fs-extra "^11.1.1" @@ -1932,7 +1895,7 @@ "@docusaurus/utils-common@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.9.2.tgz#e89bfcf43d66359f43df45293fcdf22814847460" + resolved "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz" integrity sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw== dependencies: "@docusaurus/types" "3.9.2" @@ -1940,7 +1903,7 @@ "@docusaurus/utils-validation@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz#04aec285604790806e2fc5aa90aa950dc7ba75ae" + resolved "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz" integrity sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A== dependencies: "@docusaurus/logger" "3.9.2" @@ -1954,7 +1917,7 @@ "@docusaurus/utils@3.9.2": version "3.9.2" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.9.2.tgz#ffab7922631c7e0febcb54e6d499f648bf8a89eb" + resolved "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz" integrity sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ== dependencies: "@docusaurus/logger" "3.9.2" @@ -1981,12 +1944,12 @@ "@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": version "9.3.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz" integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== "@hapi/topo@^5.1.0": version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + resolved "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz" integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== dependencies: "@hapi/hoek" "^9.0.0" @@ -2028,21 +1991,21 @@ "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/source-map@^0.3.3": - version "0.3.11" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" - integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== + version "0.3.6" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + 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.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" @@ -2103,15 +2066,14 @@ integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== "@mdx-js/mdx@^3.0.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-3.1.1.tgz#c5ffd991a7536b149e17175eee57a1a2a511c6d1" - integrity sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ== + version "3.1.0" + resolved "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz" + integrity sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw== dependencies: "@types/estree" "^1.0.0" "@types/estree-jsx" "^1.0.0" "@types/hast" "^3.0.0" "@types/mdx" "^2.0.0" - acorn "^8.0.0" collapse-white-space "^2.0.0" devlop "^1.0.0" estree-util-is-identifier-name "^3.0.0" @@ -2142,30 +2104,25 @@ "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@opentelemetry/api@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" - integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== - "@pnpm/config.env-replace@^1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz" @@ -2194,19 +2151,19 @@ "@sideway/address@^4.1.5": version "4.1.5" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" + resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz" integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== dependencies: "@hapi/hoek" "^9.0.0" "@sideway/formula@^3.0.1": version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + resolved "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz" integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== "@sideway/pinpoint@^2.0.0": version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + resolved "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== "@sinclair/typebox@^0.27.8": @@ -2216,7 +2173,7 @@ "@sindresorhus/is@^4.6.0": version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== "@sindresorhus/is@^5.2.0": @@ -2226,18 +2183,13 @@ "@slorber/remark-comment@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/@slorber/remark-comment/-/remark-comment-1.0.0.tgz#2a020b3f4579c89dec0361673206c28d67e08f5a" + resolved "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz" integrity sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA== dependencies: micromark-factory-space "^1.0.0" micromark-util-character "^1.1.0" micromark-util-symbol "^1.0.1" -"@standard-schema/spec@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" - integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== - "@svgr/babel-plugin-add-jsx-attribute@8.0.0": version "8.0.0" resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz" @@ -2292,7 +2244,7 @@ "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" "@svgr/babel-plugin-transform-svg-component" "8.0.0" -"@svgr/core@8.1.0": +"@svgr/core@*", "@svgr/core@8.1.0": version "8.1.0" resolved "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz" integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== @@ -2388,37 +2340,21 @@ "@types/debug@^4.0.0": version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz" integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== dependencies: "@types/ms" "*" -"@types/eslint-scope@^3.7.7": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" - integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - "@types/estree-jsx@^1.0.0": version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18" + resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz" integrity sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg== dependencies: "@types/estree" "*" -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.8": +"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5": version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": @@ -2431,7 +2367,7 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@*", "@types/express@^4.17.21": +"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.21": version "4.17.25" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz" integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== @@ -2448,14 +2384,14 @@ "@types/hast@^3.0.0": version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + resolved "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz" integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== dependencies: "@types/unist" "*" "@types/history@^4.7.11": version "4.7.11" - resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + resolved "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz" integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== "@types/html-minifier-terser@^6.0.0": @@ -2499,7 +2435,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -2511,14 +2447,14 @@ "@types/mdast@^4.0.0", "@types/mdast@^4.0.2": version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz" integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== dependencies: "@types/unist" "*" "@types/mdx@^2.0.0": version "2.0.13" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + resolved "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz" integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== "@types/mime@^1": @@ -2528,7 +2464,7 @@ "@types/ms@*": version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + resolved "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz" integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== "@types/node-forge@^1.3.0": @@ -2539,11 +2475,11 @@ "@types/node" "*" "@types/node@*": - version "24.10.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.1.tgz#91e92182c93db8bd6224fca031e2370cef9a8f01" - integrity sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ== + version "24.0.0" + resolved "https://registry.npmjs.org/@types/node/-/node-24.0.0.tgz" + integrity sha512-yZQa2zm87aRVcqDyH5+4Hv9KYgSdgwX1rFnGvpbzMaC7YAljmhBET93TPiTd3ObwTL+gSpIzPKg5BqVxdCvxKg== dependencies: - undici-types "~7.16.0" + undici-types "~7.8.0" "@types/node@^17.0.5": version "17.0.45" @@ -2567,7 +2503,7 @@ "@types/react-router-config@*", "@types/react-router-config@^5.0.7": version "5.0.11" - resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.11.tgz#2761a23acc7905a66a94419ee40294a65aaa483a" + resolved "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz" integrity sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw== dependencies: "@types/history" "^4.7.11" @@ -2591,12 +2527,12 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react@*": - version "19.2.7" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.7.tgz#84e62c0f23e8e4e5ac2cadcea1ffeacccae7f62f" - integrity sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== +"@types/react@*", "@types/react@>= 16.8.0 < 20.0.0", "@types/react@>=16": + version "19.1.9" + resolved "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz" + integrity sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA== dependencies: - csstype "^3.2.2" + csstype "^3.0.2" "@types/retry@0.12.2": version "0.12.2" @@ -2650,12 +2586,12 @@ "@types/unist@*", "@types/unist@^3.0.0": version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" + resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz" integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== "@types/unist@^2.0.0": version "2.0.11" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz" integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== "@types/ws@^8.5.10": @@ -2679,17 +2615,12 @@ "@ungap/structured-clone@^1.0.0": version "1.3.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@vercel/oidc@3.0.5": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@vercel/oidc/-/oidc-3.0.5.tgz#bd8db7ee777255c686443413492db4d98ef49657" - integrity sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw== - -"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.12.1", "@webassemblyjs/ast@^1.14.1": +"@webassemblyjs/ast@^1.12.1", "@webassemblyjs/ast@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz" integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== dependencies: "@webassemblyjs/helper-numbers" "1.13.2" @@ -2697,22 +2628,22 @@ "@webassemblyjs/floating-point-hex-parser@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz" integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== "@webassemblyjs/helper-api-error@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz" integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== "@webassemblyjs/helper-buffer@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz" integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== "@webassemblyjs/helper-numbers@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz" integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== dependencies: "@webassemblyjs/floating-point-hex-parser" "1.13.2" @@ -2721,12 +2652,12 @@ "@webassemblyjs/helper-wasm-bytecode@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz" integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== "@webassemblyjs/helper-wasm-section@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz" integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2736,26 +2667,26 @@ "@webassemblyjs/ieee754@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz" integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" "@webassemblyjs/leb128@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz" integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" "@webassemblyjs/utf8@1.13.2": version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz" integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== -"@webassemblyjs/wasm-edit@^1.12.1", "@webassemblyjs/wasm-edit@^1.14.1": +"@webassemblyjs/wasm-edit@^1.12.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz" integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2769,7 +2700,7 @@ "@webassemblyjs/wasm-gen@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz" integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2780,7 +2711,7 @@ "@webassemblyjs/wasm-opt@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz" integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2788,9 +2719,9 @@ "@webassemblyjs/wasm-gen" "1.14.1" "@webassemblyjs/wasm-parser" "1.14.1" -"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.12.1", "@webassemblyjs/wasm-parser@^1.14.1": +"@webassemblyjs/wasm-parser@^1.12.1", "@webassemblyjs/wasm-parser@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz" integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2802,7 +2733,7 @@ "@webassemblyjs/wast-printer@1.14.1": version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz" integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== dependencies: "@webassemblyjs/ast" "1.14.1" @@ -2810,12 +2741,12 @@ "@xtuc/ieee754@^1.2.0": version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== "@xtuc/long@4.2.2": version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== accepts@~1.3.4, accepts@~1.3.8: @@ -2828,17 +2759,12 @@ accepts@~1.3.4, accepts@~1.3.8: acorn-import-attributes@^1.9.5: version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + resolved "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz" integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== -acorn-import-phases@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" - integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== - acorn-jsx@^5.0.0: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.0.0: @@ -2848,7 +2774,7 @@ acorn-walk@^8.0.0: dependencies: acorn "^8.11.0" -acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.7.1, acorn@^8.8.2: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8, acorn@^8.0.0, acorn@^8.0.4, acorn@^8.11.0, acorn@^8.7.1, acorn@^8.8.2: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -2866,16 +2792,6 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ai@5.0.106, ai@^5.0.30: - version "5.0.106" - resolved "https://registry.yarnpkg.com/ai/-/ai-5.0.106.tgz#4a9a2d249a12aea9158c3bab11d0e463e0d6a149" - integrity sha512-M5obwavxSJJ3tGlAFqI6eltYNJB0D20X6gIBCFx/KVorb/X1fxVVfiZZpZb+Gslu4340droSOjT0aKQFCarNVg== - dependencies: - "@ai-sdk/gateway" "2.0.18" - "@ai-sdk/provider" "2.0.0" - "@ai-sdk/provider-utils" "3.0.18" - "@opentelemetry/api" "1.9.0" - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" @@ -2885,7 +2801,7 @@ ajv-formats@^2.1.1: ajv-keywords@^3.5.2: version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== ajv-keywords@^5.1.0: @@ -2895,9 +2811,9 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: +ajv@^6.12.5, ajv@^6.9.1: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -2905,7 +2821,7 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.9.0: +ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: version "8.17.1" resolved "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz" integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== @@ -2917,14 +2833,14 @@ ajv@^8.0.0, ajv@^8.9.0: algoliasearch-helper@^3.26.0: version "3.26.1" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz#5b7f0874a2751c3d6de675d5403d8fa2f015023f" + resolved "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz" integrity sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw== dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^5.28.0, algoliasearch@^5.37.0: +algoliasearch@^5.14.2, algoliasearch@^5.37.0, "algoliasearch@>= 3.1 < 6", "algoliasearch@>= 4.9.1 < 6": version "5.45.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.45.0.tgz#90abba15b26d6722360a97c1e1931bc920f9c555" + resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.45.0.tgz" integrity sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA== dependencies: "@algolia/abtesting" "1.11.0" @@ -2998,14 +2914,14 @@ arg@^5.0.0: argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-flatten@1.1.1: @@ -3015,12 +2931,12 @@ array-flatten@1.1.1: array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== astring@^1.8.0: version "1.9.0" - resolved "https://registry.yarnpkg.com/astring/-/astring-1.9.0.tgz#cc73e6062a7eb03e7d19c22d8b0b3451fd9bfeef" + resolved "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz" integrity sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg== autoprefixer@^10.4.19, autoprefixer@^10.4.21: @@ -3076,7 +2992,7 @@ babel-plugin-polyfill-regenerator@^0.6.5: bail@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + resolved "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz" integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== balanced-match@^1.0.0: @@ -3086,7 +3002,7 @@ balanced-match@^1.0.0: baseline-browser-mapping@^2.9.0: version "2.9.0" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.0.tgz#b4b91c7ec4deac14527bc5495b914fb9db1a251a" + resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.0.tgz" integrity sha512-Mh++g+2LPfzZToywfE1BUzvZbfOY52Nil0rn9H1CPC5DJ7fX+Vir7nToBeoiSbB1zTNeGYbELEvJESujgGrzXw== batch@0.6.1: @@ -3096,7 +3012,7 @@ batch@0.6.1: big.js@^5.2.2: version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: @@ -3178,7 +3094,7 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.0, browserslist@^4.26.3, browserslist@^4.27.0, browserslist@^4.28.0: +browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.0, browserslist@^4.27.0, browserslist@^4.28.0, "browserslist@>= 4.21.0": version "4.28.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz" integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== @@ -3191,7 +3107,7 @@ browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.23.0, browserslist@^ buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bundle-name@^4.1.0: @@ -3201,12 +3117,17 @@ bundle-name@^4.1.0: dependencies: run-applescript "^7.0.0" +bytes@~3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + bytes@3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2, bytes@~3.1.2: +bytes@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -3295,7 +3216,7 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001754, caniuse-lite@^1.0.30001759: ccount@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== chalk@^4.0.0, chalk@^4.1.2: @@ -3313,27 +3234,27 @@ chalk@^5.0.1, chalk@^5.2.0: char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== character-entities-html4@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== character-entities-legacy@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== character-entities@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz" integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== character-reference-invalid@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz" integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== cheerio-select@^2.1.0: @@ -3378,7 +3299,7 @@ chokidar@^3.5.3, chokidar@^3.6.0: chrome-trace-event@^1.0.2: version "1.0.4" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== ci-info@^3.2.0: @@ -3428,19 +3349,19 @@ clsx@^2.0.0: collapse-white-space@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz#640257174f9f42c740b40f3b55ee752924feefca" + resolved "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz" integrity sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw== color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colord@^2.9.3: @@ -3455,12 +3376,12 @@ colorette@^2.0.10: combine-promises@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.2.0.tgz#5f2e68451862acf85761ded4d9e2af7769c2ca6a" + resolved "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz" integrity sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ== comma-separated-tokens@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== commander@^10.0.0: @@ -3470,7 +3391,7 @@ commander@^10.0.0: commander@^2.20.0: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^5.1.0: @@ -3547,11 +3468,6 @@ consola@^3.2.3: resolved "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz" integrity sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA== -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz" - integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== - content-disposition@~0.5.4: version "0.5.4" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" @@ -3559,6 +3475,11 @@ content-disposition@~0.5.4: dependencies: safe-buffer "5.2.1" +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz" + integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== + content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" @@ -3625,7 +3546,7 @@ cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: cross-spawn@^7.0.3: version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" @@ -3813,16 +3734,23 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -csstype@^3.2.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" - integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== debounce@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== +debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.1, debug@4: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -3830,17 +3758,10 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.3.1, debug@^4.4.1: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - decode-named-character-reference@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed" - integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q== + version "1.1.0" + resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz" + integrity sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w== dependencies: character-entities "^2.0.0" @@ -3907,22 +3828,22 @@ define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -depd@2.0.0, depd@~2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -dequal@^2.0.0, dequal@^2.0.3: +depd@~2.0.0, depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +dequal@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -destroy@1.2.0, destroy@~1.2.0: +destroy@~1.2.0, destroy@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -3942,14 +3863,14 @@ detect-port@^1.5.1: devlop@^1.0.0, devlop@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + resolved "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz" integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== dependencies: dequal "^2.0.0" dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" @@ -4064,7 +3985,7 @@ ee-first@1.1.1: electron-to-chromium@^1.5.263: version "1.5.264" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.264.tgz#38d2262e290bf5b424ba1488e072c7b0163400be" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.264.tgz" integrity sha512-1tEf0nLgltC3iy9wtlYDlQDc5Rg9lEKVjEmIHJ21rI9OcqkvD45K1oyNIRA4rR1z3LgJ7KeGzEBojVcV6m4qjA== emoji-regex@^8.0.0: @@ -4079,17 +4000,17 @@ emoji-regex@^9.2.2: emojilib@^2.4.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e" + resolved "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz" integrity sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw== emojis-list@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== emoticon@^4.0.1: version "4.1.0" - resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-4.1.0.tgz#d5a156868ee173095627a33de3f1e914c3dde79e" + resolved "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz" integrity sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ== encodeurl@~1.0.2: @@ -4102,10 +4023,10 @@ encodeurl@~2.0.0: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.17.1, enhanced-resolve@^5.17.3: - version "5.18.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" - integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== +enhanced-resolve@^5.17.1: + version "5.18.1" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz" + integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -4122,7 +4043,7 @@ entities@^4.2.0, entities@^4.4.0: entities@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + resolved "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz" integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== error-ex@^1.3.1: @@ -4144,7 +4065,7 @@ es-errors@^1.3.0: es-module-lexer@^1.2.1: version "1.7.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz" integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: @@ -4156,7 +4077,7 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: esast-util-from-estree@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz#8d1cfb51ad534d2f159dc250e604f3478a79f1ad" + resolved "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz" integrity sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ== dependencies: "@types/estree-jsx" "^1.0.0" @@ -4166,7 +4087,7 @@ esast-util-from-estree@^2.0.0: esast-util-from-js@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz#5147bec34cc9da44accf52f87f239a40ac3e8225" + resolved "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz" integrity sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw== dependencies: "@types/estree-jsx" "^1.0.0" @@ -4176,7 +4097,7 @@ esast-util-from-js@^2.0.0: escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-goat@^4.0.0: @@ -4196,17 +4117,17 @@ escape-string-regexp@^1.0.5: escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escape-string-regexp@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== eslint-scope@5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -4214,36 +4135,36 @@ eslint-scope@5.1.1: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== estree-util-attach-comments@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz#344bde6a64c8a31d15231e5ee9e297566a691c2d" + resolved "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz" integrity sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw== dependencies: "@types/estree" "^1.0.0" estree-util-build-jsx@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz#b6d0bced1dcc4f06f25cf0ceda2b2dcaf98168f1" + resolved "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz" integrity sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ== dependencies: "@types/estree-jsx" "^1.0.0" @@ -4253,12 +4174,12 @@ estree-util-build-jsx@^3.0.0: estree-util-is-identifier-name@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz#0b5ef4c4ff13508b34dcd01ecfa945f61fce5dbd" + resolved "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz" integrity sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg== estree-util-scope@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/estree-util-scope/-/estree-util-scope-1.0.0.tgz#9cbdfc77f5cb51e3d9ed4ad9c4adbff22d43e585" + resolved "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz" integrity sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ== dependencies: "@types/estree" "^1.0.0" @@ -4266,7 +4187,7 @@ estree-util-scope@^1.0.0: estree-util-to-js@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz#10a6fb924814e6abb62becf0d2bc4dea51d04f17" + resolved "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz" integrity sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg== dependencies: "@types/estree-jsx" "^1.0.0" @@ -4274,15 +4195,15 @@ estree-util-to-js@^2.0.0: source-map "^0.7.0" estree-util-value-to-estree@^3.0.1: - version "3.5.0" - resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz#cd70cf37e7f78eae3e110d66a3436ce0d18a8f80" - integrity sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ== + version "3.4.0" + resolved "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.4.0.tgz" + integrity sha512-Zlp+gxis+gCfK12d3Srl2PdX2ybsEA8ZYy6vQGVQTNNYLEGRQQ56XB64bjemN8kxIKXP1nC9ip4Z+ILy9LGzvQ== dependencies: "@types/estree" "^1.0.0" estree-util-visit@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz#13a9a9f40ff50ed0c022f831ddf4b58d05446feb" + resolved "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz" integrity sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww== dependencies: "@types/estree-jsx" "^1.0.0" @@ -4290,7 +4211,7 @@ estree-util-visit@^2.0.0: estree-walker@^3.0.0: version "3.0.3" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz" integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== dependencies: "@types/estree" "^1.0.0" @@ -4302,7 +4223,7 @@ esutils@^2.0.2: eta@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/eta/-/eta-2.2.0.tgz#eb8b5f8c4e8b6306561a455e62cd7492fe3a9b8a" + resolved "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz" integrity sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g== etag@~1.8.1: @@ -4325,17 +4246,12 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.4: events@^3.2.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -eventsource-parser@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" - integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== - execa@5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -4387,14 +4303,14 @@ express@^4.21.2: extend-shallow@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz" integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== dependencies: is-extendable "^0.1.0" extend@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: @@ -4402,7 +4318,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.3.0: +fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.2" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4413,20 +4329,9 @@ fast-glob@^3.2.11, fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.9: - version "3.3.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" - integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.8" - fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-uri@^3.0.1: @@ -4436,14 +4341,14 @@ fast-uri@^3.0.1: fastq@^1.6.0: version "1.19.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz" integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== dependencies: reusify "^1.0.4" fault@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c" + resolved "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz" integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ== dependencies: format "^0.2.0" @@ -4469,9 +4374,9 @@ figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-loader@^6.2.0: +file-loader@*, file-loader@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + resolved "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" @@ -4479,7 +4384,7 @@ file-loader@^6.2.0: fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -4530,7 +4435,7 @@ form-data-encoder@^2.1.2: format@^0.2.0: version "0.2.2" - resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== forwarded@0.2.0: @@ -4543,15 +4448,15 @@ fraction.js@^5.3.4: resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz" integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== -fresh@0.5.2, fresh@~0.5.2: +fresh@~0.5.2, fresh@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^11.1.1, fs-extra@^11.2.0: - version "11.3.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4" - integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A== + version "11.3.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz" + integrity sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -4559,7 +4464,7 @@ fs-extra@^11.1.1, fs-extra@^11.2.0: fsevents@~2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: @@ -4590,7 +4495,7 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-proto@^1.0.1: @@ -4608,7 +4513,7 @@ get-stream@^6.0.0, get-stream@^6.0.1: github-slugger@^1.5.0: version "1.5.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" + resolved "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz" integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== glob-parent@^5.1.2, glob-parent@~5.1.2: @@ -4632,7 +4537,7 @@ glob-to-regex.js@^1.0.1: glob-to-regexp@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== global-dirs@^3.0.0: @@ -4644,7 +4549,7 @@ global-dirs@^3.0.0: globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -4687,19 +4592,19 @@ got@^12.1.0: p-cancelable "^3.0.0" responselike "^3.0.0" -graceful-fs@4.2.10: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + gray-matter@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + resolved "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz" integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== dependencies: js-yaml "^3.13.1" @@ -4721,7 +4626,7 @@ handle-thing@^2.0.0: has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: @@ -4781,7 +4686,7 @@ hast-util-from-html@^2.0.0: hast-util-from-parse5@^8.0.0: version "8.0.3" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz#830a35022fff28c3fea3697a98c2f4cc6b835a2e" + resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz" integrity sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg== dependencies: "@types/hast" "^3.0.0" @@ -4802,14 +4707,14 @@ hast-util-is-element@^3.0.0: hast-util-parse-selector@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz" integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== dependencies: "@types/hast" "^3.0.0" hast-util-raw@^9.0.0: version "9.1.0" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz#79b66b26f6f68fb50dfb4716b2cdca90d92adf2e" + resolved "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz" integrity sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw== dependencies: "@types/hast" "^3.0.0" @@ -4828,7 +4733,7 @@ hast-util-raw@^9.0.0: hast-util-to-estree@^3.0.0: version "3.1.3" - resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz#e654c1c9374645135695cc0ab9f70b8fcaf733d7" + resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz" integrity sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w== dependencies: "@types/estree" "^1.0.0" @@ -4850,7 +4755,7 @@ hast-util-to-estree@^3.0.0: hast-util-to-jsx-runtime@^2.0.0: version "2.3.6" - resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz#ff31897aae59f62232e21594eac7ef6b63333e98" + resolved "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz" integrity sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg== dependencies: "@types/estree" "^1.0.0" @@ -4871,7 +4776,7 @@ hast-util-to-jsx-runtime@^2.0.0: hast-util-to-parse5@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" + resolved "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz" integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== dependencies: "@types/hast" "^3.0.0" @@ -4894,20 +4799,20 @@ hast-util-to-text@^4.0.0: hast-util-whitespace@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz" integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== dependencies: "@types/hast" "^3.0.0" hastscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-9.0.1.tgz#dbc84bef6051d40084342c229c451cd9dc567dff" - integrity sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w== + version "9.0.0" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-9.0.0.tgz" + integrity sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw== dependencies: "@types/hast" "^3.0.0" comma-separated-tokens "^2.0.0" hast-util-parse-selector "^4.0.0" - property-information "^7.0.0" + property-information "^6.0.0" space-separated-tokens "^2.0.0" he@^1.2.0: @@ -4982,7 +4887,7 @@ html-tags@^3.3.1: html-void-elements@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz" integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== html-webpack-plugin@^5.6.0: @@ -5026,17 +4931,6 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - http-errors@~1.6.2: version "1.6.3" resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" @@ -5058,6 +4952,17 @@ http-errors@~2.0.0, http-errors@~2.0.1: statuses "~2.0.2" toidentifier "~1.0.1" +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + http-parser-js@>=0.5.1: version "0.5.10" resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz" @@ -5093,7 +4998,7 @@ http2-wrapper@^2.1.10: human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== hyperdyperid@^1.2.0: @@ -5120,7 +5025,7 @@ ignore@^5.2.0, ignore@^5.2.4: image-size@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-2.0.2.tgz#84a7b43704db5736f364bf0d1b029821299b4bdc" + resolved "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz" integrity sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w== import-fresh@^3.3.0: @@ -5151,30 +5056,35 @@ infima@0.2.0-alpha.45: resolved "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz" integrity sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw== +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + inherits@2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@^1.3.4: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== ini@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -inline-style-parser@0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.7.tgz#b1fc68bfc0313b8685745e4464e37f9376b9c909" - integrity sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA== +inline-style-parser@0.2.4: + version "0.2.4" + resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz" + integrity sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q== invariant@^2.2.4: version "2.2.4" @@ -5183,24 +5093,24 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - ipaddr.js@^2.1.0: version "2.3.0" resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz" integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + is-alphabetical@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== is-alphanumerical@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz" integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== dependencies: is-alphabetical "^2.0.0" @@ -5234,7 +5144,7 @@ is-core-module@^2.16.1: is-decimal@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz" integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== is-docker@^2.0.0, is-docker@^2.1.1: @@ -5249,12 +5159,12 @@ is-docker@^3.0.0: is-extendable@^0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: @@ -5271,7 +5181,7 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: is-hexadecimal@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz" integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== is-inside-container@^1.0.0: @@ -5301,12 +5211,12 @@ is-npm@^6.0.0: is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-obj@^2.0.0: @@ -5326,7 +5236,7 @@ is-plain-obj@^3.0.0: is-plain-obj@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz" integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== is-plain-object@^2.0.4: @@ -5338,12 +5248,12 @@ is-plain-object@^2.0.4: is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-typedarray@^1.0.0: @@ -5370,19 +5280,19 @@ is-yarn-global@^0.4.0: resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz" integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isobject@^3.0.1: @@ -5404,7 +5314,7 @@ jest-util@^29.7.0: jest-worker@^27.4.5: version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== dependencies: "@types/node" "*" @@ -5423,12 +5333,12 @@ jest-worker@^29.4.3: jiti@^1.20.0: version "1.21.7" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" + resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz" integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== joi@^17.9.2: version "17.13.3" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec" + resolved "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz" integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== dependencies: "@hapi/hoek" "^9.3.0" @@ -5443,17 +5353,17 @@ joi@^17.9.2: integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.2" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" - integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" js-yaml@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" @@ -5474,7 +5384,7 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema-traverse@^1.0.0: @@ -5482,20 +5392,15 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json5@^2.1.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" - integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== + version "6.1.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" optionalDependencies: @@ -5517,12 +5422,12 @@ keyv@^4.5.3: kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== kleur@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== latest-version@^7.0.0: @@ -5555,14 +5460,14 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -loader-runner@^4.2.0, loader-runner@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" - integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== loader-utils@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== dependencies: big.js "^5.2.2" @@ -5598,7 +5503,7 @@ lodash@^4.17.20, lodash@^4.17.21: longest-streak@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" + resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz" integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== loose-envify@^1.0.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: @@ -5629,7 +5534,7 @@ lru-cache@^5.1.1: markdown-extensions@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz#34bebc83e9938cae16e0e017e4a9814a8330d3c4" + resolved "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz" integrity sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q== markdown-table@^2.0.0: @@ -5641,14 +5546,9 @@ markdown-table@^2.0.0: markdown-table@^3.0.0: version "3.0.4" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" + resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz" integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw== -marked@^16.3.0: - version "16.4.2" - resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3" - integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA== - math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" @@ -5656,7 +5556,7 @@ math-intrinsics@^1.1.0: mdast-util-directive@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz#f3656f4aab6ae3767d3c72cfab5e8055572ccba1" + resolved "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz" integrity sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q== dependencies: "@types/mdast" "^4.0.0" @@ -5671,7 +5571,7 @@ mdast-util-directive@^3.0.0: mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1: version "3.0.2" - resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz#70a3174c894e14df722abf43bc250cbae44b11df" + resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz" integrity sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg== dependencies: "@types/mdast" "^4.0.0" @@ -5681,7 +5581,7 @@ mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1: mdast-util-from-markdown@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a" + resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz" integrity sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA== dependencies: "@types/mdast" "^4.0.0" @@ -5699,7 +5599,7 @@ mdast-util-from-markdown@^2.0.0: mdast-util-frontmatter@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz#f5f929eb1eb36c8a7737475c7eb438261f964ee8" + resolved "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz" integrity sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA== dependencies: "@types/mdast" "^4.0.0" @@ -5711,7 +5611,7 @@ mdast-util-frontmatter@^2.0.0: mdast-util-gfm-autolink-literal@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5" + resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz" integrity sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ== dependencies: "@types/mdast" "^4.0.0" @@ -5722,7 +5622,7 @@ mdast-util-gfm-autolink-literal@^2.0.0: mdast-util-gfm-footnote@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz#7778e9d9ca3df7238cc2bd3fa2b1bf6a65b19403" + resolved "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz" integrity sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ== dependencies: "@types/mdast" "^4.0.0" @@ -5733,7 +5633,7 @@ mdast-util-gfm-footnote@^2.0.0: mdast-util-gfm-strikethrough@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16" + resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz" integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg== dependencies: "@types/mdast" "^4.0.0" @@ -5742,7 +5642,7 @@ mdast-util-gfm-strikethrough@^2.0.0: mdast-util-gfm-table@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38" + resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz" integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg== dependencies: "@types/mdast" "^4.0.0" @@ -5753,7 +5653,7 @@ mdast-util-gfm-table@^2.0.0: mdast-util-gfm-task-list-item@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936" + resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz" integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ== dependencies: "@types/mdast" "^4.0.0" @@ -5763,7 +5663,7 @@ mdast-util-gfm-task-list-item@^2.0.0: mdast-util-gfm@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz#2cdf63b92c2a331406b0fb0db4c077c1b0331751" + resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz" integrity sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ== dependencies: mdast-util-from-markdown "^2.0.0" @@ -5789,7 +5689,7 @@ mdast-util-math@^3.0.0: mdast-util-mdx-expression@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz#43f0abac9adc756e2086f63822a38c8d3c3a5096" + resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz" integrity sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ== dependencies: "@types/estree-jsx" "^1.0.0" @@ -5801,7 +5701,7 @@ mdast-util-mdx-expression@^2.0.0: mdast-util-mdx-jsx@^3.0.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz#fd04c67a2a7499efb905a8a5c578dddc9fdada0d" + resolved "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz" integrity sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q== dependencies: "@types/estree-jsx" "^1.0.0" @@ -5819,7 +5719,7 @@ mdast-util-mdx-jsx@^3.0.0: mdast-util-mdx@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz#792f9cf0361b46bee1fdf1ef36beac424a099c41" + resolved "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz" integrity sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w== dependencies: mdast-util-from-markdown "^2.0.0" @@ -5830,7 +5730,7 @@ mdast-util-mdx@^3.0.0: mdast-util-mdxjs-esm@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz#019cfbe757ad62dd557db35a695e7314bcc9fa97" + resolved "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz" integrity sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg== dependencies: "@types/estree-jsx" "^1.0.0" @@ -5842,16 +5742,16 @@ mdast-util-mdxjs-esm@^2.0.0: mdast-util-phrasing@^4.0.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz#7cc0a8dec30eaf04b7b1a9661a92adb3382aa6e3" + resolved "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz" integrity sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w== dependencies: "@types/mdast" "^4.0.0" unist-util-is "^6.0.0" mdast-util-to-hast@^13.0.0: - version "13.2.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz#d7ff84ca499a57e2c060ae67548ad950e689a053" - integrity sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA== + version "13.2.0" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== dependencies: "@types/hast" "^3.0.0" "@types/mdast" "^4.0.0" @@ -5865,7 +5765,7 @@ mdast-util-to-hast@^13.0.0: mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz#f910ffe60897f04bb4b7e7ee434486f76288361b" + resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz" integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA== dependencies: "@types/mdast" "^4.0.0" @@ -5880,7 +5780,7 @@ mdast-util-to-markdown@^2.0.0, mdast-util-to-markdown@^2.1.0: mdast-util-to-string@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz#7a5121475556a04e7eddeb67b264aae79d312814" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz" integrity sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg== dependencies: "@types/mdast" "^4.0.0" @@ -5919,12 +5819,12 @@ merge-descriptors@1.0.3: merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== methods@~1.1.2: @@ -5934,7 +5834,7 @@ methods@~1.1.2: micromark-core-commonmark@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz#c691630e485021a68cf28dbc2b2ca27ebf678cd4" + resolved "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz" integrity sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg== dependencies: decode-named-character-reference "^1.0.0" @@ -5956,7 +5856,7 @@ micromark-core-commonmark@^2.0.0: micromark-extension-directive@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz#2eb61985d1995a7c1ff7621676a4f32af29409e8" + resolved "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz" integrity sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA== dependencies: devlop "^1.0.0" @@ -5969,7 +5869,7 @@ micromark-extension-directive@^3.0.0: micromark-extension-frontmatter@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz#651c52ffa5d7a8eeed687c513cd869885882d67a" + resolved "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz" integrity sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg== dependencies: fault "^2.0.0" @@ -5979,7 +5879,7 @@ micromark-extension-frontmatter@^2.0.0: micromark-extension-gfm-autolink-literal@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935" + resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz" integrity sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw== dependencies: micromark-util-character "^2.0.0" @@ -5989,7 +5889,7 @@ micromark-extension-gfm-autolink-literal@^2.0.0: micromark-extension-gfm-footnote@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz#4dab56d4e398b9853f6fe4efac4fc9361f3e0750" + resolved "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz" integrity sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw== dependencies: devlop "^1.0.0" @@ -6003,7 +5903,7 @@ micromark-extension-gfm-footnote@^2.0.0: micromark-extension-gfm-strikethrough@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz#86106df8b3a692b5f6a92280d3879be6be46d923" + resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz" integrity sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw== dependencies: devlop "^1.0.0" @@ -6015,7 +5915,7 @@ micromark-extension-gfm-strikethrough@^2.0.0: micromark-extension-gfm-table@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz#fac70bcbf51fe65f5f44033118d39be8a9b5940b" + resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz" integrity sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg== dependencies: devlop "^1.0.0" @@ -6026,14 +5926,14 @@ micromark-extension-gfm-table@^2.0.0: micromark-extension-gfm-tagfilter@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57" + resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz" integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg== dependencies: micromark-util-types "^2.0.0" micromark-extension-gfm-task-list-item@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz#bcc34d805639829990ec175c3eea12bb5b781f2c" + resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz" integrity sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw== dependencies: devlop "^1.0.0" @@ -6044,7 +5944,7 @@ micromark-extension-gfm-task-list-item@^2.0.0: micromark-extension-gfm@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b" + resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz" integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w== dependencies: micromark-extension-gfm-autolink-literal "^2.0.0" @@ -6071,7 +5971,7 @@ micromark-extension-math@^3.0.0: micromark-extension-mdx-expression@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz#43d058d999532fb3041195a3c3c05c46fa84543b" + resolved "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz" integrity sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q== dependencies: "@types/estree" "^1.0.0" @@ -6085,7 +5985,7 @@ micromark-extension-mdx-expression@^3.0.0: micromark-extension-mdx-jsx@^3.0.0: version "3.0.2" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz#ffc98bdb649798902fa9fc5689f67f9c1c902044" + resolved "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz" integrity sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ== dependencies: "@types/estree" "^1.0.0" @@ -6101,14 +6001,14 @@ micromark-extension-mdx-jsx@^3.0.0: micromark-extension-mdx-md@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz#1d252881ea35d74698423ab44917e1f5b197b92d" + resolved "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz" integrity sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ== dependencies: micromark-util-types "^2.0.0" micromark-extension-mdxjs-esm@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz#de21b2b045fd2059bd00d36746081de38390d54a" + resolved "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz" integrity sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A== dependencies: "@types/estree" "^1.0.0" @@ -6123,7 +6023,7 @@ micromark-extension-mdxjs-esm@^3.0.0: micromark-extension-mdxjs@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz#b5a2e0ed449288f3f6f6c544358159557549de18" + resolved "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz" integrity sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ== dependencies: acorn "^8.0.0" @@ -6137,7 +6037,7 @@ micromark-extension-mdxjs@^3.0.0: micromark-factory-destination@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz#8fef8e0f7081f0474fbdd92deb50c990a0264639" + resolved "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz" integrity sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA== dependencies: micromark-util-character "^2.0.0" @@ -6146,7 +6046,7 @@ micromark-factory-destination@^2.0.0: micromark-factory-label@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz#5267efa97f1e5254efc7f20b459a38cb21058ba1" + resolved "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz" integrity sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg== dependencies: devlop "^1.0.0" @@ -6156,7 +6056,7 @@ micromark-factory-label@^2.0.0: micromark-factory-mdx-expression@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz#bb09988610589c07d1c1e4425285895041b3dfa9" + resolved "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz" integrity sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ== dependencies: "@types/estree" "^1.0.0" @@ -6171,7 +6071,7 @@ micromark-factory-mdx-expression@^2.0.0: micromark-factory-space@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" + resolved "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz" integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== dependencies: micromark-util-character "^1.0.0" @@ -6179,7 +6079,7 @@ micromark-factory-space@^1.0.0: micromark-factory-space@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz#36d0212e962b2b3121f8525fc7a3c7c029f334fc" + resolved "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz" integrity sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg== dependencies: micromark-util-character "^2.0.0" @@ -6187,7 +6087,7 @@ micromark-factory-space@^2.0.0: micromark-factory-title@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz#237e4aa5d58a95863f01032d9ee9b090f1de6e94" + resolved "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz" integrity sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw== dependencies: micromark-factory-space "^2.0.0" @@ -6197,7 +6097,7 @@ micromark-factory-title@^2.0.0: micromark-factory-whitespace@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz#06b26b2983c4d27bfcc657b33e25134d4868b0b1" + resolved "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz" integrity sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ== dependencies: micromark-factory-space "^2.0.0" @@ -6207,7 +6107,7 @@ micromark-factory-whitespace@^2.0.0: micromark-util-character@^1.0.0, micromark-util-character@^1.1.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" + resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz" integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== dependencies: micromark-util-symbol "^1.0.0" @@ -6215,7 +6115,7 @@ micromark-util-character@^1.0.0, micromark-util-character@^1.1.0: micromark-util-character@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" + resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz" integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== dependencies: micromark-util-symbol "^2.0.0" @@ -6223,14 +6123,14 @@ micromark-util-character@^2.0.0: micromark-util-chunked@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz#47fbcd93471a3fccab86cff03847fc3552db1051" + resolved "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz" integrity sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA== dependencies: micromark-util-symbol "^2.0.0" micromark-util-classify-character@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz#d399faf9c45ca14c8b4be98b1ea481bced87b629" + resolved "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz" integrity sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q== dependencies: micromark-util-character "^2.0.0" @@ -6239,7 +6139,7 @@ micromark-util-classify-character@^2.0.0: micromark-util-combine-extensions@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz#2a0f490ab08bff5cc2fd5eec6dd0ca04f89b30a9" + resolved "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz" integrity sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg== dependencies: micromark-util-chunked "^2.0.0" @@ -6247,14 +6147,14 @@ micromark-util-combine-extensions@^2.0.0: micromark-util-decode-numeric-character-reference@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz#fcf15b660979388e6f118cdb6bf7d79d73d26fe5" + resolved "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz" integrity sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw== dependencies: micromark-util-symbol "^2.0.0" micromark-util-decode-string@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz#6cb99582e5d271e84efca8e61a807994d7161eb2" + resolved "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz" integrity sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ== dependencies: decode-named-character-reference "^1.0.0" @@ -6264,12 +6164,12 @@ micromark-util-decode-string@^2.0.0: micromark-util-encode@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" + resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz" integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== micromark-util-events-to-acorn@^2.0.0: version "2.0.3" - resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz#e7a8a6b55a47e5a06c720d5a1c4abae8c37c98f3" + resolved "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz" integrity sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg== dependencies: "@types/estree" "^1.0.0" @@ -6282,26 +6182,26 @@ micromark-util-events-to-acorn@^2.0.0: micromark-util-html-tag-name@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz#e40403096481986b41c106627f98f72d4d10b825" + resolved "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz" integrity sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA== micromark-util-normalize-identifier@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz#c30d77b2e832acf6526f8bf1aa47bc9c9438c16d" + resolved "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz" integrity sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q== dependencies: micromark-util-symbol "^2.0.0" micromark-util-resolve-all@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz#e1a2d62cdd237230a2ae11839027b19381e31e8b" + resolved "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz" integrity sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg== dependencies: micromark-util-types "^2.0.0" micromark-util-sanitize-uri@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" + resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz" integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== dependencies: micromark-util-character "^2.0.0" @@ -6310,7 +6210,7 @@ micromark-util-sanitize-uri@^2.0.0: micromark-util-subtokenize@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz#d8ade5ba0f3197a1cf6a2999fbbfe6357a1a19ee" + resolved "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz" integrity sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA== dependencies: devlop "^1.0.0" @@ -6320,27 +6220,27 @@ micromark-util-subtokenize@^2.0.0: micromark-util-symbol@^1.0.0, micromark-util-symbol@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" + resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz" integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== micromark-util-symbol@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" + resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz" integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== micromark-util-types@^1.0.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" + resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz" integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== micromark-util-types@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" + resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz" integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== micromark@^4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.2.tgz#91395a3e1884a198e62116e33c9c568e39936fdb" + resolved "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz" integrity sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA== dependencies: "@types/debug" "^4.0.0" @@ -6361,7 +6261,7 @@ micromark@^4.0.0: micromark-util-symbol "^2.0.0" micromark-util-types "^2.0.0" -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8: +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.8" resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -6369,12 +6269,12 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== -"mime-db@>= 1.43.0 < 2", mime-db@^1.54.0: +"mime-db@>= 1.43.0 < 2": version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== @@ -6384,14 +6284,12 @@ mime-db@~1.33.0: resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz" integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== -mime-types@2.1.18, mime-types@~2.1.17: - version "2.1.18" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz" - integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== - dependencies: - mime-db "~1.33.0" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -6405,6 +6303,27 @@ mime-types@^3.0.1: dependencies: mime-db "^1.54.0" +mime-types@~2.1.17, mime-types@2.1.18: + version "2.1.18" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +mime-types@~2.1.24: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" @@ -6412,7 +6331,7 @@ mime@1.6.0: mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== mimic-response@^3.1.0: @@ -6455,16 +6374,16 @@ mrmime@^2.0.0: resolved "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz" integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== +ms@^2.1.3, ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.3, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - multicast-dns@^7.2.5: version "7.2.5" resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" @@ -6478,19 +6397,19 @@ nanoid@^3.3.11: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - negotiator@~0.6.4: version "0.6.4" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.6.2: version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== no-case@^3.0.4: @@ -6503,7 +6422,7 @@ no-case@^3.0.4: node-emoji@^2.1.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-2.2.0.tgz#1d000e3c76e462577895be1b436f4aa2d6760eb0" + resolved "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz" integrity sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw== dependencies: "@sindresorhus/is" "^4.6.0" @@ -6518,7 +6437,7 @@ node-forge@^1: node-releases@^2.0.27: version "2.0.27" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== normalize-path@^3.0.0, normalize-path@~3.0.0: @@ -6538,7 +6457,7 @@ normalize-url@^8.0.0: npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" @@ -6595,7 +6514,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@2.4.1, on-finished@^2.4.1, on-finished@~2.4.1: +on-finished@^2.4.1, on-finished@~2.4.1, on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -6609,7 +6528,7 @@ on-headers@~1.1.0: onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" @@ -6645,7 +6564,7 @@ p-cancelable@^3.0.0: p-finally@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^4.0.0: @@ -6671,7 +6590,7 @@ p-map@^4.0.0: p-queue@^6.6.2: version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + resolved "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz" integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== dependencies: eventemitter3 "^4.0.4" @@ -6688,7 +6607,7 @@ p-retry@^6.2.0: p-timeout@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + resolved "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz" integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== dependencies: p-finally "^1.0.0" @@ -6720,7 +6639,7 @@ parent-module@^1.0.0: parse-entities@^4.0.0: version "4.0.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz" integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw== dependencies: "@types/unist" "^2.0.0" @@ -6743,7 +6662,7 @@ parse-json@^5.2.0: parse-numeric-range@^1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3" + resolved "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz" integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ== parse5-htmlparser2-tree-adapter@^7.0.0: @@ -6756,7 +6675,7 @@ parse5-htmlparser2-tree-adapter@^7.0.0: parse5@^7.0.0: version "7.3.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz" integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== dependencies: entities "^6.0.0" @@ -6786,7 +6705,7 @@ path-is-inside@1.0.2: path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: @@ -6794,11 +6713,6 @@ path-parse@^1.0.7: resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" - integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== - path-to-regexp@^1.7.0: version "1.9.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz" @@ -6811,9 +6725,14 @@ path-to-regexp@~0.1.12: resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz" integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== +path-to-regexp@3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" + integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== + path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== picocolors@^1.0.0, picocolors@^1.1.1: @@ -7384,7 +7303,7 @@ postcss-zindex@^6.0.2: resolved "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz" integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.5.4: +"postcss@^7.0.0 || ^8.0.1", postcss@^8, postcss@^8.0.3, postcss@^8.0.9, postcss@^8.1.0, postcss@^8.2.2, postcss@^8.4, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24, postcss@^8.4.31, postcss@^8.4.33, postcss@^8.4.6, postcss@^8.5.4: version "8.5.6" resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz" integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== @@ -7426,7 +7345,7 @@ process-nextick-args@~2.0.0: prompts@^2.4.2: version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" @@ -7443,12 +7362,12 @@ prop-types@^15.6.2, prop-types@^15.7.2: property-information@^6.0.0: version "6.5.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec" + resolved "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz" integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== property-information@^7.0.0: version "7.1.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" + resolved "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz" integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== proto-list@~1.2.1: @@ -7466,7 +7385,7 @@ proxy-addr@~2.0.7: punycode@^2.1.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== pupa@^3.1.0: @@ -7485,7 +7404,7 @@ qs@~6.14.0: queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-lru@^5.1.1: @@ -7495,21 +7414,26 @@ quick-lru@^5.1.1: randombytes@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -range-parser@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" - integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== +range-parser@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@~1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +range-parser@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz" + integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A== + raw-body@~2.5.3: version "2.5.3" resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz" @@ -7530,7 +7454,7 @@ rc@1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dom@^19.0.0: +react-dom@*, "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^18.0.0 || ^19.0.0", react-dom@^19.0.0, "react-dom@>= 16.8.0 < 20.0.0": version "19.2.0" resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz" integrity sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ== @@ -7570,7 +7494,7 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" -"react-loadable@npm:@docusaurus/react-loadable@6.0.0": +react-loadable@*, "react-loadable@npm:@docusaurus/react-loadable@6.0.0": version "6.0.0" resolved "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz" integrity sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ== @@ -7597,7 +7521,7 @@ react-router-dom@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.3.4, react-router@^5.3.4: +react-router@^5.3.4, react-router@>=5, react-router@5.3.4: version "5.3.4" resolved "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz" integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== @@ -7612,7 +7536,7 @@ react-router@5.3.4, react-router@^5.3.4: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react@^19.0.0: +react@*, "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^18.0.0 || ^19.0.0", react@^19.0.0, react@^19.2.0, "react@>= 16.8.0 < 20.0.0", react@>=15, react@>=16, react@>=16.0.0: version "19.2.0" resolved "https://registry.npmjs.org/react/-/react-19.2.0.tgz" integrity sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ== @@ -7648,7 +7572,7 @@ readdirp@~3.6.0: recma-build-jsx@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz#c02f29e047e103d2fab2054954e1761b8ea253c4" + resolved "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz" integrity sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew== dependencies: "@types/estree" "^1.0.0" @@ -7656,9 +7580,9 @@ recma-build-jsx@^1.0.0: vfile "^6.0.0" recma-jsx@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/recma-jsx/-/recma-jsx-1.0.1.tgz#58e718f45e2102ed0bf2fa994f05b70d76801a1a" - integrity sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w== + version "1.0.0" + resolved "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz" + integrity sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q== dependencies: acorn-jsx "^5.0.0" estree-util-to-js "^2.0.0" @@ -7668,7 +7592,7 @@ recma-jsx@^1.0.0: recma-parse@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/recma-parse/-/recma-parse-1.0.0.tgz#c351e161bb0ab47d86b92a98a9d891f9b6814b52" + resolved "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz" integrity sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ== dependencies: "@types/estree" "^1.0.0" @@ -7678,7 +7602,7 @@ recma-parse@^1.0.0: recma-stringify@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/recma-stringify/-/recma-stringify-1.0.0.tgz#54632030631e0c7546136ff9ef8fde8e7b44f130" + resolved "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz" integrity sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g== dependencies: "@types/estree" "^1.0.0" @@ -7751,7 +7675,7 @@ rehype-katex@7: rehype-raw@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" + resolved "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz" integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== dependencies: "@types/hast" "^3.0.0" @@ -7760,7 +7684,7 @@ rehype-raw@^7.0.0: rehype-recma@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/rehype-recma/-/rehype-recma-1.0.0.tgz#d68ef6344d05916bd96e25400c6261775411aa76" + resolved "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz" integrity sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw== dependencies: "@types/estree" "^1.0.0" @@ -7774,7 +7698,7 @@ relateurl@^0.2.7: remark-directive@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/remark-directive/-/remark-directive-3.0.1.tgz#689ba332f156cfe1118e849164cc81f157a3ef0a" + resolved "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz" integrity sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A== dependencies: "@types/mdast" "^4.0.0" @@ -7784,7 +7708,7 @@ remark-directive@^3.0.0: remark-emoji@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-4.0.1.tgz#671bfda668047689e26b2078c7356540da299f04" + resolved "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz" integrity sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg== dependencies: "@types/mdast" "^4.0.2" @@ -7795,7 +7719,7 @@ remark-emoji@^4.0.0: remark-frontmatter@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz#b68d61552a421ec412c76f4f66c344627dc187a2" + resolved "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz" integrity sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ== dependencies: "@types/mdast" "^4.0.0" @@ -7805,7 +7729,7 @@ remark-frontmatter@^5.0.0: remark-gfm@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.1.tgz#33227b2a74397670d357bf05c098eaf8513f0d6b" + resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz" integrity sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg== dependencies: "@types/mdast" "^4.0.0" @@ -7826,16 +7750,16 @@ remark-math@6: unified "^11.0.0" remark-mdx@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-3.1.1.tgz#047f97038bc7ec387aebb4b0a4fe23779999d845" - integrity sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg== + version "3.1.0" + resolved "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz" + integrity sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA== dependencies: mdast-util-mdx "^3.0.0" micromark-extension-mdxjs "^3.0.0" remark-parse@^11.0.0: version "11.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1" + resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz" integrity sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA== dependencies: "@types/mdast" "^4.0.0" @@ -7845,7 +7769,7 @@ remark-parse@^11.0.0: remark-rehype@^11.0.0: version "11.1.2" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.2.tgz#2addaadda80ca9bd9aa0da763e74d16327683b37" + resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz" integrity sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw== dependencies: "@types/hast" "^3.0.0" @@ -7856,7 +7780,7 @@ remark-rehype@^11.0.0: remark-stringify@^11.0.0: version "11.0.0" - resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-11.0.0.tgz#4c5b01dd711c269df1aaae11743eb7e2e7636fd3" + resolved "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz" integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw== dependencies: "@types/mdast" "^4.0.0" @@ -7906,7 +7830,7 @@ resolve-from@^4.0.0: resolve-pathname@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" + resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== resolve@^1.22.10: @@ -7932,7 +7856,7 @@ retry@^0.13.1: reusify@^1.0.4: version "1.1.0" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rtlcss@^4.1.0: @@ -7952,12 +7876,12 @@ run-applescript@^7.0.0: run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -7984,19 +7908,37 @@ scheduler@^0.27.0: schema-dts@^1.1.2: version "1.1.5" - resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.5.tgz#9237725d305bac3469f02b292a035107595dc324" + resolved "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz" integrity sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg== -schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.0.0: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.1.1: + version "3.3.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^3.2.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: +schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.2.0: version "4.3.3" resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz" integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== @@ -8006,9 +7948,14 @@ schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.2.0, schema-utils@^4.3 ajv-formats "^2.1.1" ajv-keywords "^5.1.0" +"search-insights@>= 1 < 3": + version "2.17.3" + resolved "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz" + integrity sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ== + section-matter@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + resolved "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz" integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== dependencies: extend-shallow "^2.0.1" @@ -8044,15 +7991,15 @@ semver@^7.3.5, semver@^7.3.7, semver@^7.5.4: resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -send@0.19.0: - version "0.19.0" - resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== +send@~0.19.0: + version "0.19.1" + resolved "https://registry.npmjs.org/send/-/send-0.19.1.tgz" + integrity sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" @@ -8063,15 +8010,15 @@ send@0.19.0: range-parser "~1.2.1" statuses "2.0.1" -send@~0.19.0: - version "0.19.1" - resolved "https://registry.npmjs.org/send/-/send-0.19.1.tgz" - integrity sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~2.0.0" + encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" @@ -8082,7 +8029,7 @@ send@~0.19.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1, serialize-javascript@^6.0.2: +serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: version "6.0.2" resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz" integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== @@ -8137,16 +8084,16 @@ set-function-length@^1.2.2: gopd "^1.0.1" has-property-descriptors "^1.0.2" +setprototypeof@~1.2.0, setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0, setprototypeof@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" @@ -8161,14 +8108,14 @@ shallowequal@^1.1.0: shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.8.3: @@ -8232,7 +8179,7 @@ sirv@^2.0.3: sisteransi@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== sitemap@^7.1.1: @@ -8247,14 +8194,14 @@ sitemap@^7.1.1: skin-tone@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/skin-tone/-/skin-tone-2.0.0.tgz#4e3933ab45c0d4f4f781745d64b9f4c208e41237" + resolved "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz" integrity sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA== dependencies: unicode-emoji-modifier-base "^1.0.0" slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slash@^4.0.0: @@ -8291,25 +8238,30 @@ source-map-js@^1.0.1, source-map-js@^1.2.1: source-map-support@~0.5.20: version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.6.0, source-map@~0.6.0: +source-map@^0.6.0: version "0.6.1" resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.0: - version "0.7.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" - integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== + version "0.7.4" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== space-separated-tokens@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== spdy-transport@^3.0.0: @@ -8337,7 +8289,7 @@ spdy@^4.0.2: sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== srcset@^4.0.0: @@ -8345,11 +8297,6 @@ srcset@^4.0.0: resolved "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz" integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" @@ -8360,12 +8307,40 @@ statuses@~2.0.1, statuses@~2.0.2: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + std-env@^3.7.0: version "3.10.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz" integrity sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== -string-width@^4.1.0, string-width@^4.2.0: +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string-width@^4.1.0: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.2.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8383,23 +8358,9 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - stringify-entities@^4.0.0: version "4.0.4" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== dependencies: character-entities-html4 "^2.0.0" @@ -8407,7 +8368,7 @@ stringify-entities@^4.0.0: stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" @@ -8430,12 +8391,12 @@ strip-ansi@^7.0.1: strip-bom-string@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + resolved "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz" integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.1: @@ -8449,18 +8410,18 @@ strip-json-comments@~2.0.1: integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== style-to-js@^1.0.0: - version "1.1.21" - resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.21.tgz#2908941187f857e79e28e9cd78008b9a0b3e0e8d" - integrity sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ== + version "1.1.16" + resolved "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz" + integrity sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw== dependencies: - style-to-object "1.0.14" + style-to-object "1.0.8" -style-to-object@1.0.14: - version "1.0.14" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.14.tgz#1d22f0e7266bb8c6d8cae5caf4ec4f005e08f611" - integrity sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw== +style-to-object@1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz" + integrity sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g== dependencies: - inline-style-parser "0.2.7" + inline-style-parser "0.2.4" stylehacks@^6.1.1: version "6.1.1" @@ -8472,14 +8433,14 @@ stylehacks@^6.1.1: supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" @@ -8507,36 +8468,12 @@ svgo@^3.0.2, svgo@^3.2.0: csso "^5.0.5" picocolors "^1.0.0" -swr@^2.2.5: - version "2.3.7" - resolved "https://registry.yarnpkg.com/swr/-/swr-2.3.7.tgz#93ca89c9c06a6a8dab72e9d8e85a687123f40356" - integrity sha512-ZEquQ82QvalqTxhBVv/DlAg2mbmUjF4UgpPg9wwk4ufb9rQnZXh1iKyyKBqV6bQGu1Ie7L1QwSYO07qFIa1p+g== - dependencies: - dequal "^2.0.3" - use-sync-external-store "^1.4.0" - -tapable@^2.0.0, tapable@^2.2.1: +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tapable@^2.1.1, tapable@^2.2.0, tapable@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" - integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== - -terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.11: - version "5.3.14" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" - integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - jest-worker "^27.4.5" - schema-utils "^4.3.0" - serialize-javascript "^6.0.2" - terser "^5.31.1" - -terser-webpack-plugin@^5.3.9: +terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.9: version "5.3.10" resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz" integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== @@ -8547,7 +8484,7 @@ terser-webpack-plugin@^5.3.9: serialize-javascript "^6.0.1" terser "^5.26.0" -terser@^5.10.0, terser@^5.15.1: +terser@^5.10.0, terser@^5.15.1, terser@^5.26.0: version "5.34.1" resolved "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz" integrity sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA== @@ -8557,26 +8494,11 @@ terser@^5.10.0, terser@^5.15.1: commander "^2.20.0" source-map-support "~0.5.20" -terser@^5.26.0, terser@^5.31.1: - version "5.44.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.1.tgz#e391e92175c299b8c284ad6ded609e37303b0a9c" - integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - thingies@^2.5.0: version "2.5.0" resolved "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz" integrity sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw== -throttleit@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-2.1.0.tgz#a7e4aa0bf4845a5bd10daa39ea0c783f631a07b4" - integrity sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw== - thunky@^1.0.2: version "1.1.0" resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" @@ -8599,12 +8521,12 @@ tinypool@^1.0.2: to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" -toidentifier@1.0.1, toidentifier@~1.0.1: +toidentifier@~1.0.1, toidentifier@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -8621,15 +8543,15 @@ tree-dump@^1.0.3, tree-dump@^1.1.0: trim-lines@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== trough@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" + resolved "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz" integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.0: +tslib@^2, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.6.0, tslib@2: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -8664,15 +8586,15 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@5.9.3: +typescript@>=4.9.5, typescript@5.9.3: version "5.9.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== -undici-types@~7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" - integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== +undici-types@~7.8.0: + version "7.8.0" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz" + integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" @@ -8681,7 +8603,7 @@ unicode-canonical-property-names-ecmascript@^2.0.0: unicode-emoji-modifier-base@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz#dbbd5b54ba30f287e2a8d5a249da6c0cef369459" + resolved "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz" integrity sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g== unicode-match-property-ecmascript@^2.0.0: @@ -8704,7 +8626,7 @@ unicode-property-aliases-ecmascript@^2.0.0: unified@^11.0.0, unified@^11.0.3, unified@^11.0.4: version "11.0.5" - resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" + resolved "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz" integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== dependencies: "@types/unist" "^3.0.0" @@ -8731,22 +8653,22 @@ unist-util-find-after@^5.0.0: unist-util-is "^6.0.0" unist-util-is@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.1.tgz#d0a3f86f2dd0db7acd7d8c2478080b5c67f9c6a9" - integrity sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g== + version "6.0.0" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== dependencies: "@types/unist" "^3.0.0" unist-util-position-from-estree@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz#d94da4df596529d1faa3de506202f0c9a23f2200" + resolved "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz" integrity sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ== dependencies: "@types/unist" "^3.0.0" unist-util-position@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz" integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== dependencies: "@types/unist" "^3.0.0" @@ -8761,22 +8683,22 @@ unist-util-remove-position@^5.0.0: unist-util-stringify-position@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz" integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== dependencies: "@types/unist" "^3.0.0" unist-util-visit-parents@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz#777df7fb98652ce16b4b7cd999d0a1a40efa3a02" - integrity sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ== + version "6.0.1" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== dependencies: "@types/unist" "^3.0.0" unist-util-is "^6.0.0" unist-util-visit@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz" integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== dependencies: "@types/unist" "^3.0.0" @@ -8785,7 +8707,7 @@ unist-util-visit@^5.0.0: universalify@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@~1.0.0: @@ -8795,7 +8717,7 @@ unpipe@~1.0.0: update-browserslist-db@^1.2.0: version "1.2.1" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.1.tgz#9270a09eb224c4c77468622e4bfeaefb553b944a" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.1.tgz" integrity sha512-R9NcHbbZ45RoWfTdhn1J9SS7zxNvlddv4YRrHTUaFdtjbmfncfedB45EC9IaqJQ97iAR1GZgOfyRQO+ExIF6EQ== dependencies: escalade "^3.2.0" @@ -8823,25 +8745,20 @@ update-notifier@^6.0.2: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" url-loader@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + resolved "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz" integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== dependencies: loader-utils "^2.0.0" mime-types "^2.1.27" schema-utils "^3.0.0" -use-sync-external-store@^1.4.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" - integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -8854,7 +8771,7 @@ utila@~0.4: utility-types@^3.10.0: version "3.11.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c" + resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz" integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw== utils-merge@1.0.1: @@ -8879,31 +8796,31 @@ vary@~1.1.2: vfile-location@^5.0.0: version "5.0.3" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" + resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz" integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== dependencies: "@types/unist" "^3.0.0" vfile "^6.0.0" vfile-message@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" - integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== + version "4.0.2" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== dependencies: "@types/unist" "^3.0.0" unist-util-stringify-position "^4.0.0" vfile@^6.0.0, vfile@^6.0.1: version "6.0.3" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" + resolved "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz" integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== dependencies: "@types/unist" "^3.0.0" vfile-message "^4.0.0" -watchpack@^2.4.1, watchpack@^2.4.4: +watchpack@^2.4.1: version "2.4.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz" integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== dependencies: glob-to-regexp "^0.4.1" @@ -8918,7 +8835,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: web-namespaces@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" + resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== webpack-bundle-analyzer@^4.10.2: @@ -9003,43 +8920,12 @@ webpack-merge@^6.0.1: flat "^5.0.2" wildcard "^2.0.1" -webpack-sources@^3.2.3, webpack-sources@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" - integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== - -webpack@^5.88.1: - version "5.103.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.103.0.tgz#17a7c5a5020d5a3a37c118d002eade5ee2c6f3da" - integrity sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw== - dependencies: - "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.8" - "@types/json-schema" "^7.0.15" - "@webassemblyjs/ast" "^1.14.1" - "@webassemblyjs/wasm-edit" "^1.14.1" - "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.15.0" - acorn-import-phases "^1.0.3" - browserslist "^4.26.3" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.3" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.11" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.3.1" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^4.3.3" - tapable "^2.3.0" - terser-webpack-plugin "^5.3.11" - watchpack "^2.4.4" - webpack-sources "^3.3.3" +webpack-sources@^3.2.3: + version "3.3.2" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz" + integrity sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA== -webpack@^5.95.0: +"webpack@^4.0.0 || ^5.0.0", webpack@^5.0.0, webpack@^5.1.0, webpack@^5.20.0, webpack@^5.88.1, webpack@^5.95.0, "webpack@>=4.41.1 || 5.x", webpack@>=5, "webpack@3 || 4 || 5": version "5.95.0" resolved "https://registry.npmjs.org/webpack/-/webpack-5.95.0.tgz" integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== @@ -9082,7 +8968,7 @@ webpackbar@^6.0.1: std-env "^3.7.0" wrap-ansi "^7.0.0" -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: +websocket-driver@^0.7.4, websocket-driver@>=0.5.1: version "0.7.4" resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -9098,7 +8984,7 @@ websocket-extensions@>=0.1.1: which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" @@ -9182,12 +9068,7 @@ yocto-queue@^1.0.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz" integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ== -zod@^4.1.8: - version "4.1.13" - resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.13.tgz#93699a8afe937ba96badbb0ce8be6033c0a4b6b1" - integrity sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig== - zwitch@^2.0.0: version "2.0.4" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==