diff --git a/dojo-book/.gitignore b/dojo-book/.gitignore new file mode 100644 index 00000000..7dc3ceb2 --- /dev/null +++ b/dojo-book/.gitignore @@ -0,0 +1,21 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# production +/dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# typescript +*.tsbuildinfo \ No newline at end of file diff --git a/dojo-book/README.md b/dojo-book/README.md new file mode 100644 index 00000000..3bb11a44 --- /dev/null +++ b/dojo-book/README.md @@ -0,0 +1 @@ +This is a [Vocs](https://vocs.dev) project bootstrapped with the Vocs CLI. diff --git a/dojo-book/docs/pages/cairo/authorization.md b/dojo-book/docs/pages/cairo/authorization.md new file mode 100644 index 00000000..53f56893 --- /dev/null +++ b/dojo-book/docs/pages/cairo/authorization.md @@ -0,0 +1,23 @@ +## Authorization + +> Authorization is crucial to a world, just like how authorization is crucial to any smart contract. + +As discussed in the [World](./world.md) chapter, Autonomous Worlds (AWs) function as sovereign chains nested within a public blockchain. These Worlds are also open to the public. This structure allows anyone to enhance a World by deploying models or systems. However, this openness also introduces security considerations. Similar to Ethereum, interacting with a model's state within a System requires the appropriate authorization from the model owner. + +### Auth Architecture + +Every time a `set!` is called in a `System`, the world checks if the `System` has authorization to update the model state. Only when the `System` possesses the necessary authorization, the `set!` is executed. The following diagram illustrates the authorization architecture. + +![Authorization Architecture](/dojo-auth.png) + +### Providing Authorization + +> The deployer of the model is its initial owner. A model owner is able to grant the `owner` and `writer` roles. Only owners can grant a System the `writer` role which allows it to update the model. + +`sozo` offers a convenient tool to authorize systems. + +```shell +sozo auth writer Moves spawn +``` + +This command will generate a `writer` authorization for the `spawn` system to update the `Moves` model. diff --git a/dojo-book/docs/pages/cairo/commands.md b/dojo-book/docs/pages/cairo/commands.md new file mode 100644 index 00000000..09ea8376 --- /dev/null +++ b/dojo-book/docs/pages/cairo/commands.md @@ -0,0 +1,79 @@ +## Commands + +**_TL;DR_** + +- Commands are shorthand ways to write function calls +- Commands abstract complex queries into shorthands +- Commands are similar to rust macros + +Understanding commands is key to understanding Dojo. You will leverage them heavily within the systems you design. + +Commands in Dojo are generalized functions that are expanded at compile time to facilitate system execution. They provide a convenient way for systems to interact with the world state by abstracting common operations, such as retrieving or updating models, and generating unique IDs. By leveraging these commands, developers can streamline their system implementations and improve code readability. + +### Using commands + +Commands are used within systems to interact with the world state. They are called using the following syntax: + +### The `get!` command + +The `get!` command is used to retrieve models from the world state: + +```rust,ignore +// world = calling world +// caller = key of the entity that called the system +// (Position, Moves) = tuple of models to retrieve +let (position, moves) = get!(world, caller, (Position, Moves)); +``` + +Here we are retrieving the `Position` and `Moves` models from the world state. We are also using the `caller` to retrieve the models for the current entity. + +You can then use `position` and `moves` as you would as any other Cairo struct. + +In the case that your model defines several keys as the [resource example](./models.md#the-key-attribute), you must provide a value for each key. + +```rust,ignore +let player = get_caller_address(); +let location = 0x1234; + +let resource = get!(world, (player, location), (Resource)); +``` + +If you use the `get!` command on a model that has never been set before, all the fields that are not `#[key]` are equal to 0 in the returned model, which is the default value in the storage. + +### The `set!` command + +The `set!` command is used to update models state. + +```rust,ignore +set !(world, ( + Moves { + player: caller, remaining: 10 + }, + Position { + player: caller, x: position.x + 10, y: position.y + 10 + }, +)); + +// If the structs are already defined it can also be written as: +set!(world, (moves, position)); +``` + +Here we are updating the `Moves` and `Position` models in the world state using the `caller` as the entity id. + +### The `emit!` command + +The `emit!` command is used to emit custom events. These events are indexed by [Torii](/toolchain/torii/overview.md). + +```rust,ignore +emit!(world, Moved { address: caller, direction }); +``` + +This will emit these values which could be captured by a client or you could query these via [Torii](/toolchain/torii/overview.md). + +### The `delete!` command + +The `delete!` command deletes a model from the db. + +```rust,ignore +delete!(world, Moved { address: caller, direction }); +``` diff --git a/src/cairo/config.md b/dojo-book/docs/pages/cairo/config.md similarity index 100% rename from src/cairo/config.md rename to dojo-book/docs/pages/cairo/config.md diff --git a/src/cairo/entities.md b/dojo-book/docs/pages/cairo/entities.md similarity index 100% rename from src/cairo/entities.md rename to dojo-book/docs/pages/cairo/entities.md diff --git a/src/cairo/enum.md b/dojo-book/docs/pages/cairo/enum.md similarity index 100% rename from src/cairo/enum.md rename to dojo-book/docs/pages/cairo/enum.md diff --git a/dojo-book/docs/pages/cairo/events.md b/dojo-book/docs/pages/cairo/events.md new file mode 100644 index 00000000..9e7c056c --- /dev/null +++ b/dojo-book/docs/pages/cairo/events.md @@ -0,0 +1,112 @@ +## Events + +Events play a pivotal role in decoding the dynamics of a Dojo world. Every time there's an update to a `Model`, the `World` contract emits these events. What's even more exciting is that you can craft your own custom events to fit specific needs! Moreover, thanks to [Torii](/toolchain/torii/overview.md), all these events are seamlessly indexed, ensuring easy and efficient querying. + +### Model Events + +Consider this example of a `Moves` model: + +```rust,ignore +struct Moves { + #[key] + player: Address, + remaining: u32, +} +``` + +When this model is updated, the `World` contract will emit an event with the following structure: + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct StoreSetRecord { + table: felt252, // Moves + keys: Span, // [player] + offset: u8, // offset for the value in the table + value: Span, // [remaining] +} +``` + +This will then be captured by [Torii](/toolchain/torii/overview.md) and indexed for querying. This will allow you to then reconstruct the state of your world. + +Similarly, when a model is deleted, the `World` contract will emit an event with the following structure: + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct StoreDelRecord { + table: felt252, + keys: Span, +} +``` + +### World Events + +The `World` contract also emits events when it's initialized and when new models and contracts are registered. These events are emitted with the following structures: + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct WorldSpawned { + address: ContractAddress, + caller: ContractAddress +} +``` + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct ModelRegistered { + name: felt252, + class_hash: ClassHash, + prev_class_hash: ClassHash +} +``` + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct ContractDeployed { + salt: felt252, + class_hash: ClassHash, + address: ContractAddress, +} + +#[derive(Drop, starknet::Event)] +struct ContractUpgraded { + class_hash: ClassHash, + address: ContractAddress, +} +``` + +These events are also captured by [Torii](/toolchain/torii/overview.md) and indexed for querying. + +### Custom Events + +Within your game, emitting custom events can be highly beneficial. Fortunately, there's a handy `emit!` command that lets you release events directly from your world. These events are indexed by [Torii](/toolchain/torii/overview.md). + +Use it like so: + +```rust,ignore +emit!(world, Moved { address, direction }); +``` + +Include this in your contract and it will emit an event with the following structure: + +```rust,ignore +#[derive(Drop, starknet::Event)] +struct Moved { + address: felt252, + direction: felt252, +} +``` + +Now a full example using a custom event: + +```rust,ignore +fn move(ctx: Context, direction: Direction) { + let (mut position, mut moves) = get !(world, caller, (Position, Moves)); + moves.remaining -= 1; + + let next = next_position(position, direction); + set !(world, (moves, next)); + emit !(world, Moved { address: caller, direction }); +} +``` + +> Note: Read about the `get!` and `set!` macros in [Commands](./commands.md). diff --git a/dojo-book/docs/pages/cairo/hello-dojo.md b/dojo-book/docs/pages/cairo/hello-dojo.md new file mode 100644 index 00000000..f44307a8 --- /dev/null +++ b/dojo-book/docs/pages/cairo/hello-dojo.md @@ -0,0 +1,432 @@ +# Hello Dojo + +> This section assumes that you have already installed the Dojo toolchain and are familiar with Cairo. If not, please refer to the [Getting Started](/getting-started/quick-start.md) section. + +## Dojo as an ECS in 15 Minutes + +Although Dojo isn't exclusively an Entity Component System (ECS) framework, we recommend adopting this robust design pattern. In this context, systems shape the environment's logic, while components ([models](./models.md)) mirror the state of the world. By taking this route, you'll benefit from a structured and modular framework that promises both flexibility and scalability in a continuously evolving world. If this seems a bit intricate at first, hang tight; we'll delve into the details shortly. + +To start, let's set up a project to run locally on your machine. From an empty directory, execute: + +```console +sozo init +``` + +Congratulations! You now have a local Dojo project. This command creates a `dojo-starter` project in your current directory. It's the ideal starting point for a new project and equips you with everything you need to begin. + +#### Anatomy of a Dojo Project + +Inspect the contents of the `dojo-starter` project, and you'll notice the following structure (excluding the non-Cairo files): + +```bash +src + - lib.cairo + - systems.cairo + - actions.cairo + - models.cairo + - position.cairo + - moves.cairo + - tests.cairo + - test_world.cairo +Scarb.toml +``` + +Dojo projects bear a strong resemblance to typical Cairo projects. The primary difference is the inclusion of a special attribute tag used to define your data models. In this context, we'll refer to these models as components. + +As we're crafting an ECS, we'll adhere to the specific terminology associated with Entity Component Systems. + +Open the `src/models/moves.cairo` file to continue. + +```rust,ignore +#[derive(Model, Drop, Serde)] +struct Moves { + #[key] + player: ContractAddress, + remaining: u8, + last_direction: Direction +} +...rest of code +``` + +Notice the `#[derive(Model, Drop, Serde)]` attributes. For a model to be recognized, we _must_ include `Model`. This signals to the Dojo compiler that this struct should be treated as a model. + +Our `Moves` model houses a `player` field. At the same time, we have the `#[key]` attribute, it informs Dojo that this model is indexed by the `player` field. If this is unfamiliar to you, we'll clarify its importance later in the chapter. Essentially, it implies that you can query this model using the `player` field. Our `Moves` model also contains the `remaining` and `last_direction` fields + +Open the `src/models/position.cairo` file to continue. + +```rust,ignore +#[derive(Model, Copy, Drop, Serde)] +struct Position { + #[key] + player: ContractAddress, + vec: Vec2, +} + +#[derive(Copy, Drop, Serde, Introspect)] +struct Vec2 { + x: u32, + y: u32 +} +...rest of code +``` + +In a similar vein, we have a `Position` model that have a Vec2 data structure. Vec holds `x` and `y` values. Once again, this model is indexed by the `player` field. + +Now, let's examine the `src/systems/actions.cairo` file: + +```rust,ignore +// define the interface +#[starknet::interface] +trait IActions { + fn spawn(self: @TContractState); + fn move(self: @TContractState, direction: dojo_starter::models::moves::Direction); +} + +// dojo decorator +#[dojo::contract] +mod actions { + use super::IActions; + + use starknet::{ContractAddress, get_caller_address}; + use dojo_starter::models::{position::{Position, Vec2}, moves::{Moves, Direction}}; + + // declaring custom event struct + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + Moved: Moved, + } + + // declaring custom event struct + #[derive(Drop, starknet::Event)] + struct Moved { + player: ContractAddress, + direction: Direction + } + + // define functions in your contracts like this: + fn next_position(mut position: Position, direction: Direction) -> Position { + match direction { + Direction::None => { return position; }, + Direction::Left => { position.vec.x -= 1; }, + Direction::Right => { position.vec.x += 1; }, + Direction::Up => { position.vec.y -= 1; }, + Direction::Down => { position.vec.y += 1; }, + }; + position + } + + + // impl: implement functions specified in trait + #[abi(embed_v0)] + impl ActionsImpl of IActions { + // ContractState is defined by system decorator expansion + fn spawn(self: @ContractState) { + // Access the world dispatcher for reading. + let world = self.world_dispatcher.read(); + + // Get the address of the current caller, possibly the player's address. + let player = get_caller_address(); + + // Retrieve the player's current position from the world. + let position = get!(world, player, (Position)); + + // Retrieve the player's move data, e.g., how many moves they have left. + let moves = get!(world, player, (Moves)); + + // Update the world state with the new data. + // 1. Set players moves to 10 + // 2. Move the player's position 100 units in both the x and y direction. + set!( + world, + ( + Moves { player, remaining: 100, last_direction: Direction::None }, + Position { player, vec: Vec2 { x: 10, y: 10 } }, + ) + ); + } + + // Implementation of the move function for the ContractState struct. + fn move(self: @ContractState, direction: Direction) { + // Access the world dispatcher for reading. + let world = self.world_dispatcher.read(); + + // Get the address of the current caller, possibly the player's address. + let player = get_caller_address(); + + // Retrieve the player's current position and moves data from the world. + let (mut position, mut moves) = get!(world, player, (Position, Moves)); + + // Deduct one from the player's remaining moves. + moves.remaining -= 1; + + // Update the last direction the player moved in. + moves.last_direction = direction; + + // Calculate the player's next position based on the provided direction. + let next = next_position(position, direction); + + // Update the world state with the new moves data and position. + set!(world, (moves, next)); + + // Emit an event to the world to notify about the player's move. + emit!(world, Moved { player, direction }); + } + } +} +``` + +### Breaking it down + +#### System is a function in a contract + +As you can see a `System` is like a regular function of a dojo(starknet) contract. It imports the Models we defined earlier and exposes two functions `spawn` and `move`. These functions are called when a player spawns into the world and when they move respectively. + +```rust,ignore +// Retrieve the player's current position from the world. +let position = get!(world, player, (Position)); + +// Retrieve the player's move data, e.g., how many moves they have left. +let moves = get!(world, player, (Moves)); +``` + +Here we use `get!` [command](./commands.md) to retrieve the `Position` and `Moves` model for the `player` entity, which is the address of the caller. + +Now the next line: + +```rust,ignore +// Update the world state with the new data. +// 1. Increase the player's remaining moves by 10. +// 2. Move the player's position 10 units in both the x and y direction. +set!( + world, + ( + Moves { + player, remaining: moves.remaining + 10, last_direction: Direction::None + }, + Position { + player, vec: Vec2 { x: position.vec.x + 10, y: position.vec.y + 10} + }, + ) +); +``` + +Here we use the `set!` [command](./commands.md) to set the `Moves` and `Position` models for the `player` entity. + +We covered a lot here in a short time. Let's recap: + +- Explained the anatomy of a Dojo project +- Explained the importance of the `#[derive(Model)]`attribute +- Explained the `spawn` and `move` functions +- Explained the `Moves` and `Position` struct +- Touched on the `get!` and `set!` commands + +### Run it locally! + +Now that we've covered some theory, let's build the Dojo project! In your primary terminal: + +```bash +sozo build +``` + +That compiled the models and system into an artifact that can be deployed! Simple as that! + +Now, let's deploy it to [Katana](/toolchain/katana/overview.md)! First, we need to get Katana running. Open a second terminal and execute: + +```bash +katana --disable-fee +``` + +Success! [Katana](/toolchain/katana/overview.md) should now be running locally on your machine. Now, let's deploy! In your primary terminal, execute: + +```bash +sozo migrate +``` + +This will deploy the artifact to [Katana](/toolchain/katana/overview.md). You should see terminal output similar to this: + +```bash + +Migration account: 0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973 + +World name: dojo_examples + +[1] 🌎 Building World state.... + > No remote World found +[2] 🧰 Evaluating Worlds diff.... + > Total diffs found: 5 +[3] πŸ“¦ Preparing for migration.... + > Total items to be migrated (5): New 5 Update 0 + +# Executor + > Contract address: 0x59f31686991d7cac25a7d4844225b9647c89e3e1e2d03460dbc61e3fbfafc59 +# Base Contract + > Class Hash: 0x77638e9a645209ac1e32e143bfdbfe9caf723c4f7645fcf465c38967545ea2f +# World + > Contract address: 0x5010c31f127114c6198df8a5239e2b7a5151e1156fb43791e37e7385faa8138 +# Models (2) +Moves + > Class hash: 0x509a65bd8cc5516176a694a3b3c809011f1f0680959c567b3189e60ddab7ce1 +Position + > Class hash: 0x52a1da1853c194683ca5d6d154452d0654d23f2eacd4267c555ff2338e144d6 + > Registered at: 0x82d996aab290f086314745685c6f05bd69730d46589339763202de5264b1b6 +# Contracts (1) +actions + > Contract address: 0x31571485922572446df9e3198a891e10d3a48e544544317dbcbb667e15848cd + +πŸŽ‰ Successfully migrated World at address 0x5010c31f127114c6198df8a5239e2b7a5151e1156fb43791e37e7385faa8138 + +✨ Updating manifest.json... + +✨ Done. + +``` + +Your 🌎 is now deployed at `0x5010c31f127114c6198df8a5239e2b7a5151e1156fb43791e37e7385faa8138`! + +This establishes the world address for your project. + +Let's discuss the `Scarb.toml` file in the project. This file contains environment variables that make running CLI commands in your project a breeze (read more about it [here](./config.md)). Make sure your file specifies the version of Dojo you have installed! In this case version `0.4.4`. + +```toml +[dependencies] +dojo = { git = "https://github.com/dojoengine/dojo", version = "0.4.4" } +``` + +### Indexing + +With your local world address established, let's delve into indexing. You can index the entire world. To accomplish this we have to copy your `world address` from the output of `sozo migrate`. Now Open a new terminal and input this simple command that includes your own world address: + +```bash +torii --world 0x5010c31f127114c6198df8a5239e2b7a5151e1156fb43791e37e7385faa8138 +``` + +Running the command mentioned above starts a [Torii](/toolchain/torii/overview.md) server on your local machine. This server uses SQLite as its database and is accessible at http://0.0.0.0:8080/graphql. [Torii](/toolchain/torii/overview.md) will automatically organize your data into tables, making it easy for you to perform queries using GraphQL. When you run the command, you'll see terminal output that looks something like this: + +```bash +2023-10-18T06:49:48.184233Z INFO torii::server: πŸš€ Torii listening at http://0.0.0.0:8080 +2023-10-18T06:49:48.184244Z INFO torii::server: Graphql playground: http://0.0.0.0:8080/graphql + +2023-10-18T06:49:48.185648Z INFO torii_core::engine: processed block: 0 +2023-10-18T06:49:48.186129Z INFO torii_core::engine: processed block: 1 +2023-10-18T06:49:48.186720Z INFO torii_core::engine: processed block: 2 +2023-10-18T06:49:48.187202Z INFO torii_core::engine: processed block: 3 +2023-10-18T06:49:48.187674Z INFO torii_core::engine: processed block: 4 +2023-10-18T06:49:48.188215Z INFO torii_core::engine: processed block: 5 +2023-10-18T06:49:48.188611Z INFO torii_core::engine: processed block: 6 +2023-10-18T06:49:48.188985Z INFO torii_core::engine: processed block: 7 +2023-10-18T06:49:48.199592Z INFO torii_core::processors::register_model: Registered model: Moves +2023-10-18T06:49:48.210032Z INFO torii_core::processors::register_model: Registered model: Position +2023-10-18T06:49:48.210571Z INFO torii_core::engine: processed block: 8 +2023-10-18T06:49:48.211678Z INFO torii_core::engine: processed block: 9 +2023-10-18T06:49:48.212335Z INFO torii_core::engine: processed block: 10 + +``` + +You can observe that our `Moves` and `Position` models have been successfully registered. +Next, let's use the GraphiQL IDE to retrieve data from the `Moves` model. In your web browser, navigate to `http://0.0.0.0:8080/graphql`, and enter the following query: + +```graphql +query { + model(id: "Moves") { + id + name + classHash + transactionHash + createdAt + } +} +``` + +After you run the query, you will receive an output like this: + +```json +{ + "data": { + "model": { + "id": "Moves", + "name": "Moves", + "classHash": "0x64495ca6dc1dc328972697b30468cea364bcb7452bbb6e4aaad3e4b3f190147", + "transactionHash": "", + "createdAt": "2023-12-15 18:07:22" + } + } +} +``` + +Awesome, now let's work with subscriptions to get real-time updates. Let's clean up your workspace on the GraphiQL IDE and input the following subscription: + +```graphql +subscription { + entityUpdated { + id + keys + eventId + createdAt + updatedAt + } +} +``` + +Once you execute the subscription, you will receive notifications whenever new entities are updated or created. For now, don't make any changes to it and proceed to create a new entity. + +To accomplish this, we have to go back to our primary terminal and check the contracts section. + +```bash +# Contracts (1) +actions + > Contract address: 0x31571485922572446df9e3198a891e10d3a48e544544317dbcbb667e15848cd +``` + +We have to use `actions` contract address to start to create entities. In your main local terminal, run the following command: + +```bash +sozo execute 0x31571485922572446df9e3198a891e10d3a48e544544317dbcbb667e15848cd spawn +``` + +By running this command, you've activated the spawn system, resulting in the creation of a new entity. This action establishes a local world that you can interact with. + +Now, go back to your GraphiQL IDE, and you will notice that you have received the subscription's results, which should look something like this: + +```json +{ + "data": { + "entityUpdated": { + "id": "0x28cd7ee02d7f6ec9810e75b930e8e607793b302445abbdee0ac88143f18da20", + "keys": [ + "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" + ], + "eventId": "0x000000000000000000000000000000000000000000000000000000000000000e:0x0000:0x0000", + "createdAt": "2023-12-15 18:07:22", + "updatedAt": "2023-12-15 18:10:56" + } + } +} +-------------------------------------------------------------------------------------------------------- +{ + "data": { + "entityUpdated": { + "id": "0x28cd7ee02d7f6ec9810e75b930e8e607793b302445abbdee0ac88143f18da20", + "keys": [ + "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" + ], + "eventId": "0x000000000000000000000000000000000000000000000000000000000000000e:0x0000:0x0001", + "createdAt": "2023-12-15 18:07:22", + "updatedAt": "2023-12-15 18:10:56" + } + } +} +``` + +In the GraphiQL IDE, by clicking the `DOCS`-button on the right, you can open the API documentation. This documentation is auto-generated based on our schema definition and displays all API operations and data types of our schema.. In order to know more about query and subscription, you can jump to [GraphQL](/toolchain/torii/graphql.md) section. +We've covered quite a bit! Here's a recap: + +- Built a Dojo world +- Deployed the project to Katana +- Indexed the world with Torii +- Ran the spawn system locally +- Interacted with GraphQL + +### Next Steps + +This overview provides a rapid end-to-end glimpse into Dojo. However, the potential of these worlds is vast! Designed to manage hundreds of systems and components, Dojo is equipped for expansive creativity. So, what will you craft next? diff --git a/src/cairo/metadata.md b/dojo-book/docs/pages/cairo/metadata.md similarity index 100% rename from src/cairo/metadata.md rename to dojo-book/docs/pages/cairo/metadata.md diff --git a/src/cairo/migration.md b/dojo-book/docs/pages/cairo/migration.md similarity index 100% rename from src/cairo/migration.md rename to dojo-book/docs/pages/cairo/migration.md diff --git a/src/cairo/migration/0.3.0.md b/dojo-book/docs/pages/cairo/migration/0.3.0.md similarity index 100% rename from src/cairo/migration/0.3.0.md rename to dojo-book/docs/pages/cairo/migration/0.3.0.md diff --git a/src/cairo/migration/0.4.0.md b/dojo-book/docs/pages/cairo/migration/0.4.0.md similarity index 100% rename from src/cairo/migration/0.4.0.md rename to dojo-book/docs/pages/cairo/migration/0.4.0.md diff --git a/src/cairo/models.md b/dojo-book/docs/pages/cairo/models.md similarity index 100% rename from src/cairo/models.md rename to dojo-book/docs/pages/cairo/models.md diff --git a/dojo-book/docs/pages/cairo/origami.md b/dojo-book/docs/pages/cairo/origami.md new file mode 100644 index 00000000..908c8182 --- /dev/null +++ b/dojo-book/docs/pages/cairo/origami.md @@ -0,0 +1,18 @@ +![origami](/origami.png) + +> The magic of origami is in seeing a single piece of cairo evolve into a masterpiece through careful folds. + +## What is Origami? + +Origami is the native dojo collection of primitives that can be imported into your game. + +It contains: + +- algebra +- defi +- hex map +- random +- security +- erc tokens + +Find the [Origami repo](https://github.com/dojoengine/origami) diff --git a/src/cairo/overview.md b/dojo-book/docs/pages/cairo/overview.md similarity index 100% rename from src/cairo/overview.md rename to dojo-book/docs/pages/cairo/overview.md diff --git a/dojo-book/docs/pages/cairo/systems.md b/dojo-book/docs/pages/cairo/systems.md new file mode 100644 index 00000000..23932a86 --- /dev/null +++ b/dojo-book/docs/pages/cairo/systems.md @@ -0,0 +1,156 @@ +## Systems + +> **IMPORTANT:** Before defining your systems, prioritize permissions. Plan carefully to ensure proper access and security. + +**_TL;DR_** + +- Systems function as contract methods. +- Contracts containing Systems gain permissions to write to models. +- Systems pass a `world` address as their first parameter unless utilizing the [`#[dojo::contract]`](#the-dojocontract-decorator) decorator. +- Systems engage the world contract to alter models' state. +- The world contract is invoked through systems. +- Systems ought to be concise and specific. +- In most scenarios, systems are stateless. + +### What are Systems? + +Within dojo we define systems as functions within a Dojo Contract that act on the world. + +Systems play a pivotal role in your world's logic, directly mutating its component states. It's important to understand that to enact these mutations, a system needs explicit permission from the [`models`](./models.md) owner. + +### System Permissions + +Since the whole contract is given write access to the model, it is important to be careful when defining systems. A simple way to think about it is: + +![System Permissions](/permissions.png) + +### System Structure + +Every system function starts with a [`world`](./world.md) address as its initial parameter. This design permits these functions to alter the world's state. Notably, this structure also makes systems adaptable and reusable across multiple worlds! + +Let's look at the simplest possible system which mutates the state of the `Moves` component. + +> NOTE: This is not using the #[dojo::contract] attribute meaning it was to accept the world as a parameter. + +```rust,ignore +#[starknet::contract] +mod player_actions { + use starknet::{ContractAddress, get_caller_address}; + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + use dojo_examples::components::{Position, Moves, Direction, Vec2}; + use dojo_examples::utils::next_position; + use super::IPlayerActions; + + // no storage + #[storage] + struct Storage {} + + // implementation of the PlayerActions interface + #[abi(embed_v0)] + impl PlayerActionsImpl of IPlayerActions { + fn spawn(self: @ContractState, world: IWorldDispatcher) { + let player = get_caller_address(); + let position = get!(world, player, (Position)); + set!( + world, + ( + Moves { + player, + remaining: 10, + last_direction: Direction::None(()) + } + ) + ); + } + } +} +``` + +## Breaking it down + +#### System is a function in a contract + +As you can see a System is like a regular function of a Starknet contract. This contract can include storage, and it can implement interfaces. + +#### `Spawn` function + +The spawn function is currently the only system that exists in this contract. It is called when a player spawns into the world. It is responsible for setting up the player's initial state. + +### The `#[dojo::contract]` Decorator + +All Starknet contracts are defined using the `#[starknet::contract]` decorator, ensuring accurate compilation. In this context, Dojo introduces the `#[dojo::contract]` decorator, which aims to minimize boilerplate in contract writing. + +The `#[dojo::contract]` decorator allows developers to omit including `world: IWorldDispatcher` as a parameter. Behind the scenes, it injects the world into the contract and eliminates some imports, thereby streamlining the development process. + +```rust,ignore +#[dojo::contract] +mod player_actions { + use starknet::{ContractAddress, get_caller_address}; + use dojo_examples::models::{Position, Moves, Direction, Vec2}; + use dojo_examples::utils::next_position; + use super::IPlayerActions; + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + Moved: Moved, + } + + #[derive(Drop, starknet::Event)] + struct Moved { + player: ContractAddress, + direction: Direction + } + + // impl: implement functions specified in trait + #[abi(embed_v0)] + impl PlayerActionsImpl of IPlayerActions { + // ContractState is defined by system decorator expansion + fn spawn(self: @ContractState) { + // world dispatcher + let world = self.world_dispatcher.read(); + + // player + let player = get_caller_address(); + + // get the position + let position = get!(world, player, (Position)); + + // set the position + set!( + world, + ( + Moves { player, remaining: 10, last_direction: Direction::None(()) }, + Position { player, vec: Vec2 { x: 10, y: 10 } }, + ) + ); + } + + fn move(self: @ContractState, direction: Direction) { + // world dispatcher + let world = self.world_dispatcher.read(); + + // player + let player = get_caller_address(); + + // get the position and moves + let (mut position, mut moves) = get!(world, player, (Position, Moves)); + + // adjust + moves.remaining -= 1; + moves.last_direction = direction; + + // get next direction + let next = next_position(position, direction); + + // set models + set!(world, (moves, next)); + + // emit custom event + emit!(world, Moved { player, direction }); + } + } +} +``` + +> To interact with Systems read more in the [sozo](/toolchain/sozo/overview.md) docs. diff --git a/src/cairo/testing.md b/dojo-book/docs/pages/cairo/testing.md similarity index 100% rename from src/cairo/testing.md rename to dojo-book/docs/pages/cairo/testing.md diff --git a/dojo-book/docs/pages/cairo/world.md b/dojo-book/docs/pages/cairo/world.md new file mode 100644 index 00000000..eb74c3d1 --- /dev/null +++ b/dojo-book/docs/pages/cairo/world.md @@ -0,0 +1,74 @@ +> **To think about:** Consider Autonomous Worlds as sovereign blockchains residing within another blockchain - a nested blockchain, so to speak. Just as you can deploy contracts onto Ethereum to enhance its functionality, you can similarly introduce systems into the World contract to enrich its features. While anyone can contribute to the World, akin to Ethereum, authorization is required to interact with model state. There is a dedicated topic to [Authorisation](./authorization.md). + +![overview](/world-map.png) + +## The World Contract + +The world contract functions as a central store for the world models and systems. Every contract that interacts with the world, must use the world contract address as the first parameter. This is how the world contract is able to manage the state of the world. + +Although we suggest strongly to structure your world around an ECS pattern you are not required to do so. You can simply use the dojo-models as a keypair store along with the supporting infrastructure. + +> NOTE: Dojo core abstracts the world contract away, you do not write it and it is not meant to be altered when building a world. However, it's important to understand how it works and how it interacts with the rest of the system. + +### Events + +The world contract emits all model events via the `StoreSetRecord` event. This enables block explorers to reconstruct everything in the world by listening to one contract. + +### Full World API + +The world exposes an interface which can be interacted with by any client. It is worth noting here that as a developer you don't deploy this world, it is deployed when you [migrate](/toolchain/sozo/overview.md) the world. + +```rust,ignore +// World interface +#[starknet::interface] +trait IWorld { + fn metadata_uri(self: @T, resource: felt252) -> Span; + fn set_metadata_uri(ref self: T, resource: felt252, uri: Span); + fn model(self: @T, name: felt252) -> ClassHash; + fn register_model(ref self: T, class_hash: ClassHash); + fn deploy_contract(ref self: T, salt: felt252, class_hash: ClassHash) -> ContractAddress; + fn upgrade_contract(ref self: T, address: ContractAddress, class_hash: ClassHash) -> ClassHash; + fn uuid(ref self: T) -> usize; + fn emit(self: @T, keys: Array, values: Span); + fn entity( + self: @T, model: felt252, keys: Span, offset: u8, length: usize, layout: Span + ) -> Span; + fn set_entity( + ref self: T, + model: felt252, + keys: Span, + offset: u8, + values: Span, + layout: Span + ); + fn entities( + self: @T, + model: felt252, + index: Option, + values: Span, + values_length: usize, + values_layout: Span + ) -> (Span, Span>); + fn entity_ids(self: @T, model: felt252) -> Span; + fn set_executor(ref self: T, contract_address: ContractAddress); + fn executor(self: @T) -> ContractAddress; + fn base(self: @T) -> ClassHash; + fn delete_entity(ref self: T, model: felt252, keys: Span, layout: Span); + fn is_owner(self: @T, address: ContractAddress, resource: felt252) -> bool; + fn grant_owner(ref self: T, address: ContractAddress, resource: felt252); + fn revoke_owner(ref self: T, address: ContractAddress, resource: felt252); + fn is_writer(self: @T, model: felt252, system: ContractAddress) -> bool; + fn grant_writer(ref self: T, model: felt252, system: ContractAddress); + fn revoke_writer(ref self: T, model: felt252, system: ContractAddress); +} +``` + +### `uuid()` + +It is often useful to generate unique IDs for entities. The `uuid()` fn can be used to generate a unique ID. + +Use it like this: + +```rust,ignore +let game_id = world.uuid(); +``` diff --git a/src/client/dojojs.md b/dojo-book/docs/pages/client/dojojs.md similarity index 100% rename from src/client/dojojs.md rename to dojo-book/docs/pages/client/dojojs.md diff --git a/src/client/overview.md b/dojo-book/docs/pages/client/overview.md similarity index 100% rename from src/client/overview.md rename to dojo-book/docs/pages/client/overview.md diff --git a/src/client/sdk/c.md b/dojo-book/docs/pages/client/sdk/c.md similarity index 100% rename from src/client/sdk/c.md rename to dojo-book/docs/pages/client/sdk/c.md diff --git a/src/client/sdk/dojojs.md b/dojo-book/docs/pages/client/sdk/dojojs.md similarity index 100% rename from src/client/sdk/dojojs.md rename to dojo-book/docs/pages/client/sdk/dojojs.md diff --git a/dojo-book/docs/pages/client/sdk/unity.md b/dojo-book/docs/pages/client/sdk/unity.md new file mode 100644 index 00000000..313f837e --- /dev/null +++ b/dojo-book/docs/pages/client/sdk/unity.md @@ -0,0 +1,103 @@ +# dojo.unity + +### Prerequisites + +Before getting started, there are a few steps you must follow in order to get the project up and running. + +#### Dojo + +Ensure that you're using the latest supported Dojo [version](https://github.com/dojoengine/dojo/releases). + +#### Binaries + +If you are using Windows or Linux, you will need to build [dojo.c](https://github.com/dojoengine/dojo.c) yourself. Make sure that you're using the latest supported version + +```bash +git clone https://github.com/dojoengine/dojo.c +cargo build --release +``` + +This will generate a `.dll` or `.so` binary in the `target/release` directory, depending on your platform. You will need to copy it to the following location `Packages/Dojo/Libraries` + +--- + +### Watch video + +[![Watch the video](/unity-screen-grab.png)](/dojo.unity_demo.mp4) + +## Dojo Unity Concepts + +Building on-chain games and worlds with Unity involves understanding several key concepts and components. Let's go over them to give you a clearer picture: + +## World Manager + +![world-manager](/unity/world-manager.png) + +- **Function**: The World Manager acts as the central hub for your Dojo world within Unity. It's the starting point where all entities from your Dojo world will be managed. +- **Implementation**: In your Unity scene, you'll find a `WorldManager` game object. Under this object, all entities from your Dojo world will be instantiated. +- **Customization**: The WorldManager script component comes with default values, but you have the option to modify these. Specifically, you can update the URLs for your Katana and Torii instances and set your own world address. + +## Synchronization Master + +![world-manager](/unity/sync-master.png) + +- **Role**: This component is crucial for managing the synchronization of entities between your Dojo world and the Unity world. +- **Features**: In the SynchronizationMaster, you can specify the maximum number of entities you want to synchronize. It also handles the synchronization of your models' components. +- **Models Component**: + - **Purpose**: These are the components that will be synchronized between the two worlds. + - **Management**: You have the flexibility to add as many models as needed. However, it's important to ensure that the models you add here are also present in your Dojo world for proper synchronization. + +## Models + +![models](/unity/models.png) + +You should have a deep understanding of models in dojo if not checkout out models [here](/cairo/models.md) before continuing. + +### What are Models in Dojo? + +1. **Definition**: In Dojo, [models](/cairo/models.md) are essential state that represent various parts of [entities](/cairo/entities.md) within your game. They are the building blocks that make up the content of your game world. Read about [ECS](/cairo/hello-dojo.md). + +2. **Synchronization Role**: + + - Models act as the key elements that are synchronized between the onchain Dojo world and the Unity world (your game's visual and interactive representation). + - This synchronization ensures that changes or interactions happening within the Unity environment are accurately reflected in the Dojo world, and vice versa. + +3. **Flexibility in Adding Models**: + + - You have the freedom to add as many [models](/cairo/models.md) as needed for your game's design and functionality. + - It's vital, however, to ensure that these [models](/cairo/models.md) are consistent across both the Dojo and Unity. This means that for every model you have in Unity, there should be a corresponding model in your Dojo world. + +4. **Future Developments**: + + - An important aspect to note is that in future versions of the Dojo-Unity integration, the process of adding and synchronizing [models](/cairo/models.md) will be further streamlined. + - The plan is to have these [models](/cairo/models.md) auto-generated, which would significantly simplify the development process and reduce the manual effort required for synchronization. + +5. **Importance of Understanding Models**: + - Before diving into game development with Dojo in Unity, it’s recommended to have a solid understanding of how [models](/cairo/models.md) work in the Dojo environment. + - This knowledge is crucial for effectively designing and implementing game elements that interact seamlessly between the blockchain and the game's user interface. + +In summary, [models](/cairo/models.md) are the bridge between the onchain (Dojo) and off-chain (Unity) aspects of your game. + +### Adding Models + +The process to add models is: + +1. Define in your dojo cairo contracts +2. Define in your Unity world making sure they accurately reflect + +### Adding Systems + +[insert] + +### Entities + +Via toriiClient [models](/cairo/entities.md) are synced to Unity and are comprised of the models that you defined. + +### Starter Project + +Get started by: + +0. [Prerequisites](#prerequisites) +1. Cloning the [dojo.unity](https://github.com/dojoengine/dojo.unity) +2. Open project within Unity +3. Run the [dojo-starter](https://github.com/dojoengine/dojo-starter-unity) project and make sure to have Katana and Torii running. diff --git a/src/client/torii.md b/dojo-book/docs/pages/client/torii.md similarity index 100% rename from src/client/torii.md rename to dojo-book/docs/pages/client/torii.md diff --git a/dojo-book/docs/pages/community/get-started.md b/dojo-book/docs/pages/community/get-started.md new file mode 100644 index 00000000..58df884e --- /dev/null +++ b/dojo-book/docs/pages/community/get-started.md @@ -0,0 +1,55 @@ +## Get Started + +Dojo is a thriving community of builders, artists, and deep thinkers, pushing the frontier of what is possible. + +- [Community Hub](https://dojoengine.notion.site/Dojo-Engine-Community-Hub-d316194b998941c48ddf771a4dd5ff08#bcd6a32db1b2406cb6c325f3b700d45a) +- [Discord](https://discord.gg/KG9w9BmDrV) +- [Twitter](https://twitter.com/dojostarknet) +- [Awesome Dojo](https://github.com/dojoengine/awesome-dojo) +- [Dojo Blog](https://www.dojoengine.org/en/articles/) + +## Ecosystem & Studios powered by Dojo + +![dojo](/Built%20with.svg) + +#### Realms World + +- [discord](https://discord.gg/realmsworld) +- [website](https://realms.world/) + +#### Briq World + +- [discord](https://discord.gg/kpvbDCw5pr) +- [website](https://briq.construction/) + +#### Cartridge + +- [discord](https://discord.gg/cartridge) +- [website](https://cartridge.gg/) + +#### zKorp + +- [twitter](https://twitter.com/zKorp_) + +## Templates & Libraries + +Templates, libraries or utilities that use Dojo. + +- [Origami](https://github.com/dojoengine/origami) - Cairo primitives for onchain Gaming +- [Crypts And Caverns Dojo Map](https://github.com/CheDAOLabs/cc-dojo-map) - An Example projects of integrating C&C maps developed by the CHE-DAO team with Dojo. + +## Awesome Projects + +- [Beer Baron](https://github.com/cartridge-gg/beer-baron) - An dojo onchain simulation masked as a beer brewing game. It is designed to work with 10 - 10,000 players. +- [Chess Dojo](https://github.com/rkdud007/chess-dojo) - A chess game built on Dojo. +- [Dope Wars: Roll Your Own](https://github.com/cartridge-gg/rollyourown) - An onchain adaptation of the classic Drug Wars game developed by the Cartridge team. +- [Drive AI](https://github.com/cartridge-gg/drive-ai) - An onchain driving simulator controlled by a neural network developed by the Cartridge team. +- [Emoji Man](https://github.com/dojoengine/emoji-man) - Pac-man inspired onchain game using dojo and phaser. +- [Loot Underworld](https://github.com/funDAOmental/lootunderworld) - Excavating the dangerous, endless mysteries of the subterranean in the dark depths of the Realms Autonomous (Under)World. +- [PixeLAW](https://github.com/pixelaw/game) - A pixel grid-based Autonomous World with coexisting games (i.e. Paint, Snake, Rock-Paper-Scissors). +- [Realms Autonomous World](https://github.com/BibliothecaDAO/eternum) - The Realms Autonomous World +- [Stark Lander](https://github.com/dojoengine/stark-lander) - Land on the Moon! +- [StarkLand](https://github.com/Starklandxyz) - Full On-chain Multiplayer Online Simulation Game (FOMOSLG) built on Starknet. +- [Underdark: Lair of the Slenderduck](https://github.com/funDAOmental/underdark) - An unhinged on-chain generative dungeon skin crawler. Beware the Slenderduck! +- [zDefender](https://github.com/z-korp/zdefender-front) - An onchain tower defense. +- [zKnight](https://github.com/z-korp/zknight) - An onchain strategy game diff --git a/dojo-book/docs/pages/deployment/locally.md b/dojo-book/docs/pages/deployment/locally.md new file mode 100644 index 00000000..ff126aed --- /dev/null +++ b/dojo-book/docs/pages/deployment/locally.md @@ -0,0 +1,41 @@ +## Local Deployment with Katana + +Experience the power of rapid development with Dojo, featuring the ultra-fast local development sequencer, [Katana](/toolchain/katana/overview.md). Katana acts as an on-device Starknet, enabling thorough testing of your dojo world in a controlled environment before migrating them to the remote testnet. + +### Easy Katana Deployments + +Deploying to Katana is straightforward and efficient. + +> **Pre-requisite:** Ensure you've completed the [Quick Start](/getting-started/quick-start.md) guide and have your project set up. + +To initiate Katana from your project directory, execute: + +```bash +katana --disable-fee +``` + +This command launches a local instance of Katana, setting the stage for your deployment. + +### Step-by-Step Guide to Deploy on Katana + +Deploying your project to Katana involves a few simple steps.\ + +1. **Compile Your Contracts:** + + If you haven't compiled your contracts yet, run: + + ```bash + sozo build + ``` + + Compiling ensures that your contracts are ready for deployment. + +2. **Migrate your Project:** + + To migrate, run: + + ```bash + sozo migrate + ``` + +Success! You have now migrated your world. You will be able to interact with the world using [sozo](/toolchain/sozo/overview.md). diff --git a/dojo-book/docs/pages/deployment/remote.md b/dojo-book/docs/pages/deployment/remote.md new file mode 100644 index 00000000..95cd0119 --- /dev/null +++ b/dojo-book/docs/pages/deployment/remote.md @@ -0,0 +1,52 @@ +## Deployment to Remote Network + +> _IMPORTANT: Dojo is unaudited. Use at your own risk._ + +Dojo makes it easy to deploy to remote networks, you just need to have a valid account and network endpoint. + +Scarb.toml + +```toml +[package] +name = "ohayoo" +version = "0.1.0" +cairo-version = "0.3.15" + +[cairo] +sierra-replace-ids = true + +[dependencies] +dojo = { git = "https://github.com/dojoengine/dojo", tag = "v0.3.15" } + +# KATANA on slot +# rpc_url = "https://api.cartridge.gg/x/example/katana" +# account_address = "0x2d5260ba1d62ed0ea7c598f1460d27528b27afdf3bb43524a1ba3617e8279b2" +# private_key = "0x6768b97b44cfbfa9f776a3c00ebe33c228058bf8716bb0515a1363049da2a11" +# world = "0x1fad58d91d5d121aa6dc4d16c01a161e0441ef75fe7d31e3664a61e66022b1f" + +# ENDPOINT +rpc_url = "https://api.cartridge.gg/x/shinai/madara" +account_address = "0x2" +private_key = "0xc1cf1490de1352865301bb8705143f3ef938f97fdf892f1090dcb5ac7bcd1d" +world_address = "0x5b328933afdbbfd44901fd69a2764a254edbb6e992ae87cf958c70493f2d201" + +# GOERLI +# rpc_url = "https://starknet-goerli.g.alchemy.com/v2/" +# account_address = "0x2d5260ba1d62ed0ea7c598f1460d27528b27afdf3bb43524a1ba3617e8279b2" +# private_key = "0x6768b97b44cfbfa9f776a3c00ebe33c228058bf8716bb0515a1363049da2a11" +# world = "0x1fad58d91d5d121aa6dc4d16c01a161e0441ef75fe7d31e3664a61e66022b1f" +``` + +### Deploy to public Starknet + +If you credentials are correct in the Scarb.toml then a simple migrate will deploy the world to Starknet. + +### Deploy to Remote [Katana](/toolchain/katana/overview.md) + +Katanas are able to be hosted and run as remote testnets, however this is not recommended for production use. + +Deploy to remote katana with slot [here](/tutorial/deploy-using-slot/main.md) + +### Deploy to Remote Madara + +[Madara](https://github.com/keep-starknet-strange/madara) is a blazingly fast Starknet sequencer. diff --git a/dojo-book/docs/pages/example.mdx b/dojo-book/docs/pages/example.mdx new file mode 100644 index 00000000..79a90915 --- /dev/null +++ b/dojo-book/docs/pages/example.mdx @@ -0,0 +1,3 @@ +# Example + +This is an example page. diff --git a/src/README.md b/dojo-book/docs/pages/getting-started.md similarity index 98% rename from src/README.md rename to dojo-book/docs/pages/getting-started.md index c38b9f19..a4e8d786 100644 --- a/src/README.md +++ b/dojo-book/docs/pages/getting-started.md @@ -1,4 +1,4 @@ -# Dojo: The Provable Game Engine +# Dojo The Provable Game Engine Dojo is a provable game engine built using [Cairo](https://github.com/starkware-libs/cairo). It establishes a standard for game development via smart contracts, blending best practices with streamlined development and deployment tools. With Dojo by your side, you can evolve from initial concept to a fully realized game in days, not weeks. diff --git a/0.2.0/src/getting-started/contributing.md b/dojo-book/docs/pages/getting-started/contributing.md similarity index 100% rename from 0.2.0/src/getting-started/contributing.md rename to dojo-book/docs/pages/getting-started/contributing.md diff --git a/dojo-book/docs/pages/getting-started/from-source.md b/dojo-book/docs/pages/getting-started/from-source.md new file mode 100644 index 00000000..e017c861 --- /dev/null +++ b/dojo-book/docs/pages/getting-started/from-source.md @@ -0,0 +1,40 @@ +## Building from source + +> If you are just wanting to play with the toolchain, we strongly suggest following the [Quick Start](./quick-start.md) guide. + +#### Prerequisites + +You will need the [Rust](https://rust-lang.org) compiler and Cargo, the Rust package manager. +The easiest way to install both is with [`rustup.rs`](https://rustup.rs/). + +On Windows, you will also need a recent version of [Visual Studio](https://visualstudio.microsoft.com/downloads/), +installed with the "Desktop Development With C++" Workloads option. + +#### Building + +You can either use the different [Dojoup](/toolchain/dojoup.md) flags: + +```sh +dojoup --branch master +dojoup --path path/to/dojo +``` + +Or, by using a single Cargo command: + +```sh +cargo install --git https://github.com/dojoengine/dojo --force sozo katana torii +``` + +Or, by manually building from a local copy of the [Dojo repository](https://github.com/dojoengine/dojo): + +```sh +# clone the repository +git clone https://github.com/dojoengine/dojo.git +cd dojo +# install Sozo +cargo install --path ./crates/sozo --force +# install Katana +cargo install --path ./crates/katana --force +# install Torii +cargo run -β€”bin torii +``` diff --git a/dojo-book/docs/pages/getting-started/quick-start.md b/dojo-book/docs/pages/getting-started/quick-start.md new file mode 100644 index 00000000..a401e9b8 --- /dev/null +++ b/dojo-book/docs/pages/getting-started/quick-start.md @@ -0,0 +1,24 @@ +## Quick Start + +> It is worth reading [theory](/theory/autonomous-worlds.md) to familiarize yourself with the concept of Autonomous Worlds (AWs) and the [Cairo ecosystem](/theory/cairo.md) before diving into the code. + +### Install Dojoup + +Dojo is built around a set of development tools - Katana, Torii and Sozo. Install them all easily with Dojoup. You can find detailed information about Dojoup [here](https://github.com/dojoengine/dojo/blob/master/dojoup/README.md). + +```sh +curl -L https://install.dojoengine.org | bash +``` + +This will install Dojoup, then simply follow the instructions on-screen, +which will make the `dojoup` command available in your CLI. + +```sh +dojoup +``` + +For full `dojoup` reference and debugging see [Dojoup](/toolchain/dojoup.md). + +### Next steps + +> Head to [Hello Dojo](/cairo/hello-dojo.md) to get create your first Dojo world. diff --git a/dojo-book/docs/pages/getting-started/setup.md b/dojo-book/docs/pages/getting-started/setup.md new file mode 100644 index 00000000..74495b0b --- /dev/null +++ b/dojo-book/docs/pages/getting-started/setup.md @@ -0,0 +1,49 @@ +# Development Setup + +> This is a guide to setting up a development environment for Dojo. It is not suggested to follow this guide if you are just wanting to play with the toolchain. We strongly suggest following the [Quick Start](/getting-started/quick-start.md) guide. + +### Prerequisites + +- [Rust](https://github.com/rust-lang/rust) +- [Cairo](https://github.com/starkware-libs/cairo) +- [protoc](https://github.com/protocolbuffers/protobuf) + +## Guide + +### Clone + +```sh +git clone https://github.com/dojoengine/dojo.git +``` + +### Linux & Mac + +#### 1. Install Rust and Dependencies + +Start by installing Rust and running the test suite to confirm your setup: + +```sh +rustup override set stable && rustup update && cargo test +``` + +> Note: Depending on your Linux distribution, you may need to install additional dependencies. Make sure to install any suggested or missing dependencies that arise during the setup process. + +#### 2. Install Scarb Package Manager + +Next, install the [Scarb](https://docs.swmansion.com/scarb) package manager by running: + +```sh +curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh +``` + +#### 3. Add the Cairo 1.0 VSCode Extension + +Install the [Cairo 1.0](https://marketplace.visualstudio.com/items?itemName=starkware.cairo1) extension for Visual Studio Code. + +### Windows + +_Coming soon_ + +### Container + +_Coming soon_ diff --git a/src/images/Built with.svg b/dojo-book/docs/pages/images/Built with.svg similarity index 100% rename from src/images/Built with.svg rename to dojo-book/docs/pages/images/Built with.svg diff --git a/src/images/Dojo - Contracts.png b/dojo-book/docs/pages/images/Dojo - Contracts.png similarity index 100% rename from src/images/Dojo - Contracts.png rename to dojo-book/docs/pages/images/Dojo - Contracts.png diff --git a/0.2.0/src/images/ECS.png b/dojo-book/docs/pages/images/ECS.png similarity index 100% rename from 0.2.0/src/images/ECS.png rename to dojo-book/docs/pages/images/ECS.png diff --git a/0.2.0/src/images/board.png b/dojo-book/docs/pages/images/board.png similarity index 100% rename from 0.2.0/src/images/board.png rename to dojo-book/docs/pages/images/board.png diff --git a/0.2.0/src/images/dojo-auth.png b/dojo-book/docs/pages/images/dojo-auth.png similarity index 100% rename from 0.2.0/src/images/dojo-auth.png rename to dojo-book/docs/pages/images/dojo-auth.png diff --git a/0.2.0/src/images/dojo-mark-full-dark.svg b/dojo-book/docs/pages/images/dojo-mark-full-dark.svg similarity index 100% rename from 0.2.0/src/images/dojo-mark-full-dark.svg rename to dojo-book/docs/pages/images/dojo-mark-full-dark.svg diff --git a/0.2.0/src/images/dojo-sozo-workflow.jpg b/dojo-book/docs/pages/images/dojo-sozo-workflow.jpg similarity index 100% rename from 0.2.0/src/images/dojo-sozo-workflow.jpg rename to dojo-book/docs/pages/images/dojo-sozo-workflow.jpg diff --git a/src/images/dojo.unity_demo.mp4 b/dojo-book/docs/pages/images/dojo.unity_demo.mp4 similarity index 100% rename from src/images/dojo.unity_demo.mp4 rename to dojo-book/docs/pages/images/dojo.unity_demo.mp4 diff --git a/dojo-book/docs/pages/images/favicon.ico b/dojo-book/docs/pages/images/favicon.ico new file mode 100644 index 00000000..21c80f81 Binary files /dev/null and b/dojo-book/docs/pages/images/favicon.ico differ diff --git a/src/images/katana-icon-word.png b/dojo-book/docs/pages/images/katana-icon-word.png similarity index 100% rename from src/images/katana-icon-word.png rename to dojo-book/docs/pages/images/katana-icon-word.png diff --git a/src/images/katana-icon.png b/dojo-book/docs/pages/images/katana-icon.png similarity index 100% rename from src/images/katana-icon.png rename to dojo-book/docs/pages/images/katana-icon.png diff --git a/src/images/katana.png b/dojo-book/docs/pages/images/katana.png similarity index 100% rename from src/images/katana.png rename to dojo-book/docs/pages/images/katana.png diff --git a/src/images/origami-icon-word.png b/dojo-book/docs/pages/images/origami-icon-word.png similarity index 100% rename from src/images/origami-icon-word.png rename to dojo-book/docs/pages/images/origami-icon-word.png diff --git a/src/images/origami-icon.png b/dojo-book/docs/pages/images/origami-icon.png similarity index 100% rename from src/images/origami-icon.png rename to dojo-book/docs/pages/images/origami-icon.png diff --git a/src/images/origami.png b/dojo-book/docs/pages/images/origami.png similarity index 100% rename from src/images/origami.png rename to dojo-book/docs/pages/images/origami.png diff --git a/src/images/permissions.png b/dojo-book/docs/pages/images/permissions.png similarity index 100% rename from src/images/permissions.png rename to dojo-book/docs/pages/images/permissions.png diff --git a/src/images/slot-icon-word.png b/dojo-book/docs/pages/images/slot-icon-word.png similarity index 100% rename from src/images/slot-icon-word.png rename to dojo-book/docs/pages/images/slot-icon-word.png diff --git a/src/images/slot-icon.png b/dojo-book/docs/pages/images/slot-icon.png similarity index 100% rename from src/images/slot-icon.png rename to dojo-book/docs/pages/images/slot-icon.png diff --git a/src/images/sozo-icon-word.png b/dojo-book/docs/pages/images/sozo-icon-word.png similarity index 100% rename from src/images/sozo-icon-word.png rename to dojo-book/docs/pages/images/sozo-icon-word.png diff --git a/src/images/sozo-icon.png b/dojo-book/docs/pages/images/sozo-icon.png similarity index 100% rename from src/images/sozo-icon.png rename to dojo-book/docs/pages/images/sozo-icon.png diff --git a/src/images/torii-icon-word.png b/dojo-book/docs/pages/images/torii-icon-word.png similarity index 100% rename from src/images/torii-icon-word.png rename to dojo-book/docs/pages/images/torii-icon-word.png diff --git a/src/images/torii-icon.png b/dojo-book/docs/pages/images/torii-icon.png similarity index 100% rename from src/images/torii-icon.png rename to dojo-book/docs/pages/images/torii-icon.png diff --git a/src/images/unity-screen-grab.png b/dojo-book/docs/pages/images/unity-screen-grab.png similarity index 100% rename from src/images/unity-screen-grab.png rename to dojo-book/docs/pages/images/unity-screen-grab.png diff --git a/src/images/unity/models.png b/dojo-book/docs/pages/images/unity/models.png similarity index 100% rename from src/images/unity/models.png rename to dojo-book/docs/pages/images/unity/models.png diff --git a/src/images/unity/sync-master.png b/dojo-book/docs/pages/images/unity/sync-master.png similarity index 100% rename from src/images/unity/sync-master.png rename to dojo-book/docs/pages/images/unity/sync-master.png diff --git a/src/images/unity/world-manager.png b/dojo-book/docs/pages/images/unity/world-manager.png similarity index 100% rename from src/images/unity/world-manager.png rename to dojo-book/docs/pages/images/unity/world-manager.png diff --git a/src/images/world-map.png b/dojo-book/docs/pages/images/world-map.png similarity index 100% rename from src/images/world-map.png rename to dojo-book/docs/pages/images/world-map.png diff --git a/src/images/world_flow.png b/dojo-book/docs/pages/images/world_flow.png similarity index 100% rename from src/images/world_flow.png rename to dojo-book/docs/pages/images/world_flow.png diff --git a/src/images/worlds-dev-icon-word.png b/dojo-book/docs/pages/images/worlds-dev-icon-word.png similarity index 100% rename from src/images/worlds-dev-icon-word.png rename to dojo-book/docs/pages/images/worlds-dev-icon-word.png diff --git a/src/images/worlds-dev-icon.png b/dojo-book/docs/pages/images/worlds-dev-icon.png similarity index 100% rename from src/images/worlds-dev-icon.png rename to dojo-book/docs/pages/images/worlds-dev-icon.png diff --git a/dojo-book/docs/pages/index.mdx b/dojo-book/docs/pages/index.mdx new file mode 100644 index 00000000..c1f61799 --- /dev/null +++ b/dojo-book/docs/pages/index.mdx @@ -0,0 +1,22 @@ +--- +layout: landing +--- + +import { HomePage } from "vocs/components"; + + + + {/* Enter the Dojo */} + {/* */} + + Dojo is a community driven open-source, Provable Game Engine, providing a comprehensive toolkit for building verifiable games and autonomous worlds. + + + + Get started + + + GitHub + + + diff --git a/0.2.0/src/misc/contributors.md b/dojo-book/docs/pages/misc/contributors.md similarity index 100% rename from 0.2.0/src/misc/contributors.md rename to dojo-book/docs/pages/misc/contributors.md diff --git a/src/theory/autonomous-worlds.md b/dojo-book/docs/pages/theory/autonomous-worlds.md similarity index 100% rename from src/theory/autonomous-worlds.md rename to dojo-book/docs/pages/theory/autonomous-worlds.md diff --git a/dojo-book/docs/pages/theory/cairo.md b/dojo-book/docs/pages/theory/cairo.md new file mode 100644 index 00000000..c89190ee --- /dev/null +++ b/dojo-book/docs/pages/theory/cairo.md @@ -0,0 +1,37 @@ +# Provable games + +Provable games demand [zero-knowledge](https://ethereum.org/en/zero-knowledge-proofs/) properties for efficient scaling and verification of computations. [Cairo](https://book.starknet.io/ch01-00-getting-started.html) addresses this need by providing a generalized language, eliminating the complexity of creating circuits to incorporate [SNARKs](https://consensys.net/blog/developers/introduction-to-zk-snarks/). + +**You can simply program in Cairo and your applications become automatically provable**. + +Moreover, you can deploy your programs on the [Cairo Virtual Machine](https://medium.com/starkware/cairo-welcome-on-board-1cf3487554f) (CVM), which is compatible with Starknet's Layer 2, Starknet appchains, and even in-browser through WebAssembly (WASM)! Dojo aims to supply straightforward ZK primitives to fuel your game development. + +For more information about Starknet, Cairo and its tech stack, check out the [Starknet & Cairo book](https://book.starknet.io/). + +## Cairo + +Cairo is an open-source, Turing-complete smart contract language developed by Starkware, designed to power the Validity Rollup Starknet. The language enables highly expressive and verifiable computation, making it well-suited for building scalable and secure applications, including decentralized finance (DeFi) projects. + +Dojo builds on Cairo to create a robust framework for developing Autonomous Worlds (AWs). By leveraging the capabilities of Cairo, Dojo aims to streamline the development process, improve maintainability, and enhance the performance of AWs. + +A key feature of the Dojo framework is its use of [commands](/cairo/commands.md). Commands are a design pattern that helps to reduce boilerplate code, resulting in cleaner and more maintainable applications. They achieve this by encapsulating specific actions or operations within self-contained, reusable units. + +Developers can write commands freely within Systems, and the Cairo compiler takes care of inlining the appropriate functions. + +#### Essential Reading + +- [Cairo book](https://github.com/cairo-book/cairo-book) +- [Awesome Cairo](https://github.com/auditless/awesome-cairo) +- [Starknet Book](https://book.starknet.io/) + +### Starknet as an L2 + +Starknet is a Validity Rollup Layer 2 (L2) solution designed to scale Ethereum. It operates by offering high transaction throughput and low gas costs while maintaining the same level of security as Ethereum Layer 1 (L1). The strategy it uses is akin to solving a sudoku puzzle: verifying a solution is easier than finding the solution from scratch. Similarly, Starknet replaces heavy and costly L1 computation with cheaper L1 verification through the use of STARK proofs computed off-chain. + +In more technical terms, Starknet is a permissionless Validity-Rollup (also known as a "ZK-Rollup") that supports general computation and currently runs as an L2 network over Ethereum. The network's L1 security is guaranteed by its utilization of the STARK cryptographic proof system, which is considered one of the safest and most scalable. + +### Starknet as an Appchain + +Cairo is an isomorphic, general-purpose language, optimized for Zero-Knowledge (ZK) proofs. It's the driving force behind Starknet, Starkex, and appchains. Remarkably, you can also run it in WebAssembly (WASM) to generate proofs on the client-side! Within the dojo toolchain exists [Katana](/toolchain/katana/overview.md) which is a gaming specific sequencer, which is perfectly suited to run a Dojo appchain. + +The Dojo team is also working closely with the [Madara](https://github.com/keep-starknet-strange/madara) team to enable Starknet appchains to seamlessly run Dojo worlds. diff --git a/dojo-book/docs/pages/theory/faqs.md b/dojo-book/docs/pages/theory/faqs.md new file mode 100644 index 00000000..40e7b641 --- /dev/null +++ b/dojo-book/docs/pages/theory/faqs.md @@ -0,0 +1,39 @@ +# FAQs + +#### Who owns Dojo? + +Dojo is strictly open-source and uses the Apache 2.0 license. Anyone can use Dojo for free, and anyone can contribute to the project. + +#### Why Dojo? + +Dojo was created to solve problems the founders faced when building onchain games. It standardizes the process of building such games and provides a suite of tools to make it easier. + +#### What is the Dojo roadmap? + +Dojo is rapidly evolving. You can find open issues on the [Dojo Github](https://github.com/dojoengine/dojo/issues) and join the [Discord](https://discord.gg/vUN4Xq9Qv6) to get involved. If you have ideas for the project, please open an issue. + +#### What is an onchain game? + +Onchain games are games that exist entirely on a public blockchain network; all states and logic are onchain. Clients (like web browsers) do not exist on the chain but exist purely to interact with and interpret the onchain state. + +#### What is an autonomous world? + +An autonomous world is one that exists entirely onchain. It's not controlled by any single entity but is instead governed by the rules set within that world. Dive deeper into the topic here: [Autonomous Worlds](/theory/autonomous-worlds.md). + +#### What is Cairo? + +Cairo is an opensource programming language invented by Starkware. It's a Turing-complete language meant for general-purpose computation. It's a low-level language designed to compile to the Cairo Virtual Machine. Learn more about it here: [Cairo](/theory/cairo.md). + +#### What is a provable game? + +Thanks to the magic of zero-knowledge proofs, we can ensure a game is fair by verifying a zk proof created off-chain. But what does that entail? Consider a game of chess. We aim for an experience where players trust each other's moves. In a straightforward approach β€” and given the simple rules of chess β€” if this were in a blockchain environment, every move would be a transaction on the blockchain. This is costly. We just want to know the winner, not every move. + +With zk proofs and client communications, players can establish a state channel, sharing moves off-chain and ensuring their validity. At the end, a zk proof can be submitted to the blockchain to confirm the game's fairness. This constitutes a provable game. + +#### Can dojo implement client side proofs? + +The ability to execute Dojo programs in the browser is entirely plausible and is on our roadmap. Expect q1/q2 in 2024, or if you are a specalist in this jump into the code and help out! + +#### Can I deploy dojo on Starknet? + +Yes! Dojo can run on any StarknetVM including the public blockchains. Within the dojo toolchain exists [Katana](/toolchain/katana/overview.md) which is a gaming specific sequencer, which is perfectly suited to Dojo games. diff --git a/dojo-book/docs/pages/theory/what-is-dojo.md b/dojo-book/docs/pages/theory/what-is-dojo.md new file mode 100644 index 00000000..b659ba4c --- /dev/null +++ b/dojo-book/docs/pages/theory/what-is-dojo.md @@ -0,0 +1,39 @@ +![dojo](/Dojo%20-%20Contracts.png) + +# What is Dojo? + +Dojo is the culmination of lessons learned from attempts at building [onchain games](https://naavik.co/digest/primer-fully-on-chain-gaming), an emerging sector in the gaming industry. Any developer who has endeavored to build an on-chain game recognizes the inherent engineering hurdles - a realization that drove us to create Dojo. Just as you wouldn't recreate Unity every time you develop a new game, the same principle applies here. Dojo is designed to handle the complex infrastructure, allowing developers to focus on the unique aspects of their games. + +Dojo aspires to be the go-to tool for building provable games. It is radically open-source, and all contributions are welcome. + +--- + +## Stop building infrastructure; start building games + +Dojo's suite of tools takes the infrastructure complexity out of building on-chain games. It includes: + +### Entity Component System (ECS) + +Dojo offers a standardized approach to building games on smart contracts. Recognizing the intricacies of game design, Dojo simplifies the development process, allowing creators to focus on gameplay logic. This standardization paves the way for an interconnected network of worlds, streamlining developer expertise and promoting game integration. + +Utilizing the ECS (Entity Component System) as its core architecture, Dojo effectively manages the state and behavior of Autonomous Worlds (AWs). This model revolves around systems acting on entities, which are collections of pure data components. Systems efficiently determine which entities to process based on persistent queries over these components. + +Read detailed information about the [Dojo ECS](/cairo/overview.md). + +### [Torii](/toolchain/torii/overview.md) - Starknet Indexer + +Building on-chain games often involves grappling with the challenge of indexing on-chain state. However, Dojo standardizes contract states to mirror traditional relational databases. This setup enables the [Torii Indexer](/toolchain/torii/overview.md) to auto-index all contract states, ensuring efficient and streamlined queries. Torii then exposes these states via a GraphQL API or gRPC, allowing developers to easily query and retrieve data. + +Using Torii drastically reduces the time and effort required to build on-chain games. It also eliminates the need to manually create indexers, which can be a tedious and error-prone process. + +### [Katana](/crates/katana/README.md) - Blazingly fast development network + +Katana is a customizable Starknet development network. It is blazingly fast and allows you to iterate on your game logic swiftly. + +### [Sozo CLI](/crates/sozo/README.md) - CLI Management Tool + +Dojo worlds are poised to become some of the largest contracts. Sozo is a CLI tool that assists you in managing your worlds. It enables you to create, build, test, and deploy your worlds. Additionally, you can craft new components and systems and register them with your world. + +### What Dojo doesn't give you + +1. Visual graphics - While Dojo provides networking and contracts, it doesn't offer graphical engines. You can bring your graphics of choice! Integrate your Dojo world with Unreal, Godot, or Unity. diff --git a/src/toolchain/dojoup.md b/dojo-book/docs/pages/toolchain/dojoup.md similarity index 100% rename from src/toolchain/dojoup.md rename to dojo-book/docs/pages/toolchain/dojoup.md diff --git a/0.2.0/src/toolchain/katana/development.md b/dojo-book/docs/pages/toolchain/katana/development.md similarity index 100% rename from 0.2.0/src/toolchain/katana/development.md rename to dojo-book/docs/pages/toolchain/katana/development.md diff --git a/dojo-book/docs/pages/toolchain/katana/overview.md b/dojo-book/docs/pages/toolchain/katana/overview.md new file mode 100644 index 00000000..d97af72d --- /dev/null +++ b/dojo-book/docs/pages/toolchain/katana/overview.md @@ -0,0 +1,71 @@ +![katana](/katana-icon-word.png) + +Katana is a _blazingly fast_ sequencer, designed to support both local development as well as production deployments. + +In development mode, Katana provides the tool necessary for rapid iteration, including custom development RPCs for manipulating the execution context. + +In produciton mode, Katana provides a high performance sequencer optimized for gaming workloads, with support for settlment and cross layer communication. + +### Features + +- [Starknet JSON-RPC v0.3.0](https://github.com/starkware-libs/starknet-specs/tree/v0.3.0) support +- Cross layer communication (L1 <> L2, LN <> LN+1) +- Custom methods for manipulating the blockchain states + +## Installation + +`katana` binary is available via [`dojoup`](/getting-started/quick-start.md). + +### Installing from source + +```sh +git clone https://github.com/dojoengine/dojo +cd dojo +cargo install --path ./crates/katana --locked --force +``` + +### Usage + +```console +katana +``` + +```console + + +β–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— +β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•— +β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ +β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•— β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ +β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ +β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β• β•šβ•β• + + + +PREFUNDED ACCOUNTS +================== + +| Account address | 0x3ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 +| Private key | 0x300001800000000300000180000000000030000000000003006001800006600 +| Public key | 0x1b7b37a580d91bc3ad4f9933ed61f3a395e0e51c9dd5553323b8ca3942bb44e + +| Account address | 0x33c627a3e5213790e246a917770ce23d7e562baa5b4d2917c23b1be6d91961c +| Private key | 0x333803103001800039980190300d206608b0070db0012135bd1fb5f6282170b +| Public key | 0x4486e2308ef3513531042acb8ead377b887af16bd4cdd8149812dfef1ba924d + + +ACCOUNTS SEED +============= +0 + + +πŸš€ JSON-RPC server started: http://0.0.0.0:5050 + + +``` + +To enable development features, run using the `--dev` flag. + +> πŸ“š **Reference** +> +> See the [`katana` Reference](./reference.md) for an in depth reference and documentation on Katana. diff --git a/src/toolchain/katana/reference.md b/dojo-book/docs/pages/toolchain/katana/reference.md similarity index 100% rename from src/toolchain/katana/reference.md rename to dojo-book/docs/pages/toolchain/katana/reference.md diff --git a/src/toolchain/slot/deployments-commands/deployments.md b/dojo-book/docs/pages/toolchain/slot/deployments-commands/deployments.md similarity index 100% rename from src/toolchain/slot/deployments-commands/deployments.md rename to dojo-book/docs/pages/toolchain/slot/deployments-commands/deployments.md diff --git a/dojo-book/docs/pages/toolchain/slot/overview.md b/dojo-book/docs/pages/toolchain/slot/overview.md new file mode 100644 index 00000000..73fbf5c6 --- /dev/null +++ b/dojo-book/docs/pages/toolchain/slot/overview.md @@ -0,0 +1,21 @@ +# Slot + +Slot is a toolchain developed by [Cartrige.gg](https://github.com/cartridge-gg/slot) for rapidly spinning up Katana and Torii instances. Play test your game in seconds. + +## Installation + +Run the following command to install slot: + +```sh +curl -L https://slot.cartridge.sh | bash +``` + +Once finished, run `slotup` to manage slot installations and follow the outputted directions. + +## Deploy using Slot + +To deploy your projects using slot, check out the tutorial [Deploy using Slot](/tutorial/deploy-using-slot/main.md). + +> πŸ“š **Reference** +> +> See the [`slot` Reference](./reference.md) for a complete overview of all the available subcommands. diff --git a/src/toolchain/slot/reference.md b/dojo-book/docs/pages/toolchain/slot/reference.md similarity index 100% rename from src/toolchain/slot/reference.md rename to dojo-book/docs/pages/toolchain/slot/reference.md diff --git a/src/toolchain/sozo/common-options/offline.md b/dojo-book/docs/pages/toolchain/sozo/common-options/offline.md similarity index 100% rename from src/toolchain/sozo/common-options/offline.md rename to dojo-book/docs/pages/toolchain/sozo/common-options/offline.md diff --git a/src/toolchain/sozo/common-options/profile.md b/dojo-book/docs/pages/toolchain/sozo/common-options/profile.md similarity index 100% rename from src/toolchain/sozo/common-options/profile.md rename to dojo-book/docs/pages/toolchain/sozo/common-options/profile.md diff --git a/0.2.0/src/toolchain/sozo/common/account-options.md b/dojo-book/docs/pages/toolchain/sozo/common/account-options.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/common/account-options.md rename to dojo-book/docs/pages/toolchain/sozo/common/account-options.md diff --git a/0.2.0/src/toolchain/sozo/common/signer-options-keystore.md b/dojo-book/docs/pages/toolchain/sozo/common/signer-options-keystore.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/common/signer-options-keystore.md rename to dojo-book/docs/pages/toolchain/sozo/common/signer-options-keystore.md diff --git a/0.2.0/src/toolchain/sozo/common/signer-options-raw.md b/dojo-book/docs/pages/toolchain/sozo/common/signer-options-raw.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/common/signer-options-raw.md rename to dojo-book/docs/pages/toolchain/sozo/common/signer-options-raw.md diff --git a/0.2.0/src/toolchain/sozo/common/starknet-options.md b/dojo-book/docs/pages/toolchain/sozo/common/starknet-options.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/common/starknet-options.md rename to dojo-book/docs/pages/toolchain/sozo/common/starknet-options.md diff --git a/0.2.0/src/toolchain/sozo/common/world-options.md b/dojo-book/docs/pages/toolchain/sozo/common/world-options.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/common/world-options.md rename to dojo-book/docs/pages/toolchain/sozo/common/world-options.md diff --git a/0.2.0/src/toolchain/sozo/development.md b/dojo-book/docs/pages/toolchain/sozo/development.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/development.md rename to dojo-book/docs/pages/toolchain/sozo/development.md diff --git a/dojo-book/docs/pages/toolchain/sozo/overview.md b/dojo-book/docs/pages/toolchain/sozo/overview.md new file mode 100644 index 00000000..2ce1e696 --- /dev/null +++ b/dojo-book/docs/pages/toolchain/sozo/overview.md @@ -0,0 +1,27 @@ +![katana](/sozo-icon-word.png) + +## Sozo + +`sozo` is a powerful all-in-one tool for managing your Dojo projects. It helps with everything from scaffolding a new project, all the way to deploying and interacting with your Dojo Worlds. It includes a migration planning tool, designed to streamline the updating and deployment of AWs. It provides a robust command-line interface (CLI) that simplifies World management tasks, enabling you to focus on the creative aspects of World-building. In the future, it may include a GUI. + +## Features + +- **Binary CLI**: Sozo provides an intuitive binary CLI, ensuring easy management of your Worlds, whether you're updating existing ones or deploying new ones. + +## Installation + +`sozo` binary can be installed via [`dojoup`](/getting-started/quick-start.md), our dedicated installation package manager. + +### Installing from Source + +```sh +git clone https://github.com/dojoengine/dojo +cd dojo +cargo install --path ./crates/sozo --locked --force +``` + +This will install Sozo and the required dependencies on your local system. + +> πŸ“š **Reference** +> +> See the [`sozo` Reference](./reference.md) for a complete overview of all the available subcommands. diff --git a/0.2.0/src/toolchain/sozo/project-commands/build.md b/dojo-book/docs/pages/toolchain/sozo/project-commands/build.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/project-commands/build.md rename to dojo-book/docs/pages/toolchain/sozo/project-commands/build.md diff --git a/0.2.0/src/toolchain/sozo/project-commands/init.md b/dojo-book/docs/pages/toolchain/sozo/project-commands/init.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/project-commands/init.md rename to dojo-book/docs/pages/toolchain/sozo/project-commands/init.md diff --git a/src/toolchain/sozo/project-commands/migrate.md b/dojo-book/docs/pages/toolchain/sozo/project-commands/migrate.md similarity index 100% rename from src/toolchain/sozo/project-commands/migrate.md rename to dojo-book/docs/pages/toolchain/sozo/project-commands/migrate.md diff --git a/0.2.0/src/toolchain/sozo/project-commands/test.md b/dojo-book/docs/pages/toolchain/sozo/project-commands/test.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/project-commands/test.md rename to dojo-book/docs/pages/toolchain/sozo/project-commands/test.md diff --git a/src/toolchain/sozo/reference.md b/dojo-book/docs/pages/toolchain/sozo/reference.md similarity index 100% rename from src/toolchain/sozo/reference.md rename to dojo-book/docs/pages/toolchain/sozo/reference.md diff --git a/src/toolchain/sozo/world-commands/auth.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/auth.md similarity index 100% rename from src/toolchain/sozo/world-commands/auth.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/auth.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/events.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/events.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/events.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/events.md diff --git a/src/toolchain/sozo/world-commands/execute.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/execute.md similarity index 100% rename from src/toolchain/sozo/world-commands/execute.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/execute.md diff --git a/src/toolchain/sozo/world-commands/model.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/model.md similarity index 100% rename from src/toolchain/sozo/world-commands/model.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/model.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/register.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/register.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/register.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/register.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/system.md b/dojo-book/docs/pages/toolchain/sozo/world-commands/system.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/system.md rename to dojo-book/docs/pages/toolchain/sozo/world-commands/system.md diff --git a/dojo-book/docs/pages/toolchain/torii/graphql.md b/dojo-book/docs/pages/toolchain/torii/graphql.md new file mode 100644 index 00000000..d47ecfb9 --- /dev/null +++ b/dojo-book/docs/pages/toolchain/torii/graphql.md @@ -0,0 +1,408 @@ +## Torii - GraphQL + +### Name + +In Dojo, you have access to custom queries and subscriptions that are specifically designed to work with the `caller` for client applications. GraphQL is the technology that makes this possible. + +GraphQL is the rising star of backend technologies. It replaces REST as an API design paradigm and is becoming the new standard for exposing the data and functionality of a web server. It allows you to specify exactly what data you want to retrieve, and it delivers that data in a structured JSON format. This flexibility in data retrieval ensures that you get the information you need efficiently and in a format that's easy to work with. + +#### GraphQL Playground + +GraphQL Playground is a `GraphQL IDE` that allows you to interactively explore the functionality of a GraphQL API by sending queries and mutations to it. It’s somewhat similar to Postman which offers comparable functionality for REST APIs. + +### USAGE + +#### Pre-requisites + +Make sure torii is running in your local terminal. + +```sh +torii --world +``` + +It starts GraphQL server at `http://0.0.0.0:8080/graphql` + +After the torii server starts on your local machine, you're ready to make query and subscription operations. + +### Schema and query defintions + +Torii generates both the schema and queries at runtime specific to your world. There are mainly two groups of queries, predefined queries and dynamically generated custom queries. + +Predefined queries like `entities` provide a generic entry point to the entities data of the world. Custom queries on the other hand are built according to the models of the world. Each model has a correpsonding `{name}Models` query and retrieves the associated model data. For example: `positionModels`. + +The benefit of custom queries becomes apparent when filtering and sorting is needed. They allow much more finer control of the returned dataset. + +### Query operation + +In [`hello-dojo`](/cairo/hello-dojo.md#next-steps) we fetched some data from the `Moves` model. This time let's fetch only `id`, `name`, `classHash` fields from `Position` model . + +```graphql +query { + model(id: "Position") { + id + name + classHash + } +} +``` + +After you run the query, you will receive an output like this: + +```json +{ + "data": { + "model": { + "id": "Position", + "name": "Position", + "classHash": "0x6ffc643cbc4b2fb9c424242b18175a5e142269b45f4463d1cd4dddb7a2e5095" + } + } +} +``` + +Great! If you're wondering about the number of fields a `Model` has or the details of a `Entities`, you can find all the information about the schema definition in the `Documentation Explorer` section of the GraphQL IDE. It's your go-to place for exploring the rest of the documentation. + +Now lets retrieve more data from `Moves` model. + +```graphql +query { + movesModels { + edges { + node { + player + remaining + last_direction + } + } + } +} +``` + +After you run the query, you will receive an output like this: + +```json +{ + "data": { + "movesModels": { + "edges": [ + { + "node": { + "player": "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "remaining": 10, + "last_direction": "None" + } + } + ] + } + } +} +``` + +#### Transactions + +GraphQL additionally offers an API to fetch transactions emitted from your `world`. Presently, you can retrieve `transaction data` with the potential for future support of `transaction receipt`. Current API includes pagination support, although filtering is not yet supported. Let's explore an example. + +```grapql +query{ + transactions{ + edges{ + node{ + id + transactionHash + senderAddress + calldata + } + } + totalCount + } +} +``` + +If you execute this query after you applied `sozo migrate` in your [`hello-dojo`](/cairo/hello-dojo.md) example. You will get an output similar to this. + +```json +{ + "data": { + "transactions": { + "edges": [ + { + "node": { + "id": "0x000000000000000000000000000000000000000000000000000000000000000a:0x0000", + "transactionHash": "0x2da3d65e223362c72906f97663a4e7dc81ab0bbd04bbde5532a230c1e97d93e", + "senderAddress": "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "calldata": [ + "0x1", + "0x405a3c5421ca7e23052abce78057e27384ba9db5e4feff7b4041a74e769a98a", + "0x2730079d734ee55315f4f141eaed376bddd8c2133523d223a344c5604e0f7f8", + "0x0", + "0x2", + "0x2", + "0x35ec9fd22092dc0c8fc9341e94d5f361924d921c128fa46a0648f2dac519ce4", + "0x2ffecbe8de6c7c10c785a6eb964ee6489f8dcf139000adbe2c0f12d249be7d8" + ] + } + }, + { + "node": { + "id": "0x0000000000000000000000000000000000000000000000000000000000000008:0x0000", + "transactionHash": "0x2aa02de0e3fa582b3cb6cf9e4371051f44ae2e0d6c94f5c936338ffc8c2ac12", + "senderAddress": "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "calldata": [ + "0x2", + "0x405a3c5421ca7e23052abce78057e27384ba9db5e4feff7b4041a74e769a98a", + "0x1e7875674bcb09daaf984cbf77264ac98120cb39e6d17522520defcdc347476", + "0x0", + "0x1", + "0x405a3c5421ca7e23052abce78057e27384ba9db5e4feff7b4041a74e769a98a", + "0x1e7875674bcb09daaf984cbf77264ac98120cb39e6d17522520defcdc347476", + "0x1", + "0x1", + "0x2", + "0x2e5174b54aef0b99d4685827ffa51488447e1f5607908293d5c715d6bd22433", + "0x6a11b5b3003a3aa0ae7f8f443e48314cc0bc51eaea7c3ed1c19beb909f5dda3" + ] + } + }, + { + "node": { + "id": "0x0000000000000000000000000000000000000000000000000000000000000005:0x0000", + "transactionHash": "0x1f03fa7dc5a673f96d53b728785a98d6ff089c182a7bb32735b150e91817e5b", + "senderAddress": "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "calldata": [ + "0x1", + "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf", + "0x1987cbd17808b9a23693d4de7e246a443cfe37e6e7fbaeabd7d7e6532b07c3d", + "0x0", + "0x6", + "0x6", + "0xb3e374b8087dca92601afbb9881fed855ac0d568e3bf878a876fca5ffcb479", + "0x41d7f42bf7a362f0420aaae66d7a91df981100a039ac116a1d9cb632c74ad27", + "0x0", + "0x2", + "0x59f31686991d7cac25a7d4844225b9647c89e3e1e2d03460dbc61e3fbfafc59", + "0x77638e9a645209ac1e32e143bfdbfe9caf723c4f7645fcf465c38967545ea2f" + ] + } + } + ], + "totalCount": 3 + } + } +} +``` + +Now feel free to play around with the query by removing any fields from the selection set and observe the responses sent by the server. It is your turn to create any kind of query for entities and models! + +#### Pagination + +As the entities in your world grows, fetching all of that data at once can become inefficient and slow. + +Torii provides two methods to address this - cursor or offset/limit based pagination. To keep the return type consistent, both methods will return a [`Connection`](https://relay.dev/graphql/connections.htm#sec-Connection-Types) type. + +You can read more about graphql pagination [here](https://graphql.org/learn/pagination). + +##### Cursor + +Cursor based pagination is the most efficient, allowing us to query a subset or slice of the entire set of data. Both forward and backward pagination are supported using a combination of `first, last, before, after` input arguments. + +Forward pagination uses `first`/`after` and backward pagination uses `last`/`before`. `first`/`last` are integers representing the number of items to return. `after`/`before` are the cursors to paginate from. + +Query for first page of 2 entities + +```graphql +query { + entities (first: 2) { + totalCount + edges { + cursor + node { + ... + } + } + } +} +``` + +Result shows there are 5 entities and returns the first two + +```json +{ + "entities" { + "totalCount": 5, + "edges" [ + { + "cursor": "Y3Vyc29yX29uZQ==", + "node" : { } + }, + { + "cursor": "Y3Vyc29yX3R3bw==", + "node" : { } + }, + ] + } +} +``` + +Query 3 entities after the second node (last 3) + +```graphql +query { + entities (first: 3, after: "Y3Vyc29yX3R3bw==") { + ... + } +} +``` + +##### Offset/limit + +Offset/limit based pagination can be more intuitive and easier to use. However, for very, very large datasets they can be inefficient. + +```graphql +# essentially the same as the last query in cursor example +query { + entities (offset: 2, limit 3) { + ... + } +} +``` + +### Subscription operations + +Subscriptions are a GraphQL feature that allows a server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets. In that setup, the server maintains a steady connection to its subscribed client. This also breaks the β€œRequest-Response-Cycle” that is used for with REST APIs. + +Instead, the client initially opens up a long-lived connection to the server by sending a subscription query that specifies which event it is interested in. Every time this particular event happens, the server uses the connection to push the event data to the subscribed client(s). + +In this example, you can listen when an `Model` is registered by executing this subscription + +```graphql +subscription modelRegistered { + modelRegistered { + id + name + } +} +``` + +Graphql also supports subscription to a targeted entity or model, for this we have to pass its id as an argument + +In this example, our server provides a `entityUpdated` subscription, which should notify clients whenever an entity with id `0x28cd7ee02d7f6ec9810e75b930e8e607793b302445abbdee0ac88143f18da20` is updated. On the same subscription we can get the model(components) values of the updated entity . A client can execute a subscription that looks like this: + +```graphql +subscription { + entityUpdated( + id: "0x28cd7ee02d7f6ec9810e75b930e8e607793b302445abbdee0ac88143f18da20" + ) { + id + keys + eventId + createdAt + updatedAt + models { + __typename + ... on Moves { + remaining + player + } + ... on Position { + vec { + x + y + } + } + } + } +} +``` + +According to your input, you will receive an output like this: + +```json +{ + "data": { + "entityUpdated": { + "id": "0x28cd7ee02d7f6ec9810e75b930e8e607793b302445abbdee0ac88143f18da20", + "keys": [ + "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" + ], + "eventId": "0x0000000000000000000000000000000000000000000000000000000000000013:0x0000:0x0000", + "createdAt": "2023-10-17 11:39:42", + "updatedAt": "2023-10-17 11:52:48", + "models": [ + { + "__typename": "Moves", + "remaining": 10, + "player": "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" + }, + { + "__typename": "Position", + "vec": { + "x": 10, + "y": 10 + } + } + ] + } + } +} +``` + +#### Susbcription to events + +A valuable approach for harnessing the power of GraphQL is by actively monitoring the events emitted throughout your game. This allows you to extract essential information such as key values, data, and transaction hashes. These events are customizable and can be filtered based on keys, much like `entities query`, and they seamlessly support pagination. In the subsequent example, we will demonstrate how to listen for any event emitted within your program. + +```graphql +subscription { + eventEmitted { + id + keys + data + transactionHash + } +} +``` + +If you execute this suscription after you applied `sozo execute spawn` in your [`hello-dojo`](/cairo/hello-dojo.md) example. You will get an output similar to this. + +```json +{ + "data": { + "eventEmitted": { + "id": "0x000000000000000000000000000000000000000000000000000000000000000b:0x0000:0x0000", + "keys": [ + "0x1a2f334228cee715f1f0f54053bb6b5eac54fa336e0bc1aacf7516decb0471d" + ], + "data": [ + "0x4d6f766573", + "0x1", + "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "0x0", + "0x2", + "0x64", + "0x0" + ], + "transactionHash": "0x3b7b034a087355c996abb52e363932c1135f8dd49587bc9a05902d3cf0650b" + } + } +} +----------------------------------------------------------------------------------------------- +{ + "data": { + "eventEmitted": { + "id": "0x000000000000000000000000000000000000000000000000000000000000000b:0x0000:0x0001", + "keys": [ + "0x1a2f334228cee715f1f0f54053bb6b5eac54fa336e0bc1aacf7516decb0471d" + ], + "data": [ + "0x506f736974696f6e", + "0x1", + "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973", + "0x0", + "0x2", + "0xa", + "0xa" + ], + "transactionHash": "0x3b7b034a087355c996abb52e363932c1135f8dd49587bc9a05902d3cf0650b" + } + } +} +``` diff --git a/dojo-book/docs/pages/toolchain/torii/grpc.md b/dojo-book/docs/pages/toolchain/torii/grpc.md new file mode 100644 index 00000000..2bcc4da1 --- /dev/null +++ b/dojo-book/docs/pages/toolchain/torii/grpc.md @@ -0,0 +1,9 @@ +## gRPC + +_TL;DR_ + +- gRPC is an efficient way to fetch your data +- You can subscribe to entity and model events via the gRPC +- Read more - [gRPC](https://grpc.io/docs/what-is-grpc/introduction/) + +You can use the gRPC directly or you can use it through a developed client. A great way to use it is via [dojo.js](/client/dojojs.md) torii-client package. diff --git a/dojo-book/docs/pages/toolchain/torii/overview.md b/dojo-book/docs/pages/toolchain/torii/overview.md new file mode 100644 index 00000000..1b48431e --- /dev/null +++ b/dojo-book/docs/pages/toolchain/torii/overview.md @@ -0,0 +1,45 @@ +![katana](/torii-icon-word.png) + +## Torii + +Torii is an automatic indexer and client for dojo worlds. Built in rust to be blazingly fast and exceptionally scalable. Torii provides a fully typed, dynamically generated GraphqQL interface and a high performance gRPC api for binding clients to the world state. There are two parts to torii, the client and the server. + +### Torii Server + +The torii server comprises of the rust backend that exposes the graphql and gRPC endpoints. + +### Torii Client + +Torii client interfaces with the server to provide an easy to use api for your clients: + +- [wasm](/client/dojojs.md#dojoenginetorii-wasm) +- [unity](/client/torii/unity.md) +- [c](/client/torii/unity.md) + +### Usage + +Torii leverages world introspection to bootstrap directly from an onchain deployment. Simply run: + +```sh +torii --world +``` + +You'll have a GraphQL API running at `http://localhost:8080/graphql` and a gRPC api at `http://localhost:8080` + +## Installation + +The `torii` binary can be installed via [`dojoup`](/getting-started/quick-start.md), our dedicated installation package manager. + +### Installing from Source + +If you prefer to install from the source code: + +```sh +cargo install --path ./crates/torii --profile local --force +``` + +This will install Torii and the required dependencies on your local system. + +> πŸ“š **Reference** +> +> See the [`torii` Reference](./reference.md) for a complete reference. diff --git a/src/toolchain/torii/reference.md b/dojo-book/docs/pages/toolchain/torii/reference.md similarity index 100% rename from src/toolchain/torii/reference.md rename to dojo-book/docs/pages/toolchain/torii/reference.md diff --git a/src/tutorial/deploy-using-slot/main.md b/dojo-book/docs/pages/tutorial/deploy-using-slot/main.md similarity index 100% rename from src/tutorial/deploy-using-slot/main.md rename to dojo-book/docs/pages/tutorial/deploy-using-slot/main.md diff --git a/dojo-book/docs/pages/tutorial/onchain-chess/0-setup.md b/dojo-book/docs/pages/tutorial/onchain-chess/0-setup.md new file mode 100644 index 00000000..15c54e4f --- /dev/null +++ b/dojo-book/docs/pages/tutorial/onchain-chess/0-setup.md @@ -0,0 +1,334 @@ +# 0. Setup + +_Before starting recommend following the [`hello-dojo`](/cairo/hello-dojo.md) chapter to gain a basic understanding of the Dojo game._ + +## Initializing the Project + +Create a new Dojo project folder. You can name your project what you want. + +```sh +mkdir chess +``` + +Open the project folder. + +```sh +cd chess +``` + +And initialize the project using sozo init. + +```sh +sozo init +``` + +## Cleaning Up the Boilerplate + +The project comes with a lot of boilerplate codes. Clear it all. Make sure your directory looks like this + +```shell +β”œβ”€β”€ README.md +β”œβ”€β”€ Scarb.toml +└── src + β”œβ”€β”€ actions.cairo + β”œβ”€β”€ lib.cairo + β”œβ”€β”€ models + β”‚ β”œβ”€β”€ game.cairo + β”‚ β”œβ”€β”€ piece.cairo + β”‚ └── player.cairo + β”œβ”€β”€ models.cairo + β”œβ”€β”€ tests + β”‚ β”œβ”€β”€ integration.cairo + β”‚ └── units.cairo + └── tests.cairo +``` + +Remodel your `lib.cairo`, to look like this : + +```rust,ignore +mod actions; +mod models; +mod tests; +``` + +Remodel your `models.cairo`, to look like this : + +```rust,ignore +mod game; +mod piece; +mod player; +``` + +Remodel your `tests.cairo`, to look like this : + +```rust,ignore +mod integration; +mod units; +``` + +Make sure your `Scarb.toml` looks like this: + +```toml +[package] +cairo-version = "2.4.0" +name = "chess" +version = "0.4.0" + +[cairo] +sierra-replace-ids = true + +[dependencies] +dojo = { git = "https://github.com/dojoengine/dojo", version = "0.4.2" } + +[[target.dojo]] + +[tool.dojo] +initializer_class_hash = "0xbeef" + +[tool.dojo.env] +rpc_url = "http://localhost:5050/" +# Default account for katana with seed = 0 +account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" + +``` + +Compile your project with: + +```sh +sozo build +``` + +## Basic Models + +While there are many ways to design a chess game using the ECS model, we'll follow this approach: + +> Every square of the chess board (e.g., A1) will be treated as an entity. If a piece exists on a square position, that position will hold that piece. + +First, add this basic `player` model to `models/player.cairo` file. If you are not familar with model syntax in Dojo engine, go back to this [chapter](/cairo/models.md). + +```rust,ignore +use starknet::ContractAddress; + +#[derive(Model, Drop, Serde)] +struct Player { + #[key] + game_id: u32, + #[key] + address: ContractAddress, + color: Color +} + +#[derive(Serde, Drop, Copy, PartialEq, Introspect)] +enum Color { + White, + Black, + None, +} +``` + +Second, we do the same for `game` model. Edit your `models/player.cairo` file and add this content. + +```rust,ignore +use chess::models::player::Color; +use starknet::ContractAddress; + +#[derive(Model, Drop, Serde)] +struct Game { + #[key] + game_id: u32, + winner: Color, + white: ContractAddress, + black: ContractAddress +} + +#[derive(Model, Drop, Serde)] +struct GameTurn { + #[key] + game_id: u32, + player_color: Color +} +``` + +Lastly we create `piece` model in our `models/player.cairo` file. + +```rust,ignore +use chess::models::player::Color; +use starknet::ContractAddress; + +#[derive(Model, Drop, Serde)] +struct Piece { + #[key] + game_id: u32, + #[key] + position: Vec2, + color: Color, + piece_type: PieceType, +} + +#[derive(Copy, Drop, Serde, Introspect)] +struct Vec2 { + x: u32, + y: u32 +} + +#[derive(Serde, Drop, Copy, PartialEq, Introspect)] +enum PieceType { + Pawn, + Knight, + Bishop, + Rook, + Queen, + King, + None, +} +``` + +## Basic systems + +Starting from the next chapter, you will implement the `actions.cairo` file. This is where our game logic/contract will reside. + +For now, `actions.cairo` should look like this: + +```rust,ignore +#[dojo::contract] +mod actions { +} +``` + +It should be noted that Systems function are contract methods, by implication, rather than implementing the game logic in systems, we are implementing it in a contract. + +## Compile your project + +Now try `sozo build` to build. + +Complied? Great! then let's move on. If not fix the issues, so that you can run the `sozo build` command successfully. + +## Implement Traits for models + +Before you move on, implement traits for models so we can use them in the next chapter when creating the action contract. + +### Requirements + +Firt we have to define the following traits for `Game`, `Player`, `Piece` models respectively. + +```rust,ignore +trait GameTurnTrait { + fn next_turn(self: @GameTurn) -> Color; +} + +trait PlayerTrait { +fn is_not_my_piece(self: @Player, piece_color: Color) -> bool; +} + +trait PieceTrait { +fn is_out_of_board(next_position: Vec2) -> bool; +fn is_right_piece_move(self: @Piece, next_position: Vec2) -> bool; +} +``` + +Try to implement this code by yourself, Otherwise + +
+Click to see full `models.cairo` code + +```c +// code for player.cairo file +trait PlayerTrait { + fn is_not_my_piece(self: @Player, piece_color: Color) -> bool; +} + +impl PalyerImpl of PlayerTrait { + fn is_not_my_piece(self: @Player, piece_color: Color) -> bool { + *self.color != piece_color + } +} + +// code for game.cairo file +trait GameTurnTrait { + fn next_turn(self: @GameTurn) -> Color; +} +impl GameTurnImpl of GameTurnTrait { + fn next_turn(self: @GameTurn) -> Color { + match self.player_color { + Color::White => Color::Black, + Color::Black => Color::White, + Color::None => panic(array!['Illegal turn']) + } + } +} + +// code for piece.cairo file +trait PieceTrait { + fn is_out_of_board(next_position: Vec2) -> bool; + fn is_right_piece_move(self: @Piece, next_position: Vec2) -> bool; +} + +impl PieceImpl of PieceTrait { + fn is_out_of_board(next_position: Vec2) -> bool { + next_position.x > 7 || next_position.y > 7 + } + + fn is_right_piece_move(self: @Piece, next_position: Vec2) -> bool { + let n_x = next_position.x; + let n_y = next_position.y; + assert(!(n_x == *self.position.x && n_y == *self.position.y), 'Cannot move same position'); + match self.piece_type { + PieceType::Pawn => { + match self.color { + Color::White => { + (n_x == *self.position.x && n_y == *self.position.y + 1) + || (n_x == *self.position.x && n_y == *self.position.y + 2) + || (n_x == *self.position.x + 1 && n_y == *self.position.y + 1) + || (n_x == *self.position.x - 1 && n_y == *self.position.y + 1) + }, + Color::Black => { + (n_x == *self.position.x && n_y == *self.position.y - 1) + || (n_x == *self.position.x && n_y == *self.position.y - 2) + || (n_x == *self.position.x + 1 && n_y == *self.position.y - 1) + || (n_x == *self.position.x - 1 && n_y == *self.position.y - 1) + }, + Color::None => panic(array!['Should not move empty piece']), + } + }, + PieceType::Knight => { n_x == *self.position.x + 2 && n_y == *self.position.y + 1 }, + PieceType::Bishop => { + (n_x <= *self.position.x && n_y <= *self.position.y && *self.position.y + - n_y == *self.position.x + - n_x) + || (n_x <= *self.position.x && n_y >= *self.position.y && *self.position.y + - n_y == *self.position.x + - n_x) + || (n_x >= *self.position.x && n_y <= *self.position.y && *self.position.y + - n_y == *self.position.x + - n_x) + || (n_x >= *self.position.x && n_y >= *self.position.y && *self.position.y + - n_y == *self.position.x + - n_x) + }, + PieceType::Rook => { + (n_x == *self.position.x || n_y != *self.position.y) + || (n_x != *self.position.x || n_y == *self.position.y) + }, + PieceType::Queen => { + (n_x == *self.position.x || n_y != *self.position.y) + || (n_x != *self.position.x || n_y == *self.position.y) + || (n_x != *self.position.x || n_y != *self.position.y) + }, + PieceType::King => { + (n_x <= *self.position.x + 1 && n_y <= *self.position.y + 1) + || (n_x <= *self.position.x + 1 && n_y <= *self.position.y - 1) + || (n_x <= *self.position.x - 1 && n_y <= *self.position.y + 1) + || (n_x <= *self.position.x - 1 && n_y <= *self.position.y - 1) + }, + PieceType::None => panic(array!['Should not move empty piece']), + } + } +} +``` + +
+ +This tutorial is extracted from [here](https://github.com/dojoengine/origami/tree/main/examples/chess) + +Congratulations! You've completed the basic setup for building an on-chain chess game πŸŽ‰ diff --git a/dojo-book/docs/pages/tutorial/onchain-chess/1-action.md b/dojo-book/docs/pages/tutorial/onchain-chess/1-action.md new file mode 100644 index 00000000..f3996c08 --- /dev/null +++ b/dojo-book/docs/pages/tutorial/onchain-chess/1-action.md @@ -0,0 +1,159 @@ +# 1. Actions + +This chapter will address implementing `actions.cairo`, which spawns the game & squares containing pieces and also allow players to move pieces. + +## What is `actions` contract? + +To play chess, you need, to start game, spawn the pieces, and move around the board. The `actions` contract has two dominant functions `spawn` function which spawns the game entity, places each piece in its proper position on the board and returns the game_id, and the `move` funtion which allows pieces to be moved around the board. + +

+image + +## Requirements + +1. Write an interface for the `actions` contract on top of your code. In this case, `move` and `spawn` + +```rust,ignore + use starknet::ContractAddress; + use chess::models::piece::Vec2; + #[starknet::interface] + trait IActions { + fn move( + self: @ContractState, + curr_position: Vec2, + next_position: Vec2, + caller: ContractAddress, //player + game_id: u32 + ); + fn spawn( + self: @ContractState, white_address: ContractAddress, black_address: ContractAddress + ) -> u32; + } +``` + +2. Bring in required imports into the contract like this : + +```rust,ignore + #[dojo::contract] + mod actions { + use chess::models::player::{Player, Color, PlayerTrait}; + use chess::models::piece::{Piece, PieceType, PieceTrait}; + use chess::models::game::{Game, GameTurn, GameTurnTrait}; + use super::{ContractAddress, IActions, Vec2}; + } +``` + +Should be noted that `actions` is the contract name. + +3. Write a `spawn` function that accepts the `white address`, and `black address` as input and set necessary states using `set!(...)`. Implement the `player` entity from player model. Implement the game entity, comprised of the `Game` model and `GameTurn` model we created in the `game.cairo` and implement the piece entities from a1 to h8 containing the correct `PieceType` in the `spawn` fn. + +```rust,ignore + #[abi(embed_v0)] + impl IActionsImpl of IActions { + fn spawn( + self: @ContractState, white_address: ContractAddress, black_address: ContractAddress + ) -> u32 { + let world = self.world_dispatcher.read(); + let game_id = world.uuid(); + + // set Players + set!( + world, + ( + Player { game_id, address: black_address, color: Color::Black }, + Player { game_id, address: white_address, color: Color::White }, + ) + ); + + // set Game and GameTurn + set!( + world, + ( + Game { + game_id, winner: Color::None, white: white_address, black: black_address + }, + GameTurn { game_id, player_color: Color::White }, + ) + ); + + // set Pieces + set!( + world, + (Piece { + game_id, + color: Color::White, + position: Vec2 { x: 0, y: 0 }, + piece_type: PieceType::Rook + }) + ); + set!( + world, + (Piece { + game_id, + color: Color::White, + position: Vec2 { x: 0, y: 1 }, + piece_type: PieceType::Pawn + }) + ); + set!( + world, + (Piece { + game_id, + color: Color::Black, + position: Vec2 { x: 1, y: 6 }, + piece_type: PieceType::Pawn + }) + ); + set!( + world, + (Piece { + game_id, + color: Color::White, + position: Vec2 { x: 1, y: 0 }, + piece_type: PieceType::Knight + }) + ); + set!( + world, + (Piece { + game_id, + color: Color::None, + position: Vec2 { x: 0, y: 2 }, + piece_type: PieceType::None + }) + ); + + set!( + world, + (Piece { + game_id, + color: Color::None, + position: Vec2 { x: 0, y: 3 }, + piece_type: PieceType::None + }) + ); + set!( + world, + (Piece { + game_id, + color: Color::None, + position: Vec2 { x: 1, y: 4 }, + piece_type: PieceType::None + }) + ); + + //the rest of the positions on the board goes here.... + + game_id + } + fn move( + self: @ContractState, + curr_position: Vec2, + next_position: Vec2, + caller: ContractAddress, //player + game_id: u32 + ) { + // Upcoming code + } + } +``` diff --git a/src/tutorial/onchain-chess/2-move.md b/dojo-book/docs/pages/tutorial/onchain-chess/2-move.md similarity index 100% rename from src/tutorial/onchain-chess/2-move.md rename to dojo-book/docs/pages/tutorial/onchain-chess/2-move.md diff --git a/src/tutorial/onchain-chess/3-test.md b/dojo-book/docs/pages/tutorial/onchain-chess/3-test.md similarity index 100% rename from src/tutorial/onchain-chess/3-test.md rename to dojo-book/docs/pages/tutorial/onchain-chess/3-test.md diff --git a/src/tutorial/onchain-chess/README.md b/dojo-book/docs/pages/tutorial/onchain-chess/README.md similarity index 100% rename from src/tutorial/onchain-chess/README.md rename to dojo-book/docs/pages/tutorial/onchain-chess/README.md diff --git a/dojo-book/docs/public/Built with.svg b/dojo-book/docs/public/Built with.svg new file mode 100644 index 00000000..12c5d2ce --- /dev/null +++ b/dojo-book/docs/public/Built with.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/dojo-book/docs/public/Dojo - Contracts.png b/dojo-book/docs/public/Dojo - Contracts.png new file mode 100644 index 00000000..95412269 Binary files /dev/null and b/dojo-book/docs/public/Dojo - Contracts.png differ diff --git a/src/images/ECS.png b/dojo-book/docs/public/ECS.png similarity index 100% rename from src/images/ECS.png rename to dojo-book/docs/public/ECS.png diff --git a/src/images/board.png b/dojo-book/docs/public/board.png similarity index 100% rename from src/images/board.png rename to dojo-book/docs/public/board.png diff --git a/src/images/dojo-auth.png b/dojo-book/docs/public/dojo-auth.png similarity index 100% rename from src/images/dojo-auth.png rename to dojo-book/docs/public/dojo-auth.png diff --git a/src/images/dojo-mark-full-dark.svg b/dojo-book/docs/public/dojo-mark-full-dark.svg similarity index 100% rename from src/images/dojo-mark-full-dark.svg rename to dojo-book/docs/public/dojo-mark-full-dark.svg diff --git a/src/images/dojo-sozo-workflow.jpg b/dojo-book/docs/public/dojo-sozo-workflow.jpg similarity index 100% rename from src/images/dojo-sozo-workflow.jpg rename to dojo-book/docs/public/dojo-sozo-workflow.jpg diff --git a/dojo-book/docs/public/dojo.unity_demo.mp4 b/dojo-book/docs/public/dojo.unity_demo.mp4 new file mode 100644 index 00000000..e1b9c99d Binary files /dev/null and b/dojo-book/docs/public/dojo.unity_demo.mp4 differ diff --git a/dojo-book/docs/public/katana-icon-word.png b/dojo-book/docs/public/katana-icon-word.png new file mode 100644 index 00000000..cc71e76e Binary files /dev/null and b/dojo-book/docs/public/katana-icon-word.png differ diff --git a/dojo-book/docs/public/katana-icon.png b/dojo-book/docs/public/katana-icon.png new file mode 100644 index 00000000..79c978b7 Binary files /dev/null and b/dojo-book/docs/public/katana-icon.png differ diff --git a/dojo-book/docs/public/katana.png b/dojo-book/docs/public/katana.png new file mode 100644 index 00000000..25077302 Binary files /dev/null and b/dojo-book/docs/public/katana.png differ diff --git a/dojo-book/docs/public/origami-icon-word.png b/dojo-book/docs/public/origami-icon-word.png new file mode 100644 index 00000000..ccac1432 Binary files /dev/null and b/dojo-book/docs/public/origami-icon-word.png differ diff --git a/dojo-book/docs/public/origami-icon.png b/dojo-book/docs/public/origami-icon.png new file mode 100644 index 00000000..f4ed595a Binary files /dev/null and b/dojo-book/docs/public/origami-icon.png differ diff --git a/dojo-book/docs/public/origami.png b/dojo-book/docs/public/origami.png new file mode 100644 index 00000000..f1eba0d0 Binary files /dev/null and b/dojo-book/docs/public/origami.png differ diff --git a/dojo-book/docs/public/permissions.png b/dojo-book/docs/public/permissions.png new file mode 100644 index 00000000..1fca70d8 Binary files /dev/null and b/dojo-book/docs/public/permissions.png differ diff --git a/dojo-book/docs/public/slot-icon-word.png b/dojo-book/docs/public/slot-icon-word.png new file mode 100644 index 00000000..b424160f Binary files /dev/null and b/dojo-book/docs/public/slot-icon-word.png differ diff --git a/dojo-book/docs/public/slot-icon.png b/dojo-book/docs/public/slot-icon.png new file mode 100644 index 00000000..28090367 Binary files /dev/null and b/dojo-book/docs/public/slot-icon.png differ diff --git a/dojo-book/docs/public/sozo-icon-word.png b/dojo-book/docs/public/sozo-icon-word.png new file mode 100644 index 00000000..d8c85888 Binary files /dev/null and b/dojo-book/docs/public/sozo-icon-word.png differ diff --git a/dojo-book/docs/public/sozo-icon.png b/dojo-book/docs/public/sozo-icon.png new file mode 100644 index 00000000..0b96151b Binary files /dev/null and b/dojo-book/docs/public/sozo-icon.png differ diff --git a/dojo-book/docs/public/torii-icon-word.png b/dojo-book/docs/public/torii-icon-word.png new file mode 100644 index 00000000..120efbc9 Binary files /dev/null and b/dojo-book/docs/public/torii-icon-word.png differ diff --git a/dojo-book/docs/public/torii-icon.png b/dojo-book/docs/public/torii-icon.png new file mode 100644 index 00000000..3e1e9b28 Binary files /dev/null and b/dojo-book/docs/public/torii-icon.png differ diff --git a/dojo-book/docs/public/unity-screen-grab.png b/dojo-book/docs/public/unity-screen-grab.png new file mode 100644 index 00000000..fa9834bd Binary files /dev/null and b/dojo-book/docs/public/unity-screen-grab.png differ diff --git a/dojo-book/docs/public/unity/models.png b/dojo-book/docs/public/unity/models.png new file mode 100644 index 00000000..0c608585 Binary files /dev/null and b/dojo-book/docs/public/unity/models.png differ diff --git a/dojo-book/docs/public/unity/sync-master.png b/dojo-book/docs/public/unity/sync-master.png new file mode 100644 index 00000000..e4a25a6f Binary files /dev/null and b/dojo-book/docs/public/unity/sync-master.png differ diff --git a/dojo-book/docs/public/unity/world-manager.png b/dojo-book/docs/public/unity/world-manager.png new file mode 100644 index 00000000..0979a2de Binary files /dev/null and b/dojo-book/docs/public/unity/world-manager.png differ diff --git a/dojo-book/docs/public/world-map.png b/dojo-book/docs/public/world-map.png new file mode 100644 index 00000000..4fc2664f Binary files /dev/null and b/dojo-book/docs/public/world-map.png differ diff --git a/dojo-book/docs/public/world_flow.png b/dojo-book/docs/public/world_flow.png new file mode 100644 index 00000000..6812f3e8 Binary files /dev/null and b/dojo-book/docs/public/world_flow.png differ diff --git a/dojo-book/docs/public/worlds-dev-icon-word.png b/dojo-book/docs/public/worlds-dev-icon-word.png new file mode 100644 index 00000000..3e50b09a Binary files /dev/null and b/dojo-book/docs/public/worlds-dev-icon-word.png differ diff --git a/dojo-book/docs/public/worlds-dev-icon.png b/dojo-book/docs/public/worlds-dev-icon.png new file mode 100644 index 00000000..d8327a52 Binary files /dev/null and b/dojo-book/docs/public/worlds-dev-icon.png differ diff --git a/dojo-book/package.json b/dojo-book/package.json new file mode 100644 index 00000000..44571176 --- /dev/null +++ b/dojo-book/package.json @@ -0,0 +1,15 @@ +{ + "name": "dojo-book", + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vocs dev", + "build": "vocs build", + "preview": "vocs preview" + }, + "dependencies": { + "react": "latest", + "react-dom": "latest", + "vocs": "latest" + } +} diff --git a/dojo-book/pnpm-lock.yaml b/dojo-book/pnpm-lock.yaml new file mode 100644 index 00000000..4bc51b0c --- /dev/null +++ b/dojo-book/pnpm-lock.yaml @@ -0,0 +1,5057 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + react: + specifier: latest + version: 18.2.0 + react-dom: + specifier: latest + version: 18.2.0(react@18.2.0) + vocs: + specifier: latest + version: 1.0.0-alpha.25(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.5)(typescript@5.3.3) + +packages: + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: false + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.22 + dev: false + + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + dev: false + + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/core@7.23.7: + resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helpers': 7.23.8 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.22 + jsesc: 2.5.2 + dev: false + + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: false + + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + dev: false + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: false + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helpers@7.23.8: + resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: false + + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.7): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + dev: false + + /@babel/runtime@7.23.8: + resolution: {integrity: sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + dev: false + + /@babel/traverse@7.23.7: + resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: false + + /@clack/core@0.3.3: + resolution: {integrity: sha512-5ZGyb75BUBjlll6eOa1m/IZBxwk91dooBWhPSL67sWcLS0zt9SnswRL0l26TVdBhb0wnWORRxUn//uH6n4z7+A==} + dependencies: + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: false + + /@clack/prompts@0.7.0: + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + dependencies: + '@clack/core': 0.3.3 + picocolors: 1.0.0 + sisteransi: 1.0.5 + dev: false + bundledDependencies: + - is-unicode-supported + + /@emotion/hash@0.9.1: + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + dev: false + + /@esbuild/aix-ppc64@0.19.11: + resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.17.6: + resolution: {integrity: sha512-YnYSCceN/dUzUr5kdtUzB+wZprCafuD89Hs0Aqv9QSdwhYQybhXTaSTcrl6X/aWThn1a/j0eEpUBGOE7269REg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.19.11: + resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.17.6: + resolution: {integrity: sha512-bSC9YVUjADDy1gae8RrioINU6e1lCkg3VGVwm0QQ2E1CWcC4gnMce9+B6RpxuSsrsXsk1yojn7sp1fnG8erE2g==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.19.11: + resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.17.6: + resolution: {integrity: sha512-MVcYcgSO7pfu/x34uX9u2QIZHmXAB7dEiLQC5bBl5Ryqtpj9lT2sg3gNDEsrPEmimSJW2FXIaxqSQ501YLDsZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.19.11: + resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.17.6: + resolution: {integrity: sha512-bsDRvlbKMQMt6Wl08nHtFz++yoZHsyTOxnjfB2Q95gato+Yi4WnRl13oC2/PJJA9yLCoRv9gqT/EYX0/zDsyMA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.19.11: + resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.17.6: + resolution: {integrity: sha512-xh2A5oPrYRfMFz74QXIQTQo8uA+hYzGWJFoeTE8EvoZGHb+idyV4ATaukaUvnnxJiauhs/fPx3vYhU4wiGfosg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.19.11: + resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.17.6: + resolution: {integrity: sha512-EnUwjRc1inT4ccZh4pB3v1cIhohE2S4YXlt1OvI7sw/+pD+dIE4smwekZlEPIwY6PhU6oDWwITrQQm5S2/iZgg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.19.11: + resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.17.6: + resolution: {integrity: sha512-Uh3HLWGzH6FwpviUcLMKPCbZUAFzv67Wj5MTwK6jn89b576SR2IbEp+tqUHTr8DIl0iDmBAf51MVaP7pw6PY5Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.19.11: + resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.17.6: + resolution: {integrity: sha512-bUR58IFOMJX523aDVozswnlp5yry7+0cRLCXDsxnUeQYJik1DukMY+apBsLOZJblpH+K7ox7YrKrHmJoWqVR9w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.19.11: + resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.17.6: + resolution: {integrity: sha512-7YdGiurNt7lqO0Bf/U9/arrPWPqdPqcV6JCZda4LZgEn+PTQ5SMEI4MGR52Bfn3+d6bNEGcWFzlIxiQdS48YUw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.19.11: + resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.17.6: + resolution: {integrity: sha512-ujp8uoQCM9FRcbDfkqECoARsLnLfCUhKARTP56TFPog8ie9JG83D5GVKjQ6yVrEVdMie1djH86fm98eY3quQkQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.19.11: + resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.17.6: + resolution: {integrity: sha512-y2NX1+X/Nt+izj9bLoiaYB9YXT/LoaQFYvCkVD77G/4F+/yuVXYCWz4SE9yr5CBMbOxOfBcy/xFL4LlOeNlzYQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.19.11: + resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.17.6: + resolution: {integrity: sha512-09AXKB1HDOzXD+j3FdXCiL/MWmZP0Ex9eR8DLMBVcHorrWJxWmY8Nms2Nm41iRM64WVx7bA/JVHMv081iP2kUA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.19.11: + resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.17.6: + resolution: {integrity: sha512-AmLhMzkM8JuqTIOhxnX4ubh0XWJIznEynRnZAVdA2mMKE6FAfwT2TWKTwdqMG+qEaeyDPtfNoZRpJbD4ZBv0Tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.19.11: + resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.17.6: + resolution: {integrity: sha512-Y4Ri62PfavhLQhFbqucysHOmRamlTVK10zPWlqjNbj2XMea+BOs4w6ASKwQwAiqf9ZqcY9Ab7NOU4wIgpxwoSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.19.11: + resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.17.6: + resolution: {integrity: sha512-SPUiz4fDbnNEm3JSdUW8pBJ/vkop3M1YwZAVwvdwlFLoJwKEZ9L98l3tzeyMzq27CyepDQ3Qgoba44StgbiN5Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.19.11: + resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.17.6: + resolution: {integrity: sha512-a3yHLmOodHrzuNgdpB7peFGPx1iJ2x6m+uDvhP2CKdr2CwOaqEFMeSqYAHU7hG+RjCq8r2NFujcd/YsEsFgTGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.19.11: + resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.17.6: + resolution: {integrity: sha512-EanJqcU/4uZIBreTrnbnre2DXgXSa+Gjap7ifRfllpmyAU7YMvaXmljdArptTHmjrkkKm9BK6GH5D5Yo+p6y5A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.19.11: + resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.17.6: + resolution: {integrity: sha512-xaxeSunhQRsTNGFanoOkkLtnmMn5QbA0qBhNet/XLVsc+OVkpIWPHcr3zTW2gxVU5YOHFbIHR9ODuaUdNza2Vw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.19.11: + resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.17.6: + resolution: {integrity: sha512-gnMnMPg5pfMkZvhHee21KbKdc6W3GR8/JuE0Da1kjwpK6oiFU3nqfHuVPgUX2rsOx9N2SadSQTIYV1CIjYG+xw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.19.11: + resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.17.6: + resolution: {integrity: sha512-G95n7vP1UnGJPsVdKXllAJPtqjMvFYbN20e8RK8LVLhlTiSOH1sd7+Gt7rm70xiG+I5tM58nYgwWrLs6I1jHqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.19.11: + resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.17.6: + resolution: {integrity: sha512-96yEFzLhq5bv9jJo5JhTs1gI+1cKQ83cUpyxHuGqXVwQtY5Eq54ZEsKs8veKtiKwlrNimtckHEkj4mRh4pPjsg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.19.11: + resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.17.6: + resolution: {integrity: sha512-n6d8MOyUrNp6G4VSpRcgjs5xj4A91svJSaiwLIDWVWEsZtpN5FA9NlBbZHDmAJc2e8e6SF4tkBD3HAvPF+7igA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.19.11: + resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@floating-ui/core@1.5.3: + resolution: {integrity: sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==} + dependencies: + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/dom@1.5.4: + resolution: {integrity: sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==} + dependencies: + '@floating-ui/core': 1.5.3 + '@floating-ui/utils': 0.2.1 + dev: false + + /@floating-ui/react-dom@2.0.6(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-IB8aCRFxr8nFkdYZgH+Otd9EVQPJoynxeFRGTB8voPoZMRWo8XjYuCRgpI1btvuKY69XMiLnW+ym7zoBHM90Rw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.5.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + dev: false + + /@hono/node-server@1.4.0: + resolution: {integrity: sha512-bhDkhldW7w9VgjrX0gG1vJ2YyvTxFWd5WG9nHjSR4UauhVECQZC3qy7mVVuQ054I5NWhKttHfKzYfoPzmUzAjw==} + engines: {node: '>=18.14.1'} + dev: false + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: false + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.22 + dev: false + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: false + + /@jridgewell/trace-mapping@0.3.22: + resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@mdx-js/mdx@3.0.0: + resolution: {integrity: sha512-Icm0TBKBLYqroYbNW3BPnzMGn+7mwpQOK310aZ7+fkCtiU3aqv2cdcX+nd0Ydo3wI5Rx8bX2Z2QmGb/XcAClCw==} + dependencies: + '@types/estree': 1.0.5 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdx': 2.0.10 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-build-jsx: 3.0.1 + estree-util-is-identifier-name: 3.0.0 + estree-util-to-js: 2.0.0 + estree-walker: 3.0.3 + hast-util-to-estree: 3.1.0 + hast-util-to-jsx-runtime: 2.3.0 + markdown-extensions: 2.0.0 + periscopic: 3.1.0 + remark-mdx: 3.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.0 + source-map: 0.7.4 + unified: 11.0.4 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@mdx-js/react@3.0.0(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-nDctevR9KyYFyV+m+/+S4cpzCWHqj+iHDHq3QrsWezcC+B17uZdIWgCguESUkwFhM3n/56KxWVE3V6EokrmONQ==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + dependencies: + '@types/mdx': 2.0.10 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@mdx-js/rollup@3.0.0(rollup@4.9.5): + resolution: {integrity: sha512-ITvGiwPGEBW+D7CCnpSA9brzAosIWHAi4y+Air8wgfLnez8aWue50avHtWMfnFLCp7vt+JQ9UM8nwfuQuuydxw==} + peerDependencies: + rollup: '>=2' + dependencies: + '@mdx-js/mdx': 3.0.0 + '@rollup/pluginutils': 5.1.0(rollup@4.9.5) + rollup: 4.9.5 + source-map: 0.7.4 + vfile: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@noble/hashes@1.3.3: + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + dev: false + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: false + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: false + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.16.0 + dev: false + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: false + optional: true + + /@popperjs/core@2.11.8: + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + dev: false + + /@radix-ui/colors@3.0.0: + resolution: {integrity: sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==} + dev: false + + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.23.8 + dev: false + + /@radix-ui/react-accordion@1.1.2(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collapsible': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-arrow@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-collapsible@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-collection@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0) + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-dismissable-layer@1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-icons@1.3.0(react@18.2.0): + resolution: {integrity: sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==} + peerDependencies: + react: ^16.x || ^17.x || ^18.x + dependencies: + react: 18.2.0 + dev: false + + /@radix-ui/react-id@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-label@2.0.2(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-navigation-menu@1.1.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-popover@1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0) + dev: false + + /@radix-ui/react-popper@1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@floating-ui/react-dom': 2.0.6(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-portal@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-presence@1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-primitive@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-roving-focus@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-slot@1.0.2(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-tabs@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + dev: false + + /@radix-ui/react-visually-hidden@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.8 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.48 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@radix-ui/rect@1.0.1: + resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} + dependencies: + '@babel/runtime': 7.23.8 + dev: false + + /@remix-run/router@1.14.2: + resolution: {integrity: sha512-ACXpdMM9hmKZww21yEqWwiLws/UPLhNKvimN8RrYSqPSvB3ov7sLvAcfvaxePeLvccTQKGdkDIhLYApZVDFuKg==} + engines: {node: '>=14.0.0'} + dev: false + + /@rollup/pluginutils@5.1.0(rollup@4.9.5): + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 4.9.5 + dev: false + + /@rollup/rollup-android-arm-eabi@4.9.5: + resolution: {integrity: sha512-idWaG8xeSRCfRq9KpRysDHJ/rEHBEXcHuJ82XY0yYFIWnLMjZv9vF/7DOq8djQ2n3Lk6+3qfSH8AqlmHlmi1MA==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-android-arm64@4.9.5: + resolution: {integrity: sha512-f14d7uhAMtsCGjAYwZGv6TwuS3IFaM4ZnGMUn3aCBgkcHAYErhV1Ad97WzBvS2o0aaDv4mVz+syiN0ElMyfBPg==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-arm64@4.9.5: + resolution: {integrity: sha512-ndoXeLx455FffL68OIUrVr89Xu1WLzAG4n65R8roDlCoYiQcGGg6MALvs2Ap9zs7AHg8mpHtMpwC8jBBjZrT/w==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-x64@4.9.5: + resolution: {integrity: sha512-UmElV1OY2m/1KEEqTlIjieKfVwRg0Zwg4PLgNf0s3glAHXBN99KLpw5A5lrSYCa1Kp63czTpVll2MAqbZYIHoA==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.9.5: + resolution: {integrity: sha512-Q0LcU61v92tQB6ae+udZvOyZ0wfpGojtAKrrpAaIqmJ7+psq4cMIhT/9lfV6UQIpeItnq/2QDROhNLo00lOD1g==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.9.5: + resolution: {integrity: sha512-dkRscpM+RrR2Ee3eOQmRWFjmV/payHEOrjyq1VZegRUa5OrZJ2MAxBNs05bZuY0YCtpqETDy1Ix4i/hRqX98cA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-musl@4.9.5: + resolution: {integrity: sha512-QaKFVOzzST2xzY4MAmiDmURagWLFh+zZtttuEnuNn19AiZ0T3fhPyjPPGwLNdiDT82ZE91hnfJsUiDwF9DClIQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.9.5: + resolution: {integrity: sha512-HeGqmRJuyVg6/X6MpE2ur7GbymBPS8Np0S/vQFHDmocfORT+Zt76qu+69NUoxXzGqVP1pzaY6QIi0FJWLC3OPA==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-gnu@4.9.5: + resolution: {integrity: sha512-Dq1bqBdLaZ1Gb/l2e5/+o3B18+8TI9ANlA1SkejZqDgdU/jK/ThYaMPMJpVMMXy2uRHvGKbkz9vheVGdq3cJfA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-musl@4.9.5: + resolution: {integrity: sha512-ezyFUOwldYpj7AbkwyW9AJ203peub81CaAIVvckdkyH8EvhEIoKzaMFJj0G4qYJ5sw3BpqhFrsCc30t54HV8vg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.9.5: + resolution: {integrity: sha512-aHSsMnUw+0UETB0Hlv7B/ZHOGY5bQdwMKJSzGfDfvyhnpmVxLMGnQPGNE9wgqkLUs3+gbG1Qx02S2LLfJ5GaRQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.9.5: + resolution: {integrity: sha512-AiqiLkb9KSf7Lj/o1U3SEP9Zn+5NuVKgFdRIZkvd4N0+bYrTOovVd0+LmYCPQGbocT4kvFyK+LXCDiXPBF3fyA==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-x64-msvc@4.9.5: + resolution: {integrity: sha512-1q+mykKE3Vot1kaFJIDoUFv5TuW+QQVaf2FmTT9krg86pQrGStOSJJ0Zil7CFagyxDuouTepzt5Y5TVzyajOdQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@types/acorn@4.0.6: + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + dependencies: + '@types/estree': 1.0.5 + dev: false + + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 + dev: false + + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + dev: false + + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + dependencies: + '@babel/types': 7.23.6 + dev: false + + /@types/debug@4.1.12: + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + dependencies: + '@types/ms': 0.7.34 + dev: false + + /@types/estree-jsx@1.0.3: + resolution: {integrity: sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==} + dependencies: + '@types/estree': 1.0.5 + dev: false + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: false + + /@types/hast@3.0.3: + resolution: {integrity: sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /@types/mdast@4.0.3: + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /@types/mdx@2.0.10: + resolution: {integrity: sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg==} + dev: false + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: false + + /@types/node@20.11.5: + resolution: {integrity: sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + dev: false + + /@types/react@18.2.48: + resolution: {integrity: sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==} + dependencies: + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 + csstype: 3.1.3 + dev: false + + /@types/scheduler@0.16.8: + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + dev: false + + /@types/unist@2.0.10: + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + dev: false + + /@types/unist@3.0.2: + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + dev: false + + /@typescript/vfs@1.5.0: + resolution: {integrity: sha512-AJS307bPgbsZZ9ggCT3wwpg3VbTKMFNHfaY/uF0ahSkYYrPF2dSSKDNIDIQAHm9qJqbLvCsSJH7yN4Vs/CsMMg==} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: false + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: false + + /@vanilla-extract/babel-plugin-debug-ids@1.0.4: + resolution: {integrity: sha512-mevYcVMwsT6960xnXRw/Rr2K7SOEwzwVBApg/2SJ3eg2KGsHfj1rN0oQ12WdoTT3RzThq+0551bVQKPvQnjeaA==} + dependencies: + '@babel/core': 7.23.7 + transitivePeerDependencies: + - supports-color + dev: false + + /@vanilla-extract/css@1.14.0: + resolution: {integrity: sha512-rYfm7JciWZ8PFzBM/HDiE2GLnKI3xJ6/vdmVJ5BSgcCZ5CxRlM9Cjqclni9lGzF3eMOijnUhCd/KV8TOzyzbMA==} + dependencies: + '@emotion/hash': 0.9.1 + '@vanilla-extract/private': 1.0.3 + chalk: 4.1.2 + css-what: 6.1.0 + cssesc: 3.0.0 + csstype: 3.1.3 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.0.1 + outdent: 0.8.0 + dev: false + + /@vanilla-extract/dynamic@2.1.0: + resolution: {integrity: sha512-8zl0IgBYRtgD1h+56Zu13wHTiMTJSVEa4F7RWX9vTB/5Xe2KtjoiqApy/szHPVFA56c+ex6A4GpCQjT1bKXbYw==} + dependencies: + '@vanilla-extract/private': 1.0.3 + dev: false + + /@vanilla-extract/integration@6.2.5: + resolution: {integrity: sha512-CK8KyxteNQZtUgo8TCMIYb93SD6vk5bWPPOco853Om2BoxqRV1MgAQkjSUVPR3XxVFl6BGyYLN7D++3+9/82/g==} + dependencies: + '@babel/core': 7.23.7 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.7) + '@vanilla-extract/babel-plugin-debug-ids': 1.0.4 + '@vanilla-extract/css': 1.14.0 + esbuild: 0.17.6 + eval: 0.1.8 + find-up: 5.0.0 + javascript-stringify: 2.1.0 + lodash: 4.17.21 + mlly: 1.5.0 + outdent: 0.8.0 + vite: 5.0.12 + vite-node: 1.2.1 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /@vanilla-extract/private@1.0.3: + resolution: {integrity: sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==} + dev: false + + /@vitejs/plugin-react@4.2.0(vite@5.0.12): + resolution: {integrity: sha512-+MHTH/e6H12kRp5HUkzOGqPMksezRMmW+TNzlh/QXfI8rRf6l2Z2yH/v12no1UvTwhZgEDMuQ7g7rrfMseU6FQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + dependencies: + '@babel/core': 7.23.7 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.0.12 + transitivePeerDependencies: + - supports-color + dev: false + + /@vocs/vanilla-extract-vite-plugin@3.9.3-0(vite@5.0.12): + resolution: {integrity: sha512-FfsRecpuCKWcLK9SIk3AOHPkSPmatYb7D/EsK+RkK4CJCc7TCOcOhiiCA4h/0EVyX+AfxUlKmAuJKktED0tx1w==} + peerDependencies: + vite: ^2.2.3 || ^3.0.0 || ^4.0.3 || ^5.0.0 + dependencies: + '@vanilla-extract/integration': 6.2.5 + outdent: 0.8.0 + postcss: 8.4.33 + postcss-load-config: 4.0.2(postcss@8.4.33) + vite: 5.0.12 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + dev: false + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: false + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: false + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: false + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: false + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: false + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: false + + /aria-hidden@1.2.3: + resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + engines: {node: '>=10'} + dependencies: + tslib: 2.6.2 + dev: false + + /astring@1.8.6: + resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + hasBin: true + dev: false + + /autoprefixer@10.4.17(postcss@8.4.33): + resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.22.2 + caniuse-lite: 1.0.30001579 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.33 + postcss-value-parser: 4.2.0 + dev: false + + /bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: false + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: false + + /bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: false + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: false + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: false + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: false + + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001579 + electron-to-chromium: 1.4.640 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + dev: false + + /buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: false + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: false + + /camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + dev: false + + /caniuse-lite@1.0.30001579: + resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==} + dev: false + + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + dev: false + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: false + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: false + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: false + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: false + + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: false + + /character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + dev: false + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /chroma-js@2.4.2: + resolution: {integrity: sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==} + dev: false + + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: false + + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: false + + /clsx@2.1.0: + resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} + engines: {node: '>=6'} + dev: false + + /collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + dev: false + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: false + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: false + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: false + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: false + + /create-vocs@1.0.0-alpha.3: + resolution: {integrity: sha512-jP+KC26XcWVAFRbDt311V4fsHakTDxJ9cDyMSKmUpiqbp3mDs0WDeckiSzhf3qgpiHHHzcbuTmm4yDZgoFkddA==} + hasBin: true + dependencies: + '@clack/prompts': 0.7.0 + cac: 6.7.14 + detect-package-manager: 3.0.1 + fs-extra: 11.2.0 + picocolors: 1.0.0 + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: false + + /css-selector-parser@3.0.4: + resolution: {integrity: sha512-pnmS1dbKsz6KA4EW4BznyPL2xxkNDRg62hcD0v8g6DEw2W7hxOln5M953jsp9hmw5Dg57S6o/A8GOn37mbAgcQ==} + dev: false + + /css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: false + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dev: false + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: false + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: false + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: false + + /deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + dev: false + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: false + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: false + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: false + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: false + + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: false + + /detect-package-manager@3.0.1: + resolution: {integrity: sha512-qoHDH6+lMcpJPAScE7+5CYj91W0mxZNXTwZPrCqi1KMk+x+AoQScQ2V1QyqTln1rHU5Haq5fikvOGHv+leKD8A==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: false + + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dependencies: + dequal: 2.0.3 + dev: false + + /didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + dev: false + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: false + + /direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + dev: false + + /dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dev: false + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: false + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: false + + /electron-to-chromium@1.4.640: + resolution: {integrity: sha512-z/6oZ/Muqk4BaE7P69bXhUhpJbUM9ZJeka43ZwxsDshKtePns4mhBlh8bU5+yrnOnz3fhG82XLzGUXazOmsWnA==} + dev: false + + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: false + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: false + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: false + + /esbuild@0.17.6: + resolution: {integrity: sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.6 + '@esbuild/android-arm64': 0.17.6 + '@esbuild/android-x64': 0.17.6 + '@esbuild/darwin-arm64': 0.17.6 + '@esbuild/darwin-x64': 0.17.6 + '@esbuild/freebsd-arm64': 0.17.6 + '@esbuild/freebsd-x64': 0.17.6 + '@esbuild/linux-arm': 0.17.6 + '@esbuild/linux-arm64': 0.17.6 + '@esbuild/linux-ia32': 0.17.6 + '@esbuild/linux-loong64': 0.17.6 + '@esbuild/linux-mips64el': 0.17.6 + '@esbuild/linux-ppc64': 0.17.6 + '@esbuild/linux-riscv64': 0.17.6 + '@esbuild/linux-s390x': 0.17.6 + '@esbuild/linux-x64': 0.17.6 + '@esbuild/netbsd-x64': 0.17.6 + '@esbuild/openbsd-x64': 0.17.6 + '@esbuild/sunos-x64': 0.17.6 + '@esbuild/win32-arm64': 0.17.6 + '@esbuild/win32-ia32': 0.17.6 + '@esbuild/win32-x64': 0.17.6 + dev: false + + /esbuild@0.19.11: + resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.11 + '@esbuild/android-arm': 0.19.11 + '@esbuild/android-arm64': 0.19.11 + '@esbuild/android-x64': 0.19.11 + '@esbuild/darwin-arm64': 0.19.11 + '@esbuild/darwin-x64': 0.19.11 + '@esbuild/freebsd-arm64': 0.19.11 + '@esbuild/freebsd-x64': 0.19.11 + '@esbuild/linux-arm': 0.19.11 + '@esbuild/linux-arm64': 0.19.11 + '@esbuild/linux-ia32': 0.19.11 + '@esbuild/linux-loong64': 0.19.11 + '@esbuild/linux-mips64el': 0.19.11 + '@esbuild/linux-ppc64': 0.19.11 + '@esbuild/linux-riscv64': 0.19.11 + '@esbuild/linux-s390x': 0.19.11 + '@esbuild/linux-x64': 0.19.11 + '@esbuild/netbsd-x64': 0.19.11 + '@esbuild/openbsd-x64': 0.19.11 + '@esbuild/sunos-x64': 0.19.11 + '@esbuild/win32-arm64': 0.19.11 + '@esbuild/win32-ia32': 0.19.11 + '@esbuild/win32-x64': 0.19.11 + dev: false + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: false + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: false + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: false + + /estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + dependencies: + '@types/estree': 1.0.5 + dev: false + + /estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + dependencies: + '@types/estree-jsx': 1.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + dev: false + + /estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + dev: false + + /estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + dependencies: + '@types/estree-jsx': 1.0.3 + astring: 1.8.6 + source-map: 0.7.4 + dev: false + + /estree-util-value-to-estree@3.0.1: + resolution: {integrity: sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==} + engines: {node: '>=16.0.0'} + dependencies: + '@types/estree': 1.0.5 + is-plain-obj: 4.1.0 + dev: false + + /estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/unist': 3.0.2 + dev: false + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: false + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + dev: false + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false + + /eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + dependencies: + '@types/node': 20.11.5 + require-like: 0.1.2 + dev: false + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: false + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: false + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: false + + /fastq@1.16.0: + resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + dependencies: + reusify: 1.0.4 + dev: false + + /fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + dependencies: + format: 0.2.2 + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: false + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: false + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: false + + /format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + dev: false + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: false + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: false + + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: false + + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: false + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: false + + /github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + dev: false + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: false + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: false + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 + minipass: 7.0.4 + path-scurry: 1.10.1 + dev: false + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: false + + /globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.0 + merge2: 1.4.1 + slash: 4.0.0 + dev: false + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: false + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: false + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: false + + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: false + + /hast-util-classnames@3.0.0: + resolution: {integrity: sha512-tI3JjoGDEBVorMAWK4jNRsfLMYmih1BUOG3VV36pH36njs1IEl7xkNrVTD2mD2yYHmQCa5R/fj61a8IAF4bRaQ==} + dependencies: + '@types/hast': 3.0.3 + space-separated-tokens: 2.0.2 + dev: false + + /hast-util-from-html@2.0.1: + resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==} + dependencies: + '@types/hast': 3.0.3 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.1 + parse5: 7.1.2 + vfile: 6.0.1 + vfile-message: 4.0.2 + dev: false + + /hast-util-from-parse5@8.0.1: + resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} + dependencies: + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + devlop: 1.1.0 + hastscript: 8.0.0 + property-information: 6.4.0 + vfile: 6.0.1 + vfile-location: 5.0.2 + web-namespaces: 2.0.1 + dev: false + + /hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hast-util-select@6.0.2: + resolution: {integrity: sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==} + dependencies: + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.0.4 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.0 + hast-util-whitespace: 3.0.0 + not: 0.1.0 + nth-check: 2.1.1 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + dev: false + + /hast-util-to-estree@3.1.0: + resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} + dependencies: + '@types/estree': 1.0.5 + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.4 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /hast-util-to-jsx-runtime@2.3.0: + resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} + dependencies: + '@types/estree': 1.0.5 + '@types/hast': 3.0.3 + '@types/unist': 3.0.2 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + style-to-object: 1.0.5 + unist-util-position: 5.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /hast-util-to-string@3.0.0: + resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + dependencies: + '@types/hast': 3.0.3 + dev: false + + /hastscript@8.0.0: + resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + dependencies: + '@types/hast': 3.0.3 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.4.0 + space-separated-tokens: 2.0.2 + dev: false + + /hono@3.12.6: + resolution: {integrity: sha512-nnLMJbBA8k+tW8XD1Xt0BfNmJswppYF2pSOVo5U3DdU72SPYUjFkPg7/Q9KfkNcsrXzxFdJQ00JYjPGancmOOA==} + engines: {node: '>=16.0.0'} + dev: false + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: false + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: false + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} + engines: {node: '>= 4'} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + dev: false + + /inline-style-parser@0.2.2: + resolution: {integrity: sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==} + dev: false + + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + dev: false + + /is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + dev: false + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: false + + /is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + dev: false + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + dev: false + + /is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + dev: false + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: false + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: false + + /is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + dev: false + + /is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: false + + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: false + + /is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + dependencies: + '@types/estree': 1.0.5 + dev: false + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false + + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: false + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: false + + /javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + dev: false + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: false + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: false + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: false + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + dev: false + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: false + + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: false + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: false + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: false + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false + + /log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + dev: false + + /longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + dev: false + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: false + + /lru-cache@10.1.0: + resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} + engines: {node: 14 || >=16.14} + dev: false + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: false + + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + dev: false + + /markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + dev: false + + /markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + dev: false + + /mdast-util-directive@3.0.0: + resolution: {integrity: sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.3 + unist-util-visit-parents: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + dependencies: + '@types/mdast': 4.0.3 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: false + + /mdast-util-from-markdown@2.0.0: + resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + dependencies: + '@types/mdast': 4.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.0.1 + dev: false + + /mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + dependencies: + mdast-util-from-markdown: 2.0.0 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx-expression@2.0.0: + resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx-jsx@3.0.0: + resolution: {integrity: sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.3 + unist-util-remove-position: 5.0.0 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + dependencies: + mdast-util-from-markdown: 2.0.0 + mdast-util-mdx-expression: 2.0.0 + mdast-util-mdx-jsx: 3.0.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + dependencies: + '@types/estree-jsx': 1.0.3 + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: false + + /mdast-util-phrasing@4.0.0: + resolution: {integrity: sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==} + dependencies: + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 + dev: false + + /mdast-util-to-hast@13.1.0: + resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + dependencies: + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + dev: false + + /mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.0.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + dev: false + + /mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + dependencies: + '@types/mdast': 4.0.3 + dev: false + + /media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + dependencies: + '@babel/runtime': 7.23.8 + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: false + + /micromark-core-commonmark@2.0.0: + resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-directive@3.0.0: + resolution: {integrity: sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==} + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + parse-entities: 4.0.1 + dev: false + + /micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} + dependencies: + fault: 2.0.1 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==} + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-table@2.0.0: + resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==} + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + dependencies: + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm-task-list-item@2.0.1: + resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==} + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + dependencies: + micromark-extension-gfm-autolink-literal: 2.0.0 + micromark-extension-gfm-footnote: 2.0.0 + micromark-extension-gfm-strikethrough: 2.0.0 + micromark-extension-gfm-table: 2.0.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.0.1 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdx-expression@3.0.0: + resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} + dependencies: + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdx-jsx@3.0.0: + resolution: {integrity: sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + dependencies: + micromark-util-types: 2.0.0 + dev: false + + /micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + dependencies: + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + micromark-extension-mdx-expression: 3.0.0 + micromark-extension-mdx-jsx: 3.0.0 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-mdx-expression@2.0.1: + resolution: {integrity: sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==} + dependencies: + '@types/estree': 1.0.5 + devlop: 1.1.0 + micromark-util-character: 2.0.1 + micromark-util-events-to-acorn: 2.0.2 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-character@2.0.1: + resolution: {integrity: sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==} + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + dev: false + + /micromark-util-events-to-acorn@2.0.2: + resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.5 + '@types/unist': 3.0.2 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + vfile-message: 4.0.2 + dev: false + + /micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + dev: false + + /micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + dependencies: + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + dependencies: + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + dependencies: + micromark-util-character: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-subtokenize@2.0.0: + resolution: {integrity: sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==} + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + dev: false + + /micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + dev: false + + /micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.0.1 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: false + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: false + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: false + + /minisearch@6.3.0: + resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} + dev: false + + /mlly@1.5.0: + resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.3.2 + dev: false + + /modern-ahocorasick@1.0.1: + resolution: {integrity: sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==} + dev: false + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: false + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: false + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: false + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: false + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: false + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: false + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: false + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: false + + /not@0.1.0: + resolution: {integrity: sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==} + dev: false + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: false + + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: false + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: false + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: false + + /on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: false + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: false + + /ora@7.0.1: + resolution: {integrity: sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==} + engines: {node: '>=16'} + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + stdin-discarder: 0.1.0 + string-width: 6.1.0 + strip-ansi: 7.1.0 + dev: false + + /outdent@0.8.0: + resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: false + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: false + + /parse-entities@4.0.1: + resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + dependencies: + '@types/unist': 2.0.10 + character-entities: 2.0.2 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.0.2 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + dev: false + + /parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + dev: false + + /parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + dependencies: + entities: 4.5.0 + dev: false + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: false + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: false + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: false + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.1.0 + minipass: 7.0.4 + dev: false + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: false + + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + + /periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + dependencies: + '@types/estree': 1.0.5 + estree-walker: 3.0.3 + is-reference: 3.0.2 + dev: false + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: false + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: false + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: false + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.5.0 + pathe: 1.1.2 + dev: false + + /postcss-import@15.1.0(postcss@8.4.33): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.33 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + dev: false + + /postcss-js@4.0.1(postcss@8.4.33): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.33 + dev: false + + /postcss-load-config@4.0.2(postcss@8.4.33): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 3.0.0 + postcss: 8.4.33 + yaml: 2.3.4 + dev: false + + /postcss-nested@6.0.1(postcss@8.4.33): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.33 + postcss-selector-parser: 6.0.15 + dev: false + + /postcss-selector-parser@6.0.15: + resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: false + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: false + + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: false + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: false + + /property-information@6.4.0: + resolution: {integrity: sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ==} + dev: false + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: false + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + dev: false + + /react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + dev: false + + /react-helmet@6.1.0(react@18.2.0): + resolution: {integrity: sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==} + peerDependencies: + react: '>=16.3.0' + dependencies: + object-assign: 4.1.1 + prop-types: 15.8.1 + react: 18.2.0 + react-fast-compare: 3.2.2 + react-side-effect: 2.1.2(react@18.2.0) + dev: false + + /react-intersection-observer@9.5.3(react@18.2.0): + resolution: {integrity: sha512-NJzagSdUPS5rPhaLsHXYeJbsvdpbJwL6yCHtMk91hc0ufQ2BnXis+0QQ9NBh6n9n+Q3OyjR6OQLShYbaNBkThQ==} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: false + + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: false + + /react-remove-scroll-bar@2.3.4(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.48 + react: 18.2.0 + react-style-singleton: 2.2.1(@types/react@18.2.48)(react@18.2.0) + tslib: 2.6.2 + dev: false + + /react-remove-scroll@2.5.5(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.48 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4(@types/react@18.2.48)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.48)(react@18.2.0) + tslib: 2.6.2 + use-callback-ref: 1.3.1(@types/react@18.2.48)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.48)(react@18.2.0) + dev: false + + /react-router-dom@6.21.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-kNzubk7n4YHSrErzjLK72j0B5i969GsuCGazRl3G6j1zqZBLjuSlYBdVdkDOgzGdPIffUOc9nmgiadTEVoq91g==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.14.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.21.3(react@18.2.0) + dev: false + + /react-router@6.21.3(react@18.2.0): + resolution: {integrity: sha512-a0H638ZXULv1OdkmiK6s6itNhoy33ywxmUFT/xtSoVyf9VnC7n7+VT4LjVzdIHSaF5TIh9ylUgxMXksHTgGrKg==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.14.2 + react: 18.2.0 + dev: false + + /react-side-effect@2.1.2(react@18.2.0): + resolution: {integrity: sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==} + peerDependencies: + react: ^16.3.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: false + + /react-style-singleton@2.2.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.48 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: false + + /read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + dependencies: + pify: 2.3.0 + dev: false + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: false + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: false + + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false + + /rehype-autolink-headings@7.1.0: + resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} + dependencies: + '@types/hast': 3.0.3 + '@ungap/structured-clone': 1.2.0 + hast-util-heading-rank: 3.0.0 + hast-util-is-element: 3.0.0 + unified: 11.0.4 + unist-util-visit: 5.0.0 + dev: false + + /rehype-class-names@1.0.14: + resolution: {integrity: sha512-eFBt6Qxb7K77y6P82tUtN9rKpU7guWlaK4XA4RrrSFHkUTCvr2D3cgb9OR5d4t1AaGOvR59FH9nRwUnbpn9AEg==} + dependencies: + '@types/hast': 3.0.3 + hast-util-classnames: 3.0.0 + hast-util-select: 6.0.2 + unified: 10.1.2 + dev: false + + /rehype-parse@9.0.0: + resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==} + dependencies: + '@types/hast': 3.0.3 + hast-util-from-html: 2.0.1 + unified: 11.0.4 + dev: false + + /rehype-pretty-code@0.12.5(shikiji@0.10.0-beta.9): + resolution: {integrity: sha512-EnLi5MrL9PROc2jfEnp6bAT+ui/k/uixg6dAT35LA1V2xq0RCpgZYD8bWbpaAUnyAgVfgsmKgXbjCqAJejFc+w==} + engines: {node: '>=18'} + peerDependencies: + shikiji: ^0.7.0 || ^0.8.0 || ^0.9.0 + dependencies: + '@types/hast': 3.0.3 + hast-util-to-string: 3.0.0 + parse-numeric-range: 1.3.0 + rehype-parse: 9.0.0 + shikiji: 0.10.0-beta.9 + unified: 11.0.4 + unist-util-visit: 5.0.0 + dev: false + + /rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + dependencies: + '@types/hast': 3.0.3 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.0 + unist-util-visit: 5.0.0 + dev: false + + /remark-directive@3.0.0: + resolution: {integrity: sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-directive: 3.0.0 + micromark-extension-directive: 3.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-frontmatter@5.0.0: + resolution: {integrity: sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-frontmatter: 2.0.1 + micromark-extension-frontmatter: 2.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-gfm@4.0.0: + resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-mdx-frontmatter@4.0.0: + resolution: {integrity: sha512-PZzAiDGOEfv1Ua7exQ8S5kKxkD8CDaSb4nM+1Mprs6u8dyvQifakh+kCj6NovfGXW+bTvrhjaR3srzjS2qJHKg==} + dependencies: + '@types/mdast': 4.0.3 + estree-util-is-identifier-name: 3.0.0 + estree-util-value-to-estree: 3.0.1 + toml: 3.0.0 + unified: 11.0.4 + yaml: 2.3.4 + dev: false + + /remark-mdx@3.0.0: + resolution: {integrity: sha512-O7yfjuC6ra3NHPbRVxfflafAj3LTwx3b73aBvkEFU5z4PsD6FD4vrqJAkE5iNGLz71GdjXfgRqm3SQ0h0VuE7g==} + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.0 + micromark-util-types: 2.0.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + dev: false + + /remark-rehype@11.1.0: + resolution: {integrity: sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==} + dependencies: + '@types/hast': 3.0.3 + '@types/mdast': 4.0.3 + mdast-util-to-hast: 13.1.0 + unified: 11.0.4 + vfile: 6.0.1 + dev: false + + /remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + dependencies: + '@types/mdast': 4.0.3 + mdast-util-to-markdown: 2.1.0 + unified: 11.0.4 + dev: false + + /require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + dev: false + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: false + + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: false + + /rollup@4.9.5: + resolution: {integrity: sha512-E4vQW0H/mbNMw2yLSqJyjtkHY9dslf/p0zuT1xehNRqUTBOFMqEjguDvqhXr7N7r/4ttb2jr4T41d3dncmIgbQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.9.5 + '@rollup/rollup-android-arm64': 4.9.5 + '@rollup/rollup-darwin-arm64': 4.9.5 + '@rollup/rollup-darwin-x64': 4.9.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.9.5 + '@rollup/rollup-linux-arm64-gnu': 4.9.5 + '@rollup/rollup-linux-arm64-musl': 4.9.5 + '@rollup/rollup-linux-riscv64-gnu': 4.9.5 + '@rollup/rollup-linux-x64-gnu': 4.9.5 + '@rollup/rollup-linux-x64-musl': 4.9.5 + '@rollup/rollup-win32-arm64-msvc': 4.9.5 + '@rollup/rollup-win32-ia32-msvc': 4.9.5 + '@rollup/rollup-win32-x64-msvc': 4.9.5 + fsevents: 2.3.3 + dev: false + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: false + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: false + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: false + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: false + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: false + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: false + + /shikiji-core@0.10.0-beta.9: + resolution: {integrity: sha512-7dgwTyN9PeKyc4KJeyKo/qW8gi8XbR//c1CO+0B5GaeozWexNTpEL/tSohyIKkj0Z+7spfm2REmAaS39NlC4Lw==} + dev: false + + /shikiji-transformers@0.10.0-beta.9: + resolution: {integrity: sha512-giqkVspbFtl7wwX1k/wcz+MKEHFlfEAxAkk+d7hU3XfPeLf38TTbTH0zEzr2cPfCZNnL6AN1uRkMnbDchjhKMw==} + dependencies: + shikiji: 0.10.0-beta.9 + dev: false + + /shikiji-twoslash@0.10.0-beta.9(typescript@5.3.3): + resolution: {integrity: sha512-VZNysft2sky0I5p4xCwoJ4BN1VxtRrY+aBu20hYGbX5IetUZl0jDFtdpNC32GUUhOddx/gy0X/fSCoomv0FE2Q==} + dependencies: + shikiji-core: 0.10.0-beta.9 + twoslash: 0.0.11(typescript@5.3.3) + transitivePeerDependencies: + - supports-color + - typescript + dev: false + + /shikiji@0.10.0-beta.9: + resolution: {integrity: sha512-I+sv642n9M7/FK/dVcXp9vMv7v5Wa8gU2UuKwkIWKQFvyo+qKB8eV1zNNtRYas+jC7BLwdAaflc5BFUozAonFQ==} + dependencies: + shikiji-core: 0.10.0-beta.9 + dev: false + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: false + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: false + + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: false + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: false + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: false + + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: false + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: false + + /stdin-discarder@0.1.0: + resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.1.0 + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: false + + /string-width@6.1.0: + resolution: {integrity: sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==} + engines: {node: '>=16'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 10.3.0 + strip-ansi: 7.1.0 + dev: false + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /stringify-entities@4.0.3: + resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: false + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: false + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: false + + /style-to-object@0.4.4: + resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} + dependencies: + inline-style-parser: 0.1.1 + dev: false + + /style-to-object@1.0.5: + resolution: {integrity: sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==} + dependencies: + inline-style-parser: 0.2.2 + dev: false + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: false + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: false + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: false + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /tailwindcss@3.4.1: + resolution: {integrity: sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.5.3 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.0 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.33 + postcss-import: 15.1.0(postcss@8.4.33) + postcss-js: 4.0.1(postcss@8.4.33) + postcss-load-config: 4.0.2(postcss@8.4.33) + postcss-nested: 6.0.1(postcss@8.4.33) + postcss-selector-parser: 6.0.15 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + dev: false + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: false + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: false + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: false + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: false + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: false + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: false + + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + dev: false + + /trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + dev: false + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: false + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: false + + /twoslash@0.0.11(typescript@5.3.3): + resolution: {integrity: sha512-XCxpr8Of+swV66Ox5aTqkozax6tFjJrfP0UZrGNaKlqHDyvY1gUNZE2lUqj9phyF4cKoo/LxzOhkQw7zBmRyVw==} + peerDependencies: + typescript: '*' + dependencies: + '@typescript/vfs': 1.5.0 + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: false + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /ua-parser-js@1.0.37: + resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} + dev: false + + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + dev: false + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + + /unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + dependencies: + '@types/unist': 2.0.10 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 5.3.7 + dev: false + + /unified@11.0.4: + resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + dependencies: + '@types/unist': 3.0.2 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 6.0.1 + dev: false + + /unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + dependencies: + '@types/unist': 3.0.2 + unist-util-visit: 5.0.0 + dev: false + + /unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + dependencies: + '@types/unist': 2.0.10 + dev: false + + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + dev: false + + /unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: false + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + dev: false + + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: false + + /use-callback-ref@1.3.1(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.48 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /use-sidecar@1.1.2(@types/react@18.2.48)(react@18.2.0): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.48 + detect-node-es: 1.1.0 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: false + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: false + + /vfile-location@5.0.2: + resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} + dependencies: + '@types/unist': 3.0.2 + vfile: 6.0.1 + dev: false + + /vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + dependencies: + '@types/unist': 2.0.10 + unist-util-stringify-position: 3.0.3 + dev: false + + /vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + dev: false + + /vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + dependencies: + '@types/unist': 2.0.10 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + dev: false + + /vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + dev: false + + /vite-node@1.2.1: + resolution: {integrity: sha512-fNzHmQUSOY+y30naohBvSW7pPn/xn3Ib/uqm+5wAJQJiqQsU0NBR78XdRJb04l4bOFKjpTWld0XAfkKlrDbySg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.0.12 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /vite@5.0.12: + resolution: {integrity: sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.19.11 + postcss: 8.4.33 + rollup: 4.9.5 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /vocs@1.0.0-alpha.25(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)(rollup@4.9.5)(typescript@5.3.3): + resolution: {integrity: sha512-oqJh2XCjq1WI6g809YLPEAzeYBabLAvOxVZCvJwTmZpSxDlaD4XdDOUWefXNscg72/L98jp9DFwUB3G7p6IbFg==} + hasBin: true + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + '@hono/node-server': 1.4.0 + '@mdx-js/react': 3.0.0(@types/react@18.2.48)(react@18.2.0) + '@mdx-js/rollup': 3.0.0(rollup@4.9.5) + '@noble/hashes': 1.3.3 + '@popperjs/core': 2.11.8 + '@radix-ui/colors': 3.0.0 + '@radix-ui/react-accordion': 1.1.2(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-icons': 1.3.0(react@18.2.0) + '@radix-ui/react-label': 2.0.2(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-navigation-menu': 1.1.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-popover': 1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tabs': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0) + '@vanilla-extract/css': 1.14.0 + '@vanilla-extract/dynamic': 2.1.0 + '@vitejs/plugin-react': 4.2.0(vite@5.0.12) + '@vocs/vanilla-extract-vite-plugin': 3.9.3-0(vite@5.0.12) + autoprefixer: 10.4.17(postcss@8.4.33) + cac: 6.7.14 + chroma-js: 2.4.2 + clsx: 2.1.0 + compression: 1.7.4 + create-vocs: 1.0.0-alpha.3 + fs-extra: 11.2.0 + globby: 13.2.2 + hastscript: 8.0.0 + hono: 3.12.6 + mark.js: 8.11.1 + mdast-util-directive: 3.0.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-gfm: 3.0.0 + mdast-util-to-hast: 13.1.0 + minimatch: 9.0.3 + minisearch: 6.3.0 + ora: 7.0.1 + postcss: 8.4.33 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-helmet: 6.1.0(react@18.2.0) + react-intersection-observer: 9.5.3(react@18.2.0) + react-router-dom: 6.21.3(react-dom@18.2.0)(react@18.2.0) + rehype-autolink-headings: 7.1.0 + rehype-class-names: 1.0.14 + rehype-pretty-code: 0.12.5(shikiji@0.10.0-beta.9) + rehype-slug: 6.0.0 + remark-directive: 3.0.0 + remark-frontmatter: 5.0.0 + remark-gfm: 4.0.0 + remark-mdx-frontmatter: 4.0.0 + remark-parse: 11.0.0 + serve-static: 1.15.0 + shikiji: 0.10.0-beta.9 + shikiji-transformers: 0.10.0-beta.9 + shikiji-twoslash: 0.10.0-beta.9(typescript@5.3.3) + tailwindcss: 3.4.1 + toml: 3.0.0 + twoslash: 0.0.11(typescript@5.3.3) + ua-parser-js: 1.0.37 + unified: 11.0.4 + unist-util-visit: 5.0.0 + vite: 5.0.12 + transitivePeerDependencies: + - '@types/node' + - '@types/react' + - '@types/react-dom' + - less + - lightningcss + - rollup + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + - typescript + dev: false + + /web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + dev: false + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: false + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + dev: false + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: false + + /yaml@2.3.4: + resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + engines: {node: '>= 14'} + dev: false + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: false + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: false diff --git a/dojo-book/tsconfig.json b/dojo-book/tsconfig.json new file mode 100644 index 00000000..d2636aac --- /dev/null +++ b/dojo-book/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["**/*.ts", "**/*.tsx"] +} diff --git a/dojo-book/vocs.config.ts b/dojo-book/vocs.config.ts new file mode 100644 index 00000000..3d008a95 --- /dev/null +++ b/dojo-book/vocs.config.ts @@ -0,0 +1,203 @@ +import { defineConfig } from "vocs"; + +export default defineConfig({ + iconUrl: "/dojo-mark-full-dark.svg", + ogImageUrl: + "https://vocs.dev/api/og?logo=%logo&title=%title&description=%description", + topNav: [ + { text: "Blog", link: "https://www.dojoengine.org/en/articles" }, + { text: "Releases", link: "https://github.com/dojoengine/dojo/releases" }, + { + text: "0.5.0", + items: [ + { + text: "Changelog", + link: "https://github.com/wevm/vocs/blob/main/src/CHANGELOG.md", + }, + { + text: "Contributing", + link: "https://github.com/wevm/vocs/blob/main/.github/CONTRIBUTING.md", + }, + ], + }, + ], + font: { + google: "Poppins", + }, + // theme: { + + // accentColor: "#", + // }, + theme: { + accentColor: "#FF2F42", + variables: { + color: { + background: { + light: "white", + dark: "black", + }, + }, + content: { + horizontalPadding: "40px", + verticalPadding: "80px", + }, + }, + }, + sidebar: [ + { + text: "🏁 Theory", + collapsed: true, + items: [ + { text: "Foreword", link: "/getting-started" }, + { text: "What is Dojo?", link: "/theory/what-is-dojo" }, + { text: "AW Theory", link: "/theory/autonomous-worlds" }, + { text: "Cairo Ecosystem", link: "/theory/cairo" }, + { text: "FAQs", link: "/theory/faqs" }, + ], + }, + { + text: "πŸš€ Getting Started", + collapsed: true, + items: [ + { text: "Quick Start", link: "/getting-started/quick-start" }, + { text: "Manual Install", link: "/getting-started/from-source" }, + { text: "Development Setup", link: "/getting-started/setup" }, + { text: "Contributing", link: "/getting-started/contributing" }, + ], + }, + { + text: "πŸ«‚ Community", + link: "/community/get-started", + }, + { + text: "πŸ›οΈ Architecture", + collapsed: true, + items: [ + { text: "Overview", link: "/cairo/overview" }, + { text: "World", link: "/cairo/world" }, + { text: "Systems", link: "/cairo/systems" }, + { text: "Models", link: "/cairo/models" }, + { text: "Commands", link: "/cairo/commands" }, + { text: "Config", link: "/cairo/config" }, + { text: "Events", link: "/cairo/events" }, + { text: "Authorization", link: "/cairo/authorization" }, + { text: "Metadata", link: "/cairo/metadata" }, + { text: "Enum", link: "/cairo/enum" }, + { text: "Migration", link: "/cairo/migration" }, + { + text: "0.2.0 -> 0.3.0", + link: "/cairo/migration/0.3.0", + }, + { text: "ECS in 15 minutes", link: "/cairo/hello-dojo" }, + { text: "Entities", link: "/cairo/entities" }, + { text: "Testing", link: "/cairo/testing" }, + ], + }, + { + text: "πŸ–₯️ Client SDKs + Origami", + collapsed: true, + items: [ + { text: "Origami", link: "/cairo/origami" }, + { + text: "SDKs", + link: "/client/overview", + items: [ + { text: "dojo.js", link: "/client/sdk/dojojs" }, + { text: "unity", link: "/client/sdk/unity" }, + { text: "c", link: "/client/sdk/c" }, + ], + }, + ], + }, + { + text: "⛓️ Toolchain", + collapsed: true, + items: [ + { text: "Dojoup", link: "/toolchain/dojoup" }, + { + text: "Sozo", + link: "/toolchain/sozo/overview", + items: [ + { text: "Reference", link: "/toolchain/sozo/reference" }, + { text: "profile", link: "/toolchain/sozo/common-options/profile" }, + { text: "offline", link: "/toolchain/sozo/common-options/offline" }, + { text: "init", link: "/toolchain/sozo/project-commands/init" }, + { text: "build", link: "/toolchain/sozo/project-commands/build" }, + { text: "test", link: "/toolchain/sozo/project-commands/test" }, + { + text: "migrate", + link: "/toolchain/sozo/project-commands/migrate", + }, + { text: "execute", link: "/toolchain/sozo/world-commands/execute" }, + { + text: "register", + link: "/toolchain/sozo/world-commands/register", + }, + { text: "system", link: "/toolchain/sozo/world-commands/system" }, + { text: "model", link: "/toolchain/sozo/world-commands/model" }, + { text: "events", link: "/toolchain/sozo/world-commands/events" }, + { text: "auth", link: "/toolchain/sozo/world-commands/auth" }, + ], + }, + { + text: "Katana", + link: "/toolchain/katana/overview", + items: [{ text: "Reference", link: "/toolchain/katana/reference" }], + }, + { + text: "Torii", + link: "/toolchain/torii/overview", + items: [ + { text: "Reference", link: "/toolchain/torii/reference" }, + { text: "Graphql", link: "/toolchain/torii/graphql" }, + { text: "gRPC", link: "/toolchain/torii/grpc" }, + ], + }, + { + text: "Slot", + link: "/toolchain/slot/overview", + items: [ + { text: "Reference", link: "/toolchain/slot/reference" }, + { + text: "Deployments", + link: "/toolchain/slot/deployments-commands/deployments", + }, + ], + }, + ], + }, + { + text: "🌌 Deploying", + collapsed: true, + items: [ + { text: "Locally", link: "/deployment/locally" }, + { text: "Remote", link: "/deployment/remote" }, + ], + }, + { + text: "πŸ™Œ Tutorial", + collapsed: true, + items: [ + { + text: "Onchain Chess", + link: "/tutorial/onchain-chess/README", + items: [ + { text: "0. Setup", link: "/tutorial/onchain-chess/0-setup" }, + { text: "1. Initiate", link: "/tutorial/onchain-chess/1-action" }, + { text: "2. Move", link: "/tutorial/onchain-chess/2-move" }, + { text: "3. Test Chess", link: "/tutorial/onchain-chess/3-test" }, + ], + }, + { + text: "Deploy using Slot", + link: "/tutorial/deploy-using-slot/main", + }, + ], + }, + { + text: "Contributors", + link: "/misc/contributors", + }, + ], + title: "Dojo Book", +}); diff --git a/readme.md b/readme.md index 3d286de1..b9a6ae23 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,7 @@ ## πŸ“– The Dojo Book +> Migration from rustbook to vocs in process. Make all edits and PRs into dojo-book. + Explore the world of Autonomous Worlds with Dojo, your trusted toolchain. [Dive in now](https://book.dojoengine.org/). ### Contributing @@ -7,62 +9,3 @@ Explore the world of Autonomous Worlds with Dojo, your trusted toolchain. [Dive Embrace the open-source spirit of Dojo. As it's in its nascent phase, we welcome contributors with open arms. Peruse our [contributing guidelines](./src/misc/contributors.md). From minor wording adjustments to extensive chapters, every contribution matters! - -### Setup - -1. **Rust-related Packages**: - - Obtain the `cargo` toolchain via [rustup](https://rustup.rs/). - - Get [mdBook](https://rust-lang.github.io/mdBook/guide/installation.html) and its translation extension with the command: - `cargo install mdbook mdbook-i18n-helpers` -2. **Host Machine Packages**: - - To assist with translations, install [gettext](https://www.gnu.org/software/gettext/). It's typically accessible via most package managers. Use: `sudo apt install gettext`. -3. Clone this repository to get started. - -### Working Locally (English - Primary Language) - -Always edit Markdown files in English. Here's how to work on it: - -- Spin up a local server using `mdbook serve`. Navigate to [localhost:3000](http://localhost:3000). For an automated browser launch, append the `--open` flag: `mdbook serve --open`. -- Modify the content as desired. Refresh your browser to review edits. -- Ready to share? Open a PR with your enhancements. -- Don't forge to use prettier locally to format your markdown files: - ```bash - npm i -g prettier - prettier -w "**/*.md" - ``` - -### Working Locally (Translations) - -Catering to a global audience, we aspire for multilingual content. - -**Note**: Ensure all files in the `src` directory are in English, facilitating automated generation and updates of translation files. - -For translation tasks: - -- Start a local server for a specific language, e.g., `./translations.sh es`. Without specifying a language, the script defaults to extracting English translations. -- Focus on the relevant translation file, such as `po/es.po`. Tools like [poedit](https://poedit.net/) can make this task easier. -- Conclude your session with changes only in the `po/xx.po` file. Commit and open a PR. Ensure the PR begins with `i18n` to signal it involves translation. - -This translation model draws inspiration from the [Comprehensive Rust repository](https://github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md). - -#### Starting a New Language Translation - -If initiating a new language translation without a local server: - -- Use `./translations.sh new xx`, replacing `xx` with your language code. This command spawns the `xx.po` file for your language. -- Update your `xx.po` file with `./translations.sh xx` (swap `xx` with your language code), as detailed above. -- For pre-existing `xx.po` files, refrain from using the `new` command. - -#### GPT Translation - -Setup env: - -```bash -python3 -m venv ~/lang - -source ~/lang/bin/activate - -pip install -r requirements.txt -``` - -See script `./main.py` for instructions. diff --git a/.gitignore b/rust-book-old/.gitignore similarity index 100% rename from .gitignore rename to rust-book-old/.gitignore diff --git a/0.2.0/book.toml b/rust-book-old/0.2.0/book.toml similarity index 100% rename from 0.2.0/book.toml rename to rust-book-old/0.2.0/book.toml diff --git a/0.2.0/po/es.po b/rust-book-old/0.2.0/po/es.po similarity index 100% rename from 0.2.0/po/es.po rename to rust-book-old/0.2.0/po/es.po diff --git a/0.2.0/po/ja.po b/rust-book-old/0.2.0/po/ja.po similarity index 100% rename from 0.2.0/po/ja.po rename to rust-book-old/0.2.0/po/ja.po diff --git a/0.2.0/po/ko.po b/rust-book-old/0.2.0/po/ko.po similarity index 100% rename from 0.2.0/po/ko.po rename to rust-book-old/0.2.0/po/ko.po diff --git a/0.2.0/po/messages.pot b/rust-book-old/0.2.0/po/messages.pot similarity index 100% rename from 0.2.0/po/messages.pot rename to rust-book-old/0.2.0/po/messages.pot diff --git a/0.2.0/po/vi.po b/rust-book-old/0.2.0/po/vi.po similarity index 100% rename from 0.2.0/po/vi.po rename to rust-book-old/0.2.0/po/vi.po diff --git a/0.2.0/po/zh-cn.po b/rust-book-old/0.2.0/po/zh-cn.po similarity index 100% rename from 0.2.0/po/zh-cn.po rename to rust-book-old/0.2.0/po/zh-cn.po diff --git a/0.2.0/src/README.md b/rust-book-old/0.2.0/src/README.md similarity index 100% rename from 0.2.0/src/README.md rename to rust-book-old/0.2.0/src/README.md diff --git a/0.2.0/src/SUMMARY.md b/rust-book-old/0.2.0/src/SUMMARY.md similarity index 100% rename from 0.2.0/src/SUMMARY.md rename to rust-book-old/0.2.0/src/SUMMARY.md diff --git a/0.2.0/src/cairo/authorization.md b/rust-book-old/0.2.0/src/cairo/authorization.md similarity index 100% rename from 0.2.0/src/cairo/authorization.md rename to rust-book-old/0.2.0/src/cairo/authorization.md diff --git a/0.2.0/src/cairo/commands.md b/rust-book-old/0.2.0/src/cairo/commands.md similarity index 100% rename from 0.2.0/src/cairo/commands.md rename to rust-book-old/0.2.0/src/cairo/commands.md diff --git a/0.2.0/src/cairo/components.md b/rust-book-old/0.2.0/src/cairo/components.md similarity index 100% rename from 0.2.0/src/cairo/components.md rename to rust-book-old/0.2.0/src/cairo/components.md diff --git a/0.2.0/src/cairo/config.md b/rust-book-old/0.2.0/src/cairo/config.md similarity index 100% rename from 0.2.0/src/cairo/config.md rename to rust-book-old/0.2.0/src/cairo/config.md diff --git a/0.2.0/src/cairo/entities.md b/rust-book-old/0.2.0/src/cairo/entities.md similarity index 100% rename from 0.2.0/src/cairo/entities.md rename to rust-book-old/0.2.0/src/cairo/entities.md diff --git a/0.2.0/src/cairo/events.md b/rust-book-old/0.2.0/src/cairo/events.md similarity index 100% rename from 0.2.0/src/cairo/events.md rename to rust-book-old/0.2.0/src/cairo/events.md diff --git a/0.2.0/src/cairo/hello-dojo.md b/rust-book-old/0.2.0/src/cairo/hello-dojo.md similarity index 100% rename from 0.2.0/src/cairo/hello-dojo.md rename to rust-book-old/0.2.0/src/cairo/hello-dojo.md diff --git a/0.2.0/src/cairo/modules.md b/rust-book-old/0.2.0/src/cairo/modules.md similarity index 100% rename from 0.2.0/src/cairo/modules.md rename to rust-book-old/0.2.0/src/cairo/modules.md diff --git a/0.2.0/src/cairo/modules/defi.md b/rust-book-old/0.2.0/src/cairo/modules/defi.md similarity index 100% rename from 0.2.0/src/cairo/modules/defi.md rename to rust-book-old/0.2.0/src/cairo/modules/defi.md diff --git a/0.2.0/src/cairo/modules/erc1155.md b/rust-book-old/0.2.0/src/cairo/modules/erc1155.md similarity index 100% rename from 0.2.0/src/cairo/modules/erc1155.md rename to rust-book-old/0.2.0/src/cairo/modules/erc1155.md diff --git a/0.2.0/src/cairo/modules/erc20.md b/rust-book-old/0.2.0/src/cairo/modules/erc20.md similarity index 100% rename from 0.2.0/src/cairo/modules/erc20.md rename to rust-book-old/0.2.0/src/cairo/modules/erc20.md diff --git a/0.2.0/src/cairo/modules/erc721.md b/rust-book-old/0.2.0/src/cairo/modules/erc721.md similarity index 100% rename from 0.2.0/src/cairo/modules/erc721.md rename to rust-book-old/0.2.0/src/cairo/modules/erc721.md diff --git a/0.2.0/src/cairo/systems.md b/rust-book-old/0.2.0/src/cairo/systems.md similarity index 100% rename from 0.2.0/src/cairo/systems.md rename to rust-book-old/0.2.0/src/cairo/systems.md diff --git a/0.2.0/src/cairo/testing.md b/rust-book-old/0.2.0/src/cairo/testing.md similarity index 100% rename from 0.2.0/src/cairo/testing.md rename to rust-book-old/0.2.0/src/cairo/testing.md diff --git a/0.2.0/src/cairo/world.md b/rust-book-old/0.2.0/src/cairo/world.md similarity index 100% rename from 0.2.0/src/cairo/world.md rename to rust-book-old/0.2.0/src/cairo/world.md diff --git a/0.2.0/src/client/npm.md b/rust-book-old/0.2.0/src/client/npm.md similarity index 100% rename from 0.2.0/src/client/npm.md rename to rust-book-old/0.2.0/src/client/npm.md diff --git a/0.2.0/src/client/npm/core.md b/rust-book-old/0.2.0/src/client/npm/core.md similarity index 100% rename from 0.2.0/src/client/npm/core.md rename to rust-book-old/0.2.0/src/client/npm/core.md diff --git a/0.2.0/src/client/overview.md b/rust-book-old/0.2.0/src/client/overview.md similarity index 100% rename from 0.2.0/src/client/overview.md rename to rust-book-old/0.2.0/src/client/overview.md diff --git a/0.2.0/src/community/get-started.md b/rust-book-old/0.2.0/src/community/get-started.md similarity index 100% rename from 0.2.0/src/community/get-started.md rename to rust-book-old/0.2.0/src/community/get-started.md diff --git a/0.2.0/src/deployment/locally.md b/rust-book-old/0.2.0/src/deployment/locally.md similarity index 100% rename from 0.2.0/src/deployment/locally.md rename to rust-book-old/0.2.0/src/deployment/locally.md diff --git a/0.2.0/src/deployment/remote.md b/rust-book-old/0.2.0/src/deployment/remote.md similarity index 100% rename from 0.2.0/src/deployment/remote.md rename to rust-book-old/0.2.0/src/deployment/remote.md diff --git a/0.2.0/src/framework.md b/rust-book-old/0.2.0/src/framework.md similarity index 100% rename from 0.2.0/src/framework.md rename to rust-book-old/0.2.0/src/framework.md diff --git a/src/getting-started/contributing.md b/rust-book-old/0.2.0/src/getting-started/contributing.md similarity index 100% rename from src/getting-started/contributing.md rename to rust-book-old/0.2.0/src/getting-started/contributing.md diff --git a/0.2.0/src/getting-started/from-source.md b/rust-book-old/0.2.0/src/getting-started/from-source.md similarity index 100% rename from 0.2.0/src/getting-started/from-source.md rename to rust-book-old/0.2.0/src/getting-started/from-source.md diff --git a/0.2.0/src/getting-started/quick-start.md b/rust-book-old/0.2.0/src/getting-started/quick-start.md similarity index 100% rename from 0.2.0/src/getting-started/quick-start.md rename to rust-book-old/0.2.0/src/getting-started/quick-start.md diff --git a/0.2.0/src/getting-started/setup.md b/rust-book-old/0.2.0/src/getting-started/setup.md similarity index 100% rename from 0.2.0/src/getting-started/setup.md rename to rust-book-old/0.2.0/src/getting-started/setup.md diff --git a/rust-book-old/0.2.0/src/images/ECS.png b/rust-book-old/0.2.0/src/images/ECS.png new file mode 100644 index 00000000..638e86c0 Binary files /dev/null and b/rust-book-old/0.2.0/src/images/ECS.png differ diff --git a/rust-book-old/0.2.0/src/images/board.png b/rust-book-old/0.2.0/src/images/board.png new file mode 100644 index 00000000..ce3ab4c8 Binary files /dev/null and b/rust-book-old/0.2.0/src/images/board.png differ diff --git a/rust-book-old/0.2.0/src/images/dojo-auth.png b/rust-book-old/0.2.0/src/images/dojo-auth.png new file mode 100644 index 00000000..46cf7ec5 Binary files /dev/null and b/rust-book-old/0.2.0/src/images/dojo-auth.png differ diff --git a/rust-book-old/0.2.0/src/images/dojo-mark-full-dark.svg b/rust-book-old/0.2.0/src/images/dojo-mark-full-dark.svg new file mode 100644 index 00000000..5bc5b839 --- /dev/null +++ b/rust-book-old/0.2.0/src/images/dojo-mark-full-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/rust-book-old/0.2.0/src/images/dojo-sozo-workflow.jpg b/rust-book-old/0.2.0/src/images/dojo-sozo-workflow.jpg new file mode 100644 index 00000000..7a6ecb5e Binary files /dev/null and b/rust-book-old/0.2.0/src/images/dojo-sozo-workflow.jpg differ diff --git a/src/misc/contributors.md b/rust-book-old/0.2.0/src/misc/contributors.md similarity index 100% rename from src/misc/contributors.md rename to rust-book-old/0.2.0/src/misc/contributors.md diff --git a/0.2.0/src/theory/autonomous-worlds.md b/rust-book-old/0.2.0/src/theory/autonomous-worlds.md similarity index 100% rename from 0.2.0/src/theory/autonomous-worlds.md rename to rust-book-old/0.2.0/src/theory/autonomous-worlds.md diff --git a/0.2.0/src/theory/cairo.md b/rust-book-old/0.2.0/src/theory/cairo.md similarity index 100% rename from 0.2.0/src/theory/cairo.md rename to rust-book-old/0.2.0/src/theory/cairo.md diff --git a/0.2.0/src/theory/faqs.md b/rust-book-old/0.2.0/src/theory/faqs.md similarity index 100% rename from 0.2.0/src/theory/faqs.md rename to rust-book-old/0.2.0/src/theory/faqs.md diff --git a/0.2.0/src/theory/what-is-dojo.md b/rust-book-old/0.2.0/src/theory/what-is-dojo.md similarity index 100% rename from 0.2.0/src/theory/what-is-dojo.md rename to rust-book-old/0.2.0/src/theory/what-is-dojo.md diff --git a/0.2.0/src/toolchain/dojoup.md b/rust-book-old/0.2.0/src/toolchain/dojoup.md similarity index 100% rename from 0.2.0/src/toolchain/dojoup.md rename to rust-book-old/0.2.0/src/toolchain/dojoup.md diff --git a/src/toolchain/katana/development.md b/rust-book-old/0.2.0/src/toolchain/katana/development.md similarity index 100% rename from src/toolchain/katana/development.md rename to rust-book-old/0.2.0/src/toolchain/katana/development.md diff --git a/0.2.0/src/toolchain/katana/overview.md b/rust-book-old/0.2.0/src/toolchain/katana/overview.md similarity index 100% rename from 0.2.0/src/toolchain/katana/overview.md rename to rust-book-old/0.2.0/src/toolchain/katana/overview.md diff --git a/0.2.0/src/toolchain/katana/reference.md b/rust-book-old/0.2.0/src/toolchain/katana/reference.md similarity index 100% rename from 0.2.0/src/toolchain/katana/reference.md rename to rust-book-old/0.2.0/src/toolchain/katana/reference.md diff --git a/src/toolchain/sozo/common/account-options.md b/rust-book-old/0.2.0/src/toolchain/sozo/common/account-options.md similarity index 100% rename from src/toolchain/sozo/common/account-options.md rename to rust-book-old/0.2.0/src/toolchain/sozo/common/account-options.md diff --git a/src/toolchain/sozo/common/signer-options-keystore.md b/rust-book-old/0.2.0/src/toolchain/sozo/common/signer-options-keystore.md similarity index 100% rename from src/toolchain/sozo/common/signer-options-keystore.md rename to rust-book-old/0.2.0/src/toolchain/sozo/common/signer-options-keystore.md diff --git a/src/toolchain/sozo/common/signer-options-raw.md b/rust-book-old/0.2.0/src/toolchain/sozo/common/signer-options-raw.md similarity index 100% rename from src/toolchain/sozo/common/signer-options-raw.md rename to rust-book-old/0.2.0/src/toolchain/sozo/common/signer-options-raw.md diff --git a/src/toolchain/sozo/common/starknet-options.md b/rust-book-old/0.2.0/src/toolchain/sozo/common/starknet-options.md similarity index 100% rename from src/toolchain/sozo/common/starknet-options.md rename to rust-book-old/0.2.0/src/toolchain/sozo/common/starknet-options.md diff --git a/src/toolchain/sozo/common/world-options.md b/rust-book-old/0.2.0/src/toolchain/sozo/common/world-options.md similarity index 100% rename from src/toolchain/sozo/common/world-options.md rename to rust-book-old/0.2.0/src/toolchain/sozo/common/world-options.md diff --git a/src/toolchain/sozo/development.md b/rust-book-old/0.2.0/src/toolchain/sozo/development.md similarity index 100% rename from src/toolchain/sozo/development.md rename to rust-book-old/0.2.0/src/toolchain/sozo/development.md diff --git a/0.2.0/src/toolchain/sozo/overview.md b/rust-book-old/0.2.0/src/toolchain/sozo/overview.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/overview.md rename to rust-book-old/0.2.0/src/toolchain/sozo/overview.md diff --git a/src/toolchain/sozo/project-commands/build.md b/rust-book-old/0.2.0/src/toolchain/sozo/project-commands/build.md similarity index 100% rename from src/toolchain/sozo/project-commands/build.md rename to rust-book-old/0.2.0/src/toolchain/sozo/project-commands/build.md diff --git a/src/toolchain/sozo/project-commands/init.md b/rust-book-old/0.2.0/src/toolchain/sozo/project-commands/init.md similarity index 100% rename from src/toolchain/sozo/project-commands/init.md rename to rust-book-old/0.2.0/src/toolchain/sozo/project-commands/init.md diff --git a/0.2.0/src/toolchain/sozo/project-commands/migrate.md b/rust-book-old/0.2.0/src/toolchain/sozo/project-commands/migrate.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/project-commands/migrate.md rename to rust-book-old/0.2.0/src/toolchain/sozo/project-commands/migrate.md diff --git a/src/toolchain/sozo/project-commands/test.md b/rust-book-old/0.2.0/src/toolchain/sozo/project-commands/test.md similarity index 100% rename from src/toolchain/sozo/project-commands/test.md rename to rust-book-old/0.2.0/src/toolchain/sozo/project-commands/test.md diff --git a/0.2.0/src/toolchain/sozo/reference.md b/rust-book-old/0.2.0/src/toolchain/sozo/reference.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/reference.md rename to rust-book-old/0.2.0/src/toolchain/sozo/reference.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/auth.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/auth.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/auth.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/auth.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/component.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/component.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/component.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/component.md diff --git a/src/toolchain/sozo/world-commands/events.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/events.md similarity index 100% rename from src/toolchain/sozo/world-commands/events.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/events.md diff --git a/0.2.0/src/toolchain/sozo/world-commands/execute.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/execute.md similarity index 100% rename from 0.2.0/src/toolchain/sozo/world-commands/execute.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/execute.md diff --git a/src/toolchain/sozo/world-commands/register.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/register.md similarity index 100% rename from src/toolchain/sozo/world-commands/register.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/register.md diff --git a/src/toolchain/sozo/world-commands/system.md b/rust-book-old/0.2.0/src/toolchain/sozo/world-commands/system.md similarity index 100% rename from src/toolchain/sozo/world-commands/system.md rename to rust-book-old/0.2.0/src/toolchain/sozo/world-commands/system.md diff --git a/0.2.0/src/toolchain/torii/overview.md b/rust-book-old/0.2.0/src/toolchain/torii/overview.md similarity index 100% rename from 0.2.0/src/toolchain/torii/overview.md rename to rust-book-old/0.2.0/src/toolchain/torii/overview.md diff --git a/0.2.0/src/toolchain/torii/reference.md b/rust-book-old/0.2.0/src/toolchain/torii/reference.md similarity index 100% rename from 0.2.0/src/toolchain/torii/reference.md rename to rust-book-old/0.2.0/src/toolchain/torii/reference.md diff --git a/0.2.0/src/tutorial/onchain-chess/0-setup.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/0-setup.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/0-setup.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/0-setup.md diff --git a/0.2.0/src/tutorial/onchain-chess/1-initiate.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/1-initiate.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/1-initiate.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/1-initiate.md diff --git a/0.2.0/src/tutorial/onchain-chess/2-move.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/2-move.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/2-move.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/2-move.md diff --git a/0.2.0/src/tutorial/onchain-chess/3-legal.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/3-legal.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/3-legal.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/3-legal.md diff --git a/0.2.0/src/tutorial/onchain-chess/4-test.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/4-test.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/4-test.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/4-test.md diff --git a/0.2.0/src/tutorial/onchain-chess/README.md b/rust-book-old/0.2.0/src/tutorial/onchain-chess/README.md similarity index 100% rename from 0.2.0/src/tutorial/onchain-chess/README.md rename to rust-book-old/0.2.0/src/tutorial/onchain-chess/README.md diff --git a/LANGUAGES b/rust-book-old/LANGUAGES similarity index 100% rename from LANGUAGES rename to rust-book-old/LANGUAGES diff --git a/book.toml b/rust-book-old/book.toml similarity index 100% rename from book.toml rename to rust-book-old/book.toml diff --git a/main.py b/rust-book-old/main.py similarity index 100% rename from main.py rename to rust-book-old/main.py diff --git a/po/cn.po b/rust-book-old/po/cn.po similarity index 100% rename from po/cn.po rename to rust-book-old/po/cn.po diff --git a/po/jp.po b/rust-book-old/po/jp.po similarity index 100% rename from po/jp.po rename to rust-book-old/po/jp.po diff --git a/po/ko.po b/rust-book-old/po/ko.po similarity index 100% rename from po/ko.po rename to rust-book-old/po/ko.po diff --git a/po/lt.po b/rust-book-old/po/lt.po similarity index 100% rename from po/lt.po rename to rust-book-old/po/lt.po diff --git a/po/messages.pot b/rust-book-old/po/messages.pot similarity index 100% rename from po/messages.pot rename to rust-book-old/po/messages.pot diff --git a/po/vi.po b/rust-book-old/po/vi.po similarity index 100% rename from po/vi.po rename to rust-book-old/po/vi.po diff --git a/rust-book-old/readme.md b/rust-book-old/readme.md new file mode 100644 index 00000000..3d286de1 --- /dev/null +++ b/rust-book-old/readme.md @@ -0,0 +1,68 @@ +## πŸ“– The Dojo Book + +Explore the world of Autonomous Worlds with Dojo, your trusted toolchain. [Dive in now](https://book.dojoengine.org/). + +### Contributing + +Embrace the open-source spirit of Dojo. As it's in its nascent phase, we welcome contributors with open arms. + +Peruse our [contributing guidelines](./src/misc/contributors.md). From minor wording adjustments to extensive chapters, every contribution matters! + +### Setup + +1. **Rust-related Packages**: + - Obtain the `cargo` toolchain via [rustup](https://rustup.rs/). + - Get [mdBook](https://rust-lang.github.io/mdBook/guide/installation.html) and its translation extension with the command: + `cargo install mdbook mdbook-i18n-helpers` +2. **Host Machine Packages**: + - To assist with translations, install [gettext](https://www.gnu.org/software/gettext/). It's typically accessible via most package managers. Use: `sudo apt install gettext`. +3. Clone this repository to get started. + +### Working Locally (English - Primary Language) + +Always edit Markdown files in English. Here's how to work on it: + +- Spin up a local server using `mdbook serve`. Navigate to [localhost:3000](http://localhost:3000). For an automated browser launch, append the `--open` flag: `mdbook serve --open`. +- Modify the content as desired. Refresh your browser to review edits. +- Ready to share? Open a PR with your enhancements. +- Don't forge to use prettier locally to format your markdown files: + ```bash + npm i -g prettier + prettier -w "**/*.md" + ``` + +### Working Locally (Translations) + +Catering to a global audience, we aspire for multilingual content. + +**Note**: Ensure all files in the `src` directory are in English, facilitating automated generation and updates of translation files. + +For translation tasks: + +- Start a local server for a specific language, e.g., `./translations.sh es`. Without specifying a language, the script defaults to extracting English translations. +- Focus on the relevant translation file, such as `po/es.po`. Tools like [poedit](https://poedit.net/) can make this task easier. +- Conclude your session with changes only in the `po/xx.po` file. Commit and open a PR. Ensure the PR begins with `i18n` to signal it involves translation. + +This translation model draws inspiration from the [Comprehensive Rust repository](https://github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md). + +#### Starting a New Language Translation + +If initiating a new language translation without a local server: + +- Use `./translations.sh new xx`, replacing `xx` with your language code. This command spawns the `xx.po` file for your language. +- Update your `xx.po` file with `./translations.sh xx` (swap `xx` with your language code), as detailed above. +- For pre-existing `xx.po` files, refrain from using the `new` command. + +#### GPT Translation + +Setup env: + +```bash +python3 -m venv ~/lang + +source ~/lang/bin/activate + +pip install -r requirements.txt +``` + +See script `./main.py` for instructions. diff --git a/requirements.txt b/rust-book-old/requirements.txt similarity index 100% rename from requirements.txt rename to rust-book-old/requirements.txt diff --git a/src/SUMMARY.md b/rust-book-old/src/SUMMARY.md similarity index 100% rename from src/SUMMARY.md rename to rust-book-old/src/SUMMARY.md diff --git a/src/cairo/authorization.md b/rust-book-old/src/cairo/authorization.md similarity index 100% rename from src/cairo/authorization.md rename to rust-book-old/src/cairo/authorization.md diff --git a/src/cairo/commands.md b/rust-book-old/src/cairo/commands.md similarity index 100% rename from src/cairo/commands.md rename to rust-book-old/src/cairo/commands.md diff --git a/rust-book-old/src/cairo/config.md b/rust-book-old/src/cairo/config.md new file mode 100644 index 00000000..ce2dac58 --- /dev/null +++ b/rust-book-old/src/cairo/config.md @@ -0,0 +1,30 @@ +# Config + +Dojo worlds are defined in their `Scarb.toml` files. This is just a regular [Scarb](https://docs.swmansion.com/scarb/) file which is an excellent Cairo package manager and project manager. + +Full example of a `Scarb.toml` file: + +```toml +[package] +cairo-version = "2.4.0" +name = "dojo_examples" +version = "0.4.0" + +[cairo] +sierra-replace-ids = true + +[dependencies] +# IMPORTANT: Dojo should be pinned to a specific version or else your world might not compile. +dojo = { git = "https://github.com/dojoengine/dojo", version = "0.4.1" } + +[[target.dojo]] + +[tool.dojo] +initializer_class_hash = "0xbeef" + +[tool.dojo.env] +rpc_url = "http://localhost:5050/" +# Default account for katana with seed = 0 +account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" +``` diff --git a/rust-book-old/src/cairo/entities.md b/rust-book-old/src/cairo/entities.md new file mode 100644 index 00000000..6343b6fe --- /dev/null +++ b/rust-book-old/src/cairo/entities.md @@ -0,0 +1,26 @@ +## Entities + +> Entities are the primary key value within the world, to which models can be attached. + +Different ECS systems handle entities in various ways. In Dojo, entities are treated as a primary key value within the world, to which models can be attached. To illustrate this concept, consider a simple example of a character in a game that has a `Moves` and a `Position` model. + +When defining the models for this entity, it is important to note that we do not reference the entity directly. Instead, we simply provide two structs that the entity will contain. + +```rust,ignore +#[derive(Models, Drop, Serde)] +struct Moves { + #[key] + player: ContractAddress, + remaining: u8, +} + +#[derive(Models, Drop, Serde)] +struct Health { + #[key] + player: ContractAddress, + x: u32, + y: u32 +} +``` + +> ECS Theory: Plenty has been written on ECS systems, to go deeper read [ECS-FAQ](https://github.com/SanderMertens/ecs-faq) diff --git a/rust-book-old/src/cairo/enum.md b/rust-book-old/src/cairo/enum.md new file mode 100644 index 00000000..32269006 --- /dev/null +++ b/rust-book-old/src/cairo/enum.md @@ -0,0 +1,55 @@ +## Enum + +Enums are very useful in game design, as they simplify the creation of clean, complex logic. + +You can define an enum as follows: + +```rust,ignore + +// This enum simply defines the states of a game. +#[derive(Serde, Copy, Drop, Introspect, PartialEq, Print)] +enum GameStatus { + NotStarted: (), + Lobby: (), + InProgress: (), + Finished: (), +} + +// We define an into trait +impl GameStatusFelt252 of Into { + fn into(self: GameStatus) -> felt252 { + match self { + GameStatus::NotStarted => 0, + GameStatus::Lobby => 1, + GameStatus::InProgress => 2, + GameStatus::Finished => 3, + } + } +} +``` + +Then within a trait you can create something like this: + +```rust,ignore +#[derive(Model, Copy, Drop, Serde)] +struct Game { + #[key] + game_id: u32, + status: GameStatus, +} + +#[generate_trait] +impl GameImpl of GameTrait { + fn assert_in_progress(self: Game) { + assert(self.status == GameStatus::InProgress, "Game not started"); + } + fn assert_lobby(self: Game) { + assert(self.status == GameStatus::Lobby, "Game not in lobby"); + } + fn assert_not_started(self: Game) { + assert(self.status == GameStatus::NotStarted, "Game already started"); + } +} +``` + +> Read more about Cairo enums [here](https://book.cairo-lang.org/ch06-00-enums-and-pattern-matching.html) diff --git a/src/cairo/events.md b/rust-book-old/src/cairo/events.md similarity index 100% rename from src/cairo/events.md rename to rust-book-old/src/cairo/events.md diff --git a/src/cairo/hello-dojo.md b/rust-book-old/src/cairo/hello-dojo.md similarity index 100% rename from src/cairo/hello-dojo.md rename to rust-book-old/src/cairo/hello-dojo.md diff --git a/rust-book-old/src/cairo/metadata.md b/rust-book-old/src/cairo/metadata.md new file mode 100644 index 00000000..0507be76 --- /dev/null +++ b/rust-book-old/src/cairo/metadata.md @@ -0,0 +1,27 @@ +## Metadata + +Dojo supports associating offchain metadata with the world contract and other deployed contracts. This can provide additional context about the world, such as it's name, description, social links and other media. Enabling external services to easily index and distribute worlds and experiences built on them. + +### World Metadata + +During migration, `sozo` will automatically manage the worlds metadata for you, uploading it to ipfs and setting it in the world contract. It does so by parsing the metadata defined in the projects `Scarb.toml`. + +To set a worlds metadata, create the following section in your `Scarb.toml`: + +```toml +[tool.dojo.world] +name = "example" +description = "example world" +icon_uri = "file://assets/icon.png" +cover_uri = "file://assets/cover.png" +website = "https://dojoengine.org" +socials.x = "https://twitter.com/dojostarknet" +``` + +The toolchain supports the `name`, `description`, `icon_uri`, `cover_uri`, `website` and `socials` attributes by default. `_uri` attributes can point to a asset in the repo using the `file://` schema or to remote resouces using either `ipfs://` or `https://`. Arbitrary social links can be set by setting a key value on the `socials` attribute. For example, we could add a `socials.github = "..."`. + +During migration, `sozo` will upload any local assets to ipfs, replace the corresponding uris, upload the metadata json to ipfs, and set the `metadata_uri` for the world (resource `0`). + +### Contract Metadata + +It is possible for contract owners to set a `metadata_uri` for any contract. However, this specification has not yet been defined and it is not supported by the toolchain at this time. diff --git a/rust-book-old/src/cairo/migration.md b/rust-book-old/src/cairo/migration.md new file mode 100644 index 00000000..9578a443 --- /dev/null +++ b/rust-book-old/src/cairo/migration.md @@ -0,0 +1,5 @@ +## Migration + +[0.2.0 -> 0.3.0](./migration/0.3.0.md) + +[0.3.0 -> 0.4.0](./migration/0.3.0.md) diff --git a/rust-book-old/src/cairo/migration/0.3.0.md b/rust-book-old/src/cairo/migration/0.3.0.md new file mode 100644 index 00000000..b9848407 --- /dev/null +++ b/rust-book-old/src/cairo/migration/0.3.0.md @@ -0,0 +1,218 @@ +## Migration Guide to 0.3.0 + +0.3.0 introduced some breaking changes to Systems and Models which requires reworking of your worlds. + +- [Components](#components-to-models) +- [Systems](#systems-update) +- [Events](#events) +- [Npm](#npm) + +### Components to Models + +In version 0.3.0, "components" have been renamed to "models". This has been done due to Cairo introducing the concept of Components natively. + +You must: + +- Replace `#[component]` with `#[model]`. +- Update `#[derive(Component)]` to `#[derive(Model)]` throughout your code. + +**Note**: Ensure all related files and imports are updated accordingly. + +### Changes in Model Implementation + +The trait `SerdeLen` is no longer implemented for models. If you relied on this previously, you should now use `SchemaIntrospection`. + +### Schema Introduction + +For models containing complex types, it's crucial to implement the `SchemaIntrospection` trait. + +Consider the model below: + +```rust,ignore +struct Card { + + #[key] + token_id: u256, + /// The card's designated role. + role: Roles, +} +``` + +For complex types, like `Roles` in the above example, you need to implement `SchemaIntrospection`. Here's how: + +```rust,ignore +impl RolesSchemaIntrospectionImpl of SchemaIntrospection { + #[inline(always)] + fn size() -> usize { + 1 // Represents the byte size of the enum. + } + + #[inline(always)] + fn layout(ref layout: Array) { + layout.append(8); // Specifies the layout byte size; + } + + #[inline(always)] + fn ty() -> Ty { + Ty::Enum( + Enum { + name: 'Roles', + attrs: array![].span(), + children: array![ + ('Goalkeeper', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Defender', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Midfielder', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Attacker', serialize_member_type(@Ty::Tuple(array![].span()))), + ] + .span() + } + ) + } +} +``` + +**Key Takeaways from custom types**: + +- **size**: Defines the byte size of the type. +- **layout**: Outlines the byte structure/layout for the type. Validate and adjust as necessary. +- **ty**: Details the specific type, attributes, and subcomponents. For enums, like `Roles`, you need to specify each member and its type. + +### Systems Update + +Systems in 0.3.0 are very similar now to Cairo Contracts. You can write your systems just like regular contracts, and each dojo contract can contain mulitple systems. + +Important high level changes: + +- Systems are now starknet contracts +- Define [Interfaces](#interface-creation) for each system contract +- New optional `#[dojo::contract]` decorator defining systems +- Multiple systems per dojo contract, rather than singular +- `execute` is no longer required system selector name + +#### Interface Creation + +System management has been revamped. Start by defining an interface for each system, which specifies its implementation: + +```rust,ignore +#[starknet::interface] +trait ICreateCard { + fn create_card( + self: @TContractState, + world: IWorldDispatcher, + token_id: u256, + dribble: u8, + defense: u8, + cost: u8, + role: Roles, + is_captain: bool + ); +} +``` + +Ensure the trait is typed with `TContractState`. + +**Note**: Earlier versions required functions within the system to be named `execute`. This is no longer the case. + +#### Interface Implementation + +To implement the interface: + +1. Add `#[abi(embed_v0)]` before each method. +2. Ensure to reference the created interface in the module with `use super::ICreateCard;`. + +```rust,ignore +#[abi(embed_v0)] +impl CreateCardImpl of ICreateCard { + fn create_card( + self: @ContractState, + world: IWorldDispatcher, + token_id: u256, + dribble: u8, + defense: u8, + cost: u8, + role: Roles, + is_captain: bool + ) { + // your logic here + } +} +``` + +This then allows the `create_card` to be called just like a regular starknet function. + +#### `#[dojo::contract]` decorator + +0.3.0 introduces a new optional decorator `#[dojo::contract]` which indicates to the compiler to inject imports and the world dispatcher. This allows for minimal boilerplate. + +```rust,ignore +#[dojo::contract] +mod move { +....code TODO +} +``` + +### Events + +Events should now reside within the models. Here's an example of how to migrate your events: + +**Previous Format**: + +```rust,ignore +#[derive(Drop, starknet::Event, Copy)] +struct DeckCreated { + player: ContractAddress, + token_list: Span, +} +``` + +**New Format**: + +```rust,ignore +#[event] +#[derive(Drop, starknet::Event)] +enum Event { + DeckCreated: DeckCreated +} + +#[derive(Drop, starknet::Event)] +struct DeckCreated { + player: ContractAddress, + token_list: Span, +} +``` + +### Testing Changes + +#### Setup + +Testing has seen significant changes with the change to systems as Contracts. Instead of using `world.execute`, use the dispatcher. + +1. Import necessary modules and traits: + +```rust,ignore +use dojo::test_utils::deploy_contract; +use tsubasa::systems::{ICreateCardDispatcher, ICreateCardDispatcherTrait}; +``` + +2. Deploy the contract and instantiate the dispatcher: + +```rust,ignore +let contract_create_card = deploy_contract( + create_card_system::TEST_CLASS_HASH, array![].span() +); +let create_card_system = ICreateCardDispatcher { contract_address: contract_create_card }; +``` + +#### Function Testing + +With the contract deployed and the dispatcher instantiated, proceed to test your functions: + +```rust,ignore +// ... (previous setup code) + +let result = create_card_system.create_card( + // ... provide necessary parameters here +); + +// Assert or validate the 'result' as per your test conditions +``` diff --git a/rust-book-old/src/cairo/migration/0.4.0.md b/rust-book-old/src/cairo/migration/0.4.0.md new file mode 100644 index 00000000..a4150a39 --- /dev/null +++ b/rust-book-old/src/cairo/migration/0.4.0.md @@ -0,0 +1,3 @@ +## Migration Guide to 0.4.0 + +[todo] diff --git a/rust-book-old/src/cairo/models.md b/rust-book-old/src/cairo/models.md new file mode 100644 index 00000000..d83ee886 --- /dev/null +++ b/rust-book-old/src/cairo/models.md @@ -0,0 +1,287 @@ +## Models + +> Models = Data + +**_TL;DR_** + +- Models store structured data in your world. +- Models are Cairo structs with additional features. +- Models can implement traits. +- Use the `#[derive(Model)]` decorator to define them. +- Custom enums and types are supported. +- Define the primary key using the `#[key]` attribute. + +### Models are Structs + +Models are structs annotated with the `#[derive(Model)]` attribute. Consider these models as a key-value store, where the `#[key]` attribute is utilized to define the primary key. While models can contain any number of fields, adhering to best practices in Entity-Component-System (ECS) design involves maintaining small, isolated models. + +This approach fosters modularity and composability, enabling you to reuse models across various entity types. + +```rust,ignore +#[derive(Model, Copy, Drop, Serde)] +struct Moves { + #[key] + player: ContractAddress, + remaining: u8, +} +``` + +#### The #[key] attribute + +The `#[key]` attribute indicates to Dojo that this model is indexed by the `player` field. A field that is identified as a `#[key]` is not stored. It is used by the dojo database system to uniquely identify the storage location that contains your model. + +You need to define at least one key for each model, as this is how you query the model. However, you can create composite keys by defining multiple fields as keys. If you define multiple keys, they must **all** be provided to query the model. + +```rust,ignore +#[derive(Model, Copy, Drop, Serde)] +struct Resource { + #[key] + player: ContractAddress, + #[key] + location: ContractAddress, + balance: u8, +} +``` + +In this case you then would set the model with both the player and location fields: + +```rust,ignore +set!( + world, + ( + Resource { + player: caller, + location: 12, + balance: 10 + }, + ) +); +``` + +To retrieve a model with a composite key using the [get!](./commands.md#the-get-command) command, you must provide a value for each key as follow: + +```rust,ignore +let player = get_caller_address(); +let location = 0x1234; + +let resource = get!(world, (player, location), (Resource)); +``` + +#### Implementing Traits + +Models can implement traits. This is useful for defining common functionality across models. For example, you may want to define a `Position` model that implements a `PositionTrait` trait. This trait could define functions such as `is_zero` and `is_equal` which could be used when accessing the model. + +```rust,ignore +trait PositionTrait { + fn is_zero(self: Position) -> bool; + fn is_equal(self: Position, b: Position) -> bool; +} + +impl PositionImpl of PositionTrait { + fn is_zero(self: Position) -> bool { + if self.x - self.y == 0 { + return true; + } + false + } + + fn is_equal(self: Position, b: Position) -> bool { + self.x == b.x && self.y == b.y + } +} +``` + +#### Custom Setting models + +Suppose we need a place to keep a global value with the flexibility to modify it in the future. Take, for instance, a global `combat_cool_down` parameter that defines the duration required for an entity to be primed for another attack. To achieve this, we can craft a model dedicated to storing this value, while also allowing for its modification via a decentralized governance model. + +To establish these models, you'd follow the usual creation method. However, when initializing them, employ a constant identifier, such as GAME_SETTINGS_ID. + +```rust,ignore +const GAME_SETTINGS_ID: u32 = 9999999999999; + +#[derive(model, Copy, Drop, Serde)] +struct GameSettings { + #[key] + game_settings_id: u32, + combat_cool_down: u32, +} +``` + +#### Types + +Support model types: + +- `u8` +- `u16` +- `u32` +- `u64` +- `u128` +- `u256` +- `ContractAddress` +- Enums +- Custom Types + +It is currently not possible to use Arrays. + +#### Custom Types + Enums + +For models containing complex types, it's crucial to implement the `SchemaIntrospection` trait. + +Consider the model below: + +```rust,ignore +struct Card { + #[key] + token_id: u256, + /// The card's designated role. + role: Roles, +} +``` + +For complex types, like `Roles` in the above example, you need to implement `SchemaIntrospection`. Here's how: + +```rust,ignore +impl RolesSchemaIntrospectionImpl for SchemaIntrospection { + #[inline(always)] + fn size() -> usize { + 1 // Represents the byte size of the enum. + } + + #[inline(always)] + fn layout(ref layout: Array) { + layout.append(8); // Specifies the layout byte size; + } + + #[inline(always)] + fn ty() -> Ty { + Ty::Enum( + Enum { + name: 'Roles', + attrs: array![].span(), + children: array![ + ('Goalkeeper', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Defender', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Midfielder', serialize_member_type(@Ty::Tuple(array![].span()))), + ('Attacker', serialize_member_type(@Ty::Tuple(array![].span()))), + ] + .span() + } + ) + } +} +``` + +### In practice with modularity in mind + +Consider a tangible analogy: Humans and Goblins. While they possess intrinsic differences, they share common traits, such as having a position and health. However, humans possess an additional model. Furthermore, we introduce a Counter model, a distinct feature that tallies the numbers of humans and goblins. + +```rust,ignore +#[derive(Model, Copy, Drop, Serde)] +struct Potions { + #[key] + entity_id: u32, + quantity: u8, +} + +#[derive(Model, Copy, Drop, Serde)] +struct Health { + #[key] + entity_id: u32, + health: u8, +} + +#[derive(Model, Copy, Drop, Serde)] +struct Position { + #[key] + entity_id: u32, + x: u32, + y: u32 +} + +// Special counter model +#[derive(Model, Copy, Drop, Serde)] +struct Counter { + #[key] + counter: u32, + goblin_count: u32, + human_count: u32, +} +``` + +So the Human will have a `Potions`, `Health` and `Position` model, and the Goblin will have a `Health` and `Position` model. By doing we save having to create Health and Position models for each entity type. + +So then a contract would look like this: + +```rust,ignore +#[dojo::contract] +mod spawnHuman { + use array::ArrayTrait; + use box::BoxTrait; + use traits::Into; + use dojo::world::Context; + + use dojo_examples::models::Position; + use dojo_examples::models::Health; + use dojo_examples::models::Potions; + use dojo_examples::models::Counter; + + // we can set the counter value as a const, then query it easily! This pattern is useful for settings. + const COUNTER_ID: u32 = 9999999999999; + + // impl: implement functions specified in trait + #[abi(embed_v0)] + impl GoblinActionsImpl of IGoblinActions { + fn goblin_actions(self: @ContractState, entity_id: u32) { + let world = self.world_dispatcher.read(); + + let counter = get!(world, COUNTER_ID, (Counter)); + + let human_count = counter.human_count + 1; + let goblin_count = counter.goblin_count + 1; + + // spawn a human + set!( + world, + ( + Health { + entity_id: human_count, health: 100 + }, + Position { + entity_id: human_count, x: position.x + 10, y: position.y + 10, + }, + Potions { + entity_id: human_count, quantity: 10 + + }, + ) + ); + + // spawn a goblin + set!( + world, + ( + Health { + entity_id: goblin_count, health: 100 + }, + Position { + entity_id: goblin_count, x: position.x + 10, y: position.y + 10, + }, + ) + ); + + // increment the counter + set!( + world, + ( + Counter { + counter: COUNTER_ID, human_count: human_count, goblin_count: goblin_count + }, + ) + ); + } + } +} +``` + +> A complete example can be found in the [Dojo Starter](https://github.com/dojoengine/dojo-starter) diff --git a/src/cairo/origami.md b/rust-book-old/src/cairo/origami.md similarity index 100% rename from src/cairo/origami.md rename to rust-book-old/src/cairo/origami.md diff --git a/rust-book-old/src/cairo/overview.md b/rust-book-old/src/cairo/overview.md new file mode 100644 index 00000000..d56ae1db --- /dev/null +++ b/rust-book-old/src/cairo/overview.md @@ -0,0 +1,93 @@ +> You should have a good understanding of Cairo before proceeding. If you're unfamiliar with Cairo, we recommend you read the [Cairo documentation](https://book.cairo-lang.org/title-page.html) first. + +## A New Approach to Onchain Game Development + +Dojo provides an advanced abstraction layer over Cairo, mirroring React's relationship with JavaScript. Its specialized architecture simplifies game design and development. + +By leveraging Dojo, developers can use succinct [commands](./commands.md) that transform into comprehensive queries at compile time. + +#### Delving into the Architecture + +Dojo efficiently encapsulates boilerplate contracts within the compiler, letting developers concentrate on the distinct aspects of their game or app. + +Consider this as the most basic Dojo world setup: + +```rust,ignore +- src + - main.cairo + - lib.cairo +- Scarb.toml +``` + +While seemingly simple, behind the scenes Dojo compiler generates foundational contracts, setting the stage for you to focus purely on data and logic. + +Lets take a look at the `main.cairo`: + +```rust,ignore +use starknet::ContractAddress; + +// dojo data models +#[derive(Model, Copy, Drop, Serde)] +struct Position { + #[key] // primary key + player: ContractAddress, + vec: Vec2, +} + +// regular cairo struct +#[derive(Copy, Drop, Serde, Introspect)] +struct Vec2 { + x: u32, + y: u32 +} + +// interface +#[starknet::interface] +trait IPlayerActions { + fn spawn(self: @TContractState); +} + +// contract +#[dojo::contract] +mod player_actions { + use starknet::{ContractAddress, get_caller_address}; + use super::{Position, Vec2}; + use super::IPlayerActions; + + #[abi(embed_v0)] + impl PlayerActionsImpl of IPlayerActions { + // + // This is how we interact with the world contract. + // + fn spawn(self: @ContractState) { + // Access the world dispatcher for reading. + let world = self.world_dispatcher.read(); + + // get player address + let player = get_caller_address(); + + // dojo command - get player position + let position = get!(world, player, (Position)); + + // dojo command - set player position + set!(world, (Position { player, vec: Vec2 { x: 10, y: 10 } })); + } + } +} +``` + +### Breakdown + +Dojo contract is just a regular Cairo contract, with some dojo specifics. + +#### `Position` struct - the dojo model + +In a Dojo world, state is defined using models. These are structs marked with the `#[derive(Model)]` attribute, functioning similarly to a key-pair store. The primary key for a model is indicated using the `#[key]` attribute; for instance, the `player` field serves as the primary key in this context. + +Read more about models [here](./models.md). + +#### `spawn` function - a dojo system + +In the `spawn` function, we just call `self.world_dispatcher`. This provides a gateway to the world contract. This facilitates the effortless utilization of the get! and set! commands, allowing seamless interaction with the world contract. + +Commands, a significant innovation in Dojo, are further explored [here](./commands.md). diff --git a/src/cairo/systems.md b/rust-book-old/src/cairo/systems.md similarity index 100% rename from src/cairo/systems.md rename to rust-book-old/src/cairo/systems.md diff --git a/rust-book-old/src/cairo/testing.md b/rust-book-old/src/cairo/testing.md new file mode 100644 index 00000000..107e0871 --- /dev/null +++ b/rust-book-old/src/cairo/testing.md @@ -0,0 +1,112 @@ +## Testing + +Testing is a crucial part of any software development process. Dojo provides a testing framework that allows you to write tests for your smart contracts. Since Dojo uses a custom compiler, you need to use `sozo` to test your contracts. + +From your project directory, simply: + +```shell +sozo test +``` + +This will search for all tests within your project and run them. + +### Writing Unit Tests + +It is best practise to include unit tests in the same file as the Model/System you are writing. + +Lets show a `model` test example from the [dojo-starter](https://github.com/dojoengine/dojo-starter): + +`models.cairo` + +```rust,ignore + +...//rest of code + +#[cfg(test)] +mod tests { + use super::{Position, Vec2, Vec2Trait}; + + #[test] + #[available_gas(100000)] + fn test_vec_is_zero() { + assert(Vec2Trait::is_zero(Vec2 { x: 0, y: 0 }), 'not zero'); + } + + #[test] + #[available_gas(100000)] + fn test_vec_is_equal() { + let position = Vec2 { x: 420, y: 0 }; + assert(position.is_equal(Vec2 { x: 420, y: 0 }), 'not equal'); + } +} +``` + +In this test we are testing the `is_zero` and `is_equal` functions of the `Position` model. It is good practise to test all functions of your models. + +### Writing Integration Tests + +Integration tests are e2e tests that test the entire system. You can write integration tests for your world by creating a `tests` directory in your project root. Then create a file for each integration test you want to write. + +This is the example from the [dojo-starter](https://github.com/dojoengine/dojo-starter): + +`move.cairo` + +```rust,ignore +#[cfg(test)] +mod tests { + use dojo::world::{IWorldDispatcherTrait, IWorldDispatcher}; + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use dojo_examples::models::{position, moves}; + use dojo_examples::models::{Position, Moves, Direction}; + + use super::{actions, IActionsDispatcher, IActionsDispatcherTrait}; + + // helper setup function + // reusable function for tests + fn setup_world() -> IActionsDispatcher { + // components + let mut models = array![position::TEST_CLASS_HASH, moves::TEST_CLASS_HASH]; + + // deploy world with models + let world = spawn_test_world(models); + + // deploy systems contract + let contract_address = world + .deploy_contract('salt', actions::TEST_CLASS_HASH.try_into().unwrap()); + let actions_system = IActionsDispatcher { contract_address }; + + actions_system + } + + + #[test] + #[available_gas(30000000)] + fn test_move() { + // caller + let caller = starknet::contract_address_const::<0x0>(); + + let actions_system = setup_world(); + + // System calls + actions_system.spawn(); + actions_system.move(Direction::Right(())); + + // check moves + let moves = get!(world, caller, (Moves)); + assert(moves.remaining == 99, 'moves is wrong'); + + // get new_position + let new_position = get!(world, caller, Position); + + // check new position x + assert(new_position.vec.x == 11, 'position x is wrong'); + + // check new position y + assert(new_position.vec.y == 10, 'position y is wrong'); + } +} +``` + +#### Useful Dojo Test Functions + +`spawn_test_world(models)` - This function will create a test world with the models and systems you pass in. It will also deploy the world and register the models and systems. diff --git a/src/cairo/world.md b/rust-book-old/src/cairo/world.md similarity index 100% rename from src/cairo/world.md rename to rust-book-old/src/cairo/world.md diff --git a/rust-book-old/src/client/dojojs.md b/rust-book-old/src/client/dojojs.md new file mode 100644 index 00000000..f8ed6b9f --- /dev/null +++ b/rust-book-old/src/client/dojojs.md @@ -0,0 +1,63 @@ +# Dojo.js + +> Javascript is a great way to get started with Dojo. It's easy to use, and you can get started in minutes. + +### @dojoengine/core + +This is the lowest level library, and is used by all other downstream libraries. It contains the core functionality of Dojo and exposes the contract interfaces. Use it if you want to build your own library on top of Dojo. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/core) + +```console +bun add @dojoengine/core +``` + +### @dojoengine/create-burner + +Create burner is a simple way to incorporate burner wallets into your Dojo app. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/create-burner) + +```console +bun add @dojoengine/create-burner +``` + +### @dojoengine/utils + +These are utils for helping with interfacing dojo. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/utils) + +```console +bun add @dojoengine/utils +``` + +### @dojoengine/react + +React hooks for dojo. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/react) + +```console +bun add @dojoengine/react +``` + +### @dojoengine/torii-client + +The wasm client to access torii via grpc. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/torii-client) + +```console +bun add @dojoengine/torii-client +``` + +### @dojoengine/torii-wasm + +Torii client for wasm bindings. + +[Repository](https://github.com/dojoengine/packages/tree/main/packages/torii-wasm) + +```console +bun add @dojoengine/torii-wasm +``` diff --git a/rust-book-old/src/client/overview.md b/rust-book-old/src/client/overview.md new file mode 100644 index 00000000..f24feeb0 --- /dev/null +++ b/rust-book-old/src/client/overview.md @@ -0,0 +1,8 @@ +# Overview + +Dojo is BYO client, meaning that you can use any client you want to connect to the Dojo network. + +- [npm](./npm.md) +- [torii](torii.md) + +> Dojo is always looking to expand these clients, if you would like to contribute reach out into the [Discord](https://discord.gg/KG9w9BmDrV) diff --git a/rust-book-old/src/client/sdk/c.md b/rust-book-old/src/client/sdk/c.md new file mode 100644 index 00000000..d20e3181 --- /dev/null +++ b/rust-book-old/src/client/sdk/c.md @@ -0,0 +1,3 @@ +# Dojo c + +[c bindings](https://github.com/dojoengine/dojo.c) diff --git a/rust-book-old/src/client/sdk/dojojs.md b/rust-book-old/src/client/sdk/dojojs.md new file mode 100644 index 00000000..d650fd10 --- /dev/null +++ b/rust-book-old/src/client/sdk/dojojs.md @@ -0,0 +1 @@ +# dojo.js diff --git a/src/client/sdk/unity.md b/rust-book-old/src/client/sdk/unity.md similarity index 100% rename from src/client/sdk/unity.md rename to rust-book-old/src/client/sdk/unity.md diff --git a/rust-book-old/src/client/torii.md b/rust-book-old/src/client/torii.md new file mode 100644 index 00000000..01086fe7 --- /dev/null +++ b/rust-book-old/src/client/torii.md @@ -0,0 +1,9 @@ +## Torii Client + +Torii client is a rust client for interacting with Dojo worlds. It can be compiled to wasm to be used in JS clients, or can used directly in Rust clients or other lower level languages with bindings. + +### Usage in Rust projects + +**@kairy** + +### Usage in JS Clients diff --git a/src/community/get-started.md b/rust-book-old/src/community/get-started.md similarity index 100% rename from src/community/get-started.md rename to rust-book-old/src/community/get-started.md diff --git a/src/deployment/locally.md b/rust-book-old/src/deployment/locally.md similarity index 100% rename from src/deployment/locally.md rename to rust-book-old/src/deployment/locally.md diff --git a/src/deployment/remote.md b/rust-book-old/src/deployment/remote.md similarity index 100% rename from src/deployment/remote.md rename to rust-book-old/src/deployment/remote.md diff --git a/rust-book-old/src/getting-started/contributing.md b/rust-book-old/src/getting-started/contributing.md new file mode 100644 index 00000000..073dd2d0 --- /dev/null +++ b/rust-book-old/src/getting-started/contributing.md @@ -0,0 +1,7 @@ +# Contributing to the Core + +Dojo is an open-source project, currently in its early development phase, and warmly welcomes contributors. + +## How to Contribute + +Head to the [Github](https://github.com/dojoengine/dojo/issues) for open issues, if you see an issue that is unassigned, please request in the comments to be assigned to it. If you have an idea for a new feature, please create an issue with the `enhancement` tag. diff --git a/src/getting-started/from-source.md b/rust-book-old/src/getting-started/from-source.md similarity index 100% rename from src/getting-started/from-source.md rename to rust-book-old/src/getting-started/from-source.md diff --git a/src/getting-started/quick-start.md b/rust-book-old/src/getting-started/quick-start.md similarity index 100% rename from src/getting-started/quick-start.md rename to rust-book-old/src/getting-started/quick-start.md diff --git a/src/getting-started/setup.md b/rust-book-old/src/getting-started/setup.md similarity index 100% rename from src/getting-started/setup.md rename to rust-book-old/src/getting-started/setup.md diff --git a/rust-book-old/src/images/Built with.svg b/rust-book-old/src/images/Built with.svg new file mode 100644 index 00000000..12c5d2ce --- /dev/null +++ b/rust-book-old/src/images/Built with.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/rust-book-old/src/images/Dojo - Contracts.png b/rust-book-old/src/images/Dojo - Contracts.png new file mode 100644 index 00000000..95412269 Binary files /dev/null and b/rust-book-old/src/images/Dojo - Contracts.png differ diff --git a/rust-book-old/src/images/ECS.png b/rust-book-old/src/images/ECS.png new file mode 100644 index 00000000..638e86c0 Binary files /dev/null and b/rust-book-old/src/images/ECS.png differ diff --git a/rust-book-old/src/images/board.png b/rust-book-old/src/images/board.png new file mode 100644 index 00000000..ce3ab4c8 Binary files /dev/null and b/rust-book-old/src/images/board.png differ diff --git a/rust-book-old/src/images/dojo-auth.png b/rust-book-old/src/images/dojo-auth.png new file mode 100644 index 00000000..46cf7ec5 Binary files /dev/null and b/rust-book-old/src/images/dojo-auth.png differ diff --git a/rust-book-old/src/images/dojo-mark-full-dark.svg b/rust-book-old/src/images/dojo-mark-full-dark.svg new file mode 100644 index 00000000..5bc5b839 --- /dev/null +++ b/rust-book-old/src/images/dojo-mark-full-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/rust-book-old/src/images/dojo-sozo-workflow.jpg b/rust-book-old/src/images/dojo-sozo-workflow.jpg new file mode 100644 index 00000000..7a6ecb5e Binary files /dev/null and b/rust-book-old/src/images/dojo-sozo-workflow.jpg differ diff --git a/rust-book-old/src/images/dojo.unity_demo.mp4 b/rust-book-old/src/images/dojo.unity_demo.mp4 new file mode 100644 index 00000000..e1b9c99d Binary files /dev/null and b/rust-book-old/src/images/dojo.unity_demo.mp4 differ diff --git a/rust-book-old/src/images/katana-icon-word.png b/rust-book-old/src/images/katana-icon-word.png new file mode 100644 index 00000000..cc71e76e Binary files /dev/null and b/rust-book-old/src/images/katana-icon-word.png differ diff --git a/rust-book-old/src/images/katana-icon.png b/rust-book-old/src/images/katana-icon.png new file mode 100644 index 00000000..79c978b7 Binary files /dev/null and b/rust-book-old/src/images/katana-icon.png differ diff --git a/rust-book-old/src/images/katana.png b/rust-book-old/src/images/katana.png new file mode 100644 index 00000000..25077302 Binary files /dev/null and b/rust-book-old/src/images/katana.png differ diff --git a/rust-book-old/src/images/origami-icon-word.png b/rust-book-old/src/images/origami-icon-word.png new file mode 100644 index 00000000..ccac1432 Binary files /dev/null and b/rust-book-old/src/images/origami-icon-word.png differ diff --git a/rust-book-old/src/images/origami-icon.png b/rust-book-old/src/images/origami-icon.png new file mode 100644 index 00000000..f4ed595a Binary files /dev/null and b/rust-book-old/src/images/origami-icon.png differ diff --git a/rust-book-old/src/images/origami.png b/rust-book-old/src/images/origami.png new file mode 100644 index 00000000..f1eba0d0 Binary files /dev/null and b/rust-book-old/src/images/origami.png differ diff --git a/rust-book-old/src/images/permissions.png b/rust-book-old/src/images/permissions.png new file mode 100644 index 00000000..1fca70d8 Binary files /dev/null and b/rust-book-old/src/images/permissions.png differ diff --git a/rust-book-old/src/images/slot-icon-word.png b/rust-book-old/src/images/slot-icon-word.png new file mode 100644 index 00000000..b424160f Binary files /dev/null and b/rust-book-old/src/images/slot-icon-word.png differ diff --git a/rust-book-old/src/images/slot-icon.png b/rust-book-old/src/images/slot-icon.png new file mode 100644 index 00000000..28090367 Binary files /dev/null and b/rust-book-old/src/images/slot-icon.png differ diff --git a/rust-book-old/src/images/sozo-icon-word.png b/rust-book-old/src/images/sozo-icon-word.png new file mode 100644 index 00000000..d8c85888 Binary files /dev/null and b/rust-book-old/src/images/sozo-icon-word.png differ diff --git a/rust-book-old/src/images/sozo-icon.png b/rust-book-old/src/images/sozo-icon.png new file mode 100644 index 00000000..0b96151b Binary files /dev/null and b/rust-book-old/src/images/sozo-icon.png differ diff --git a/rust-book-old/src/images/torii-icon-word.png b/rust-book-old/src/images/torii-icon-word.png new file mode 100644 index 00000000..120efbc9 Binary files /dev/null and b/rust-book-old/src/images/torii-icon-word.png differ diff --git a/rust-book-old/src/images/torii-icon.png b/rust-book-old/src/images/torii-icon.png new file mode 100644 index 00000000..3e1e9b28 Binary files /dev/null and b/rust-book-old/src/images/torii-icon.png differ diff --git a/rust-book-old/src/images/unity-screen-grab.png b/rust-book-old/src/images/unity-screen-grab.png new file mode 100644 index 00000000..fa9834bd Binary files /dev/null and b/rust-book-old/src/images/unity-screen-grab.png differ diff --git a/rust-book-old/src/images/unity/models.png b/rust-book-old/src/images/unity/models.png new file mode 100644 index 00000000..0c608585 Binary files /dev/null and b/rust-book-old/src/images/unity/models.png differ diff --git a/rust-book-old/src/images/unity/sync-master.png b/rust-book-old/src/images/unity/sync-master.png new file mode 100644 index 00000000..e4a25a6f Binary files /dev/null and b/rust-book-old/src/images/unity/sync-master.png differ diff --git a/rust-book-old/src/images/unity/world-manager.png b/rust-book-old/src/images/unity/world-manager.png new file mode 100644 index 00000000..0979a2de Binary files /dev/null and b/rust-book-old/src/images/unity/world-manager.png differ diff --git a/rust-book-old/src/images/world-map.png b/rust-book-old/src/images/world-map.png new file mode 100644 index 00000000..4fc2664f Binary files /dev/null and b/rust-book-old/src/images/world-map.png differ diff --git a/rust-book-old/src/images/world_flow.png b/rust-book-old/src/images/world_flow.png new file mode 100644 index 00000000..6812f3e8 Binary files /dev/null and b/rust-book-old/src/images/world_flow.png differ diff --git a/rust-book-old/src/images/worlds-dev-icon-word.png b/rust-book-old/src/images/worlds-dev-icon-word.png new file mode 100644 index 00000000..3e50b09a Binary files /dev/null and b/rust-book-old/src/images/worlds-dev-icon-word.png differ diff --git a/rust-book-old/src/images/worlds-dev-icon.png b/rust-book-old/src/images/worlds-dev-icon.png new file mode 100644 index 00000000..d8327a52 Binary files /dev/null and b/rust-book-old/src/images/worlds-dev-icon.png differ diff --git a/rust-book-old/src/misc/contributors.md b/rust-book-old/src/misc/contributors.md new file mode 100644 index 00000000..cfa655fe --- /dev/null +++ b/rust-book-old/src/misc/contributors.md @@ -0,0 +1,51 @@ +## Contributing to Dojo Book + +As the Dojo engine progresses and develops, it is essential for the Dojo book to keep pace with these advancements. Updating and refining the book ensures that it remains a relevant and valuable resource for those interested in understanding and utilizing the latest Dojo engine features and capabilities. All help is welcome! + +### The purpose of the book + +The Dojo book is designed to be a comprehensive resource that caters to users at various levels of experience. It aims to serve as both an introductory guide for those new to Dojo and its ancillary packages, as well as a reference for more experienced users seeking to deepen their understanding of the engine's features and capabilities. + +The book is split into some major chapters: + +- Framework Theory +- Getting Started +- Building a World + +### Code of Conduct + +The book follows the [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct). + +### Ways to contribute + +#### Issues + +If you think that some content is missing or out-of-date, feel free to open an issue. If you find multiple pieces of content lacking, please open up a separate issue for each. + +The issues will then be labeled so other contributors can find chunks of work they are interested in more easily. + +The issue should contain what is missing, or what could be improved, in as much detail as you deem necessary. + +#### Pull requests + +Feel free to contribute changes to the book by opening a pull request - anything is welcome, from reformulating a sentence, fixing a typo, to adding new sections or chapters. + +When your pull request is open, other contributors will take a look and may request changes. Do not be discouraged! + +### Writing style + +This section documents a few standards for writing used throughout the book. + +#### Chapters start with a second level heading + +We use: + +```md +## Some Page +``` + +We do not use: + +```md +# Some Page +``` diff --git a/rust-book-old/src/theory/autonomous-worlds.md b/rust-book-old/src/theory/autonomous-worlds.md new file mode 100644 index 00000000..0031b6b0 --- /dev/null +++ b/rust-book-old/src/theory/autonomous-worlds.md @@ -0,0 +1,24 @@ +## Autonomous Worlds + +> "Autonomous worlds represent persistent, permissionless, and decentralized open environments that users can freely interact with and contribute to." + +The precise definition of Autonomous Worlds (AWs) remains somewhat elusive, as it is more of an abstract concept that has yet to be fully crystallized. Lattice first [introduced](https://0xparc.org/blog/autonomous-worlds) the terminology in 2022, but the notion of open worlds operating on the blockchain has been around for a while. The abstraction introduced by MUD served as a catalyst for the market to recognize the potential of these worlds. + +Autonomous Worlds share notable similarities with blockchains in their fundamental nature. Once established, they persist, maintaining their state throughout the lifespan of the chain. Players can join or leave, and developers can expand these worlds by deploying features in a permissionless manner, much like how contracts are added to a chain. While there is no universally accepted definition for an Autonomous World, we believe that a game must possess at least the following two essential features to be considered as such: + +1. Decentralized data availability layer: While the state execution may reside on a centralized layer, it is crucial that the state can be reconstructed if the execution layer ceases to exist. Rollups offer a solution, providing increased capacity execution layers while ensuring data is permanently settled on Ethereum. This guarantees the world's perpetual persistence. + +2. Permissionless entry point for expanding the world: The World contract must be capable of accepting new systems and components without requiring permission. While this doesn't imply that every component and system will be utilized, they must adhere to this pattern, ensuring open and unrestricted access for potential enhancements. + +We're firm believers in the potential for Autonomous Worlds to catalyze the exploration of novel forms in the medium provided by zk proofs and blockchain technology. This is not only about games, but also about new forms of artwork, coordination, fun, emerging from tinkering and radical innovation, eventually questioning the very notion of "play" in this brave new decentralized and trustless world. + +### Homework + +- [Wired - Autonomous Worlds Primer](https://www.wired.com/story/autonomous-worlds-aim-to-free-online-games-from-corporate-control/) +- [0xParc - Autonomous Worlds (Part 1)](https://0xparc.org/blog/autonomous-worlds) +- [Gubsheep - The Strongest Crypto Gaming Thesis](https://gubsheep.substack.com/p/the-strongest-crypto-gaming-thesis) +- [Lattice - MUD: An engine for Autonomous Worlds](https://lattice.xyz/blog/mud-an-engine-for-autonomous-worlds) +- [Guiltygyoza - Game 2.0](https://www.guiltygyoza.xyz/2022/07/game2) +- [Guiltygyoza - Composable Engineering](https://www.guiltygyoza.xyz/2023/05/composable-engineering) +- [Jay Springett - Wind-up Worlds](https://www.thejaymo.net/2022/05/06/wind-up-worlds/) +- [Are.na collection on Autonomous Worlds](https://www.are.na/sylve-chevet/on-chain-realities-and-autonomous-worlds) diff --git a/src/theory/cairo.md b/rust-book-old/src/theory/cairo.md similarity index 100% rename from src/theory/cairo.md rename to rust-book-old/src/theory/cairo.md diff --git a/src/theory/faqs.md b/rust-book-old/src/theory/faqs.md similarity index 100% rename from src/theory/faqs.md rename to rust-book-old/src/theory/faqs.md diff --git a/src/theory/what-is-dojo.md b/rust-book-old/src/theory/what-is-dojo.md similarity index 100% rename from src/theory/what-is-dojo.md rename to rust-book-old/src/theory/what-is-dojo.md diff --git a/rust-book-old/src/toolchain/dojoup.md b/rust-book-old/src/toolchain/dojoup.md new file mode 100644 index 00000000..7382bd3d --- /dev/null +++ b/rust-book-old/src/toolchain/dojoup.md @@ -0,0 +1,87 @@ +# `dojoup` + +Update or revert to a specific Dojo branch with ease. + +## Installing + +```sh +curl -L https://install.dojoengine.org | bash +``` + +## Usage + +To install latest **stable** version: + +```sh +dojoup +``` + +> Note: You may have to install `jq` to use `dojoup`. You can do so with the following commands: + +```sh +# Debian +sudo apt-get install jq + +# Mac +brew install jq +``` + +To install a specific **version** (in this case the `nightly` version): + +```sh +dojoup --version nightly +``` + +To install a specific **branch** (in this case the `release/0.1.0` branch's latest commit): + +```sh +dojoup --branch release/0.1.0 +``` + +To install a **fork's main branch** (in this case `tarrencev/dojo`'s main branch): + +```sh +dojoup --repo tarrencev/dojo +``` + +To install a **specific branch in a fork** (in this case the `patch-10` branch's latest commit in `tarrencev/dojo`): + +```sh +dojoup --repo tarrencev/dojo --branch patch-10 +``` + +To install from a **specific Pull Request**: + +```sh +dojoup --pr 1071 +``` + +To install from a **specific commit**: + +```sh +dojoup -c 94bfdb2 +``` + +To install a local directory or repository (e.g. one located at `~/git/dojo`, assuming you're in the home directory) + +##### Note: --branch, --repo, and --version flags are ignored during local installations. + +```sh +dojoup --path ./git/dojo +``` + +--- + +**Tip**: All flags have a single character shorthand equivalent! You can use `-v` instead of `--version`, etc. + +--- + +### Precompiled binaries + +Precompiled binaries are available from the [GitHub releases page](https://github.com/dojoengine/dojo/releases). +These are better managed by using [Dojoup](#using-dojoup). + +> ℹ️ **Note** +> +> If you're on Windows, you will need to install and use [Git BASH](https://gitforwindows.org/) or [WSL](https://learn.microsoft.com/en-us/windows/wsl/install), +> as your terminal, since Dojoup currently does not support Powershell or Cmd. diff --git a/rust-book-old/src/toolchain/katana/development.md b/rust-book-old/src/toolchain/katana/development.md new file mode 100644 index 00000000..459110d3 --- /dev/null +++ b/rust-book-old/src/toolchain/katana/development.md @@ -0,0 +1 @@ +# Development diff --git a/src/toolchain/katana/overview.md b/rust-book-old/src/toolchain/katana/overview.md similarity index 100% rename from src/toolchain/katana/overview.md rename to rust-book-old/src/toolchain/katana/overview.md diff --git a/rust-book-old/src/toolchain/katana/reference.md b/rust-book-old/src/toolchain/katana/reference.md new file mode 100644 index 00000000..28e28ba1 --- /dev/null +++ b/rust-book-old/src/toolchain/katana/reference.md @@ -0,0 +1,260 @@ +## katana reference + +### NAME + +katana - Create a local testnet node for deploying and testing Starknet smart contracts. + +### USAGE + +```sh +katana [OPTIONS] +``` + +### DESCRIPTION + +Create a local testnet node for deploying and testing Starknet smart contracts. Katana supports deployment and execution of the **new** as well as the **legacy** (Cairo 0) Cairo contracts. + +This section covers an extensive list of information about Mining Modes, Supported RPC Methods, Katana flags and their usages. You can run multiple flags at the same time. + +#### Mining Modes + +In Katana, mining modes determine how frequent blocks are mined. By default, a new block is automatically mined as soon as a transaction is submitted. + +You can switch from the default mining behaviour to interval mining, where a new block is created at a fixed time interval selected by the user. To enable this mode of mining, use the `--block-time ` flag, as demonstrated in the following example. + +```sh +# Produces a new block every 10 seconds +katana --block-time 10000 +``` + +#### Forking + +Katana supports forking from a Starknet RPC provider. You can configure your node to enable the forking feature by providing a valid RPC provider using the `--rpc-url ` flag., which would initiate Katana to fork the latest block of the provided network. If you would like to fork from a specific block, you can do so using `--fork-block-number `. + +NOTE: This does not allow fetching of historical blocks but only blocks that are mined by Katana. However, support for fetching historical blocks will be added in the future. + +```sh +# Forks the network at block 1200 +katana --rpc-url http://your-rpc-provider.com --fork-block-number 1200 +``` + +#### Messaging + +Katana also allows users to perform L1 <-> L2 integration using the messaging feature. There are two types of messaging service supported by Katana: + +1. _Ethereum_ +2. _Starknet_ (**experimental**) + +If configured to _Ethereum_ messaging, Katana will listen/send messages on an Ethereum chain. This type of messaging behaves similar to the canonical Starknet sequencer with the exception that messages from L2 -> L1 will be sent directly to the settlement chain for consumption, instead of having to wait for the corresponding blocks of the messages to be proven on the settlement chain (which in reality would be a very time consuming process). + +The _Starknet_ messaging, however, is an experimental feature that allows Katana to listen/send messages on a Starknet chain. It attempts to replicate the behaviour of Ethereum messaging but with a Starknet chain as the settlement layer. This is achieved by having Katana listen to the Starknet chain for new blocks and then sending the messages to the settlement chain for consumption. This is an experimental and opinionated feature, and is not recommended for production use. + +```sh +katana --messaging path/to/messaging/config.json +``` + +The messaging config file is a JSON file that contains the following fields: + +```json +{ + /// The type of messaging service to use. Can be either "ethereum" or "starknet". + "chain": "ethereum", + /// The RPC-URL of the settlement chain. + "rpc_url": "http://127.0.0.1:8545", + /// The messaging-contract address on the settlement chain. + "contract_address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + /// The address to use for settling messages. It should be a valid address that + /// can be used to send a transaction on the settlement chain. + "sender_address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + /// The private key associated to `sender_address`. + "private_key": "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + /// The interval, in seconds, at which the messaging service will fetch and settle messages + /// from/to the settlement chain. + "interval": 2, + /// The block on settlement chain from where Katana will start fetching messages. + "from_block": 0 +} +``` + +#### Supported Transport Layers + +Only HTTP connection is supported at the moment. The server listens on port 5050 by default, but it can be changed by running the following command: + +```sh +katana --port +``` + +#### Starknet Feature Compatibility + +##### Supported Transaction Type + +| Type | Version | +| -------------- | ------- | +| INVOKE | 1 | +| DECLARE | 1, 2 | +| DEPLOY_ACCOUNT | | + +#### Supported RPC Methods + +##### Starknet Methods + +Katana supports version **v0.3.0** of the Starknet JSON-RPC specifications. The standard methods are based on [this](https://github.com/starkware-libs/starknet-specs/tree/v0.3.0) reference. + +- `starknet_blockNumber` +- `starknet_blockHashAndNumber` +- `starknet_getBlockWithTxs` +- `starknet_getBlockWithTxHashes` +- `starknet_getBlockTransactionCount` +- `starknet_getTransactionByHash` +- `starknet_getTransactionByBlockIdAndIndex` +- `starknet_getTransactionReceipt` +- `starknet_pendingTransactions` +- `starknet_getStateUpdate` + +- `starknet_call` +- `starknet_estimateFee` + +- `starknet_chainId` + +- `starknet_getNonce` +- `starknet_getEvents` +- `starknet_getStorageAt` +- `starknet_getClassHashAt` +- `starknet_getClass` +- **`starknet_getClassAt`** + +- `starknet_addInvokeTransaction` +- `starknet_addDeclareTransaction` +- `starknet_addDeployAccountTransaction` + +##### Custom Methods + +Katana provides a convenient set of custom RPC methods to quickly and easily configure the node to suit your testing environment. + +`katana_generateBlock` +Mine a new block which includes all currently pending transactions. + +`katana_nextBlockTimestamp` +Get the time for the next block. + +`katana_increaseNextBlockTimestamp` +Increase the time for the block by a given amount of time, in seconds. + +`katana_setNextBlockTimestamp` +Similar to `katana_increaseNextBlockTimestamp` but takes the exact timestamp that you want in the next block. + +`katana_predeployedAccounts` +Get the info for all of the predeployed accounts. + +`katana_setStorageAt` +Set an exact value of a contract's storage slot. + +### OPTIONS + +#### General Options + +`--silent` +     Don't print anything on startup. + +`--no-mining` +     Disable auto and interval mining, and mine on demand instead. + +`-b, --block-time ` +     Block time in milliseconds for interval mining. + +`--dump-state ` +     Dump the state of chain on exit to the given file. +     If the value is a directory, the state will be written to `/state.bin`. + +`--rpc-url ` +     The Starknet RPC provider to fork the network from. + +`--json-log` +     Output logs in JSON format. + +`--fork-block-number ` +     Fork the network at a specific block. + +`--messaging ` +     Configure the messaging service to allow Katana to listen/send messages on a settlement chain that can be either Ethereum or another Starknet sequencer (experimental). + +`-h, --help` +     Print help (see a summary with '-h'). + +`-V, --version` +     Print version information. + +#### Server Options + +`-p, --port ` +     Port number to listen on. [default: 5050] + +`--host ` +     The IP address the server will listen on. + +#### Starknet Options + +`--seed ` +     Specify the seed for randomness of accounts to be predeployed. + +`--accounts ` +     Number of pre-funded accounts to generate. [default: 10] + +`--disable-fee` +     Disable charging fee for transactions. + +#### Environment Options + +`--chain-id ` +     The chain ID. [default: KATANA] + +`--gas-price ` +     The gas price. + +`--validate-max-steps ` +     The maximum number of steps available for the account validation logic. + +`--invoke-max-steps ` +     The maximum number of steps available for the account execution logic. + +### Shell Completions + +`katana` completions shell + +Generates a shell completions script for the given shell. + +Supported shells are: + +- bash +- elvish +- fish +- powershell +- zsh + +#### EXAMPLES + +Generate shell completions script for `bash` and appends it to a `.bashrc` file: + +```bash +katana completions bash >> ~/.bashrc +``` + +### EXAMPLES + +1. Create 15 dev accounts and disable transaction fee mechanism + +```sh +katana --accounts 15 --disable-fee +``` + +2. Set the chain id to `SN_GOERLI` and run the server on port 8545 + +```sh +katana --chain-id SN_GOERLI --port 8545 +``` + +3. Load previously stored state and dump the state of this session to a file on shutdown + +```sh +katana --load-state ./dump-state.bin --dump-state ./dump-state.bin +``` diff --git a/rust-book-old/src/toolchain/slot/deployments-commands/deployments.md b/rust-book-old/src/toolchain/slot/deployments-commands/deployments.md new file mode 100644 index 00000000..806911e0 --- /dev/null +++ b/rust-book-old/src/toolchain/slot/deployments-commands/deployments.md @@ -0,0 +1,26 @@ +## slot deployments + +It allows you the manage your slot deployments. + +### Commands + +`create` +    Create a new deployment. + +`delete` +    Delete a deployment. + +`update` +    Update a deployment. + +`describe` +    Describe a deployment's configuration. + +`list` +    List all deployments. + +`logs` +    Fetch logs for a deployment. + +`help` +    Print this message or the help of the given subcommand(s) diff --git a/src/toolchain/slot/overview.md b/rust-book-old/src/toolchain/slot/overview.md similarity index 100% rename from src/toolchain/slot/overview.md rename to rust-book-old/src/toolchain/slot/overview.md diff --git a/rust-book-old/src/toolchain/slot/reference.md b/rust-book-old/src/toolchain/slot/reference.md new file mode 100644 index 00000000..c62e1a6e --- /dev/null +++ b/rust-book-old/src/toolchain/slot/reference.md @@ -0,0 +1,23 @@ +## slot reference + +### Name + +slot - a toolchain developed for rapidly spinning up Katana and Torii instances. + +### Usage + +```sh +slot [COMMANDS] [OPTIONS] +``` + +### Commands + +`auth` +     Manage auth credentials for the Slot CLI. + +[`deployments`](./deployments-commands/deployments.md) + +     Manage Slot deployments. + +`help` +     Print this message or the help of the given subcommand(s) diff --git a/rust-book-old/src/toolchain/sozo/common-options/offline.md b/rust-book-old/src/toolchain/sozo/common-options/offline.md new file mode 100644 index 00000000..2e435b3f --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common-options/offline.md @@ -0,0 +1,19 @@ +# offline + +## use sozo offline + +`--offline` +    Run without accessing the network. +    [env: SOZO_OFFLINE=] + +### USAGE + +```sh +sozo --offline [COMMAND] +``` + +For example + +```sh +sozo --offline build +``` diff --git a/rust-book-old/src/toolchain/sozo/common-options/profile.md b/rust-book-old/src/toolchain/sozo/common-options/profile.md new file mode 100644 index 00000000..a90ce4b6 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common-options/profile.md @@ -0,0 +1,40 @@ +## use sozo profiles + +Profiles can be convenient when dealing with multiple environments (dev, staging, prod) + +`--profile` +    Specify profile to use by name. + +`--dev` +    Use dev profile. + +`--release` +    Use release profile. + +### USAGE + +Multiple profiles can be defined in Scarb.toml + +```sh +[profile.dev.tool.dojo.env] +rpc_url = "http://localhost:5050" +account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" + +[profile.staging.tool.dojo.env] +rpc_url = "https://api.cartridge.gg/x/mydojoproject/katana" +account_address = "0x5686a647a9cdd63ade617e0baf3b364856b813b508f03903eb58a7e622d5855" +private_key = "0x33003003001800009900180300d206308b0070db00121318d17b5e6262150b" +``` + +Then used with sozo commands + +```sh +sozo --profile dev migrate +``` + +is equivalent to + +```sh +sozo migrate --rpc-url http://localhost:5050 --account-address 0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973 --private-key 0x1800000000300000180000000000030000000000003006001800006600 +``` diff --git a/rust-book-old/src/toolchain/sozo/common/account-options.md b/rust-book-old/src/toolchain/sozo/common/account-options.md new file mode 100644 index 00000000..7e48da08 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common/account-options.md @@ -0,0 +1,3 @@ +`--account-address` _ACCOUNT_ADDRESS_ +    The Starknet account address. +    ENV: `DOJO_ACCOUNT_ADDRESS` diff --git a/rust-book-old/src/toolchain/sozo/common/signer-options-keystore.md b/rust-book-old/src/toolchain/sozo/common/signer-options-keystore.md new file mode 100644 index 00000000..f58cca5f --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common/signer-options-keystore.md @@ -0,0 +1,6 @@ +`--keystore` _PATH_ +    Use the keystore in the given folder or file. + +`--password` _PASSWORD_ +    The keystore password. Used with --keystore. +    ENV: `DOJO_KEYSTORE_PASSWORD` diff --git a/rust-book-old/src/toolchain/sozo/common/signer-options-raw.md b/rust-book-old/src/toolchain/sozo/common/signer-options-raw.md new file mode 100644 index 00000000..21f6eeb2 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common/signer-options-raw.md @@ -0,0 +1,3 @@ +`--private-key` _PRIVATE_KEY_ +    The raw private key associated with the account contract. +    ENV: `DOJO_PRIVATE_KEY` diff --git a/rust-book-old/src/toolchain/sozo/common/starknet-options.md b/rust-book-old/src/toolchain/sozo/common/starknet-options.md new file mode 100644 index 00000000..acc58704 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common/starknet-options.md @@ -0,0 +1,3 @@ +`--rpc-url` _URL_ +    The Starknet RPC endpoint. [default: http://localhost:5050] +    ENV: `STARKNET_RPC_URL` diff --git a/rust-book-old/src/toolchain/sozo/common/world-options.md b/rust-book-old/src/toolchain/sozo/common/world-options.md new file mode 100644 index 00000000..358e0e18 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/common/world-options.md @@ -0,0 +1,3 @@ +`--world` _WORLD_ADDRESS_ +    The address of the World contract. +    ENV: `DOJO_WORLD_ADDRESS` diff --git a/rust-book-old/src/toolchain/sozo/development.md b/rust-book-old/src/toolchain/sozo/development.md new file mode 100644 index 00000000..459110d3 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/development.md @@ -0,0 +1 @@ +# Development diff --git a/src/toolchain/sozo/overview.md b/rust-book-old/src/toolchain/sozo/overview.md similarity index 100% rename from src/toolchain/sozo/overview.md rename to rust-book-old/src/toolchain/sozo/overview.md diff --git a/rust-book-old/src/toolchain/sozo/project-commands/build.md b/rust-book-old/src/toolchain/sozo/project-commands/build.md new file mode 100644 index 00000000..f88c90e5 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/project-commands/build.md @@ -0,0 +1,7 @@ +## sozo build + +`build` is used to compile the cairo contracts, generating the necessary artifacts for deployment. + +```sh +sozo build +``` diff --git a/rust-book-old/src/toolchain/sozo/project-commands/init.md b/rust-book-old/src/toolchain/sozo/project-commands/init.md new file mode 100644 index 00000000..ed21dc69 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/project-commands/init.md @@ -0,0 +1,7 @@ +## sozo init + +`init` is used to initialize a new project. It will initialize a new project in the current directory by cloning the [dojo-starter](https://github.com/dojoengine/dojo-starter). + +```sh +sozo init +``` diff --git a/rust-book-old/src/toolchain/sozo/project-commands/migrate.md b/rust-book-old/src/toolchain/sozo/project-commands/migrate.md new file mode 100644 index 00000000..6ea01a24 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/project-commands/migrate.md @@ -0,0 +1,58 @@ +## sozo migrate + +`migrate` is used to perform the migration (deployment) process, declaring and deploying contracts as necessary to deploy or update the World. + +Changes made to the local World after the initial deployment, can easily be pushed to the remote counterpart by running `sozo migrate --world ` with `WORLD_ADDRESS` being the address of the remote World. In the background, `migrate` will compute the diffs of the local and remote World, then, start constructing a migration strategy to determine, if any, which part of the local World needs to be pushed upstream. + +### USAGE + +```sh +sozo migrate [OPTIONS] +``` + +### OPTIONS + +#### General Options + +`--name` _NAME_ +    Name of the World. At the moment, the only usage for this option is to be used as a salt when deploying the World contract to avoid address conflicts. This option is **required** when performing the initial migration of the World. + +#### World Options + +{{#include ../common/world-options.md}} + +#### Starknet Options + +{{#include ../common/starknet-options.md}} + +#### Account Options + +{{#include ../common/account-options.md}} + +#### Signer Options - Raw + +{{#include ../common/signer-options-raw.md}} + +#### Signer Options - Keystore + +{{#include ../common/signer-options-keystore.md}} + +### EXAMPLES + +1. Deploying your World for the first time to a local Katana node + +```sh +sozo migrate --name ohayo --rpc-url http://localhost:5050 +``` + +2. Updating a remote World after making some changes + +```sh +sozo migrate --world 0x123456 +``` + +3. Deploying your World using [profile options](../common-options/profile.md) + +```sh +sozo --profile dev migrate +``` diff --git a/rust-book-old/src/toolchain/sozo/project-commands/test.md b/rust-book-old/src/toolchain/sozo/project-commands/test.md new file mode 100644 index 00000000..cc48b1e8 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/project-commands/test.md @@ -0,0 +1,7 @@ +## sozo test + +`test` is used to test the project's cairo contracts. It will run all tests found within the project. + +```sh +sozo test +``` diff --git a/rust-book-old/src/toolchain/sozo/reference.md b/rust-book-old/src/toolchain/sozo/reference.md new file mode 100644 index 00000000..ecaba70f --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/reference.md @@ -0,0 +1,22 @@ +## sozo reference + +### Common options + +- [profile](./common-options/profile.md) +- [offline](./common-options/offline.md) + +### Project Commands + +- [init](./project-commands/init.md) +- [build](./project-commands/build.md) +- [test](./project-commands/test.md) +- [migrate](./project-commands/migrate.md) + +### World Commands + +- [execute](./world-commands/execute.md) +- [register](./world-commands/register.md) +- [system](./world-commands/system.md) +- [model](./world-commands/model.md) +- [events](./world-commands/events.md) +- [auth](./world-commands/auth.md) diff --git a/rust-book-old/src/toolchain/sozo/world-commands/auth.md b/rust-book-old/src/toolchain/sozo/world-commands/auth.md new file mode 100644 index 00000000..59ee20fb --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/auth.md @@ -0,0 +1,19 @@ +## sozo auth + +`auth` is used to manage world authorization. + +```sh +sozo auth [OPTIONS] --world +``` + +```sh +Commands: + writer Auth a system with the given calldata. + help Print this message or the help of the given subcommand(s) +``` + +```sh +# example: writer - auth a system with the given calldata +# This will auth the spawn system with the writer role for Position component +sozo auth writer Moves --world +``` diff --git a/rust-book-old/src/toolchain/sozo/world-commands/events.md b/rust-book-old/src/toolchain/sozo/world-commands/events.md new file mode 100644 index 00000000..e16da2d9 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/events.md @@ -0,0 +1,7 @@ +## sozo events + +`events` is used to queries world events. + +```sh +sozo events +``` diff --git a/rust-book-old/src/toolchain/sozo/world-commands/execute.md b/rust-book-old/src/toolchain/sozo/world-commands/execute.md new file mode 100644 index 00000000..00928675 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/execute.md @@ -0,0 +1,48 @@ +## sozo execute + +`execute` is used to execute a World's system. + +Performing a system execution requires sending a transaction, therefore, `execute` expects an account address as well as its respective private key in order to sign the transaction before sending it. + +### USAGE + +```sh +# you can use the name or address of the contract +sozo execute +``` + +### OPTIONS + +#### General Options + +`--calldata` _CALLDATA_ +    The calldata to be passed to the system that you want to execute. +    Comma separated values e.g., 0x12345,0x69420. + +#### World Options + +{{#include ../common/world-options.md}} + +#### Starknet Options + +{{#include ../common/starknet-options.md}} + +#### Account Options + +{{#include ../common/account-options.md}} + +#### Signer Options - Raw + +{{#include ../common/signer-options-raw.md}} + +#### Signer Options - Keystore + +{{#include ../common/signer-options-keystore.md}} + +### EXAMPLES + +1. Executing the _position_ system which takes two values (_x_: 0x77 and _y_: 0x44) + +```sh +sozo execute moving_contract position --calldata 0x77,0x44 +``` diff --git a/rust-book-old/src/toolchain/sozo/world-commands/model.md b/rust-book-old/src/toolchain/sozo/world-commands/model.md new file mode 100644 index 00000000..8d860955 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/model.md @@ -0,0 +1,82 @@ +# models + +## sozo model + +`model` is used to interact with a World's models. It is useful for querying about a model's information, or a model value of an entity. + +### USAGE + +```sh +sozo model + +Commands: + class-hash Get the class hash of a model + schema Retrieve the schema for a model + get Get the model value for an entity +``` + +### SUBCOMMANDS + +**Note**: Before to execute the following subcommands, ensure you have added your `world address` to your Scarb.toml file. + +```toml +[tool.dojo.env] +rpc_url = "http://localhost:5050/" +# Default account for katana with seed = 0 +account_address = "0x517ececd29116499f4a1b64b094da79ba08dfd54a3edaa316134c41f8160973" +private_key = "0x1800000000300000180000000000030000000000003006001800006600" +world_address = "0x28f5999ae62fec17c09c52a800e244961dba05251f5aaf923afabd9c9804d1a" +``` + +#### `class-hash` + +Get the class hash of a model + +```sh +sozo model class-hash +``` + +##### Arguments + +_`NAME`_ +    The name of the model + +#### `schema` + +Retrieve the schema for a model + +```sh +sozo model schema +``` + +##### Arguments + +_`NAME`_ +    The name of the model + +#### `get` + +Get the model value for an entity + +```sh +sozo model get [KEYS]... +``` + +##### Arguments + +_`NAME`_ +     The name of the model + +_`KEYS`_ +     The keys of the entity that you want to query. +     Comma separated values e.g., 0x12345,0x69420,... + +### OPTIONS + +#### World Options + +{{#include ../common/world-options.md}} + +#### Starknet Options + +{{#include ../common/starknet-options.md}} diff --git a/rust-book-old/src/toolchain/sozo/world-commands/register.md b/rust-book-old/src/toolchain/sozo/world-commands/register.md new file mode 100644 index 00000000..fbb1ed7e --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/register.md @@ -0,0 +1,24 @@ +## sozo register + +`register` is used to register new systems and components. + +```sh +sozo register [OPTIONS] +``` + +```sh +Commands: + component Register a component to a world. + system Register a system to a world. + help Print this message or the help of the given subcommand(s) +``` + +```sh +# example: component - register a component to a world +# this will register the Moves component to the world +sozo register component Moves + +# example: system - register a system to a world +# this will register the spawn system to the world +sozo register system spawn +``` diff --git a/rust-book-old/src/toolchain/sozo/world-commands/system.md b/rust-book-old/src/toolchain/sozo/world-commands/system.md new file mode 100644 index 00000000..160f4321 --- /dev/null +++ b/rust-book-old/src/toolchain/sozo/world-commands/system.md @@ -0,0 +1,65 @@ +## sozo system + +`system` is used to interact with a World's systems. It is useful for querying about a system's information. + +### USAGE + +```sh +sozo system + +Commands: + get Get the class hash of a system. + dependency Retrieve the component dependencies of a system. +``` + +### SUBCOMMANDS + +#### `get` + +Get the class hash of a system + +```sh +sozo system get +``` + +##### Arguments + +_`NAME`_ +    The name of the system + +#### `dependency` + +Retrieve the component dependencies of a system + +```sh +sozo system dependency +``` + +##### Arguments + +_`NAME`_ +    The name of the system + +### OPTIONS + +#### World Options + +{{#include ../common/world-options.md}} + +#### Starknet Options + +{{#include ../common/starknet-options.md}} + +### EXAMPLES + +1. Get the class hash of the _spawn_ system + +```sh +sozo system get spawn +``` + +2. Get the component dependencies of the _spawn_ system + +```sh +sozo system dependency spawn +``` diff --git a/src/toolchain/torii/graphql.md b/rust-book-old/src/toolchain/torii/graphql.md similarity index 100% rename from src/toolchain/torii/graphql.md rename to rust-book-old/src/toolchain/torii/graphql.md diff --git a/src/toolchain/torii/grpc.md b/rust-book-old/src/toolchain/torii/grpc.md similarity index 100% rename from src/toolchain/torii/grpc.md rename to rust-book-old/src/toolchain/torii/grpc.md diff --git a/src/toolchain/torii/overview.md b/rust-book-old/src/toolchain/torii/overview.md similarity index 100% rename from src/toolchain/torii/overview.md rename to rust-book-old/src/toolchain/torii/overview.md diff --git a/rust-book-old/src/toolchain/torii/reference.md b/rust-book-old/src/toolchain/torii/reference.md new file mode 100644 index 00000000..2ec50f41 --- /dev/null +++ b/rust-book-old/src/toolchain/torii/reference.md @@ -0,0 +1,59 @@ +## torii reference + +### Name + +torii - An automatic indexer and networking layer for a world contract. + +### USAGE + +```sh +torii [OPTIONS] +``` + +### DESCRIPTION + +`torii` starts the indexer and exposes GraphQL/gRPC API endpoints. The indexer queries the specified Starknet RPC endpoint for transaction blocks and listens for transactions related to the world contract. These transactions can include component/system registrations, entity state updates, system calls, and events. The parsed data is then stored in a local SQLite database. + +The GraphQL and gRPC API endpoints run in tandem with the indexer, providing custom queries specific to the world contract for client applications. + +#### Database URL + +`torii` uses a sqlite database to store indexed data. The database can be stored either in-memory or persistently on the filesystem. + +- The in-memory database is ephemeral and only lasts as long as the indexer is running. This is a fast and simple option to start the indexer for development/testing. +- Persistent storage should be used in production. It relies on the local filesystem for storage. + +Note: If using in-memory db, the memory will be garbage collected after a period of inactivity, causing queries to result in errors. Workaround is to use a persistent database. + +```sh +# Persistent database storage using file indexer.db +torii --database indexer.db +``` + +### OPTIONS + +#### General Options + +`-w, --world` +     Address of the world contract to index + +`--rpc` +     Starknet RPC endpoint to use [default: http//localhost:5050] + +`-d, --database ` +     Database filepath (ex: indexer.db) [default: :memory:] + +`-s, --start-block ` +     Specify a block to start indexing from, ignored if stored head exists [default: 0] + +`--allowed-origins ` +     Specify allowed origins for api endpoints (comma-separated list of allowed origins, or "\*" for all) [default: *] + +`--external-url ` +     The external url of the server, used for configuring the GraphQL Playground in a hosted environment + +`-h, --help` +     Print help + +`-V, --version` +     Print version diff --git a/rust-book-old/src/tutorial/deploy-using-slot/main.md b/rust-book-old/src/tutorial/deploy-using-slot/main.md new file mode 100644 index 00000000..9530f0c8 --- /dev/null +++ b/rust-book-old/src/tutorial/deploy-using-slot/main.md @@ -0,0 +1,94 @@ +# Deploy your game using Slot + +Welcome to this tutorial where we'll guide you through deploying a project using the Slot. + +--- + +Before we start, make sure you are using the latest dojo version. Run `dojoup` to have the latest version installed. + +Now, let's create a new folder and initialize it with sozo. + +```sh +mkdir dojo-starter && cd dojo-starter +sozo init +``` + +First, we need to set up our configuration, starting by authenticating with Cartridge. To do this, run the following command, which will then prompt a new screen where you will need to go through the authentication process. + +```sh +slot auth login + +# Slot Auth debug (if old auth credentials): +rm ~/Library/Application\ Support/slot/credentials.json +``` + +Once successful, you can create a new deployment with a unique `DEPLOYMENT_NAME`. To do this, run the following command: + +```sh +slot deployments create DEPLOYMENT_NAME katana +``` + +After that, you should receive the RPC endpoint for the katana slot. Now, you can use that and update your `Scarb.toml` file with the new RPC endpoint as follows: + +```toml +[tool.dojo.env] +rpc_url = "YOUR_NEW_RPC_URL" +``` + +Now, you can stream katana in a new terminal. Open a new terminal and run the following command: + +```sh +slot deployments logs DEPLOYMENT_NAME katana -f +``` + +Then, copy the account address and the private key from the first account into the `Scarb.toml` file and replace the existing ones as follows: + +```toml +account_address = "YOUR_NEW_ACCOUNT_ADDRESS" +private_key = "YOUR_NEW_PRIVATE_KEY" +``` + +Note: For each new Katana slot, a different account seed is used, making all the accounts unique! + +--- + +Once finished with the new configurations, we are ready to build and migrate the project. To build the project, run the following command: + +```sh +sozo build +``` + +Now, let's migrate the project to our new katana slot: + +```sh +sozo migrate --name YOUR_PROJECT_NAME +``` + +If the migrations have been successful, you will receive the `WORLD_ADDRESS`, which then you can use to interact with your world. + +```sh +πŸŽ‰ Successfully migrated World at address WORLD_ADDRESS + +✨ Updating manifest.json... + +✨ Done. + +``` + +Congratulations! You have successfully deployed your project with a Katana slot. + +## Torii + +To initiate a Torri indexer slot, execute the following command: + +```sh +slot deployments create DEPLOYMENT_NAME torii --world YOUR_WORLD_ADDRESS --rpc YOUR_NEW_RPC_URL --start-block 1 +``` + +Once deployment is successful, you should receive the endpoints for GraphQL and gRPC. + +If you wish to stream the logs, you can run the following command in a new terminal: + +```sh +slot deployments logs DEPLOYMENT_NAME torii -f +``` diff --git a/src/tutorial/onchain-chess/0-setup.md b/rust-book-old/src/tutorial/onchain-chess/0-setup.md similarity index 100% rename from src/tutorial/onchain-chess/0-setup.md rename to rust-book-old/src/tutorial/onchain-chess/0-setup.md diff --git a/src/tutorial/onchain-chess/1-action.md b/rust-book-old/src/tutorial/onchain-chess/1-action.md similarity index 100% rename from src/tutorial/onchain-chess/1-action.md rename to rust-book-old/src/tutorial/onchain-chess/1-action.md diff --git a/rust-book-old/src/tutorial/onchain-chess/2-move.md b/rust-book-old/src/tutorial/onchain-chess/2-move.md new file mode 100644 index 00000000..944c4b08 --- /dev/null +++ b/rust-book-old/src/tutorial/onchain-chess/2-move.md @@ -0,0 +1,236 @@ +# 2 Move function + +1. Write a `move` function that accepts the `current position`, `next position`, `caller address`, and `game_id`. The `move` function should look like this: + +```c + #[abi(embed_v0)] + impl PlayerActionsImpl of IActions { + fn spawn( + self: @ContractState, white_address: ContractAddress, black_address: ContractAddress + ) -> u32 { + // Rest of code + } + fn move( + self: @ContractState, + curr_position: Vec2, + next_position: Vec2, + caller: ContractAddress, //player + game_id: u32 + ) { + let world = self.world_dispatcher.read(); + let mut current_piece = get!(world, (game_id, curr_position), (Piece)); + // check if next_position is out of board or not + assert(!PieceTrait::is_out_of_board(next_position), 'Should be inside board'); + + // check if this is the right move for this piece type + assert( + current_piece.is_right_piece_move(next_position), 'Illegal move for type of piece' + ); + // Get piece data from to next_position in the board + let mut next_position_piece = get!(world, (game_id, next_position), (Piece)); + + let player = get!(world, (game_id, caller), (Player)); + // check if there is already a piece in next_position + assert( + next_position_piece.piece_type == PieceType::None + || player.is_not_my_piece(next_position_piece.color), + 'Already same color piece exist' + ); + + next_position_piece.piece_type = current_piece.piece_type; + next_position_piece.color = player.color; + // make current_piece piece none + current_piece.piece_type = PieceType::None; + current_piece.color = Color::None; + set!(world, (next_position_piece)); + set!(world, (current_piece)); + + // change turn + let mut game_turn = get!(world, game_id, (GameTurn)); + game_turn.player_color = game_turn.next_turn(); + set!(world, (game_turn)); + } + } +``` + +2. Run `sozo build` to compile the code. + + Great, Now we can start testing our functions + +## Test Flow + +- Spawn the test world (`spawn_test_world`) that imports the models in testing. +- Deploy actions contract +- Interact with `spawn` function in the `actions` contract by providing white and black player's wallet addresses as inputs. +- Retrieve the game entity and piece entity created in `actions` contract. +- Ensure the game has been correctly created. +- Verify that each `Piece` is located in the correct position. + +## Unit Tests + +- Copy the test below and add it to your `tests/units.cairo` file. + +```c +#[cfg(test)] +mod tests { + use starknet::ContractAddress; + use dojo::test_utils::{spawn_test_world, deploy_contract}; + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + use chess::models::player::{Player, Color, player}; + use chess::models::piece::{Piece, PieceType, Vec2, piece}; + use chess::models::game::{Game, GameTurn, game, game_turn}; + use chess::actions::{actions, IActionsDispatcher, IActionsDispatcherTrait}; + + // helper setup function + fn setup_world() -> (IWorldDispatcher, IActionsDispatcher) { + // models + let mut models = array![ + game::TEST_CLASS_HASH, + player::TEST_CLASS_HASH, + game_turn::TEST_CLASS_HASH, + piece::TEST_CLASS_HASH + ]; + // deploy world with models + let world = spawn_test_world(models); + + // deploy systems contract + let contract_address = world + .deploy_contract('salt', actions::TEST_CLASS_HASH.try_into().unwrap()); + let actions_system = IActionsDispatcher { contract_address }; + + (world, actions_system) + } + + #[test] + #[available_gas(3000000000000000)] + fn test_spawn() { + let white = starknet::contract_address_const::<0x01>(); + let black = starknet::contract_address_const::<0x02>(); + let (world, actions_system) = setup_world(); + + //system calls + let game_id = actions_system.spawn(white, black); + + //get game + let game = get!(world, game_id, (Game)); + let game_turn = get!(world, game_id, (GameTurn)); + assert(game_turn.player_color == Color::White, 'should be white turn'); + assert(game.white == white, 'white address is incorrect'); + assert(game.black == black, 'black address is incorrect'); + + //get a1 piece + let curr_pos = Vec2 { x: 0, y: 0 }; + let a1 = get!(world, (game_id, curr_pos), (Piece)); + assert(a1.piece_type == PieceType::Rook, 'should be Rook'); + assert(a1.color == Color::White, 'should be white color'); + assert(a1.piece_type != PieceType::None, 'should have piece'); + } + + #[test] + #[available_gas(3000000000000000)] + fn test_move() { + let white = starknet::contract_address_const::<0x01>(); + let black = starknet::contract_address_const::<0x02>(); + + let (world, actions_system) = setup_world(); + let game_id = actions_system.spawn(white, black); + let curr_pos = Vec2 { x: 0, y: 1 }; + let a2 = get!(world, (game_id, curr_pos), (Piece)); + assert(a2.piece_type == PieceType::Pawn, 'should be Pawn'); + assert(a2.color == Color::White, 'should be white color piece 1'); + assert(a2.piece_type != PieceType::None, 'should have piece'); + + let next_pos = Vec2 { x: 0, y: 2 }; + let game_turn = get!(world, game_id, (GameTurn)); + assert(game_turn.player_color == Color::White, 'should be white player turn'); + actions_system.move(curr_pos, next_pos, white.into(), game_id); + + let curr_pos = next_pos; + let c3 = get!(world, (game_id, curr_pos), (Piece)); + assert(c3.piece_type == PieceType::Pawn, 'should be Pawn'); + assert(c3.color == Color::White, 'should be white color piece 2'); + assert(c3.piece_type != PieceType::None, 'should have piece'); + + let game_turn = get!(world, game_id, (GameTurn)); + assert(game_turn.player_color == Color::Black, 'should be black player turn'); + } +} +``` + +## Diving into the Code + +### setup_world + +We should list all models with each having CLASS_HASH as elements and then we deploy world to models with `spawn_test_world` + +```rust,ignore + //models + let mut models = array![ + game::TEST_CLASS_HASH, + player::TEST_CLASS_HASH, + game_turn::TEST_CLASS_HASH, + piece::TEST_CLASS_HASH + ]; + // deploy world with models + let world = spawn_test_world(models); +``` + +After that, we deploy our system contracts, then we return our `world` and `actions_systems` dispatchers. + +```rust,ignore + let contract_address = world + .deploy_contract('salt', actions::TEST_CLASS_HASH.try_into().unwrap()); + let actions_system = IActionsDispatcher { contract_address }; + + (world, actions_system) +``` + +### test_spawn + +First, we'll set up the players address and their colors. + +```rust,ignore + let white = starknet::contract_address_const::<0x01>(); + let black = starknet::contract_address_const::<0x02>(); +``` + +We use `spawn` function in `actions.cairo` to put our pieces on the board. Each square position holds a piece. The system's `spawn` function needs some input i.e the addresses of the players. + +```rust,ignore + // spawn + let game_id = actions_system.spawn(white, black); +``` + +Then we check if the players got their setup address. After that we check if a White rook is at (0,0). Remember, to get a piece that exists on the position, you need to use the keys of the `Piece` model, which are `game_id`, and `curr_pos`. + +```c + //get a1 square + let curr_pos = Vec2 { x: 0, y: 0 }; + let a1 = get!(world, (game_id, curr_pos), (Piece)); + assert(a1.piece_type == PieceType::Rook, 'should be Rook'); + assert(a1.color == Color::White, 'should be white color'); + assert(a1.piece_type != PieceType::None, 'should have piece'); +``` + +### test_move + +Here, after setting up the board, we use `move` function in the contract to make moves. Provide the current position, the next position, the player's address, and the game id. + +```rust,ignore + //Move White Pawn to (0,2) + actions_system.move(curr_pos, next_pos, white.into(), game_id); +``` + +Then we check if a White Pawn is at the new position. + +```c + let curr_pos = next_pos; + let c3 = get!(world, (game_id, curr_pos), (Piece)); + assert(c3.piece_type == PieceType::Pawn, 'should be Pawn'); + assert(c3.color == Color::White, 'should be white color piece 2'); + assert(c3.piece_type != PieceType::None, 'should have piece'); +``` + +## Need help? + +If you're stuck, don't hesitate to ask questions at the [Dojo community](https://discord.gg/akd2yfuRS3)! diff --git a/rust-book-old/src/tutorial/onchain-chess/3-test.md b/rust-book-old/src/tutorial/onchain-chess/3-test.md new file mode 100644 index 00000000..fe9b79f9 --- /dev/null +++ b/rust-book-old/src/tutorial/onchain-chess/3-test.md @@ -0,0 +1,98 @@ +# 3 Test Contract + +In this chapter, we'll use everything we've learned to run a full chess game scenario. + +Here's what we'll do in our test: + +1. Call spawn to setup `white_pawn` to (0,1) and `black_pawn` to (1,6) +2. Move `white_pawn` to (0,3) +3. Move `black_pawn` to (1,4) +4. Move `white_pawn` to (1,4) +5. Capture `black_pawn` + +To place the pieces, use our `spawn` function in our `actions` contract. For moving them, use the `move` contract. Remember to check if a piece can be captured when using `move`. + +Before we get to the code, set up your integration test like this: + +- Copy the test below and add it to your `tests/integration.cairo` file. + +## Full Code + +```c +mod tests { + use chess::models::piece::{Piece, PieceType, Vec2}; + use dojo::world::IWorldDispatcherTrait; + use chess::tests::units::tests::setup_world; + use chess::actions::{IActionsDispatcher, IActionsDispatcherTrait}; + use chess::models::player::{Color}; + + #[test] + #[available_gas(3000000000000000)] + fn integration() { + let white = starknet::contract_address_const::<0x01>(); + let black = starknet::contract_address_const::<0x02>(); + + let (world, actions_system) = setup_world(); + + //system calls + let game_id = actions_system.spawn(white, black); + + //White pawn is setup in (0,1) + let wp_curr_pos = Vec2 { x: 0, y: 1 }; + let a2 = get!(world, (game_id, wp_curr_pos), (Piece)); + assert(a2.piece_type == PieceType::Pawn, 'should be Pawn in (0,1)'); + assert(a2.color == Color::White, 'should be white color'); + assert(a2.piece_type != PieceType::None, 'should have piece in (0,1)'); + + //Black pawn is setup in (1,6) + let bp_curr_pos = Vec2 { x: 1, y: 6 }; + let b7 = get!(world, (game_id, bp_curr_pos), (Piece)); + assert(b7.piece_type == PieceType::Pawn, 'should be Pawn in (1,6)'); + assert(b7.color == Color::Black, 'should be black color'); + assert(b7.piece_type != PieceType::None, 'should have piece in (1,6)'); + + //Move White Pawn to (0,3) + let wp_next_pos = Vec2 { x: 0, y: 3 }; + actions_system.move(wp_curr_pos, wp_next_pos, white.into(), game_id); + + //White pawn is now in (0,3) + let wp_curr_pos = wp_next_pos; + let a4 = get!(world, (game_id, wp_curr_pos), (Piece)); + assert(a4.piece_type == PieceType::Pawn, 'should be Pawn in (0,3)'); + assert(a4.color == Color::White, 'should be white color'); + assert(a4.piece_type != PieceType::None, 'should have piece in (0,3)'); + + //Move black Pawn to (1,4) + let bp_next_pos = Vec2 { x: 1, y: 4 }; + actions_system.move(bp_curr_pos, bp_next_pos, black.into(), game_id); + + //Black pawn is now in (1,4) + let bp_curr_pos = bp_next_pos; + let b5 = get!(world, (game_id, bp_curr_pos), (Piece)); + assert(b5.piece_type == PieceType::Pawn, 'should be Pawn in (1,4)'); + assert(b5.color == Color::Black, 'should be black color'); + assert(b5.piece_type != PieceType::None, 'should have piece in (1,4)'); + + // Move White Pawn to (1,4) and capture black pawn + actions_system.move(wp_curr_pos, bp_curr_pos, white.into(), game_id); + + let wp_curr_pos = bp_curr_pos; + let b5 = get!(world, (game_id, wp_curr_pos), (Piece)); + assert(b5.piece_type == PieceType::Pawn, 'should be Pawn in (1,4)'); + assert(b5.color == Color::White, 'should be white color'); + assert(b5.piece_type != PieceType::None, 'should have piece in (1,4)'); + } +} +``` + +Keep moving pieces and checking if they're in the right places. + +## Congratulations! + +You've made the basic contracts for a chess game using the Dojo engine! This tutorial was just the beginning. There are many ways to make the game better, like optimizing parts, adding checks, or considering special cases. If you want to do more with this chess game, try these challenges: + +- Add a checkmate feature. Our game doesn't end now, so decide when it should! +- Include special moves like castling, En Passant Capture, or Pawn Promotion. +- Make your own chess rules! You could even create your own version of the [immortal game](https://immortal.game/) + +Lastly, share your project with others in the [Dojo community](https://discord.gg/akd2yfuRS3)! diff --git a/rust-book-old/src/tutorial/onchain-chess/README.md b/rust-book-old/src/tutorial/onchain-chess/README.md new file mode 100644 index 00000000..32668c7b --- /dev/null +++ b/rust-book-old/src/tutorial/onchain-chess/README.md @@ -0,0 +1,28 @@ +# Building a Chess Game + +_"I just finished reading The Dojo Book. What should I do next?"_ + +The answers to this question are always "Make something!", sometimes followed by a list of cool projects. This is a great answer for some people, but others might be looking for a little more direction. + +This guide is intended to fill the gap between heavily directed beginner tutorials and working on your projects. The primary goal here is to get you to write code. The secondary goal is to get you reading documentation. + +If you haven't read the Dojo Book yet, it is highly encouraged for you to do so before starting this project. + +## What are we building? + +We're building an on-chain chess game contract that lets you start a new game and play chess. This guide does not cover every rules of the chess game. You will build step by step as follows: + +1. A system contract to spawn all the chess pieces +2. A system contract to make pieces move +3. Add some functions to check a legal move +4. Play chess β™Ÿβ™™ - integration test! + +The full code of tutorial is based on [this repo](https://github.com/dojoengine/origami/tree/main/examples/chess). + +If this seems too hard, don't worry! This guide is for beginners. If you know some basics about Cairo and Dojo, you're good. We won't make a full chess game with all the rules. We're keeping it simple. + +## What after this guide? + +We're making another guide to help design the frontend. This will make our chess game complete. + +After you finish all the four chapters, we can move on to the frontend guide. diff --git a/theme/book.js b/rust-book-old/theme/book.js similarity index 100% rename from theme/book.js rename to rust-book-old/theme/book.js diff --git a/theme/card.png b/rust-book-old/theme/card.png similarity index 100% rename from theme/card.png rename to rust-book-old/theme/card.png diff --git a/theme/css/chrome.css b/rust-book-old/theme/css/chrome.css similarity index 100% rename from theme/css/chrome.css rename to rust-book-old/theme/css/chrome.css diff --git a/theme/css/general.css b/rust-book-old/theme/css/general.css similarity index 100% rename from theme/css/general.css rename to rust-book-old/theme/css/general.css diff --git a/theme/css/print.css b/rust-book-old/theme/css/print.css similarity index 100% rename from theme/css/print.css rename to rust-book-old/theme/css/print.css diff --git a/theme/css/variables.css b/rust-book-old/theme/css/variables.css similarity index 100% rename from theme/css/variables.css rename to rust-book-old/theme/css/variables.css diff --git a/theme/favicon.png b/rust-book-old/theme/favicon.png similarity index 100% rename from theme/favicon.png rename to rust-book-old/theme/favicon.png diff --git a/theme/favicon.svg b/rust-book-old/theme/favicon.svg similarity index 100% rename from theme/favicon.svg rename to rust-book-old/theme/favicon.svg diff --git a/theme/fonts/OPEN-SANS-LICENSE.txt b/rust-book-old/theme/fonts/OPEN-SANS-LICENSE.txt similarity index 100% rename from theme/fonts/OPEN-SANS-LICENSE.txt rename to rust-book-old/theme/fonts/OPEN-SANS-LICENSE.txt diff --git a/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt b/rust-book-old/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt similarity index 100% rename from theme/fonts/SOURCE-CODE-PRO-LICENSE.txt rename to rust-book-old/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt diff --git a/theme/fonts/fonts.css b/rust-book-old/theme/fonts/fonts.css similarity index 100% rename from theme/fonts/fonts.css rename to rust-book-old/theme/fonts/fonts.css diff --git a/theme/fonts/open-sans-v17-all-charsets-300.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-300.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-300.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-300.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-300italic.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-600.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-600.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-600.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-600.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-600italic.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-700.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-700.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-700.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-700.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-700italic.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-800.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-800.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-800.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-800.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-800italic.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-800italic.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-800italic.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-800italic.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-italic.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-italic.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-italic.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-italic.woff2 diff --git a/theme/fonts/open-sans-v17-all-charsets-regular.woff2 b/rust-book-old/theme/fonts/open-sans-v17-all-charsets-regular.woff2 similarity index 100% rename from theme/fonts/open-sans-v17-all-charsets-regular.woff2 rename to rust-book-old/theme/fonts/open-sans-v17-all-charsets-regular.woff2 diff --git a/theme/fonts/source-code-pro-v11-all-charsets-500.woff2 b/rust-book-old/theme/fonts/source-code-pro-v11-all-charsets-500.woff2 similarity index 100% rename from theme/fonts/source-code-pro-v11-all-charsets-500.woff2 rename to rust-book-old/theme/fonts/source-code-pro-v11-all-charsets-500.woff2 diff --git a/theme/head.hbs b/rust-book-old/theme/head.hbs similarity index 100% rename from theme/head.hbs rename to rust-book-old/theme/head.hbs diff --git a/theme/highlight.css b/rust-book-old/theme/highlight.css similarity index 100% rename from theme/highlight.css rename to rust-book-old/theme/highlight.css diff --git a/theme/highlight.js b/rust-book-old/theme/highlight.js similarity index 100% rename from theme/highlight.js rename to rust-book-old/theme/highlight.js diff --git a/theme/index.hbs b/rust-book-old/theme/index.hbs similarity index 100% rename from theme/index.hbs rename to rust-book-old/theme/index.hbs diff --git a/translations.sh b/rust-book-old/translations.sh similarity index 100% rename from translations.sh rename to rust-book-old/translations.sh