From 59c24041a9aa9e352ef2487d34860d95239ffcb2 Mon Sep 17 00:00:00 2001 From: Kushagra Sarathe <76868364+kushagrasarathe@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:15:41 +0530 Subject: [PATCH 1/2] feat: migrate frontend framework from mdbook to vocs (#185) * feat: migration to vocs * Update CONTRIBUTING.md * Update README.md * fix: pr review requested changes --- .gitignore | 10 +- CONTRIBUTING.md | 87 +- LANGUAGES | 2 - README.md | 9 +- book.toml | 33 - build.sh | 9 - .../src/ecdsa_verification.cairo | 5 +- .../hash_trait/src/hash_trait.cairo | 6 +- .../components/src/switchable.cairo | 8 +- .../src/contract_countable.cairo | 6 +- .../src/contract_countable_switchable.cairo | 6 +- ...ntract_countable_switchable_internal.cairo | 6 +- .../src/countable_dep_switch.cairo | 10 +- .../constant_product_amm/src/contracts.cairo | 4 +- listings/applications/erc20/src/token.cairo | 8 +- .../src/upgradeable_contract_v0.cairo | 9 +- .../bytearray/src/bytearray.cairo | 6 +- .../cairo_cheatsheet/src/felt_example.cairo | 4 +- .../cairo_cheatsheet/src/if_let_example.cairo | 4 +- .../cairo_cheatsheet/src/loop_example.cairo | 4 +- .../cairo_cheatsheet/src/tuple_example.cairo | 4 +- .../src/type_casting_example.cairo | 4 +- .../cairo_cheatsheet/src/while_example.cairo | 4 +- .../src/while_let_example.cairo | 4 +- .../calling_other_contracts/src/caller.cairo | 10 +- .../constructor/src/constructor.cairo | 6 +- .../getting-started/counter/src/counter.cairo | 6 +- .../custom_type_serde/src/contract.cairo | 6 +- .../errors/src/custom_errors.cairo | 6 +- .../errors/src/simple_errors.cairo | 6 +- .../errors/src/vault_errors.cairo | 6 +- .../getting-started/events/src/counter.cairo | 15 +- .../factory/src/simple_factory.cairo | 10 +- .../interfaces_traits/src/explicit.cairo | 6 +- .../interfaces_traits/src/implicit.cairo | 6 +- .../src/implicit_internal.cairo | 6 +- .../mappings/src/mappings.cairo | 7 +- .../storage/src/contract.cairo | 6 +- .../storage/src/minimal_contract.cairo | 7 +- .../storing_custom_types/src/contract.cairo | 6 +- .../testing_how_to/src/contract.cairo | 14 +- .../variables/src/global_variables.cairo | 6 +- .../variables/src/local_variables.cairo | 6 +- .../variables/src/storage_variables.cairo | 6 +- .../visibility/src/visibility.cairo | 6 +- package.json | 17 + pages/ch00/basics/bytearrays-strings.md | 56 + pages/ch00/basics/constructor.md | 29 + pages/ch00/basics/counter.md | 35 + .../basics/custom-types-in-entrypoints.md | 34 + pages/ch00/basics/documentation.md | 47 + pages/ch00/basics/errors.md | 77 + pages/ch00/basics/events.md | 25 + pages/ch00/basics/introduction.md | 10 + pages/ch00/basics/mappings.md | 30 + pages/ch00/basics/storage.md | 57 + pages/ch00/basics/storing-custom-types.md | 22 + pages/ch00/basics/syscalls.md | 288 + pages/ch00/basics/variables.md | 90 + pages/ch00/basics/visibility-mutability.md | 42 + pages/ch00/cairo_cheatsheet/arrays.md | 36 + .../ch00/cairo_cheatsheet/cairo_cheatsheet.md | 10 + pages/ch00/cairo_cheatsheet/felt.md | 17 + pages/ch00/cairo_cheatsheet/if_let.md | 24 + pages/ch00/cairo_cheatsheet/loop.md | 25 + pages/ch00/cairo_cheatsheet/mapping.md | 14 + pages/ch00/cairo_cheatsheet/match.md | 16 + pages/ch00/cairo_cheatsheet/struct.md | 16 + pages/ch00/cairo_cheatsheet/tuples.md | 22 + pages/ch00/cairo_cheatsheet/type_casting.md | 17 + pages/ch00/cairo_cheatsheet/while.md | 19 + pages/ch00/cairo_cheatsheet/while_let.md | 25 + pages/ch00/env_setup.md | 5 + .../interacting/calling_other_contracts.md | 56 + pages/ch00/interacting/factory.md | 42 + pages/ch00/interacting/interacting.md | 10 + pages/ch00/interacting/interfaces-traits.md | 76 + pages/ch00/testing/contract-testing.md | 113 + pages/ch01/constant-product-amm.md | 14 + pages/ch01/erc20.md | 37 + pages/ch01/signature_verification.md | 1 + pages/ch01/simple_vault.md | 24 + pages/ch01/upgradeable_contract.md | 47 + pages/ch02/hash-solidity-compatible.md | 9 + pages/ch02/hashing.md | 31 + pages/ch02/list.md | 70 + pages/ch02/optimisations/optimisations.md | 10 + .../ch02/optimisations/store_using_packing.md | 35 + pages/ch02/plugins.md | 14 + pages/ch02/signature_verification.md | 17 + pages/ch02/storing_arrays.md | 26 + pages/ch02/struct-mapping-key.md | 22 + pages/ch02/write_to_any_slot.md | 25 + {src => pages}/components/collisions.md | 23 + {src => pages}/components/dependencies.md | 75 + {src => pages}/components/how_to.md | 26 + pages/components/ownable.md | 40 + pages/getting-started.mdx | 3 + src/starknet-by-example.md => pages/index.mdx | 18 +- pages/indexdasds.mdx | 16 + pnpm-lock.yaml | 5052 +++++++ po/es.po | 11855 ---------------- po/messages.po | 2228 --- po/zh-cn.po | 7124 ---------- .../optimisations/store_using_packing.md | 5 + src/advanced-concepts/struct-mapping-key.md | 12 + src/advanced-concepts/write_to_any_slot.md | 12 + src/applications/erc20.md | 17 + src/applications/simple_vault.md | 12 + src/applications/upgradeable_contract.md | 16 + src/components/ownable.md | 15 - .../basics/bytearrays-strings.md | 13 + src/getting-started/basics/constructor.md | 20 + src/getting-started/basics/counter.md | 20 + .../basics/custom-types-in-entrypoints.md | 24 + src/getting-started/basics/documentation.md | 8 + src/getting-started/basics/errors.md | 39 + src/getting-started/basics/introduction.md | 7 + src/getting-started/basics/storage.md | 36 + src/getting-started/basics/syscalls.md | 15 + src/getting-started/basics/variables.md | 39 + .../basics/visibility-mutability.md | 13 + .../cairo_cheatsheet/arrays.md | 12 + .../cairo_cheatsheet/cairo_cheatsheet.md | 7 + .../cairo_cheatsheet/if_let.md | 14 +- src/getting-started/cairo_cheatsheet/loop.md | 12 + .../cairo_cheatsheet/tuples.md | 13 + .../cairo_cheatsheet/while_let.md | 13 + .../interacting/calling_other_contracts.md | 34 + src/getting-started/interacting/factory.md | 13 + .../interacting/interacting.md | 9 +- .../interacting/interfaces-traits.md | 39 + .../testing/contract-testing.md | 22 +- theme/book.js | 792 -- theme/css/catppuccin.css | 787 - theme/css/chrome.css | 545 - theme/css/general.css | 259 - theme/css/last-changed.css | 6 - theme/css/print.css | 54 - theme/css/variables.css | 295 - theme/favicon.png | Bin 5679 -> 0 bytes theme/favicon.svg | 22 - theme/fonts/OPEN-SANS-LICENCE.txt | 202 - theme/fonts/SOURCE-CODE-PRO-LICENSE.txt | 93 - theme/fonts/fonts.css | 100 - .../open-sans-v17-all-charsets-300.woff2 | Bin 44352 -> 0 bytes ...open-sans-v17-all-charsets-300italic.woff2 | Bin 40656 -> 0 bytes .../open-sans-v17-all-charsets-600.woff2 | Bin 44936 -> 0 bytes ...open-sans-v17-all-charsets-600italic.woff2 | Bin 42120 -> 0 bytes .../open-sans-v17-all-charsets-700.woff2 | Bin 44988 -> 0 bytes ...open-sans-v17-all-charsets-700italic.woff2 | Bin 40800 -> 0 bytes .../open-sans-v17-all-charsets-800.woff2 | Bin 44536 -> 0 bytes ...open-sans-v17-all-charsets-800italic.woff2 | Bin 40812 -> 0 bytes .../open-sans-v17-all-charsets-italic.woff2 | Bin 41076 -> 0 bytes .../open-sans-v17-all-charsets-regular.woff2 | Bin 43236 -> 0 bytes ...source-code-pro-v11-all-charsets-500.woff2 | Bin 59140 -> 0 bytes theme/highlight.css | 82 - theme/highlight.js | 2010 --- theme/index.hbs | 393 - translations.sh | 67 - tsconfig.json | 24 + vocs.config.ts | 238 + 162 files changed, 7988 insertions(+), 27141 deletions(-) delete mode 100644 LANGUAGES delete mode 100644 book.toml delete mode 100755 build.sh create mode 100644 package.json create mode 100644 pages/ch00/basics/bytearrays-strings.md create mode 100644 pages/ch00/basics/constructor.md create mode 100644 pages/ch00/basics/counter.md create mode 100644 pages/ch00/basics/custom-types-in-entrypoints.md create mode 100644 pages/ch00/basics/documentation.md create mode 100644 pages/ch00/basics/errors.md create mode 100644 pages/ch00/basics/events.md create mode 100644 pages/ch00/basics/introduction.md create mode 100644 pages/ch00/basics/mappings.md create mode 100644 pages/ch00/basics/storage.md create mode 100644 pages/ch00/basics/storing-custom-types.md create mode 100644 pages/ch00/basics/syscalls.md create mode 100644 pages/ch00/basics/variables.md create mode 100644 pages/ch00/basics/visibility-mutability.md create mode 100644 pages/ch00/cairo_cheatsheet/arrays.md create mode 100644 pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md create mode 100644 pages/ch00/cairo_cheatsheet/felt.md create mode 100644 pages/ch00/cairo_cheatsheet/if_let.md create mode 100644 pages/ch00/cairo_cheatsheet/loop.md create mode 100644 pages/ch00/cairo_cheatsheet/mapping.md create mode 100644 pages/ch00/cairo_cheatsheet/match.md create mode 100644 pages/ch00/cairo_cheatsheet/struct.md create mode 100644 pages/ch00/cairo_cheatsheet/tuples.md create mode 100644 pages/ch00/cairo_cheatsheet/type_casting.md create mode 100644 pages/ch00/cairo_cheatsheet/while.md create mode 100644 pages/ch00/cairo_cheatsheet/while_let.md create mode 100644 pages/ch00/env_setup.md create mode 100644 pages/ch00/interacting/calling_other_contracts.md create mode 100644 pages/ch00/interacting/factory.md create mode 100644 pages/ch00/interacting/interacting.md create mode 100644 pages/ch00/interacting/interfaces-traits.md create mode 100644 pages/ch00/testing/contract-testing.md create mode 100644 pages/ch01/constant-product-amm.md create mode 100644 pages/ch01/erc20.md create mode 100644 pages/ch01/signature_verification.md create mode 100644 pages/ch01/simple_vault.md create mode 100644 pages/ch01/upgradeable_contract.md create mode 100644 pages/ch02/hash-solidity-compatible.md create mode 100644 pages/ch02/hashing.md create mode 100644 pages/ch02/list.md create mode 100644 pages/ch02/optimisations/optimisations.md create mode 100644 pages/ch02/optimisations/store_using_packing.md create mode 100644 pages/ch02/plugins.md create mode 100644 pages/ch02/signature_verification.md create mode 100644 pages/ch02/storing_arrays.md create mode 100644 pages/ch02/struct-mapping-key.md create mode 100644 pages/ch02/write_to_any_slot.md rename {src => pages}/components/collisions.md (60%) rename {src => pages}/components/dependencies.md (54%) rename {src => pages}/components/how_to.md (71%) create mode 100644 pages/components/ownable.md create mode 100644 pages/getting-started.mdx rename src/starknet-by-example.md => pages/index.mdx (81%) create mode 100644 pages/indexdasds.mdx create mode 100644 pnpm-lock.yaml delete mode 100644 po/es.po delete mode 100644 po/messages.po delete mode 100644 po/zh-cn.po delete mode 100644 src/components/ownable.md delete mode 100644 theme/book.js delete mode 100644 theme/css/catppuccin.css delete mode 100644 theme/css/chrome.css delete mode 100644 theme/css/general.css delete mode 100644 theme/css/last-changed.css delete mode 100644 theme/css/print.css delete mode 100644 theme/css/variables.css delete mode 100644 theme/favicon.png delete mode 100644 theme/favicon.svg delete mode 100644 theme/fonts/OPEN-SANS-LICENCE.txt delete mode 100644 theme/fonts/SOURCE-CODE-PRO-LICENSE.txt delete mode 100644 theme/fonts/fonts.css delete mode 100644 theme/fonts/open-sans-v17-all-charsets-300.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-300italic.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-600.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-600italic.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-700.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-700italic.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-800.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-800italic.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-italic.woff2 delete mode 100644 theme/fonts/open-sans-v17-all-charsets-regular.woff2 delete mode 100644 theme/fonts/source-code-pro-v11-all-charsets-500.woff2 delete mode 100644 theme/highlight.css delete mode 100644 theme/highlight.js delete mode 100644 theme/index.hbs delete mode 100755 translations.sh create mode 100644 tsconfig.json create mode 100644 vocs.config.ts diff --git a/.gitignore b/.gitignore index 72306c0f..595d23b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -book -target -output +node_modules +.env # Editors tmp files. *~ @@ -10,3 +9,8 @@ output .snfoundry_cache .vscode/settings.json **/starkli-wallet + +# From previous mdbook build +book/* +target/* +src/**/*.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc9766aa..891e40ca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,14 +11,12 @@ Please note we have a code of conduct, please follow it in all your interactions - [Contributing](#contributing) - [Table of Contents](#table-of-contents) - [Setup](#setup) - - [MdBook](#mdbook) + - [Working with Markdown Files](#working-with-markdown-files) - [Adding a new chapter](#adding-a-new-chapter) - [Adding a new Cairo program](#adding-a-new-cairo-program) - [Verification script](#verification-script) - [Tests](#tests) - - [Use of anchor](#use-of-anchor) - - [Translations](#translations) - - [Initiate a new translation for your language](#initiate-a-new-translation-for-your-language) + - [Use of region](#use-of-region) - [Code of Conduct](#code-of-conduct) - [Our Pledge](#our-pledge) - [Our Standards](#our-standards) @@ -31,29 +29,37 @@ Please note we have a code of conduct, please follow it in all your interactions 1. Clone this repository. -2. Rust related packages: +2. Install the required dependencies using pnpm: - - Install toolchain providing `cargo` using [rustup](https://rustup.rs/). - - Install [mdBook](https://rust-lang.github.io/mdBook/guide/installation.html) and the required extension with `cargo install mdbook mdbook-i18n-helpers mdbook-last-changed `. +``` +pnpm i +``` 3. Install `scarb` using [asdf](https://asdf-vm.com/) with `asdf install`. Alternatively, you can install `scarb` manually by following the instructions [here](https://docs.swmansion.com/scarb/). -## MdBook +4. Start the development server: -All the Markdown files **MUST** be edited in english. To work locally in english: +``` +pnpm dev +``` -- Start a local server with `mdbook serve` and visit [localhost:3000](http://localhost:3000) to view the book. - You can use the `--open` flag to open the browser automatically: `mdbook serve --open`. +## Working with Markdown Files -- Make changes to the book and refresh the browser to see the changes. +All Markdown files (\*.md) MUST be edited in English. Follow these steps to work locally with Markdown files: -- Open a PR with your changes. +- Make changes to the desired .md files in your preferred text editor. +- Save the changes, and your browser window should automatically refresh to reflect the updates. +- Once you've finished making your changes, build the application to ensure everything works as expected: + ``` + pnpm build + ``` +- If everything looks good, commit your changes and open a pull request with your modifications. ## Adding a new chapter -To add a new chapter, create a new markdown file in the `src` directory. All the Markdown files **MUST** be edited in english. In order to add them to the book, you need to add a link to it in the `src/SUMMARY.md` file. +- To add a new chapter, create a new markdown file in the `pages` directory. All the Markdown files **MUST** be edited in english. In order to add them to the book, you need to add in the `vocs.config.ts` file. -Do not write directly Cairo program inside the markdown files. Instead, use code blocks that import the Cairo programs from the `listing` directory. These programs are bundled into scarb projects, which makes it easier to test and build all programs. See the next section for more details. +- Do not write directly Cairo program inside the markdown files. Instead, use code blocks that import the Cairo programs from the `listings` directory. These programs are bundled into scarb projects, which makes it easier to test and build all programs. See the next section for more details. Be sure to check for typos with `typos`: @@ -183,7 +189,7 @@ mod tests { You can use Starknet Foundry to write and run your tests. -### Use of anchor +### Use of region You can add delimiting comments to select part of the code in the book. @@ -191,19 +197,18 @@ You can add delimiting comments to select part of the code in the book. file.cairo: a -// ANCHOR: anchor_name +// [!region region_name] b -// ANCHOR_END: anchor_name +// [!endregion region_name] c ``` Then, in the markdown file, you can use the following syntax to include only the code between the delimiting comments: ````markdown -````cairo -{{#include ../../listings/path/to/listing/src/contract.cairo:anchor_name}} -\``` -```` + ```cairo + // [!include ~/listings/src/contract.cairo:region_name] + ``` ```` This will result in the following code being included in the book: @@ -212,39 +217,21 @@ This will result in the following code being included in the book: b ``` -Using `#rustdoc_include` you can have the same result, but users can expand the code in the book to see the whole file (used for showing tests): +To render code in tabs format you can use `:::code-group`. Example you can render contract and tests in separate tabs like this: -````markdown -````cairo -{{#rustdoc_include ../../listings/path/to/listing/src/contract.cairo:anchor_name}} -\``` ```` -```` - -## Translations + :::code-group -> Translations efforts are currently on hold. If you are interested in helping out, please send a message in the telegram channel. + ```cairo [contract] + // [!include ~/listings/src/contract.cairo:contract] + ``` -To work with translations, those are the steps to update the translated content: + ```cairo [tests] + // [!include ~/listings/src/contract.cairo:tests] + ``` -- Run a local server for the language you want to edit: `./translations.sh zh-cn` for instance. If no language is provided, the script will only extract translations from english. - -- Open the translation file you are interested in `po/zh-cn.po` for instance. You can also use editors like [poedit](https://poedit.net/) to help you on this task. - -- When you are done, you should only have changes into the `po/xx.po` file. Commit them and open a PR. - The PR must stars with `i18n` to let the maintainers know that the PR is only changing translation. - -The translation work is inspired from [Comprehensive Rust repository](https://github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md). - -You can test to build the book with all translations using the `build.sh` script and serve locally the `book` directory. - -### Initiate a new translation for your language - -If you wish to initiate a new translation for your language without running a local server, consider the following tips: - -- Execute the command `./translations.sh new xx` (replace `xx` with your language code). This method can generate the `xx.po` file of your language for you. -- To update your `xx.po` file, execute the command `./translations.sh xx` (replace `xx` with your language code), as mentioned in the previous chapter. -- If the `xx.po` file already exists (which means you are not initiating a new translation), you should not run this command. + ::: +```` ## Code of Conduct diff --git a/LANGUAGES b/LANGUAGES deleted file mode 100644 index 80cf6750..00000000 --- a/LANGUAGES +++ /dev/null @@ -1,2 +0,0 @@ -zh-cn -es diff --git a/README.md b/README.md index a3e0bf5c..bf09c9e4 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,15 @@ Please refer to the Contribution Guidelines page: - [Contributing](CONTRIBUTING.md#contributing) - [Table of Contents](CONTRIBUTING.md#table-of-contents) - [Setup](CONTRIBUTING.md#setup) - - [MdBook](CONTRIBUTING.md#mdbook) + - [Working with Markdown Files](CONTRIBUTING.md#working-with-markdown-files) - [Adding a new chapter](CONTRIBUTING.md#adding-a-new-chapter) - [Adding a new Cairo program](CONTRIBUTING.md#adding-a-new-cairo-program) - - [Verification script](CONTRIBUTING.md#verification-script) - [Tests](CONTRIBUTING.md#tests) - - [Use of anchor](CONTRIBUTING.md#use-of-anchor) - - [Translations](CONTRIBUTING.md#translations) - - [Initiate a new translation for your language](CONTRIBUTING.md#initiate-a-new-translation-for-your-language) + - [Use of region](CONTRIBUTING.md#use-of-region) - [Code of Conduct](CONTRIBUTING.md#code-of-conduct) - [Our Pledge](CONTRIBUTING.md#our-pledge) - [Our Standards](CONTRIBUTING.md#our-standards) - [Our Responsibilities](CONTRIBUTING.md#our-responsibilities) - [Scope](CONTRIBUTING.md#scope) - [Enforcement](CONTRIBUTING.md#enforcement) - - [Attribution](CONTRIBUTING.md#attribution) \ No newline at end of file + - [Attribution](CONTRIBUTING.md#attribution) diff --git a/book.toml b/book.toml deleted file mode 100644 index e135d0f3..00000000 --- a/book.toml +++ /dev/null @@ -1,33 +0,0 @@ -[book] -authors = ["msaug", "julio4"] -language = "en" -multilingual = false -src = "src" -title = "Starknet by Example" - -[build] -extra-watch-dirs = ["listings", "po"] - -[preprocessor.cairo] -after = ["links"] - -[preprocessor.gettext] -after = ["cairo"] - -[preprocessor.last-changed] -command = "mdbook-last-changed" -renderer = ["html"] - -[output.html.code.hidelines] -cairo = "# " - -[output.html] -git-repository-url = "https://github.com/NethermindEth/StarknetByExample" -edit-url-template = "https://github.com/NethermindEth/StarknetByExample/edit/main/{path}" -playground.runnable = false -fold.enable = true -fold.level = 2 -additional-css = ["./theme/css/last-changed.css", "./theme/css/catppuccin.css"] -default-theme = "latte" -preferred-dark-theme = "frappe" -mathjax-support = true diff --git a/build.sh b/build.sh deleted file mode 100755 index 5012d0d9..00000000 --- a/build.sh +++ /dev/null @@ -1,9 +0,0 @@ -echo "::group::Building main book" -mdbook build -d book -echo "::endgroup::" -for po_lang in $(cat ./LANGUAGES); do - echo "::group::Building $po_lang translation" - MDBOOK_BOOK__LANGUAGE=$po_lang \ - mdbook build -d book/$po_lang - echo "::endgroup::" -done \ No newline at end of file diff --git a/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo b/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo index 4fbbb6ff..ab1697ed 100644 --- a/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo +++ b/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!endregion contract] use core::starknet::eth_address::EthAddress; use starknet::secp256_trait::{Signature}; @@ -7,6 +7,7 @@ use starknet::secp256_trait::{Signature}; // 1. Create message to sign // 2. Hash the message // 3. Sign the hash (off chain, keep your private key secret) +// [!region contract] #[starknet::interface] trait IVerifySignature { fn get_signature(self: @TContractState, r: u256, s: u256, v: u32,) -> Signature; @@ -89,7 +90,7 @@ mod verifySignature { } } } -// ANCHOR_END: contract +// [!endregion contract] #[cfg(test)] mod tests { diff --git a/listings/advanced-concepts/hash_trait/src/hash_trait.cairo b/listings/advanced-concepts/hash_trait/src/hash_trait.cairo index 4dfb9994..e5415068 100644 --- a/listings/advanced-concepts/hash_trait/src/hash_trait.cairo +++ b/listings/advanced-concepts/hash_trait/src/hash_trait.cairo @@ -1,3 +1,4 @@ +// [!region hash] #[starknet::interface] pub trait IHashTrait { fn save_user_with_poseidon( @@ -8,7 +9,6 @@ pub trait IHashTrait { ) -> felt252; } -// ANCHOR: hash #[starknet::contract] pub mod HashTraits { use starknet::storage::StoragePointerWriteAccess; @@ -60,8 +60,9 @@ pub mod HashTraits { } } } -// ANCHOR_END: hash +// [!endregion hash] +// [!region tests] #[cfg(test)] mod tests { use starknet::SyscallResultTrait; @@ -103,3 +104,4 @@ mod tests { assert_eq!(test_hash, 0x4d165e1d398ae4864854518d3c58c3d7a21ed9c1f8f3618fbb0031d208aab7b); } } +// [!endregion tests] diff --git a/listings/applications/components/src/switchable.cairo b/listings/applications/components/src/switchable.cairo index 75fa0555..e626996f 100644 --- a/listings/applications/components/src/switchable.cairo +++ b/listings/applications/components/src/switchable.cairo @@ -1,11 +1,11 @@ -// ANCHOR: component +// [!region component] #[starknet::interface] -// ANCHOR: interface +// [!region interface] pub trait ISwitchable { fn is_on(self: @TContractState) -> bool; fn switch(ref self: TContractState); } -// ANCHOR_END: interface +// [!endregion interface] #[starknet::component] pub mod switchable_component { @@ -48,7 +48,7 @@ pub mod switchable_component { } } } -// ANCHOR_END: component +// [!endregion component] // ANCHOR: contract #[starknet::contract] diff --git a/listings/applications/components_dependencies/src/contract_countable.cairo b/listings/applications/components_dependencies/src/contract_countable.cairo index bb587b36..f991a6a0 100644 --- a/listings/applications/components_dependencies/src/contract_countable.cairo +++ b/listings/applications/components_dependencies/src/contract_countable.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] mod CountableContract { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -40,8 +40,9 @@ mod CountableContract { CountableEvent: countable_component::Event, } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::CountableContract; @@ -112,3 +113,4 @@ mod tests { assert_eq!(counter.get(), 6); } } +// [!endregion tests] diff --git a/listings/applications/components_dependencies/src/contract_countable_switchable.cairo b/listings/applications/components_dependencies/src/contract_countable_switchable.cairo index fdf8df55..c18aaafa 100644 --- a/listings/applications/components_dependencies/src/contract_countable_switchable.cairo +++ b/listings/applications/components_dependencies/src/contract_countable_switchable.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] mod CountableContract { use components_dependencies::countable_dep_switch::countable_component; @@ -33,8 +33,9 @@ mod CountableContract { SwitchableEvent: switchable_component::Event, } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::CountableContract; @@ -105,3 +106,4 @@ mod tests { assert_eq!(counter.get(), 6); } } +// [!endregion tests] diff --git a/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo b/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo index bfc64933..7e232947 100644 --- a/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo +++ b/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] pub mod CountableContract { use components_dependencies::countable_internal_dep_switch::countable_component; @@ -33,8 +33,9 @@ pub mod CountableContract { SwitchableEvent: switchable_component::Event, } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::CountableContract; @@ -103,3 +104,4 @@ mod tests { assert_eq!(counter.get(), 3); } } +// [!endregion tests] diff --git a/listings/applications/components_dependencies/src/countable_dep_switch.cairo b/listings/applications/components_dependencies/src/countable_dep_switch.cairo index 4cc2a1a6..0ffa1633 100644 --- a/listings/applications/components_dependencies/src/countable_dep_switch.cairo +++ b/listings/applications/components_dependencies/src/countable_dep_switch.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::component] pub mod countable_component { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -10,7 +10,7 @@ pub mod countable_component { countable_value: u32, } - // ANCHOR: impl + // [!region impl] #[embeddable_as(Countable)] impl CountableImpl< TContractState, +HasComponent, +ISwitchable @@ -25,10 +25,9 @@ pub mod countable_component { } } } - // ANCHOR_END: impl + // [!endregion impl] } - -//ANCHOR_END: contract +// [!endregion contract] #[starknet::contract] mod MockContract { @@ -62,7 +61,6 @@ mod MockContract { } } - #[cfg(test)] mod test { use super::MockContract; diff --git a/listings/applications/constant_product_amm/src/contracts.cairo b/listings/applications/constant_product_amm/src/contracts.cairo index 9b6ebfa4..b5649115 100644 --- a/listings/applications/constant_product_amm/src/contracts.cairo +++ b/listings/applications/constant_product_amm/src/contracts.cairo @@ -1,4 +1,4 @@ -// ANCHOR: ConstantProductAmmContract +// [!region ConstantProductAmmContract] use starknet::ContractAddress; #[starknet::interface] @@ -264,6 +264,6 @@ pub mod ConstantProductAmm { } } } -// ANCHOR_END: ConstantProductAmmContract +// [!endregion ConstantProductAmmContract] diff --git a/listings/applications/erc20/src/token.cairo b/listings/applications/erc20/src/token.cairo index 741ae21d..467e6e85 100644 --- a/listings/applications/erc20/src/token.cairo +++ b/listings/applications/erc20/src/token.cairo @@ -1,6 +1,6 @@ use starknet::ContractAddress; -// ANCHOR: interface +// [!region interface] #[starknet::interface] pub trait IERC20 { fn get_name(self: @TContractState) -> felt252; @@ -24,9 +24,9 @@ pub trait IERC20 { ref self: TContractState, spender: ContractAddress, subtracted_value: felt252 ); } -// ANCHOR_END: interface +// [!endregion interface] -// ANCHOR: erc20 +// [!region erc20] #[starknet::contract] pub mod erc20 { use core::num::traits::Zero; @@ -214,7 +214,7 @@ pub mod erc20 { } } } -// ANCHOR_END: erc20 +// [!endregion erc20] #[cfg(test)] mod tests { diff --git a/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo b/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo index a6e1b402..1de3f1cd 100644 --- a/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo +++ b/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] use starknet::class_hash::ClassHash; #[starknet::interface] @@ -29,19 +29,18 @@ pub mod UpgradeableContract_V0 { #[abi(embed_v0)] impl UpgradeableContract of super::IUpgradeableContract { - // ANCHOR: upgrade + // [!region upgrade] fn upgrade(ref self: ContractState, impl_hash: ClassHash) { assert(impl_hash.is_non_zero(), 'Class hash cannot be zero'); starknet::syscalls::replace_class_syscall(impl_hash).unwrap_syscall(); self.emit(Event::Upgraded(Upgraded { implementation: impl_hash })) } - // ANCHOR_END: upgrade - + // [!endregion upgrade] fn version(self: @ContractState) -> u8 { 0 } } } -// ANCHOR_END: contract +// [!endregion contract] diff --git a/listings/getting-started/bytearray/src/bytearray.cairo b/listings/getting-started/bytearray/src/bytearray.cairo index 52d8de06..684534e6 100644 --- a/listings/getting-started/bytearray/src/bytearray.cairo +++ b/listings/getting-started/bytearray/src/bytearray.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IMessage { fn append(ref self: TContractState, str: ByteArray); fn prepend(ref self: TContractState, str: ByteArray); } -// ANCHOR: contract #[starknet::contract] pub mod MessageContract { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -30,8 +30,9 @@ pub mod MessageContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -53,3 +54,4 @@ mod tests { assert(state.message.read() == "Hello, World! Good day, sir!", 'wrong message (prepend)'); } } +// [!endregion tests] diff --git a/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo b/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo index 43ab4360..73165206 100644 --- a/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo @@ -1,8 +1,8 @@ fn felt() { - // ANCHOR: sheet + // [!region sheet] let felt: felt252 = 100; let felt_as_str = 'Hello Starknet!'; let _felt = felt + felt_as_str; - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo b/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo index 4f651748..5fd56033 100644 --- a/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo @@ -1,4 +1,4 @@ -// ANCHOR: sheet +// [!region sheet] #[derive(Drop)] enum Foo { Bar, @@ -46,6 +46,6 @@ fn if_let() { println!("c is {}", value); } } -// ANCHOR_END: sheet +// [!endregion sheet] diff --git a/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo b/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo index 65860332..aaa2ed7a 100644 --- a/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo @@ -1,5 +1,5 @@ fn do_loop() { - // ANCHOR: sheet + // [!region sheet] let mut arr = array![]; // Same as ~ while (i < 10) arr.append(i++); @@ -14,5 +14,5 @@ fn do_loop() { i += 1; }; - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo b/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo index 4f54e255..cf085ef2 100644 --- a/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo @@ -1,5 +1,5 @@ fn tuple() { - // ANCHOR: sheet + // [!region sheet] let address = "0x000"; let age = 20; let active = true; @@ -9,5 +9,5 @@ fn tuple() { // Access tuple let (address, age, active) = stored_tuple; - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo b/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo index 9e2bbfea..b28eb8fa 100644 --- a/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo @@ -1,5 +1,5 @@ fn type_casting() { - // ANCHOR: sheet + // [!region sheet] let a_number: u32 = 15; let my_felt252 = 15; @@ -23,5 +23,5 @@ fn type_casting() { // Note: usize is smaller than felt252, so we use try_into let _new_usize: usize = my_felt252.try_into().unwrap(); - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/cairo_cheatsheet/src/while_example.cairo b/listings/getting-started/cairo_cheatsheet/src/while_example.cairo index c681ac2c..7ffbc5c8 100644 --- a/listings/getting-started/cairo_cheatsheet/src/while_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/while_example.cairo @@ -1,5 +1,5 @@ fn do_loop() { - // ANCHOR: sheet + // [!region sheet] let mut arr = array![]; let mut i: u32 = 0; @@ -7,5 +7,5 @@ fn do_loop() { arr.append(i); i += 1; }; - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo b/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo index 6e3035af..54b5e7b1 100644 --- a/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo +++ b/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo @@ -1,5 +1,5 @@ fn while_let() { - // ANCHOR: sheet + // [!region sheet] let mut option = Option::Some(0_usize); // "while `let` destructures `option` into `Some(i)`, @@ -13,5 +13,5 @@ fn while_let() { option = Option::Some(i + 1); } } - // ANCHOR_END: sheet + // [!endregion sheet] } diff --git a/listings/getting-started/calling_other_contracts/src/caller.cairo b/listings/getting-started/calling_other_contracts/src/caller.cairo index b82ff2e3..fd297c5d 100644 --- a/listings/getting-started/calling_other_contracts/src/caller.cairo +++ b/listings/getting-started/calling_other_contracts/src/caller.cairo @@ -1,4 +1,4 @@ -// ANCHOR: callee_contract +// [!region callee_contract] // This will automatically generate ICalleeDispatcher and ICalleeDispatcherTrait #[starknet::interface] pub trait ICallee { @@ -22,8 +22,9 @@ pub mod Callee { } } } -// ANCHOR_END: callee_contract +// [!endregion callee_contract] +// [!region caller_contract] #[starknet::interface] pub trait ICaller { fn set_value_from_address( @@ -31,7 +32,6 @@ pub trait ICaller { ); } -// ANCHOR: caller_contract #[starknet::contract] pub mod Caller { // We need to import the dispatcher of the callee contract @@ -49,8 +49,9 @@ pub mod Caller { } } } -// ANCHOR_END: caller_contract +// [!endregion caller_contract] +// [!region tests] #[cfg(test)] mod tests { use super::{Callee, ICalleeDispatcher, Caller, ICallerDispatcher, ICallerDispatcherTrait}; @@ -87,3 +88,4 @@ mod tests { assert_eq!(value_read, init_value); } } +// [!endregion tests] \ No newline at end of file diff --git a/listings/getting-started/constructor/src/constructor.cairo b/listings/getting-started/constructor/src/constructor.cairo index bf68ac8d..cb52e6f8 100644 --- a/listings/getting-started/constructor/src/constructor.cairo +++ b/listings/getting-started/constructor/src/constructor.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] pub mod ExampleConstructor { use starknet::ContractAddress; @@ -16,8 +16,9 @@ pub mod ExampleConstructor { self.names.write(address, name); } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::ExampleConstructor; @@ -45,3 +46,4 @@ mod tests { assert_eq!(name, 'bob'); } } +// [!endregion tests] diff --git a/listings/getting-started/counter/src/counter.cairo b/listings/getting-started/counter/src/counter.cairo index 83d8e287..c4ae9f87 100644 --- a/listings/getting-started/counter/src/counter.cairo +++ b/listings/getting-started/counter/src/counter.cairo @@ -1,3 +1,4 @@ +// [!region contract] #[starknet::interface] pub trait ISimpleCounter { fn get_current_count(self: @TContractState) -> u128; @@ -5,7 +6,6 @@ pub trait ISimpleCounter { fn decrement(ref self: TContractState); } -// ANCHOR: contract #[starknet::contract] pub mod SimpleCounter { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -41,8 +41,9 @@ pub mod SimpleCounter { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{SimpleCounter, ISimpleCounterDispatcher, ISimpleCounterDispatcherTrait}; @@ -108,3 +109,4 @@ mod test { assert_eq!(contract.get_current_count(), init_value); } } +// [!endregion tests] diff --git a/listings/getting-started/custom_type_serde/src/contract.cairo b/listings/getting-started/custom_type_serde/src/contract.cairo index b70142cc..9d61ba2f 100644 --- a/listings/getting-started/custom_type_serde/src/contract.cairo +++ b/listings/getting-started/custom_type_serde/src/contract.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait ISerdeCustomType { fn person_input(ref self: TContractState, person: Person); fn person_output(self: @TContractState) -> Person; } -// ANCHOR: contract // Deriving the `Serde` trait allows us to use // the `Person` type as an entrypoint parameter and as a return value #[derive(Drop, Serde)] @@ -29,8 +29,9 @@ pub mod SerdeCustomType { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{ @@ -71,3 +72,4 @@ mod tests { contract.person_input(expected_person); } } +// [!endregion tests] \ No newline at end of file diff --git a/listings/getting-started/errors/src/custom_errors.cairo b/listings/getting-started/errors/src/custom_errors.cairo index d7216f96..ee565aae 100644 --- a/listings/getting-started/errors/src/custom_errors.cairo +++ b/listings/getting-started/errors/src/custom_errors.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait ICustomErrorsExample { fn test_assert(self: @TContractState, i: u256); fn test_panic(self: @TContractState, i: u256); } -// ANCHOR: contract pub mod Errors { pub const NOT_POSITIVE: felt252 = 'must be greater than 0'; pub const NOT_NULL: felt252 = 'must not be null'; @@ -30,8 +30,9 @@ pub mod CustomErrorsExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ @@ -61,3 +62,4 @@ mod test { contract.test_assert(0); } } +// [!endregion tests] diff --git a/listings/getting-started/errors/src/simple_errors.cairo b/listings/getting-started/errors/src/simple_errors.cairo index d1d387cd..2ce0d370 100644 --- a/listings/getting-started/errors/src/simple_errors.cairo +++ b/listings/getting-started/errors/src/simple_errors.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IErrorsExample { fn test_assert(self: @TContractState, i: u256); fn test_panic(self: @TContractState, i: u256); } -// ANCHOR: contract #[starknet::contract] pub mod ErrorsExample { #[storage] @@ -26,8 +26,9 @@ pub mod ErrorsExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ErrorsExample, IErrorsExampleDispatcher, IErrorsExampleDispatcherTrait}; @@ -55,3 +56,4 @@ mod test { contract.test_assert(0); } } +// [!endregion tests] diff --git a/listings/getting-started/errors/src/vault_errors.cairo b/listings/getting-started/errors/src/vault_errors.cairo index 20c230c8..c27e8795 100644 --- a/listings/getting-started/errors/src/vault_errors.cairo +++ b/listings/getting-started/errors/src/vault_errors.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IVaultErrorsExample { fn deposit(ref self: TContractState, amount: u256); fn withdraw(ref self: TContractState, amount: u256); } -// ANCHOR: contract pub mod VaultErrors { pub const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance'; // you can define more errors here @@ -44,8 +44,9 @@ pub mod VaultErrorsExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ @@ -76,3 +77,4 @@ mod test { contract.withdraw(15); } } +// [!endregion tests] \ No newline at end of file diff --git a/listings/getting-started/events/src/counter.cairo b/listings/getting-started/events/src/counter.cairo index 8b71d774..a8a11893 100644 --- a/listings/getting-started/events/src/counter.cairo +++ b/listings/getting-started/events/src/counter.cairo @@ -1,9 +1,9 @@ +// [!region contract] #[starknet::interface] pub trait IEventCounter { fn increment(ref self: TContractState, amount: u128); } -// ANCHOR: contract #[starknet::contract] pub mod EventCounter { use starknet::{get_caller_address, ContractAddress}; @@ -45,7 +45,7 @@ pub mod EventCounter { fn increment(ref self: ContractState, amount: u128) { self.counter.write(self.counter.read() + amount); // Emit event - // ANCHOR: emit + // [!region emit] self.emit(Event::CounterIncreased(CounterIncreased { amount })); self .emit( @@ -55,12 +55,13 @@ pub mod EventCounter { } ) ); - // ANCHOR_END: emit + // [!endregion emit] } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{ @@ -91,12 +92,13 @@ mod tests { assert_eq!(state.counter.read(), amount); // Notice the order: the first event emitted is the first to be popped. - /// ANCHOR: test_events + // [!region test_events] assert_eq!( starknet::testing::pop_log(contract_address), Option::Some(Event::CounterIncreased(CounterIncreased { amount })) ); - // ANCHOR_END: test_events + // [!endregion test_events] + assert_eq!( starknet::testing::pop_log(contract_address), Option::Some( @@ -105,3 +107,4 @@ mod tests { ); } } +// [!endregion tests] diff --git a/listings/getting-started/factory/src/simple_factory.cairo b/listings/getting-started/factory/src/simple_factory.cairo index 3146cdac..37ce9b62 100644 --- a/listings/getting-started/factory/src/simple_factory.cairo +++ b/listings/getting-started/factory/src/simple_factory.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] pub use starknet::{ContractAddress, ClassHash}; #[starknet::interface] @@ -37,7 +37,7 @@ pub mod CounterFactory { #[abi(embed_v0)] impl Factory of super::ICounterFactory { - // ANCHOR: deploy + // [!region deploy] fn create_counter_at(ref self: ContractState, init_value: u128) -> ContractAddress { // Constructor arguments let mut constructor_calldata: Array:: = array![init_value.into()]; @@ -50,7 +50,7 @@ pub mod CounterFactory { deployed_address } - // ANCHOR_END: deploy + // [!endregion deploy] fn create_counter(ref self: ContractState) -> ContractAddress { self.create_counter_at(self.init_value.read()) @@ -65,8 +65,9 @@ pub mod CounterFactory { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{CounterFactory, ICounterFactoryDispatcher, ICounterFactoryDispatcherTrait}; @@ -188,3 +189,4 @@ mod tests { assert_eq!(counter_2.get_current_count(), argument_value); } } +// [!endregion tests] diff --git a/listings/getting-started/interfaces_traits/src/explicit.cairo b/listings/getting-started/interfaces_traits/src/explicit.cairo index 0c9b109e..b90eb216 100644 --- a/listings/getting-started/interfaces_traits/src/explicit.cairo +++ b/listings/getting-started/interfaces_traits/src/explicit.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::interface] pub trait IExplicitInterfaceContract { fn get_value(self: @TContractState) -> u32; @@ -25,8 +25,9 @@ pub mod ExplicitInterfaceContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{ @@ -54,3 +55,4 @@ mod tests { assert_eq!(read_value, value); } } +// [!endregion tests] diff --git a/listings/getting-started/interfaces_traits/src/implicit.cairo b/listings/getting-started/interfaces_traits/src/implicit.cairo index 15861ba5..8bc3c140 100644 --- a/listings/getting-started/interfaces_traits/src/implicit.cairo +++ b/listings/getting-started/interfaces_traits/src/implicit.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] pub mod ImplicitInterfaceContract { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -22,8 +22,9 @@ pub mod ImplicitInterfaceContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{ImplicitInterfaceContract, ImplicitInterfaceContract::IImplicitInterfaceContract}; @@ -48,3 +49,4 @@ mod tests { assert_eq!(read_value, value); } } +// [!endregion tests] diff --git a/listings/getting-started/interfaces_traits/src/implicit_internal.cairo b/listings/getting-started/interfaces_traits/src/implicit_internal.cairo index 2dc83f15..f459d46e 100644 --- a/listings/getting-started/interfaces_traits/src/implicit_internal.cairo +++ b/listings/getting-started/interfaces_traits/src/implicit_internal.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::interface] pub trait IImplicitInternalContract { fn add(ref self: TContractState, nb: u32); @@ -46,8 +46,9 @@ pub mod ImplicitInternalContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{ @@ -74,3 +75,4 @@ mod tests { assert_eq!(contract.get_value(), initial_value + add_value); } } +// [!endregion tests] \ No newline at end of file diff --git a/listings/getting-started/mappings/src/mappings.cairo b/listings/getting-started/mappings/src/mappings.cairo index 802152cc..f3bcb431 100644 --- a/listings/getting-started/mappings/src/mappings.cairo +++ b/listings/getting-started/mappings/src/mappings.cairo @@ -1,3 +1,4 @@ +// [!region contract] use starknet::ContractAddress; #[starknet::interface] @@ -6,7 +7,6 @@ pub trait IMapContract { fn get(self: @TContractState, key: ContractAddress) -> felt252; } -// ANCHOR: contract #[starknet::contract] pub mod MapContract { use starknet::ContractAddress; @@ -28,8 +28,9 @@ pub mod MapContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{MapContract, IMapContractDispatcher, IMapContractDispatcherTrait}; @@ -52,3 +53,5 @@ mod test { assert(read_value == 1, 'wrong value read'); } } + +// [!endregion tests] \ No newline at end of file diff --git a/listings/getting-started/storage/src/contract.cairo b/listings/getting-started/storage/src/contract.cairo index 75d734a5..cb9d572e 100644 --- a/listings/getting-started/storage/src/contract.cairo +++ b/listings/getting-started/storage/src/contract.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] pub mod Contract { #[storage] @@ -8,8 +8,9 @@ pub mod Contract { pub c: u256 } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::Contract; @@ -32,3 +33,4 @@ mod test { assert_eq!(state.c.read(), 0_u256); } } +// [!endregion tests] diff --git a/listings/getting-started/storage/src/minimal_contract.cairo b/listings/getting-started/storage/src/minimal_contract.cairo index 22bb7ccc..932e3111 100644 --- a/listings/getting-started/storage/src/minimal_contract.cairo +++ b/listings/getting-started/storage/src/minimal_contract.cairo @@ -1,11 +1,12 @@ -// ANCHOR: contract +// [!region contract] #[starknet::contract] pub mod Contract { #[storage] struct Storage {} } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::Contract; @@ -20,4 +21,4 @@ mod test { // Not much to test } } - +// [!endregion tests] diff --git a/listings/getting-started/storing_custom_types/src/contract.cairo b/listings/getting-started/storing_custom_types/src/contract.cairo index f786a9be..564ffb0a 100644 --- a/listings/getting-started/storing_custom_types/src/contract.cairo +++ b/listings/getting-started/storing_custom_types/src/contract.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IStoringCustomType { fn set_person(ref self: TContractState, person: Person); fn set_name(ref self: TContractState, name: felt252); } -// ANCHOR: contract // Deriving the starknet::Store trait // allows us to store the `Person` struct in the contract's storage. #[derive(Drop, Serde, Copy, starknet::Store)] @@ -36,8 +36,9 @@ pub mod StoringCustomType { // ANCHOR_END: set_name } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod tests { use super::{IStoringCustomType, StoringCustomType, Person,}; @@ -67,3 +68,4 @@ mod tests { assert_eq!(read_person.name, 'John'); } } +// [!endregion tests] diff --git a/listings/getting-started/testing_how_to/src/contract.cairo b/listings/getting-started/testing_how_to/src/contract.cairo index 4d125cab..09dce5de 100644 --- a/listings/getting-started/testing_how_to/src/contract.cairo +++ b/listings/getting-started/testing_how_to/src/contract.cairo @@ -1,4 +1,4 @@ -// ANCHOR: contract +// [!region contract] #[starknet::interface] pub trait ISimpleContract { fn get_value(self: @TContractState) -> u32; @@ -39,9 +39,9 @@ pub mod SimpleContract { } } } -// ANCHOR_END: contract +// [!endregion contract] -// ANCHOR: tests +// [!region tests] #[cfg(test)] mod tests { // Import the interface and dispatcher to be able to interact with the contract. @@ -118,10 +118,9 @@ mod tests { fn test_deploy_gas() { deploy(10); } -} -// ANCHOR_END: tests +}// [!endregion tests] -// ANCHOR: tests_with_state +// [!region tests_with_state] #[cfg(test)] mod tests_with_states { // Only import the contract and implementation @@ -218,6 +217,5 @@ mod tests_with_states { assert_eq!(contract.get_value(), new_value); } } -// ANCHOR_END: tests - +}// [!endregion tests_with_state] diff --git a/listings/getting-started/variables/src/global_variables.cairo b/listings/getting-started/variables/src/global_variables.cairo index 1e808e50..7b32e457 100644 --- a/listings/getting-started/variables/src/global_variables.cairo +++ b/listings/getting-started/variables/src/global_variables.cairo @@ -1,9 +1,9 @@ +// [!region contract] #[starknet::interface] pub trait IGlobalExample { fn foo(ref self: TContractState); } -// ANCHOR: contract #[starknet::contract] pub mod GlobalExample { // import the required functions from the starknet core library @@ -21,8 +21,9 @@ pub mod GlobalExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::GlobalExample; @@ -37,3 +38,4 @@ mod test { // Not much to test } } +// [!endregion tests] diff --git a/listings/getting-started/variables/src/local_variables.cairo b/listings/getting-started/variables/src/local_variables.cairo index 4b2bcac5..2c294873 100644 --- a/listings/getting-started/variables/src/local_variables.cairo +++ b/listings/getting-started/variables/src/local_variables.cairo @@ -1,9 +1,9 @@ +// [!region contract] #[starknet::interface] pub trait ILocalVariablesExample { fn do_something(self: @TContractState, value: u32) -> u32; } -// ANCHOR: contract #[starknet::contract] pub mod LocalVariablesExample { #[storage] @@ -26,8 +26,9 @@ pub mod LocalVariablesExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ @@ -49,3 +50,4 @@ mod test { assert_eq!(res, value + 10); } } +// [!endregion tests] diff --git a/listings/getting-started/variables/src/storage_variables.cairo b/listings/getting-started/variables/src/storage_variables.cairo index 864c9175..06a74764 100644 --- a/listings/getting-started/variables/src/storage_variables.cairo +++ b/listings/getting-started/variables/src/storage_variables.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IStorageVariableExample { fn set(ref self: TContractState, value: u32); fn get(self: @TContractState) -> u32; } -// ANCHOR: contract #[starknet::contract] pub mod StorageVariablesExample { // You need to import these storage functions to read and write to storage variables @@ -32,8 +32,9 @@ pub mod StorageVariablesExample { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ @@ -64,3 +65,4 @@ mod test { assert_eq!(state.value.read(), initial_value); } } +// [!endregion tests] diff --git a/listings/getting-started/visibility/src/visibility.cairo b/listings/getting-started/visibility/src/visibility.cairo index e97058af..383a4097 100644 --- a/listings/getting-started/visibility/src/visibility.cairo +++ b/listings/getting-started/visibility/src/visibility.cairo @@ -1,10 +1,10 @@ +// [!region contract] #[starknet::interface] pub trait IExampleContract { fn set(ref self: TContractState, value: u32); fn get(self: @TContractState) -> u32; } -// ANCHOR: contract #[starknet::contract] pub mod ExampleContract { use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess}; @@ -52,8 +52,9 @@ pub mod ExampleContract { } } } -// ANCHOR_END: contract +// [!endregion contract] +// [!region tests] #[cfg(test)] mod test { use super::{ExampleContract, IExampleContractDispatcher, IExampleContractDispatcherTrait}; @@ -101,3 +102,4 @@ mod test { assert_eq!(state._read_value(), contract.get()); } } +// [!endregion tests] diff --git a/package.json b/package.json new file mode 100644 index 00000000..88775a95 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "starknet-by-example", + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vocs dev", + "build": "vocs build", + "preview": "vocs preview" + }, + "dependencies": { + "@types/react": "latest", + "react": "latest", + "react-dom": "latest", + "typescript": "latest", + "vocs": "latest" + } +} diff --git a/pages/ch00/basics/bytearrays-strings.md b/pages/ch00/basics/bytearrays-strings.md new file mode 100644 index 00000000..fc59f9c0 --- /dev/null +++ b/pages/ch00/basics/bytearrays-strings.md @@ -0,0 +1,56 @@ +# Strings and ByteArrays + +In Cairo, there's no native type for strings. Instead, you can use a single `felt252` to store a `short string` or a `ByteArray` for strings of arbitrary length. + +## Short strings + +Each character is encoded on 8 bits following the ASCII standard, so it's possible to store up to 31 characters in a single `felt252`. + +Short strings are declared with single quotes, like this: `'Hello, World!'`. +See the [Felt](../cairo_cheatsheet/felt.md) section for more information about short strings with the `felt252` type. + +> Notice that any short string only use up to 31 bytes, so it's possible to represent any short string with `bytes31`. + +## ByteArray (Long strings) + +The `ByteArray` struct is used to store strings of arbitrary length. It contains a field `data` of type `Array` to store a sequence of short strings. + +ByteArrays are declared with double quotes, like this: `"Hello, World!"`. + +They can be stored in the contract's storage and passed as arguments to entrypoints. + +<<<<<<<< HEAD:src/getting-started/basics/bytearrays-strings.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/bytearray/src/bytearray.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/bytearrays-strings.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:tests] +``` + +::: + +### Operations + +ByteArrays also provide a set of operations that facilitate the manipulation of strings. +Here are the available operations on an instance of `ByteArray`: + +- `append(mut other: @ByteArray)` - Append another ByteArray to the current one. +- `append_word(word: felt252, len: usize)` - Append a short string to the ByteArray. You **need to ensure** that `len` is at most 31 and that `word` can be converted to a `bytes31` with maximum `len` bytes/characters. +- `append_byte(byte: felt252)` - Append a single byte/character to the end of the ByteArray. +- `len() -> usize` - Get the length of the ByteArray. +- `at(index: usize) -> Option` - Access the character at the given index. +- `rev() -> ByteArray` - Return a new ByteArray with the characters of the original one in reverse order. +- `append_word_rev(word: felt252, len: usize)` - Append a short string to the ByteArray in reverse order. You **need to ensure** again that `len` is at most 31 and that `word` can be converted to a `bytes31` with maximum `len` bytes/characters. + +Additionally, there are some operations that can be called as static functions: + +- `concat(left: @ByteArray, right: @ByteArray)` - Concatenate two ByteArrays. + +Concatenation of `ByteArray` (`append(mut other: @ByteArray)`) can also be done with the `+` and `+=` operators directly, and access to a specific index can be done with the `[]` operator (with the maximum index being `len() - 1`). diff --git a/pages/ch00/basics/constructor.md b/pages/ch00/basics/constructor.md new file mode 100644 index 00000000..f751c0c6 --- /dev/null +++ b/pages/ch00/basics/constructor.md @@ -0,0 +1,29 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Constructor + +Constructors are a special type of function that runs only once when deploying a contract, and can be used to initialize the state of the contract. Your contract must not have more than one constructor, and that constructor function must be annotated with the `#[constructor]` attribute. Also, a good practice consists in naming that function `constructor`. + +Here's a simple example that demonstrates how to initialize the state of a contract on deployment by defining logic inside a constructor. + +<<<<<<<< HEAD:src/getting-started/basics/constructor.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/constructor/src/constructor.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/constructor/src/constructor.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/constructor.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/constructor/src/constructor.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/counter.md b/pages/ch00/basics/counter.md new file mode 100644 index 00000000..7ba0493e --- /dev/null +++ b/pages/ch00/basics/counter.md @@ -0,0 +1,35 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Simple Counter + +We now understand how to create a contract with state variables and functions. Let's create a simple counter contract that increments and decrements a counter. + +Here's how it works: + +- The contract has a state variable `counter` that is initialized to `0`. + +- When a user calls the `increment` entrypoint, the contract increments `counter` by `1`. + +- When a user calls the `decrement`, the contract decrements `counter` by `1`. + +<<<<<<<< HEAD:src/getting-started/basics/counter.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/counter/src/counter.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/counter/src/counter.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/counter.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/counter/src/counter.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/custom-types-in-entrypoints.md b/pages/ch00/basics/custom-types-in-entrypoints.md new file mode 100644 index 00000000..97e8ce79 --- /dev/null +++ b/pages/ch00/basics/custom-types-in-entrypoints.md @@ -0,0 +1,34 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Custom types in entrypoints + +Using custom types in entrypoints requires our type to implement the `Serde` trait. This is because when calling an entrypoint, the input is sent as an array of `felt252` to the entrypoint, and we need to be able to deserialize it into our custom type. Similarly, when returning a custom type from an entrypoint, we need to be able to serialize it into an array of `felt252`. +Thankfully, we can just derive the `Serde` trait for our custom type. + +<<<<<<<< HEAD:src/getting-started/basics/custom-types-in-entrypoints.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/custom_type_serde/src/contract.cairo:contract}} +``` + +> Note: The purpose of this example is to demonstrate the ability to use custom types as inputs and outputs in contract calls. For simplicity, we are not using getters and setters to manage the contract's state. +======== +The purpose is to only show the capability of using custom types as inputs and outputs in contract calls. +We are not employing getters and setters for managing the contract's state in this example for simplicity. + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:tests] +``` + +::: +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/custom-types-in-entrypoints.md diff --git a/pages/ch00/basics/documentation.md b/pages/ch00/basics/documentation.md new file mode 100644 index 00000000..81b14b37 --- /dev/null +++ b/pages/ch00/basics/documentation.md @@ -0,0 +1,47 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Documentation + +It's important to take the time to document your code. It will help developers and users to understand the contract and its functionalities. + +In Cairo, you can add comments with `//`. + +### Best Practices + +Since Cairo 1, the community has adopted a [Rust-like documentation style](https://doc.rust-lang.org/rust-by-example/meta/doc.html). + +### Contract Interface + +In smart contracts, you will often have a trait that defines the contract's interface (with `#[starknet::interface]`). +This is the perfect place to include detailed documentation explaining the purpose and functionality of the contract entry points. You can follow this template: + +```cairo +#[starknet::interface] +trait IContract { + /// High-level description of the function + /// + /// # Arguments + /// + /// * `arg_1` - Description of the argument + /// * `arg_n` - ... + /// + /// # Returns + /// + /// High-level description of the return value + fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return; +} +``` + +Keep in mind that this should not describe the implementation details of the function, but rather the high-level purpose and functionality of the contract from the perspective of a user. + +### Implementation Details + +When writing the contract logic, you can add comments to describe the technical implementation details of the functions. + +> Avoid over-commenting: Comments should provide additional value and clarity. diff --git a/pages/ch00/basics/errors.md b/pages/ch00/basics/errors.md new file mode 100644 index 00000000..7d6df40b --- /dev/null +++ b/pages/ch00/basics/errors.md @@ -0,0 +1,77 @@ +# Errors + +Errors can be used to handle validation and other conditions that may occur during the execution of a smart contract. +If an error is thrown during the execution of a smart contract call, the execution is stopped and any changes made during the transaction are reverted. + +To throw an error, use the `assert` or `panic` functions: + +- `assert` is used to validate conditions. + If the check fails, an error is thrown along with a specified value, often a message. + It's similar to the `require` statement in Solidity. + +- `panic` immediately halts the execution with the given error value. + It should be used for complex condition checks and for internal errors. It's similar to the `revert` statement in Solidity. + You can use `panic_with_felt252` to directly pass a `felt252` as the error value. + +The `assert_eq!`, `assert_ne!`, `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros can be used as an `assert` shorthand to compare two values, but **only** in tests. In contracts, you should only use the `assert` function. + +Here's a simple example that demonstrates the use of these functions: + +<<<<<<<< HEAD:src/getting-started/basics/errors.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/errors/src/simple_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:tests] +``` + +::: + +## Custom errors + +You can make error handling easier by defining your error codes in a specific module. + +<<<<<<<< HEAD:src/getting-started/basics/errors.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/errors/src/custom_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:tests] +``` + +::: + +## Vault example + +Here's another example that demonstrates the use of errors in a more complex contract: + +<<<<<<<< HEAD:src/getting-started/basics/errors.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/errors/src/vault_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/events.md b/pages/ch00/basics/events.md new file mode 100644 index 00000000..3267b6d8 --- /dev/null +++ b/pages/ch00/basics/events.md @@ -0,0 +1,25 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Events + +Events are a way to emit data from a contract. All events must be defined in the `Event` enum, which must be annotated with the `#[event]` attribute. +An event is defined as a struct that derives the `#[starknet::Event]` trait. The fields of that struct correspond to the data that will be emitted. An event can be indexed for easy and fast access when querying the data at a later time, by adding a `#[key]` attribute to a field member. + +Here's a simple example of a contract using events that emit an event each time a counter is incremented by the "increment" function: + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/events/src/counter.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/events/src/counter.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/introduction.md b/pages/ch00/basics/introduction.md new file mode 100644 index 00000000..0c3367aa --- /dev/null +++ b/pages/ch00/basics/introduction.md @@ -0,0 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Basics of Smart Contracts in Cairo + +The following chapters will introduce you to Starknet smart contracts and how to write them in Cairo. diff --git a/pages/ch00/basics/mappings.md b/pages/ch00/basics/mappings.md new file mode 100644 index 00000000..cc0f0b16 --- /dev/null +++ b/pages/ch00/basics/mappings.md @@ -0,0 +1,30 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Mappings + +Maps are a key-value data structure used to store data within a smart contract. In Cairo they are implemented using the `LegacyMap` type. It's important to note that the `LegacyMap` type can only be used inside the `Storage` struct of a contract and that it can't be used elsewhere. + +Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, to map between a key of type `ContractAddress` and value of type `felt252`. The key-value types are specified within angular brackets <>. We write to the map by calling the `write()` method, passing in both the key and value. Similarly, we can read the value associated with a given key by calling the `read()` method and passing in the relevant key. + +Some additional notes: + +- More complex key-value mappings are possible, for example we could use `LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an allowance on an ERC20 token contract. + +- In mappings, the address of the value at key `k_1,...,k_n` is `h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the Pedersen hash and the final value is taken `mod2251−256`. You can learn more about the contract storage layout in the [Starknet Documentation](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables) + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/mappings/src/mappings.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/mappings/src/mappings.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/storage.md b/pages/ch00/basics/storage.md new file mode 100644 index 00000000..7d621c2b --- /dev/null +++ b/pages/ch00/basics/storage.md @@ -0,0 +1,57 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Storage + +Here's the most minimal contract you can write in Cairo: + +<<<<<<<< HEAD:src/getting-started/basics/storage.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/storage/src/minimal_contract.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:tests] +``` + +::: + +Storage is a `struct` annotated with `#[storage]`. Every contract must have one and only one storage. +It's a key-value store, where each key will be mapped to a storage address of the contract's storage space. + +You can define [storage variables](./variables.md#storage-variables) in your contract, and then use them to store and retrieve data. + +<<<<<<<< HEAD:src/getting-started/basics/storage.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/storage/src/contract.cairo:contract}} +``` + +> Actually these two contracts have the same underlying Sierra program. +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/storage/src/contract.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/storage/src/contract.cairo:tests] +``` + +::: + +> Actually these two contracts have the same underlying sierra program. +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md +> From the compiler's perspective, the storage variables don't exist until they are used. + +You can also read about [storing custom types](./storing-custom-types.md). diff --git a/pages/ch00/basics/storing-custom-types.md b/pages/ch00/basics/storing-custom-types.md new file mode 100644 index 00000000..43820f76 --- /dev/null +++ b/pages/ch00/basics/storing-custom-types.md @@ -0,0 +1,22 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Storing Custom Types + +While native types can be stored in a contract's storage without any additional work, custom types require a bit more work. This is because at compile time, the compiler does not know how to store custom types in storage. To solve this, we need to implement the `Store` trait for our custom type. Hopefully, we can just derive this trait for our custom type - unless it contains arrays or dictionaries. + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/storing_custom_types/src/contract.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/storing_custom_types/src/contract.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/syscalls.md b/pages/ch00/basics/syscalls.md new file mode 100644 index 00000000..bac7a1c2 --- /dev/null +++ b/pages/ch00/basics/syscalls.md @@ -0,0 +1,288 @@ +# Syscalls + +At the protocol level, the Starknet Operating System (OS) is the program that manages the whole Starknet network. + +Some of the OS functionalities are exposed to smart contracts through the use of syscalls (system calls). Syscalls can be used to get information about the state of the Starknet network, to interact with/deploy contracts, emit events, send messages, and perform other low-level operations. + +Syscalls return a `SyscallResult` which is either `Success` of `Failure`, allowing the contract to handle errors. + +Here's the available syscalls: + +- [get_block_hash](#get_block_hash) +- [get_execution_info](#get_execution_info) +- [call_contract](#call_contract) +- [deploy](#deploy) +- [emit_event](#emit_event) +- [library_call](#library_call) +- [send_message_to_L1](#send_message_to_L1) +- [replace_class](#replace_class) +- [storage_read](#storage_read) +- [storage_write](#storage_write) + + +#### get_block_hash + +```cairo +fn get_block_hash_syscall(block_number: u64) -> SyscallResult +``` + +Get the hash of the block number `block_number`. + +Only within the range `[first_v0_12_0_block, current_block - 10]`. + +#### get_execution_info + +```cairo +fn get_execution_info_syscall() -> SyscallResult> +``` + +Get information about the current execution context. +The returned `ExecutionInfo` is defined as : + +```cairo +#[derive(Copy, Drop, Debug)] +pub struct ExecutionInfo { + pub block_info: Box, + pub tx_info: Box, + pub caller_address: ContractAddress, + pub contract_address: ContractAddress, + pub entry_point_selector: felt252, +} + +#[derive(Copy, Drop, Debug, Serde)] +pub struct BlockInfo { + pub block_number: u64, + pub block_timestamp: u64, + pub sequencer_address: ContractAddress, +} + +#[derive(Copy, Drop, Debug, Serde)] +pub struct TxInfo { + // The version of the transaction. Always fixed (1) + pub version: felt252, + // The account contract from which this transaction originates. + pub account_contract_address: ContractAddress, + // The max_fee field of the transaction. + pub max_fee: u128, + // The signature of the transaction. + pub signature: Span, + // The hash of the transaction. + pub transaction_hash: felt252, + // The identifier of the chain. + // This field can be used to prevent replay of testnet transactions on mainnet. + pub chain_id: felt252, + // The transaction's nonce. + pub nonce: felt252, + // A span of ResourceBounds structs. + pub resource_bounds: Span, + // The tip. + pub tip: u128, + // If specified, the paymaster should pay for the execution of the tx. + // The data includes the address of the paymaster sponsoring the transaction, followed by + // extra data to send to the paymaster. + pub paymaster_data: Span, + // The data availability mode for the nonce. + pub nonce_data_availability_mode: u32, + // The data availability mode for the account balance from which fee will be taken. + pub fee_data_availability_mode: u32, + // If nonempty, will contain the required data for deploying and initializing an account + // contract: its class hash, address salt and constructor calldata. + pub account_deployment_data: Span, +} +``` + +`starknet::info` provides helper functions to access the `ExecutionInfo` fields in a more convenient way: + +- `get_execution_info() -> Box` +- `get_caller_address() -> ContractAddress` +- `get_contract_address() -> ContractAddress` +- `get_block_info() -> Box` +- `get_tx_info() -> Box` +- `get_block_timestamp() -> u64` +- `get_block_number() -> u64` + +#### call_contract + +```cairo +fn call_contract_syscall( + address: ContractAddress, entry_point_selector: felt252, calldata: Span +) -> SyscallResult> +``` + +Call a contract at `address` with the given `entry_point_selector` and `calldata`. +Failure can't be caught for this syscall, and if the call fails, the whole transaction will revert. + +This is not the recommended way to call a contract. Instead, use the dispatcher generated from the contract interface as shown in the [Calling other contracts](../interacting/calling_other_contracts.md) chapter. + + + +#### deploy + +```cairo +fn deploy_syscall( + class_hash: ClassHash, + contract_address_salt: felt252, + calldata: Span, + deploy_from_zero: bool, +) -> SyscallResult<(ContractAddress, Span::)> +``` + +Deploy a new contract of the predeclared class `class_hash` with `calldata`. +The success result is a tuple containing the deployed contract address and the return value of the constructor. + +`contract_address_salt` and `deploy_from_zero` are used to compute the contract address. + +Example of the usage of the `deploy` syscall from the [Factory pattern](../interacting/factory.md): + +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:deploy}} +======== +```rust +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:deploy] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md +``` + +#### emit_event + +```cairo +fn emit_event_syscall( + keys: Span, data: Span +) -> SyscallResult<()> +``` + +Emit an event with the given `keys` and `data`. + +Example of the usage of the `emit_event` syscall from the [Events](../basics/events.md) chapter: + +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:emit}} +======== +```rust +// [!include ~/listings/getting-started/events/src/counter.cairo:emit] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md +``` + + + + +#### library_call + +```cairo +fn library_call_syscall( + class_hash: ClassHash, function_selector: felt252, calldata: Span +) -> SyscallResult> +``` + +Call the function `function_selector` of the class `class_hash` with `calldata`. +This is analogous to a delegate call in Ethereum, but only a single class is called. + + + +#### send_message_to_L1 + +```cairo +fn send_message_to_l1_syscall( + to_address: felt252, payload: Span +) -> SyscallResult<()> +``` + +Send a message to the L1 contract at `to_address` with the given `payload`. + + + +#### replace_class + +```cairo +fn replace_class_syscall( + class_hash: ClassHash +) -> SyscallResult<()> +``` + +Replace the class of the calling contract with the class `class_hash`. + +This is used for contract upgrades. Here's an example from the [Upgradeable Contract](../../applications/upgradeable_contract.md): + +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md +```cairo +{{#rustdoc_include ../../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade}} +======== +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md +``` + +The new class code will only be used for future calls to the contract. +The current transaction containing the `replace_class` syscall will continue to use the old class code. Note that you can explicitly use the new class code in the same transaction by calling `call_contract` after the `replace_class` syscall. + +#### storage_read + +```cairo +fn storage_read_syscall( + address_domain: u32, address: StorageAddress, +) -> SyscallResult +``` + +This low-level syscall is used to get the value in the storage of a specific key at `address` in the `address_domain`. + +`address_domain` is used to distinguish between data availability modes. +Currently, only mode `ONCHAIN` (`0`) is supported. + +#### storage_write + +```cairo +fn storage_write_syscall( + address_domain: u32, address: StorageAddress, value: felt252 +) -> SyscallResult<()> +``` + +Similar to `storage_read`, this low-level syscall is used to write the value `value` in the storage of a specific key at `address` in the `address_domain`. + +## Documentation + +Syscalls are defined in [`starknet::syscall`](https://github.com/starkware-libs/cairo/blob/ec14a5e2c484190ff40811c973a72a53739cedb7/corelib/src/starknet/syscalls.cairo). + +You can also read the [official documentation page](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/) for more details. + + diff --git a/pages/ch00/basics/variables.md b/pages/ch00/basics/variables.md new file mode 100644 index 00000000..9ad59a6e --- /dev/null +++ b/pages/ch00/basics/variables.md @@ -0,0 +1,90 @@ +# Variables + +There are 3 types of variables in Cairo contracts: + +- Local + - declared inside a function + - not stored on the blockchain +- Storage + - declared in the [Storage](./storage.md) of a contract + - can be accessed from one execution to another +- Global + - provides information about the blockchain + - accessed anywhere, even within library functions + +## Local Variables + +Local variables are used and accessed within the scope of a specific function or block of code. They are temporary and exist only for the duration of that particular function or block execution. + +Local variables are stored in memory and are not stored on the blockchain. This means they cannot be accessed from one execution to another. Local variables are useful for storing temporary data that is relevant only within a specific context. They also make the code more readable by giving names to intermediate values. + +Here's a simple example of a contract with only local variables: + +<<<<<<<< HEAD:src/getting-started/basics/variables.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/variables/src/local_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/local_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/local_variables.cairo:tests] +``` + +::: + +## Storage Variables + +Storage variables are persistent data stored on the blockchain. They can be accessed from one execution to another, allowing the contract to remember and update information over time. See [Storage](./storage.md) for more information. + +To write or update a storage variable, you need to interact with the contract through an external entrypoint by sending a transaction. + +On the other hand, you can read state variables for free, without any transaction, simply by interacting with a node. + +Here's a simple example of a contract with one storage variable: + +<<<<<<<< HEAD:src/getting-started/basics/variables.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/variables/src/storage_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:tests] +``` + +::: + +## Global Variables + +Global variables are predefined variables that provide information about the blockchain and the current execution environment. They can be accessed at any time and from anywhere! + +In Starknet, you can access global variables by using specific functions from the Starknet core library. + +For example, the `get_caller_address` function returns the address of the caller of the current transaction, and the `get_contract_address` function returns the address of the current contract. + +<<<<<<<< HEAD:src/getting-started/basics/variables.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/variables/src/global_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/global_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/global_variables.cairo:tests] +``` + +::: diff --git a/pages/ch00/basics/visibility-mutability.md b/pages/ch00/basics/visibility-mutability.md new file mode 100644 index 00000000..24cfab47 --- /dev/null +++ b/pages/ch00/basics/visibility-mutability.md @@ -0,0 +1,42 @@ +# Visibility and Mutability + +## Visibility + +There are two types of functions in Starknet contracts: + +- Functions that are accessible externally and can be called by anyone. +- Functions that are only accessible internally and can only be called by other functions in the contract. + +These functions are also typically divided into two different implementation blocks. The first `impl` block for externally accessible functions is explicitly annotated with an `#[abi(embed_v0)]` attribute. This indicates that all the functions inside this block can be called either as a transaction or as a view function. The second `impl` block for internally accessible functions is not annotated with any attribute, which means that all the functions inside this block are private by default. + +## State Mutability + +Regardless of whether a function is internal or external, it can either modify the contract's state or not. When we declare functions that interact with storage variables inside a smart contract, +we need to explicitly state that we are accessing the `ContractState` by adding it as the first parameter of the function. This can be done in two different ways: + +- If we want our function to be able to mutate the state of the contract, we pass it by reference like this: `ref self: ContractState` +- If we want our function to be read-only and not mutate the state of the contract, we pass it by snapshot like this: `self: @ContractState` + +Read-only functions, also called view functions, can be directly called without making a transaction. You can interact with them directly through an RPC node to read the contract's state, and they're free to call! +External functions, that modify the contract's state, on the other hand, can only be called by making a transaction. + +Internal functions can't be called externally, but the same principle applies regarding state mutability. + +Let's take a look at a simple example contract to see these in action: + +<<<<<<<< HEAD:src/getting-started/basics/visibility-mutability.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/visibility/src/visibility.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/visibility/src/visibility.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/visibility-mutability.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/visibility/src/visibility.cairo:tests] +``` + +::: diff --git a/pages/ch00/cairo_cheatsheet/arrays.md b/pages/ch00/cairo_cheatsheet/arrays.md new file mode 100644 index 00000000..8e7a30ba --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/arrays.md @@ -0,0 +1,36 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Arrays + +Arrays are collections of elements of the same type. +The possible operations on arrays are defined with the `array::ArrayTrait` of the corelib: + +```cairo +trait ArrayTrait { + fn new() -> Array; + fn append(ref self: Array, value: T); + fn pop_front(ref self: Array) -> Option nopanic; + fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic; + fn get(self: @Array, index: usize) -> Option>; + fn at(self: @Array, index: usize) -> @T; + fn len(self: @Array) -> usize; + fn is_empty(self: @Array) -> bool; + fn span(self: @Array) -> Span; +} +``` + +For example: + +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/arrays.md +```cairo +{{#include ../../../listings/getting-started/cairo_cheatsheet/src/array_example.cairo}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/array_example.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/arrays.md +``` diff --git a/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md b/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md new file mode 100644 index 00000000..57761760 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md @@ -0,0 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Cairo Cheatsheet + +This chapter aims to provide a quick reference for the most common Cairo constructs. diff --git a/pages/ch00/cairo_cheatsheet/felt.md b/pages/ch00/cairo_cheatsheet/felt.md new file mode 100644 index 00000000..b71778fd --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/felt.md @@ -0,0 +1,17 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Felt252 + +Felt252 is a fundamental data type in Cairo from which all other data types are derived. +Felt252 can also be used to store [short string representations](../basics/bytearrays-strings.md#short-strings) with a maximum length of 31 characters. + +For example: + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo:sheet] +``` diff --git a/pages/ch00/cairo_cheatsheet/if_let.md b/pages/ch00/cairo_cheatsheet/if_let.md new file mode 100644 index 00000000..f7edd7e7 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/if_let.md @@ -0,0 +1,24 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# `if let` + +A `if let` statement is a combination of an `if` statement and a `let` statement. It allows you to execute the block only if the pattern matches. It's a cleaner way to handle a `match` statement with only one pattern that you want to handle. + +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/if_let.md +```cairo +{{#include ../../../listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/if_let.md +``` + +### See also + +[while let](while_let.md) diff --git a/pages/ch00/cairo_cheatsheet/loop.md b/pages/ch00/cairo_cheatsheet/loop.md new file mode 100644 index 00000000..7efb6193 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/loop.md @@ -0,0 +1,25 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# `loop` + +A `loop` specifies a block of code that will run repetitively until a halting condition is encountered. + +For example: + +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/loop.md +```cairo +{{#include ../../../listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/loop.md +``` + +### See also + +[while](while.md) diff --git a/pages/ch00/cairo_cheatsheet/mapping.md b/pages/ch00/cairo_cheatsheet/mapping.md new file mode 100644 index 00000000..b3bd0c19 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/mapping.md @@ -0,0 +1,14 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Mapping + +The `LegacyMap` type can be used to represent a collection of key-value. + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo] +``` diff --git a/pages/ch00/cairo_cheatsheet/match.md b/pages/ch00/cairo_cheatsheet/match.md new file mode 100644 index 00000000..2d517def --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/match.md @@ -0,0 +1,16 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Match + +The "match" expression in Cairo allows us to control the flow of our code by comparing a felt data type or an enum against various patterns and then running specific code based on the pattern that matches. +For example: + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/match_example.cairo] +``` diff --git a/pages/ch00/cairo_cheatsheet/struct.md b/pages/ch00/cairo_cheatsheet/struct.md new file mode 100644 index 00000000..ee96a1e1 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/struct.md @@ -0,0 +1,16 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Struct + +A struct is a data type similar to tuple. Like tuples they can be used to hold data of different types. +For example: + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/struct_example.cairo] +``` diff --git a/pages/ch00/cairo_cheatsheet/tuples.md b/pages/ch00/cairo_cheatsheet/tuples.md new file mode 100644 index 00000000..6d2935b9 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/tuples.md @@ -0,0 +1,22 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Tuples + +Tuples is a data type to group a fixed number of items of potentially different types into a single compound structure. Unlike arrays, tuples have a set length and can contain elements of varying types. Once a tuple is created, its size cannot change. + +For example: + +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/tuples.md +```cairo +{{#include ../../../listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/tuples.md +``` diff --git a/pages/ch00/cairo_cheatsheet/type_casting.md b/pages/ch00/cairo_cheatsheet/type_casting.md new file mode 100644 index 00000000..ecb1ceb0 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/type_casting.md @@ -0,0 +1,17 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Type casting + +Cairo supports the conversion from one scalar types to another by using the into and try_into methods. +`traits::Into` is used for conversion from a smaller data type to a larger data type, while `traits::TryInto` is used when converting from a larger to a smaller type that might not fit. +For example: + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo:sheet] +``` diff --git a/pages/ch00/cairo_cheatsheet/while.md b/pages/ch00/cairo_cheatsheet/while.md new file mode 100644 index 00000000..b5bf0897 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/while.md @@ -0,0 +1,19 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# `while` + +A `while` loop allows you to specify a condition that must be true for the loop to continue. + +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/while_example.cairo:sheet] +``` + +### See also + +[loop](loop.md) diff --git a/pages/ch00/cairo_cheatsheet/while_let.md b/pages/ch00/cairo_cheatsheet/while_let.md new file mode 100644 index 00000000..c5ec9813 --- /dev/null +++ b/pages/ch00/cairo_cheatsheet/while_let.md @@ -0,0 +1,25 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# `while let` + +A `while let` loop is a combination of a `while` loop and a `let` statement. It allows you to execute the loop body only if the pattern matches. + +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/while_let.md +```cairo +{{#include ../../../listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/while_let.md +``` + +### See also + +- [while](while.md) +- [if let](if_let.md) diff --git a/pages/ch00/env_setup.md b/pages/ch00/env_setup.md new file mode 100644 index 00000000..e07303af --- /dev/null +++ b/pages/ch00/env_setup.md @@ -0,0 +1,5 @@ +# Local environment setup + +The current version of this book use `{{#include ../../.tool-versions}}` + + diff --git a/pages/ch00/interacting/calling_other_contracts.md b/pages/ch00/interacting/calling_other_contracts.md new file mode 100644 index 00000000..2768dffe --- /dev/null +++ b/pages/ch00/interacting/calling_other_contracts.md @@ -0,0 +1,56 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Calling other contracts + +There are two different ways to call other contracts in Cairo. + +The easiest way to call other contracts is by using the dispatcher of the contract you want to call. +You can read more about Dispatchers in the [Cairo Book](https://book.cairo-lang.org/ch15-02-interacting-with-another-contract.html#calling-contracts-using-the-contract-dispatcher). + +The other way is to use the `starknet::call_contract_syscall` syscall yourself. However, this method is not recommended and will not be covered in this chapter. + +In order to call other contracts using dispatchers, you will need to define the called contract's interface as a trait annotated with the `#[starknet::interface]` attribute, and then import the `IContractDispatcher` and `IContractDispatcherTrait` items in your contract. + +Here's the `Callee` contract interface and implementation: + +<<<<<<<< HEAD:src/getting-started/interacting/calling_other_contracts.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract}} +``` + +The following `Caller` contract uses the `Callee` dispatcher to call the `Callee` contract: + +```cairo +{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] +``` + +::: + +The following `Caller` contract use the `Callee` interface to call the `Callee` contract: + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/calling_other_contracts.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] +``` + +::: diff --git a/pages/ch00/interacting/factory.md b/pages/ch00/interacting/factory.md new file mode 100644 index 00000000..90dd5681 --- /dev/null +++ b/pages/ch00/interacting/factory.md @@ -0,0 +1,42 @@ +# Factory Pattern + +The factory pattern is a well known pattern in object oriented programming. It provides an abstraction on how to instantiate a class. + +In the case of smart contracts, we can use this pattern by defining a factory contract that has the sole responsibility of creating and managing other contracts. + +## Class hash and contract instance + +In Starknet, there's a separation between contract's classes and instances. A contract class serves as a blueprint, defined by the underlying Cairo bytecode, contract's entrypoints, ABI and Sierra program hash. The contract class is identified by a class hash. When you want to add a new class to the network, you first need to declare it. + +When deploying a contract, you need to specify the class hash of the contract you want to deploy. Each instance of a contract has their own storage regardless of the class hash. + +Using the factory pattern, we can deploy multiple instances of the same contract class and handle upgrades easily. + +## Minimal example + +Here's a minimal example of a factory contract that deploys the `SimpleCounter` contract: + +<<<<<<<< HEAD:src/getting-started/interacting/factory.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/factory.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:tests] +``` + +::: + +This factory can be used to deploy multiple instances of the `SimpleCounter` contract by calling the `create_counter` and `create_counter_at` functions. + +The `SimpleCounter` class hash is stored inside the factory, and can be upgraded with the `update_counter_class_hash` function which allows to reuse the same factory contract when the `SimpleCounter` contract is upgraded. + +> Note: This minimal example lacks several useful features such as access control, tracking of deployed contracts, events etc. + + diff --git a/pages/ch00/interacting/interacting.md b/pages/ch00/interacting/interacting.md new file mode 100644 index 00000000..67dc71eb --- /dev/null +++ b/pages/ch00/interacting/interacting.md @@ -0,0 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Deploy and interact with contracts + +In this chapter, we will see how to deploy and interact with contracts. diff --git a/pages/ch00/interacting/interfaces-traits.md b/pages/ch00/interacting/interfaces-traits.md new file mode 100644 index 00000000..b94760da --- /dev/null +++ b/pages/ch00/interacting/interfaces-traits.md @@ -0,0 +1,76 @@ +# Contract interfaces and Traits generation + +Contract interfaces define the structure and behavior of a contract, serving as the contract's public ABI. They list all the function signatures that a contract exposes. For a detailed explanation of interfaces, you can refer to the [Cairo Book](https://book.cairo-lang.org/ch13-02-anatomy-of-a-simple-contract.html#the-interface-the-contracts-blueprint). + +In Cairo, to specify the interface you need to define a trait annotated with `#[starknet::interface]` and then implement that trait in the contract. + +When a function needs to access the contract state, it must have a `self` parameter of type `ContractState`. This implies that the corresponding function signature in the interface trait must also take a `TContractState` type as a parameter. It's important to note that every function in the contract interface must have this `self` parameter of type `TContractState`. + +You can use the `#[generate_trait]` attribute to implicitly generate the trait for a specific implementation block. This attribute automatically generates a trait with the same functions as the ones in the implemented block, replacing the `self` parameter with a generic `TContractState` parameter. However, you will need to annotate the block with the `#[abi(per_item)]` attribute, and each function with the appropriate attribute depending on whether it's an external function, a constructor or an L1 handler. + +In summary, there's two ways to handle interfaces: + +- Explicitly, by defining a trait annotated with `#[starknet::interface]` +- Implicitly, by using `#[generate_trait]` combined with the `#[abi(per_item)]` attributes, and annotating each function inside the implementation block with the appropriate attribute. + +## Explicit interface + +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/explicit.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:tests] +``` + +::: + +## Implicit interface + +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:tests] +``` + +::: + +> Note: You can import an implicitly generated contract interface with `use contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not be generated automatically. + +## Internal functions + +You can also use `#[generate_trait]` for your internal functions. +Since this trait is generated in the context of the contract, you can define pure functions as well (functions without the `self` parameter). + +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:tests] +``` + +::: diff --git a/pages/ch00/testing/contract-testing.md b/pages/ch00/testing/contract-testing.md new file mode 100644 index 00000000..66c80731 --- /dev/null +++ b/pages/ch00/testing/contract-testing.md @@ -0,0 +1,113 @@ +# Contract Testing + +Testing plays a crucial role in software development, especially for smart contracts. In this section, we'll guide you through the basics of testing a smart contract on Starknet with `scarb`. + +Let's start with a simple smart contract as an example: + +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md +```cairo +{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:contract}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md +``` + +Now, take a look at the tests for this contract: + +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md +```cairo +{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md +``` + +To define our test, we use scarb, which allows us to create a separate module guarded with `#[cfg(test)]`. This ensures that the test module is only compiled when running tests using `scarb test`. + +Each test is defined as a function with the `#[test]` attribute. You can also check if a test panics using the `#[should_panic]` attribute. + +As we are in the context of a smart contract, you can also set up the gas limit for a test by using the `#[available_gas(X)]`. This is a great way to ensure that some of your contract's features stay under a certain gas limit! + +> Note: The term "gas" here refers to Sierra gas, not L1 gas. + +Now, let's move on to the testing process: + +- Use the `deploy` function logic to declare and deploy your contract +- Use `assert` to verify that the contract behaves as expected in the given context + - You can also use assertion macros: `assert_eq!`, `assert_ne!`, `assert_gt!`, `assert_ge!`, `assert_lt!`, `assert_le!` + +If you haven't noticed yet, every example in this book has hidden tests, you can see them by clicking the "Show hidden lines" (eyes icon) on the top right of code blocks. +You can also find a detailed explanation of testing in Cairo in [The Cairo Book](https://book.cairo-lang.org/ch10-00-testing-cairo-programs.html). + +## Using the contract state + +You can use the `Contract::contract_state_for_testing` function to access the contract state. This function is only available in the test environment and allows you to mutate and read the contract state directly. + +This can be useful for testing internal functions, or specific state mutations that are not exposed to the contract's interface. You can either use it with a deployed contract or as a standalone state. + +Here is an example of how to do the same previous test using the contract state: + +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md +```cairo +{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md +``` + +## Testing events + +In order to test events, you need to use the `starknet::pop_log` function. If the contract did not emit any events, the function will return `Option::None`. + +See the test for the [Events](../basics/events.md) section: + +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md +```cairo +{{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:test_events}} +======== +```rust +// [!include ~/listings/getting-started/events/src/counter.cairo:test_events] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md +``` + +## Starknet Corelib Testing Module + +To make testing more convenient, the `testing` module of the corelib provides some helpful functions: + +- `set_caller_address(address: ContractAddress)` +- `set_contract_address(address: ContractAddress)` +- `set_block_number(block_number: u64)` +- `set_block_timestamp(block_timestamp: u64)` +- `set_account_contract_address(address: ContractAddress)` +- `set_sequencer_address(address: ContractAddress)` +- `set_version(version: felt252)` +- `set_transaction_hash(hash: felt252)` +- `set_chain_id(chain_id: felt252)` +- `set_nonce(nonce: felt252)` +- `set_signature(signature: felt252)` +- `set_max_fee(fee: u128)` +- `pop_log_raw(address: ContractAddress) -> Option<(Span, Span)>` +- `pop_log>(address: ContractAddress) -> Option` +- `pop_l2_to_l1_message(address: ContractAddress) -> Option<(felt252, Span)>` + +You may also need the `info` module from the corelib, which allows you to access information about the current execution context (see [syscalls](../basics/syscalls.md)): + +- `get_caller_address() -> ContractAddress` +- `get_contract_address() -> ContractAddress` +- `get_block_info() -> Box` +- `get_tx_info() -> Box` +- `get_block_timestamp() -> u64` +- `get_block_number() -> u64` + +You can find the full list of functions in the [Starknet Corelib repo](https://github.com/starkware-libs/cairo/tree/main/corelib/src/starknet). + +## Starknet Foundry + +Starknet Foundry is a powerful toolkit for developing smart contracts on Starknet. It offers support for testing Starknet smart contracts on top of `scarb` with the `Forge` tool. + +Testing with `snforge` is similar to the process we just described, but simplified. Moreover, additional features are on the way, including cheatcodes and parallel test execution. We highly recommend exploring Starknet Foundry and incorporating it into your projects. + +For more detailed information about testing contracts with Starknet Foundry, check out the [Starknet Foundry Book - Testing Contracts](https://foundry-rs.github.io/starknet-foundry/testing/contracts.html). diff --git a/pages/ch01/constant-product-amm.md b/pages/ch01/constant-product-amm.md new file mode 100644 index 00000000..e13d7dec --- /dev/null +++ b/pages/ch01/constant-product-amm.md @@ -0,0 +1,14 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Constant Product AMM + +This is the Cairo adaptation of the [Solidity by example Constant Product AMM](https://solidity-by-example.org/defi/constant-product-amm/). + +```rust +// [!include ~/listings/applications/constant_product_amm/src/contracts.cairo:ConstantProductAmmContract] +``` diff --git a/pages/ch01/erc20.md b/pages/ch01/erc20.md new file mode 100644 index 00000000..dbc21402 --- /dev/null +++ b/pages/ch01/erc20.md @@ -0,0 +1,37 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# ERC20 Token + +Contracts that follow the [ERC20 Standard](https://eips.ethereum.org/EIPS/eip-20) are called ERC20 tokens. They are used to represent fungible assets. + +To create an ERC20 contract, it must implement the following interface: + +<<<<<<<< HEAD:src/applications/erc20.md +```cairo +{{#include ../../listings/applications/erc20/src/token.cairo:interface}} +======== +```rust +// [!include ~/listings/applications/erc20/src/token.cairo:interface] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md +``` + +In Starknet, function names should be written in _snake_case_. This is not the case in Solidity, where function names are written in _camelCase_. +The Starknet ERC20 interface is therefore slightly different from the Solidity ERC20 interface. + +Here's an implementation of the ERC20 interface in Cairo: + +<<<<<<<< HEAD:src/applications/erc20.md +```cairo +{{#include ../../listings/applications/erc20/src/token.cairo:erc20}} +======== +```rust +// [!include ~/listings/applications/erc20/src/token.cairo:erc20] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md +``` + +There's several other implementations, such as the [Open Zeppelin](https://docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the [Cairo By Example](https://cairo-by-example.com/examples/erc20/) ones. diff --git a/pages/ch01/signature_verification.md b/pages/ch01/signature_verification.md new file mode 100644 index 00000000..afd2f847 --- /dev/null +++ b/pages/ch01/signature_verification.md @@ -0,0 +1 @@ +# Signature Verification diff --git a/pages/ch01/simple_vault.md b/pages/ch01/simple_vault.md new file mode 100644 index 00000000..7f9138fc --- /dev/null +++ b/pages/ch01/simple_vault.md @@ -0,0 +1,24 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Simple Defi Vault + +This is the Cairo adaptation of the [Solidity by Example - Vault](https://solidity-by-example.org/defi/vault/). +Here's how it works: + +- When a user deposits a token, the contract calculates the amount of shares to mint. + +- When a user withdraws, the contract burns their shares, calculates the yield, and withdraws both the yield and the initial amount of tokens deposited. + +<<<<<<<< HEAD:src/applications/simple_vault.md +```cairo +{{#include ../../listings/applications/simple_vault/src/simple_vault.cairo}} +======== +```rust +// [!include ~/listings/applications/simple_vault/src/simple_vault.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/simple_vault.md +``` diff --git a/pages/ch01/upgradeable_contract.md b/pages/ch01/upgradeable_contract.md new file mode 100644 index 00000000..48388029 --- /dev/null +++ b/pages/ch01/upgradeable_contract.md @@ -0,0 +1,47 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Upgradeable Contract + +In Starknet, contracts are divided into two parts: contract classes and contract +instances. This division follows a similar concept used in object-oriented +programming languages, where we distinguish between the definition and implementation +of objects. + +A contract class is the definition of a contract: it specifies how the contract +behaves. It contains essential information like the Cairo byte code, hint +information, entry point names, and everything that defines its semantics +unambiguously. + +To identify different contract classes, Starknet assigns a unique identifier to each +class: the class hash. A contract instance is a deployed contract that corresponds to +a specific contract class. Think of it as an instance of an object in languages like +Java. + +Each class is identified by its class hash, which is analogous to a class name in an object-oriented programming language. A contract instance is a deployed contract corresponding to a class. + +You can upgrade a deployed contract to a newer version by calling the `replace_class_syscall` function. By using this function, you can update the class hash associated with a deployed contract, effectively upgrading its implementation. However, this will not modify the contract's storage, so all the data stored in the contract will remain the same. + +To illustrate this concept, let's consider an example with two contracts: `UpgradeableContract_V0`, and `UpgradeableContract_V1`. +Start by deploying `UpgradeableContract_V0` as the initial version. Next, send a transaction that invokes the `upgrade` function, with the class hash of `UpgradeableContract_V1` as parameter to upgrade the class hash of the deployed contract to the `UpgradeableContract_V1` one. Then, call the `version` method on the contract to see that the contract was upgraded to the V1 version. + +<<<<<<<< HEAD:src/applications/upgradeable_contract.md +```cairo +{{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract}} +``` + +```cairo +{{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo}} +======== +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract] +``` + +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/upgradeable_contract.md +``` diff --git a/pages/ch02/hash-solidity-compatible.md b/pages/ch02/hash-solidity-compatible.md new file mode 100644 index 00000000..7ffc7e8b --- /dev/null +++ b/pages/ch02/hash-solidity-compatible.md @@ -0,0 +1,9 @@ +# Hash Solidity Compatible + +This contract demonstrates Keccak hashing in Cairo to match Solidity's keccak256. While both use Keccak, their endianness differs: Cairo is little-endian, Solidity big-endian. The contract achieves compatibility by hashing in big-endian using `keccak_u256s_be_inputs`, and reversing the bytes of the result with `u128_byte_reverse`. + +For example: + +```cairo +{{#include ../../listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo}} +``` diff --git a/pages/ch02/hashing.md b/pages/ch02/hashing.md new file mode 100644 index 00000000..78c4b8f6 --- /dev/null +++ b/pages/ch02/hashing.md @@ -0,0 +1,31 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Hashing + +Hashing is a cryptographic technique that allows you to transform a variable length input into a fixed length output. +The resulting output is called a hash and it's completely different from the input. +Hash functions are deterministic, meaning that the same input will always produce the same output. + +The two hash functions provided by the Cairo library are `Poseidon` and `Pedersen`. +Pedersen hashes were used in the past (but still used in some scenario for backward compatibility) while Poseidon hashes are the standard nowadays since they were designed to be very efficient for Zero Knowledge proof systems. + +In Cairo it's possible to hash all the types that can be converted to `felt252` since they implement natively the `Hash` trait. It's also possible to hash more complex types like structs by deriving the Hash trait with the attribute `#[derive(Hash)]` but only if all the struct's fields are themselves hashable. + +You first need to initialize a hash state with the `new` method of the `HashStateTrait` and then you can update it with the `update` method. You can accumulate multiple updates. Then, the `finalize` method returns the final hash value as a `felt252`. + +:::code-group + +```rust [contract] +// [!include ~/listings/advanced-concepts/hash_trait/src/hash_trait.cairo:hash] +``` + +```rust [tests] +// [!include ~/listings/advanced-concepts/hash_trait/src/hash_trait.cairo:tests] +``` + +::: diff --git a/pages/ch02/list.md b/pages/ch02/list.md new file mode 100644 index 00000000..e3f8725c --- /dev/null +++ b/pages/ch02/list.md @@ -0,0 +1,70 @@ +# List + +By default, there is no list type supported in Cairo, but you can use Alexandria. You can refer to the [Alexandria documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/src/storage) for more details. + +## What is `List`? + +An ordered sequence of values that can be used in Starknet storage: + +```rust +#[storage] +struct Storage { + amounts: List +} +``` + +### Interface + +```rust +trait ListTrait { + fn len(self: @List) -> u32; + fn is_empty(self: @List) -> bool; + fn append(ref self: List, value: T) -> u32; + fn get(self: @List, index: u32) -> Option; + fn set(ref self: List, index: u32, value: T); + fn pop_front(ref self: List) -> Option; + fn array(self: @List) -> Array; +} +``` + +`List` also implements `IndexView` so you can use the familiar bracket notation to access its members: + +```rust +let second = self.amounts.read()[1]; +``` + +Note that unlike `get`, using this bracket notation panics when accessing an out of bounds index. + +### Support for custom types + +`List` supports most of the corelib types out of the box. If you want to store a your own custom type in a `List`, it has to implement the `Store` trait. You can have the compiler derive it for you using the `#[derive(starknet::Store)]` attribute. + +### Caveats + +There are two idiosyncacies you should be aware of when using `List` + +1. The `append` operation costs 2 storage writes - one for the value itself and another one for updating the List's length +2. Due to a compiler limitation, it is not possible to use mutating operations with a single inline statement. For example, `self.amounts.read().append(42);` will not work. You have to do it in 2 steps: + +```rust +let mut amounts = self.amounts.read(); +amounts.append(42); +``` + +### Dependencies + +Update your project dependencies by in the `Scarb.toml` file: + +```rust +[dependencies] +(...) +alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +``` + +For example, let's use `List` to create a contract that tracks a list of amounts and tasks: + +```rust +// [!include ~/listings/advanced-concepts/using_lists/src/contract.cairo] +``` + +istings/advanced-concepts/using_lists/src/contract.cairo diff --git a/pages/ch02/optimisations/optimisations.md b/pages/ch02/optimisations/optimisations.md new file mode 100644 index 00000000..8fd04b1e --- /dev/null +++ b/pages/ch02/optimisations/optimisations.md @@ -0,0 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Optimisations + +A collection of optimisation patterns to save gas and steps. diff --git a/pages/ch02/optimisations/store_using_packing.md b/pages/ch02/optimisations/store_using_packing.md new file mode 100644 index 00000000..48f256aa --- /dev/null +++ b/pages/ch02/optimisations/store_using_packing.md @@ -0,0 +1,35 @@ +# Storage optimisation + +A smart contract has a limited amount of **storage slots**. Each slot can store a single `felt252` value. +Writing to a storage slot has a cost, so we want to use as few storage slots as possible. + +In Cairo, every type is derived from the `felt252` type, which uses 252 bits to store a value. +This design is quite simple, but it does have a drawback: it is not storage efficient. For example, if we want to store a `u8` value, we need to use an entire slot, even though we only need 8 bits. + +## Packing + +When storing multiple values, we can use a technique called **packing**. Packing is a technique that allows us to store multiple values in a single `felt252` value. This is done by using the bits of the `felt252` value to store multiple values. + +For example, if we want to store two `u8` values, we can use the first 8 bits of the `felt252` value to store the first `u8` value, and the last 8 bits to store the second `u8` value. This way, we can store two `u8` values in a single `felt252` value. + +Cairo provides a built-in store using packing that you can use with the `StorePacking` trait. + +```cairo +trait StorePacking { + fn pack(value: T) -> PackedT; + fn unpack(value: PackedT) -> T; +} +``` + +This allows us to store the type `T` by first packing it into the type `PackedT` with the `pack` function, and then storing the `PackedT` value with it's `Store` implementation. When reading the value, we first retrieve the `PackedT` value, and then unpack it into the type `T` using the `unpack` function. + +Here's an example of storing a `Time` struct with two `u8` values using the `StorePacking` trait: + +<<<<<<<< HEAD:src/advanced-concepts/optimisations/store_using_packing.md +```cairo +{{#include ../../../listings/advanced-concepts/store_using_packing/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/store_using_packing/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/optimisations/store_using_packing.md +``` diff --git a/pages/ch02/plugins.md b/pages/ch02/plugins.md new file mode 100644 index 00000000..e2bb86ca --- /dev/null +++ b/pages/ch02/plugins.md @@ -0,0 +1,14 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Plugins + +Compilers plugin in Cairo are a way to generate additional code for specific items during the compilation process. + +There are already a set of core plugins that you may have already used, such as `#[derive]`, `#[cfg]`, `#[generate_trait]`, etc. + +It is possible to create your own plugins in rust. You can learn more about how to do that in the [hello-cairo-plugin](https://github.com/piwonskp/hello-cairo-plugin) repository. diff --git a/pages/ch02/signature_verification.md b/pages/ch02/signature_verification.md new file mode 100644 index 00000000..c7f46de0 --- /dev/null +++ b/pages/ch02/signature_verification.md @@ -0,0 +1,17 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# ECDSA Verification + +This is the Cairo adaptation of the [Solidity by example Verifying Signature](https://solidity-by-example.org/signature/) +Messages can be signed off chain and then verified on chain using a smart contract. + +```rust +// [!include ~/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo] +``` + +[Click here to interact with the deployed contract on Voyager](https://goerli.voyager.online/contract/0x070bad62072d2a30fd08a95e9de99828955cfcffc40eac8adf3b21e9970590be#writeContract) diff --git a/pages/ch02/storing_arrays.md b/pages/ch02/storing_arrays.md new file mode 100644 index 00000000..ce5c940c --- /dev/null +++ b/pages/ch02/storing_arrays.md @@ -0,0 +1,26 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Storing Arrays + +On Starknet, complex values (e.g., tuples or structs), are stored in a continuous segment starting from the address of the storage variable. There is a 256 field elements limitation to the maximal size of a complex storage value, meaning that to store arrays of more than 255 elements in storage, we would need to split it into segments of size `n <= 255` and store these segments in multiple storage addresses. There is currently no native support for storing arrays in Cairo, so you will need to write your own implementation of the `Store` trait for the type of array you wish to store. + +However, the `ByteArray` struct can be used to store `Array` in storage without additional implementation. Before implementing your own `Store` trait, consider wether the `ByteArray` struct can be used to store the data you need! See the [ByteArray](../ch00/basics/bytearrays-strings.md#bytearray-long-strings) section for more information. + +> Note: While storing arrays in storage is possible, it is not always recommended, as the read and write operations can get very costly. For example, reading an array of size `n` requires `n` storage reads, and writing to an array of size `n` requires `n` storage writes. If you only need to access a single element of the array at a time, it is recommended to use a `LegacyMap` and store the length in another variable instead. + +The following example demonstrates how to write a simple implementation of the `StorageAccess` trait for the `Array` type, allowing us to store arrays of up to 255 `felt252` elements. + +```rust +// [!include ~/listings/advanced-concepts/storing_arrays/src/contract.cairo:StorageAccessImpl] +``` + +You can then import this implementation in your contract and use it to store arrays in storage: + +```rust +// [!include ~/listings/advanced-concepts/storing_arrays/src/contract.cairo:StoreArrayContract] +``` diff --git a/pages/ch02/struct-mapping-key.md b/pages/ch02/struct-mapping-key.md new file mode 100644 index 00000000..b0eec8b1 --- /dev/null +++ b/pages/ch02/struct-mapping-key.md @@ -0,0 +1,22 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Structs as mapping keys + +In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the struct definition. This will automatically generate a hash function for the struct that can be used to represent the struct as a key in a `Map`. + +Consider the following example in which we would like to use an object of +type `Pet` as a key in a `Map`. The `Pet` struct has three fields: `name`, `age` and `owner`. We consider that the combination of these three fields uniquely identifies a pet. + +<<<<<<<< HEAD:src/advanced-concepts/struct-mapping-key.md +```cairo +{{#include ../../listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/struct-mapping-key.md +``` diff --git a/pages/ch02/write_to_any_slot.md b/pages/ch02/write_to_any_slot.md new file mode 100644 index 00000000..50dd24ba --- /dev/null +++ b/pages/ch02/write_to_any_slot.md @@ -0,0 +1,25 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Writing to any storage slot + +On Starknet, a contract's storage is a map with \\( 2^{251} \\) slots, where each slot is a `felt252` which is initialized to 0. +The address of storage variables is computed at compile time using the formula: `storage variable address := pedersen(keccak(variable name), keys)`. Interactions with storage variables are commonly performed using the `self.var.read()` and `self.var.write()` functions. + +Nevertheless, we can use the `storage_write_syscall` and `storage_read_syscall` syscalls, to write to and read from any storage slot. +This is useful when writing to storage variables that are not known at compile time, or to ensure that even if the contract is upgraded and the computation method of storage variable addresses changes, they remain accessible. + +In the following example, we use the Poseidon hash function to compute the address of a storage variable. Poseidon is a ZK-friendly hash function that is cheaper and faster than Pedersen, making it an excellent choice for onchain computations. Once the address is computed, we use the storage syscalls to interact with it. + +<<<<<<<< HEAD:src/advanced-concepts/write_to_any_slot.md +```cairo +{{#include ../../listings/advanced-concepts/write_to_any_slot/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/write_to_any_slot/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/write_to_any_slot.md +``` diff --git a/src/components/collisions.md b/pages/components/collisions.md similarity index 60% rename from src/components/collisions.md rename to pages/components/collisions.md index 9982c0f2..c3caeee8 100644 --- a/src/components/collisions.md +++ b/pages/components/collisions.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Component-Contract Storage Collisions Components can declare their own storage variables. @@ -15,6 +22,7 @@ Here's an example of a collision on the `switchable_value` storage variable of t Interface: +<<<<<<< HEAD:src/components/collisions.md ```cairo {{#include ../../listings/applications/components/src/others/switch_collision.cairo:interface}} ``` @@ -23,10 +31,25 @@ Here's the storage of the contract (you can expand the code snippet to see the f ```cairo {{#rustdoc_include ../../listings/applications/components/src/others/switch_collision.cairo:storage}} +======= +```rust +// [!include ~/listings/applications/components/src/contracts/switch_collision.cairo:interface] +``` + +Here's the storage of the contract (you can expand the code snippet to see the full contract): + +```rust +// [!include ~/listings/applications/components/src/contracts/switch_collision.cairo:storage] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/collisions.md ``` Both the contract and the component have a `switchable_value` storage variable, so they collide: +<<<<<<< HEAD:src/components/collisions.md ```cairo {{#include ../../listings/applications/components/src/others/switch_collision.cairo:collision}} +======= +```rust +// [!include ~/listings/applications/components/src/contracts/tests/switch_collision_tests.cairo:tests] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/collisions.md ``` diff --git a/src/components/dependencies.md b/pages/components/dependencies.md similarity index 54% rename from src/components/dependencies.md rename to pages/components/dependencies.md index b96f28d5..bbf15ceb 100644 --- a/src/components/dependencies.md +++ b/pages/components/dependencies.md @@ -1,11 +1,27 @@ +<<<<<<< HEAD:src/components/dependencies.md # Component Dependencies +======= +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Components Dependencies +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md A component with a dependency on a trait `T` can be used in a contract as long as the contract implements the trait `T`. We will use a new `Countable` component as an example: +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#rustdoc_include ../../listings/applications/components/src/countable.cairo:component}} +======= +```rust +// [!include ~/listings/applications/components/src/countable.cairo] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md ``` We want to add a way to enable or disable the counter, in a way that calling `increment` on a disabled counter will not increment it. @@ -16,22 +32,45 @@ Instead, we add the trait `Switchable` as a dependency to the `Countable` compon First, we import the `ISwitchable` trait defined in chapter ["Components How-To"](./how_to.md): +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#include ../../listings/applications/components/src/switchable.cairo:interface}} +======= +```rust +// [!include ~/listings/applications/components/src/switchable.cairo:interface] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md ``` Then we can modify the implementation of the `Countable` component to depend on the `ISwitchable` trait: +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#rustdoc_include ../../listings/applications/components_dependencies/src/countable_dep_switch.cairo:impl}} +======= +```rust +// [!include ~/listings/applications/components_dependencies/src/countable_dep_switch.cairo:impl] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md ``` A contract that uses the `Countable` component must implement the `ISwitchable` trait: +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#rustdoc_include ../../listings/applications/components_dependencies/src/contract_countable.cairo:contract}} +======= +:::code-group + +```rust [contract] +// [!include ~/listings/applications/components_dependencies/src/contract_countable.cairo:contract] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md ``` +```rust [tests] +// [!include ~/listings/applications/components_dependencies/src/contract_countable.cairo:tests] +``` + +::: + #### Implementation of the trait in another component In the previous example, we implemented the `ISwitchable` trait in the contract. @@ -39,11 +78,27 @@ In the previous example, we implemented the `ISwitchable` trait in the contract. We already implemented a [`Switchable`](./how_to.md) component that provides an implementation of the `ISwitchable` trait. By using the `Switchable` component in a contract, we can embed the implementation of the `ISwitchable` trait in the contract and resolve the dependency on the `ISwitchable` trait. +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#rustdoc_include ../../listings/applications/components_dependencies/src/contract_countable_switchable.cairo:contract}} ``` #### Dependency on other component's internal functions +======= +:::code-group + +```rust [contract] +// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable.cairo:tests] +``` + +::: + +#### Dependency on other components internal functions +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md The previous example shows how to use the `ISwitchable` trait implementation from the `Switchable` component inside the `Countable` component by embedding the implementation in the contract. However, suppose we would like to turn off the switch after each increment. There's no `set` function in the `ISwitchable` trait, so we can't do it directly. @@ -54,8 +109,28 @@ We can't embed `SwitchableInternalImpl`, but we can add `switchable::HasComponen We make the `Countable` component depend on the `Switchable` component. This will allow to do `switchable::ComponentState` -> `TContractState` -> `countable::ComponentState` and access the internal functions of the `Switchable` component inside the `Countable` component: +<<<<<<< HEAD:src/components/dependencies.md ```cairo {{#rustdoc_include ../../listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo:contract}} ``` The `CountableContract` contract remains the same as in the previous example, only the implementation of the `Countable` component is different. +======= +```rust +// [!include ~/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo] +``` + +The contract remains the same that the previous example, but the implementation of the `Countable` component is different: + +:::code-group + +```rust [contract] +// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo:tests] +``` + +::: +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md diff --git a/src/components/how_to.md b/pages/components/how_to.md similarity index 71% rename from src/components/how_to.md rename to pages/components/how_to.md index 50220403..0d11115c 100644 --- a/src/components/how_to.md +++ b/pages/components/how_to.md @@ -17,11 +17,19 @@ It contains a storage variable `switchable_value`, a function `switch` and an ev > It is a good practice to prefix the component storage variables with the component name to [avoid collisions](./collisions.md). +<<<<<<< HEAD:src/components/how_to.md ```cairo {{#include ../../listings/applications/components/src/switchable.cairo:component}} ``` A component is really similar to a contract and can also have: +======= +```rust +// [!include ~/listings/applications/components/src/switchable.cairo:component] +``` + +A component in itself is really similar to a contract, it _can_ also have: +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md - An interface defining entrypoints (`ISwitchableComponent`) - A Storage struct @@ -33,14 +41,20 @@ It doesn't have a constructor, but you can create an `_init` internal function a > It's currently not possible to use the same component multiple times in the same contract. > This is a known limitation that may be lifted in the future. > +<<<<<<< HEAD:src/components/how_to.md > For now, you can view components as implementations of specific interfaces or features (`Ownable`, `Upgradeable`, ... `~able`). > This is why we called the component in the above example `Switchable`, and not `Switch`; the contract _is switchable_, it does not _have a switch_. +======= +> For now, you can view components as an implementation of a specific interface/feature (`Ownable`, `Upgradeable`, ... `~able`). +> This is why we called it `Switchable` and not `Switch`; The contract _is switchable_, not _has a switch_. +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md ## How to use a component Now that we have a component, we can use it in a contract. The following contract incorporates the `Switchable` component: +<<<<<<< HEAD:src/components/how_to.md ```cairo {{#include ../../listings/applications/components/src/switchable.cairo:contract}} ``` @@ -54,8 +68,20 @@ To test the `Switchable` component, we can use the previous `SwitchableContract` ```cairo {{#include ../../listings/applications/components/src/switchable.cairo:tests}} +======= +:::code-group + +```rust [contract] +// [!include ~/listings/applications/components/src/contracts/switch.cairo:contract] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md ``` +```rust [tests] +// [!include ~/listings/applications/components/src/contracts/switch.cairo:tests] +``` + +::: + ## Deep dive into components You can find more in-depth information about components in [The Cairo book - Components](https://book.cairo-lang.org/ch16-02-00-composability-and-components.html). diff --git a/pages/components/ownable.md b/pages/components/ownable.md new file mode 100644 index 00000000..3d44f6e9 --- /dev/null +++ b/pages/components/ownable.md @@ -0,0 +1,40 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + +# Ownable + +The following `Ownable` component is a simple component that allows the contract to set an owner and provides an `_assert_is_owner` function that can be used to ensure that the caller is the owner. + +It can also be used to renounce ownership of a contract, meaning that no one will be able to satisfy the `_assert_is_owner` function. + +<<<<<<< HEAD:src/components/ownable.md +```cairo +{{#include ../../listings/applications/components/src/ownable.cairo:component}} +======= +```rust +// [!include ~/listings/applications/components/src/ownable.cairo] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/ownable.md +``` + +A mock contract that uses the `Ownable` component: + +<<<<<<< HEAD:src/components/ownable.md +```cairo +{{#rustdoc_include ../../listings/applications/components/src/ownable.cairo:contract}} +======= +:::code-group + +```rust [contract] +// [!include ~/listings/applications/components/src/contracts/owned.cairo:contract] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/ownable.md +``` + +```rust [tests] +// [!include ~/listings/applications/components/src/contracts/owned.cairo:tests] +``` + +::: diff --git a/pages/getting-started.mdx b/pages/getting-started.mdx new file mode 100644 index 00000000..99b8616e --- /dev/null +++ b/pages/getting-started.mdx @@ -0,0 +1,3 @@ +# Get started + +Hello world! \ No newline at end of file diff --git a/src/starknet-by-example.md b/pages/index.mdx similarity index 81% rename from src/starknet-by-example.md rename to pages/index.mdx index f1cff8ba..e7903161 100644 --- a/src/starknet-by-example.md +++ b/pages/index.mdx @@ -1,3 +1,5 @@ +import { Callout } from "vocs/components"; + # Starknet by Example Starknet By Example is a collection of examples of how to use the Cairo programming language to create smart contracts on Starknet. @@ -6,8 +8,11 @@ Starknet is a permissionless Validity-Rollup that supports general computation. Starknet smart contracts are written in the Cairo language. Cairo is a Turing-complete programming language designed to write provable programs, abstracting the zk-STARK proof system away from the programmer. -> ⚠️ The examples have not been audited and are not intended for production use. -> The authors are not responsible for any damages caused by the use of the code provided in this book. + + ⚠️ The examples have not been audited and are not intended for production use. + The authors are not responsible for any damages caused by the use of the code + provided in this book. + ## For whom is this for? @@ -33,6 +38,7 @@ For more resources, check [Awesome Starknet](https://github.com/keep-starknet-st ## Versions +<<<<<<< HEAD:src/starknet-by-example.md The current version this book uses: ``` @@ -40,4 +46,12 @@ cairo 2.8.2 edition = "2024_07" sierra: 1.6.0 {{#include ../.tool-versions}} +======= +The current version of this book use: + +``` +cairo 2.6.3 +edition = '2023_11' +// [!include ~/.tool-versions] +>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/index.mdx ``` diff --git a/pages/indexdasds.mdx b/pages/indexdasds.mdx new file mode 100644 index 00000000..b2bfc909 --- /dev/null +++ b/pages/indexdasds.mdx @@ -0,0 +1,16 @@ +--- +layout: landing +--- + +import { HomePage } from 'vocs/components' + + + + My Awesome Docs + + This is a description of my documentation website. + + Get started + GitHub + + \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..91bdc81b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5052 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@types/react': + specifier: latest + version: 18.2.74 + react: + specifier: latest + version: 18.2.0 + react-dom: + specifier: latest + version: 18.2.0(react@18.2.0) + typescript: + specifier: latest + version: 5.4.3 + vocs: + specifier: latest + version: 1.0.0-alpha.50(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)(rollup@4.17.2)(typescript@5.4.3) + +packages: + + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: false + + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + + /@babel/code-frame@7.24.2: + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.5 + picocolors: 1.0.1 + dev: false + + /@babel/compat-data@7.24.4: + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/core@7.24.5: + resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helpers': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + 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.24.5: + resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + 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.24.4 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + 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.24.0 + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-module-imports@7.24.3: + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5): + resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.24.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-validator-identifier': 7.24.5 + dev: false + + /@babel/helper-plugin-utils@7.24.5: + resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-simple-access@7.24.5: + resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-split-export-declaration@7.24.5: + resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/helper-string-parser@7.24.1: + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + dev: false + + /@babel/helper-validator-identifier@7.24.5: + resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + 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.24.5: + resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/highlight@7.24.5: + resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + dev: false + + /@babel/parser@7.24.5: + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.5 + dev: false + + /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + dev: false + + /@babel/plugin-transform-react-jsx-self@7.24.5(@babel/core@7.24.5): + resolution: {integrity: sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + dev: false + + /@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.5): + resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + dev: false + + /@babel/runtime@7.24.5: + resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + dev: false + + /@babel/traverse@7.24.5: + resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@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.24.5 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + + /@babel/types@7.24.5: + resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.24.5 + to-fast-properties: 2.0.0 + dev: false + + /@clack/core@0.3.4: + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} + dependencies: + picocolors: 1.0.1 + sisteransi: 1.0.5 + dev: false + + /@clack/prompts@0.7.0: + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.0.1 + 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.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + + /@esbuild/aix-ppc64@0.20.2: + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm64@0.20.2: + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-arm@0.20.2: + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/android-x64@0.20.2: + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-arm64@0.20.2: + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/darwin-x64@0.20.2: + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-arm64@0.20.2: + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/freebsd-x64@0.20.2: + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm64@0.20.2: + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-arm@0.20.2: + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ia32@0.20.2: + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-loong64@0.20.2: + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-mips64el@0.20.2: + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-ppc64@0.20.2: + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-riscv64@0.20.2: + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-s390x@0.20.2: + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/linux-x64@0.20.2: + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/netbsd-x64@0.20.2: + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/openbsd-x64@0.20.2: + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/sunos-x64@0.20.2: + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-arm64@0.20.2: + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-ia32@0.20.2: + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@esbuild/win32-x64@0.20.2: + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@floating-ui/core@1.6.1: + resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==} + dependencies: + '@floating-ui/utils': 0.2.2 + dev: false + + /@floating-ui/dom@1.6.5: + resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} + dependencies: + '@floating-ui/core': 1.6.1 + '@floating-ui/utils': 0.2.2 + dev: false + + /@floating-ui/react-dom@2.0.9(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.6.5 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@floating-ui/react@0.26.14(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-I2EhfezC+H0WfkMEkCcF9+++PU1Wq08bDKhHHGIoBZVCciiftEQHgrSI4dTUTsa7446SiIVW0gWATliIlVNgfg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/react-dom': 2.0.9(react-dom@18.2.0)(react@18.2.0) + '@floating-ui/utils': 0.2.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tabbable: 6.2.0 + dev: false + + /@floating-ui/utils@0.2.2: + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + dev: false + + /@hono/node-server@1.11.1: + resolution: {integrity: sha512-GW1Iomhmm1o4Z+X57xGby8A35Cu9UZLL7pSMdqDBkD99U5cywff8F+8hLk5aBTzNubnsFAvWQ/fZjNwPsEn9lA==} + 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.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + dev: false + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: false + + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + 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.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: false + + /@mdx-js/mdx@3.0.1: + resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==} + dependencies: + '@types/estree': 1.0.5 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + 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.1 + 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.1(@types/react@18.2.74)(react@18.2.0): + resolution: {integrity: sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@mdx-js/rollup@3.0.1(rollup@4.17.2): + resolution: {integrity: sha512-j0II91OCm4ld+l5QVgXXMQGxVVcAWIQJakYWi1dv5pefDHASJyCYER2TsdH7Alf958GoFSM7ugukWyvDq/UY4A==} + peerDependencies: + rollup: '>=2' + dependencies: + '@mdx-js/mdx': 3.0.1 + '@rollup/pluginutils': 5.1.0(rollup@4.17.2) + rollup: 4.17.2 + source-map: 0.7.4 + vfile: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /@noble/hashes@1.4.0: + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + 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.17.1 + dev: false + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: false + optional: true + + /@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.24.5 + dev: false + + /@radix-ui/react-accordion@1.1.2(@types/react@18.2.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collapsible': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-context@1.0.1(@types/react@18.2.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-dialog@1.0.5(@types/react@18.2.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.74)(react@18.2.0) + dev: false + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-dismissable-layer@1.0.5(@types/react@18.2.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-focus-scope@1.0.4(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-label@2.0.2(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-popper': 1.1.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.74)(react@18.2.0) + dev: false + + /@radix-ui/react-popper@1.1.3(@types/react@18.2.74)(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.24.5 + '@floating-ui/react-dom': 2.0.9(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-tabs@1.0.4(@types/react@18.2.74)(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.24.5 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + 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.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.74)(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.24.5 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.74)(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.24.5 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.74)(react@18.2.0) + '@types/react': 18.2.74 + react: 18.2.0 + dev: false + + /@radix-ui/react-visually-hidden@1.0.3(@types/react@18.2.74)(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.24.5 + '@radix-ui/react-primitive': 1.0.3(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.74 + 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.24.5 + dev: false + + /@remix-run/router@1.16.1: + resolution: {integrity: sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig==} + engines: {node: '>=14.0.0'} + dev: false + + /@rollup/pluginutils@5.1.0(rollup@4.17.2): + 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.17.2 + dev: false + + /@rollup/rollup-android-arm-eabi@4.17.2: + resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-android-arm64@4.17.2: + resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-arm64@4.17.2: + resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-darwin-x64@4.17.2: + resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.17.2: + resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.17.2: + resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.17.2: + resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-arm64-musl@4.17.2: + resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.17.2: + resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.17.2: + resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.17.2: + resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-gnu@4.17.2: + resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-linux-x64-musl@4.17.2: + resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.17.2: + resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.17.2: + resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rollup/rollup-win32-x64-msvc@4.17.2: + resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@shikijs/core@1.5.2: + resolution: {integrity: sha512-wSAOgaz48GmhILFElMCeQypSZmj6Ru6DttOOtl3KNkdJ17ApQuGNCfzpk4cClasVrnIu45++2DBwG4LNMQAfaA==} + dev: false + + /@shikijs/rehype@1.5.2: + resolution: {integrity: sha512-MlpLBEyLcV399AgV5ai7wD0F7E/5qTlfF3487bx5MkGZb+DMAvpF279OI0UYKXVrqKrTS1zJfZXyIJlFQ3JeTA==} + dependencies: + '@shikijs/transformers': 1.5.2 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.0 + shiki: 1.5.2 + unified: 11.0.4 + unist-util-visit: 5.0.0 + dev: false + + /@shikijs/transformers@1.5.2: + resolution: {integrity: sha512-/Sh64rKOFGMQLCvtHeL1Y7EExdq8LLxcdVkvoGx2aMHsYMOn8DckYl2gYKMHRBu/YUt1C38/Amd1Jdh48tWHgw==} + dependencies: + shiki: 1.5.2 + dev: false + + /@shikijs/twoslash@1.5.2(typescript@5.4.3): + resolution: {integrity: sha512-elXSplqPxoifKAzCO9TJ6zkNN9XjM22+zU8OD+0tH6KDgk/8qaLQ48rCTg8/Ir7nvk0VuGnFz4cc5eQ5oX009A==} + dependencies: + '@shikijs/core': 1.5.2 + twoslash: 0.2.6(typescript@5.4.3) + transitivePeerDependencies: + - supports-color + - typescript + dev: false + + /@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.24.5 + '@babel/types': 7.24.5 + '@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.24.5 + dev: false + + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + dev: false + + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + dependencies: + '@babel/types': 7.24.5 + 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.5: + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + 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.4: + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /@types/mdast@4.0.4: + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + dependencies: + '@types/unist': 3.0.2 + dev: false + + /@types/mdx@2.0.13: + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + dev: false + + /@types/ms@0.7.34: + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + dev: false + + /@types/node@20.12.12: + resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/prop-types@15.7.12: + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + dev: false + + /@types/react@18.2.74: + resolution: {integrity: sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw==} + dependencies: + '@types/prop-types': 15.7.12 + csstype: 3.1.3 + 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.5: + resolution: {integrity: sha512-Rc9A6ylsw7EBErmpgqCMvc/Z/eEZxI5k1xfLQHw7f5HHh3oc5YfzsAsYU/PdmSNjF1dp3sGEViBdDltvwnfVaA==} + dependencies: + '@babel/core': 7.24.5 + transitivePeerDependencies: + - supports-color + dev: false + + /@vanilla-extract/css@1.15.1: + resolution: {integrity: sha512-puAfTKAUtsMr2+D+grQNjU5umsdw9zdVgQflUlbzS/tGORaAHdgaYz7jfKPmz1c4ZcpJ6uFNOiI50NDOAzzhyg==} + dependencies: + '@emotion/hash': 0.9.1 + '@vanilla-extract/private': 1.0.4 + css-what: 6.1.0 + cssesc: 3.0.0 + csstype: 3.1.3 + dedent: 1.5.3 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.0.1 + picocolors: 1.0.1 + transitivePeerDependencies: + - babel-plugin-macros + dev: false + + /@vanilla-extract/dynamic@2.1.0: + resolution: {integrity: sha512-8zl0IgBYRtgD1h+56Zu13wHTiMTJSVEa4F7RWX9vTB/5Xe2KtjoiqApy/szHPVFA56c+ex6A4GpCQjT1bKXbYw==} + dependencies: + '@vanilla-extract/private': 1.0.4 + dev: false + + /@vanilla-extract/integration@6.5.0: + resolution: {integrity: sha512-E2YcfO8vA+vs+ua+gpvy1HRqvgWbI+MTlUpxA8FvatOvybuNcWAY0CKwQ/Gpj7rswYKtC6C7+xw33emM6/ImdQ==} + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) + '@vanilla-extract/babel-plugin-debug-ids': 1.0.5 + '@vanilla-extract/css': 1.15.1 + esbuild: 0.19.12 + eval: 0.1.8 + find-up: 5.0.0 + javascript-stringify: 2.1.0 + lodash: 4.17.21 + mlly: 1.7.0 + outdent: 0.8.0 + vite: 5.2.11 + vite-node: 1.6.0 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /@vanilla-extract/private@1.0.4: + resolution: {integrity: sha512-8FGD6AejeC/nXcblgNCM5rnZb9KXa4WNkR03HCWtdJBpANjTgjHEglNLFnhuvdQ78tC6afaxBPI+g7F2NX3tgg==} + dev: false + + /@vanilla-extract/vite-plugin@3.9.5(vite@5.2.11): + resolution: {integrity: sha512-CWI/CtrVW6i3HKccI6T7uGQkTJ8bd8Xl2UMBg3Pkr7dwWMmavXTeucV0I9KSbmXaYXSbEj+Q8c9y0xAZwtmTig==} + peerDependencies: + vite: ^2.2.3 || ^3.0.0 || ^4.0.3 || ^5.0.0 + dependencies: + '@vanilla-extract/integration': 6.5.0 + outdent: 0.8.0 + postcss: 8.4.38 + postcss-load-config: 4.0.2(postcss@8.4.38) + vite: 5.2.11 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + dev: false + + /@vitejs/plugin-react@4.2.0(vite@5.2.11): + 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.24.5 + '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.2.11 + transitivePeerDependencies: + - supports-color + 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.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + 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.19(postcss@8.4.38): + resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.23.0 + caniuse-lite: 1.0.30001618 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.4.38 + 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.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + 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.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001618 + electron-to-chromium: 1.4.768 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.0) + 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.30001618: + resolution: {integrity: sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==} + 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@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.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + 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.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + 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 + + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + dev: false + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: false + + /create-vocs@1.0.0-alpha.5: + resolution: {integrity: sha512-/Nr9taHX1SxL5t72DLFPYujqD8d5PDk0T8bJ9Fb/m7ck1lP20PBxHzF5IYnHI0BeTpIuGk/MQoLfT6JKpY6xnw==} + hasBin: true + dependencies: + '@clack/prompts': 0.7.0 + cac: 6.7.14 + detect-package-manager: 3.0.2 + fs-extra: 11.2.0 + picocolors: 1.0.1 + 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.5: + resolution: {integrity: sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==} + 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 + + /dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + 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.2: + resolution: {integrity: sha512-8JFjJHutStYrfWwzfretQoyNGoZVW1Fsrp4JO9spa7h/fBfwgTMEIy4/LBzRDGsxwVPHU0q+T9YvwLDJoOApLQ==} + 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.768: + resolution: {integrity: sha512-z2U3QcvNuxdkk33YV7R1bVMNq7fL23vq3WfO5BHcqrm4TnDGReouBfYKLEFh5umoK1XACjEwp8mmnhXk2EJigw==} + 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 + + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + dev: false + + /esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + dev: false + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + 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.5 + 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.5 + astring: 1.8.6 + source-map: 0.7.4 + dev: false + + /estree-util-value-to-estree@3.1.1: + resolution: {integrity: sha512-5mvUrF2suuv5f5cGDnDphIy4/gW86z82kl5qG6mM9z04SEQI4FB5Apmaw/TGEf3l55nLtMs5s51dmhUzvAHQCA==} + 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.5 + '@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.12.12 + 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.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + 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.15: + resolution: {integrity: sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.1.1 + path-scurry: 1.11.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.1 + 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 + + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + 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.4 + space-separated-tokens: 2.0.2 + dev: false + + /hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + dependencies: + '@types/hast': 3.0.4 + dev: false + + /hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + dependencies: + '@types/hast': 3.0.4 + dev: false + + /hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + dependencies: + '@types/hast': 3.0.4 + dev: false + + /hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + dependencies: + '@types/hast': 3.0.4 + dev: false + + /hast-util-select@6.0.2: + resolution: {integrity: sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==} + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.2 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.0.5 + 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.5.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.5 + '@types/hast': 3.0.4 + 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.1.2 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.5.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.4 + '@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.1.2 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + style-to-object: 1.0.6 + 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.4 + dev: false + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + dependencies: + '@types/hast': 3.0.4 + dev: false + + /hastscript@8.0.0: + resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + dev: false + + /hono@3.12.12: + resolution: {integrity: sha512-5IAMJOXfpA5nT+K0MNjClchzz0IhBHs2Szl7WFAhrFOsbtQsYmNynFyJRg/a3IPsmCfxcrf8txUGiNShXpK5Rg==} + 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.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + 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.3: + resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} + 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.3.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.2 + 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 + + /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.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + 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.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + 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.4 + '@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.4 + 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.4 + 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.4 + '@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.4 + 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.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 + dev: false + + /mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + dependencies: + '@types/mdast': 4.0.4 + 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.4 + 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.4 + 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.4 + 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.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + 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.1.2: + resolution: {integrity: sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==} + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@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.4 + 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.1.2 + 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.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + 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.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + dependencies: + '@types/mdast': 4.0.4 + 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.4 + '@types/mdast': 4.0.4 + '@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.4 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.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.4 + dev: false + + /media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + dependencies: + '@babel/runtime': 7.24.5 + 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.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + 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.1.0 + 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.1 + 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.1.0 + 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.1.0 + 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.1.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-footnote@2.0.0: + resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==} + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + 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.1 + micromark-util-character: 2.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + 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.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + dev: false + + /micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + 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.1.0 + 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.1.0 + 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.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + dev: false + + /micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + 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.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + 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.1 + 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.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: false + + /minipass@7.1.1: + resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==} + engines: {node: '>=16 || 14 >=14.17'} + dev: false + + /minisearch@6.3.0: + resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} + dev: false + + /mlly@1.7.0: + resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + 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 + + /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.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.1 + 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.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + 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.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + dependencies: + confbox: 0.1.7 + mlly: 1.7.0 + pathe: 1.1.2 + dev: false + + /postcss-import@15.1.0(postcss@8.4.38): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.38 + 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.38): + 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.38 + dev: false + + /postcss-load-config@4.0.2(postcss@8.4.38): + 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.1.1 + postcss: 8.4.38 + yaml: 2.4.2 + dev: false + + /postcss-nested@6.0.1(postcss@8.4.38): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.0.16 + dev: false + + /postcss-selector-parser@6.0.16: + resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} + 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.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + 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.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + 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.2 + 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.10.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-j2hGADK2hCbAlfaq6L3tVLb4iqngoN7B1fT16MwJ4J16YW/vWLcmAIinLsw0lgpZeMi4UDUWtHC9QDde0/P1yQ==} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react-dom: + optional: true + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: false + + /react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + dev: false + + /react-remove-scroll-bar@2.3.6(@types/react@18.2.74)(react@18.2.0): + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + 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.74 + react: 18.2.0 + react-style-singleton: 2.2.1(@types/react@18.2.74)(react@18.2.0) + tslib: 2.6.2 + dev: false + + /react-remove-scroll@2.5.5(@types/react@18.2.74)(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.74 + react: 18.2.0 + react-remove-scroll-bar: 2.3.6(@types/react@18.2.74)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.74)(react@18.2.0) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.2.74)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.74)(react@18.2.0) + dev: false + + /react-router-dom@6.23.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@remix-run/router': 1.16.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-router: 6.23.1(react@18.2.0) + dev: false + + /react-router@6.23.1(react@18.2.0): + resolution: {integrity: sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + dependencies: + '@remix-run/router': 1.16.1 + 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.74)(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.74 + 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.4 + '@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.4 + hast-util-classnames: 3.0.0 + hast-util-select: 6.0.2 + unified: 10.1.2 + dev: false + + /rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + dependencies: + '@types/hast': 3.0.4 + 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.4 + 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.4 + 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.4 + 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.4 + estree-util-is-identifier-name: 3.0.0 + estree-util-value-to-estree: 3.1.1 + toml: 3.0.0 + unified: 11.0.4 + yaml: 2.4.2 + dev: false + + /remark-mdx@3.0.1: + resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} + 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.4 + 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.4 + '@types/mdast': 4.0.4 + 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.4 + 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.17.2: + resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.17.2 + '@rollup/rollup-android-arm64': 4.17.2 + '@rollup/rollup-darwin-arm64': 4.17.2 + '@rollup/rollup-darwin-x64': 4.17.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.17.2 + '@rollup/rollup-linux-arm-musleabihf': 4.17.2 + '@rollup/rollup-linux-arm64-gnu': 4.17.2 + '@rollup/rollup-linux-arm64-musl': 4.17.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2 + '@rollup/rollup-linux-riscv64-gnu': 4.17.2 + '@rollup/rollup-linux-s390x-gnu': 4.17.2 + '@rollup/rollup-linux-x64-gnu': 4.17.2 + '@rollup/rollup-linux-x64-musl': 4.17.2 + '@rollup/rollup-win32-arm64-msvc': 4.17.2 + '@rollup/rollup-win32-ia32-msvc': 4.17.2 + '@rollup/rollup-win32-x64-msvc': 4.17.2 + 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.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + 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 + + /shiki@1.5.2: + resolution: {integrity: sha512-fpPbuSaatinmdGijE7VYUD3hxLozR3ZZ+iAx8Iy2X6REmJGyF5hQl94SgmiUNTospq346nXUVZx0035dyGvIVw==} + dependencies: + '@shikijs/core': 1.5.2 + 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.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + 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.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + 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.6: + resolution: {integrity: sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==} + dependencies: + inline-style-parser: 0.2.3 + 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.5 + commander: 4.1.1 + glob: 10.3.15 + 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-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: false + + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: false + + /tailwindcss@3.4.3: + resolution: {integrity: sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + 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.1 + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) + postcss-selector-parser: 6.0.16 + 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.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + 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-protocol@0.2.6: + resolution: {integrity: sha512-8NbJlYeRdBcCTQ7ui7pdRPC1NL16aOnoYNz06oBW+W0qWNuiQXHgE8UeNvbA038aDd6ZPuuD5WedsBIESocB4g==} + dev: false + + /twoslash@0.2.6(typescript@5.4.3): + resolution: {integrity: sha512-DcAKIyXMB6xNs+SOw/oF8GvUr/cfJSqznngVXYbAUIVfTW3M8vWSEoCaz/RgSD+M6vwtK8DJ4/FmYBF5MN8BGw==} + peerDependencies: + typescript: '*' + dependencies: + '@typescript/vfs': 1.5.0 + twoslash-protocol: 0.2.6 + typescript: 5.4.3 + transitivePeerDependencies: + - supports-color + dev: false + + /typescript@5.4.3: + resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==} + engines: {node: '>=14.17'} + hasBin: true + dev: false + + /ua-parser-js@1.0.37: + resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==} + dev: false + + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + 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.2.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.2.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.16(browserslist@4.23.0): + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.1 + dev: false + + /use-callback-ref@1.3.2(@types/react@18.2.74)(react@18.2.0): + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + 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.74 + react: 18.2.0 + tslib: 2.6.2 + dev: false + + /use-sidecar@1.1.2(@types/react@18.2.74)(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.74 + 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-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.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + 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.1 + vite: 5.2.11 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + + /vite@5.2.11: + resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==} + 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.20.2 + postcss: 8.4.38 + rollup: 4.17.2 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /vocs@1.0.0-alpha.50(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0)(rollup@4.17.2)(typescript@5.4.3): + resolution: {integrity: sha512-rzZw60A8uKmmgouN1ymPz1/0GPK0cxE4ETYJWs5vZTMS3xcTqKarrvU9rcs0niJUfOR0maSs94eWzrgNBLZO1Q==} + hasBin: true + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + '@floating-ui/react': 0.26.14(react-dom@18.2.0)(react@18.2.0) + '@hono/node-server': 1.11.1 + '@mdx-js/react': 3.0.1(@types/react@18.2.74)(react@18.2.0) + '@mdx-js/rollup': 3.0.1(rollup@4.17.2) + '@noble/hashes': 1.4.0 + '@radix-ui/colors': 3.0.0 + '@radix-ui/react-accordion': 1.1.2(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.5(@types/react@18.2.74)(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.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-navigation-menu': 1.1.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-popover': 1.0.7(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tabs': 1.0.4(@types/react@18.2.74)(react-dom@18.2.0)(react@18.2.0) + '@shikijs/rehype': 1.5.2 + '@shikijs/transformers': 1.5.2 + '@shikijs/twoslash': 1.5.2(typescript@5.4.3) + '@vanilla-extract/css': 1.15.1 + '@vanilla-extract/dynamic': 2.1.0 + '@vanilla-extract/vite-plugin': 3.9.5(vite@5.2.11) + '@vitejs/plugin-react': 4.2.0(vite@5.2.11) + autoprefixer: 10.4.19(postcss@8.4.38) + cac: 6.7.14 + chroma-js: 2.4.2 + clsx: 2.1.1 + compression: 1.7.4 + create-vocs: 1.0.0-alpha.5 + cross-spawn: 7.0.3 + fs-extra: 11.2.0 + globby: 13.2.2 + hastscript: 8.0.0 + hono: 3.12.12 + 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.4 + minisearch: 6.3.0 + ora: 7.0.1 + postcss: 8.4.38 + 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.10.2(react-dom@18.2.0)(react@18.2.0) + react-router-dom: 6.23.1(react-dom@18.2.0)(react@18.2.0) + rehype-autolink-headings: 7.1.0 + rehype-class-names: 1.0.14 + 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 + shiki: 1.5.2 + tailwindcss: 3.4.3 + toml: 3.0.0 + twoslash: 0.2.6(typescript@5.4.3) + ua-parser-js: 1.0.37 + unified: 11.0.4 + unist-util-visit: 5.0.0 + vite: 5.2.11 + transitivePeerDependencies: + - '@types/node' + - '@types/react' + - '@types/react-dom' + - babel-plugin-macros + - less + - lightningcss + - rollup + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + - typescript + 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.4.2: + resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} + engines: {node: '>= 14'} + hasBin: true + 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/po/es.po b/po/es.po deleted file mode 100644 index 18abf668..00000000 --- a/po/es.po +++ /dev/null @@ -1,11855 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: Starknet by Example\n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2024-01-09 11:10+0000\n" -"Last-Translator: Nadai \n" -"Language-Team: Spanish \n" -"Language: es\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 3.4.2\n" -"X-Poedit-Bookmarks: -1,-1,-1,78,-1,-1,-1,-1,-1,-1\n" - -#: src/SUMMARY.md:3 -msgid "Introduction" -msgstr "Introducción" - -#: src/SUMMARY.md:7 -msgid "Getting Started" -msgstr "Primeros Pasos" - -#: src/SUMMARY.md:10 -msgid "Basics of a Starknet contract" -msgstr "Conceptos Básicos de un Contrato de Starknet" - -#: src/SUMMARY.md:11 -msgid "Storage" -msgstr "Almacenamiento" - -#: src/SUMMARY.md:12 -msgid "Constructor" -msgstr "Constructor" - -#: src/SUMMARY.md:13 -msgid "Variables" -msgstr "Variables" - -#: src/SUMMARY.md:14 -msgid "Visibility and Mutability" -msgstr "Visibilidad y Mutabilidad" - -#: src/SUMMARY.md:15 -msgid "Counter Example" -msgstr "Ejemplo de Counter" - -#: src/SUMMARY.md:16 -msgid "Mappings" -msgstr "Mapas" - -#: src/SUMMARY.md:17 -msgid "Errors" -msgstr "Errores" - -#: src/SUMMARY.md:18 -msgid "Events" -msgstr "Eventos" - -#: src/SUMMARY.md:19 -msgid "Syscalls" -msgstr "Llamadas al Sistema" - -#: src/SUMMARY.md:20 -msgid "Storing Custom Types" -msgstr "Almacenamiento de Tipos Personalizados" - -#: src/SUMMARY.md:21 -msgid "Custom types in entrypoints" -msgstr "Tipos personalizados en entrypoints" - -#: src/SUMMARY.md:22 -msgid "Documentation" -msgstr "Documentación" - -#: src/SUMMARY.md:23 -msgid "Deploy and interact with contracts" -msgstr "Desplegar contratos e interactuar con ellos" - -#: src/SUMMARY.md:24 -msgid "Contract interfaces and Traits generation" -msgstr "Interfaces de Contratos y generación de Traits" - -#: src/SUMMARY.md:25 -msgid "Calling other contracts" -msgstr "Llamar a otros contratos" - -#: src/SUMMARY.md:26 -msgid "Factory pattern" -msgstr "Patrón Factory" - -#: src/SUMMARY.md:27 -msgid "Testing contracts" -msgstr "Testing de Contratos" - -#: src/SUMMARY.md:28 -msgid "Cairo cheatsheet" -msgstr "Hoja de ruta de Cairo" - -#: src/SUMMARY.md:29 -msgid "Felt" -msgstr "Felt" - -#: src/SUMMARY.md:30 -msgid "LegacyMap" -msgstr "LegacyMap" - -#: src/SUMMARY.md:31 -msgid "Arrays" -msgstr "Arrays" - -#: src/SUMMARY.md:32 -msgid "Loop" -msgstr "Loop" - -#: src/SUMMARY.md:33 -msgid "Match" -msgstr "Match" - -#: src/SUMMARY.md:34 -msgid "Tuples" -msgstr "Tuples" - -#: src/SUMMARY.md:35 -msgid "Struct" -msgstr "Struct" - -#: src/SUMMARY.md:36 -msgid "Type casting" -msgstr "Conversión de Tipos" - -#: src/SUMMARY.md:38 -msgid "Components" -msgstr "Componentes" - -#: src/SUMMARY.md:40 -msgid "Components How-To" -msgstr "Cómo hacer Componentes" - -#: src/SUMMARY.md:41 -msgid "Components Dependencies" -msgstr "Componentes Dependencias" - -#: src/SUMMARY.md:42 -msgid "Storage Collisions" -msgstr "Colisiones de Almacenamiento" - -#: src/SUMMARY.md:43 -msgid "Ownable" -msgstr "Ownable" - -#: src/SUMMARY.md:47 -msgid "Applications" -msgstr "Aplicaciones" - -#: src/SUMMARY.md:49 -msgid "Upgradeable Contract" -msgstr "Contratos Actualizables" - -#: src/SUMMARY.md:50 -msgid "Defi Vault" -msgstr "Defi Vault" - -#: src/SUMMARY.md:51 -msgid "ERC20 Token" -msgstr "Token ERC20" - -#: src/SUMMARY.md:52 -msgid "Constant Product AMM" -msgstr "AMM de Producto Constante" - -#: src/SUMMARY.md:56 -msgid "Advanced concepts" -msgstr "Conceptos Avanzados" - -#: src/SUMMARY.md:58 -msgid "Writing to any storage slot" -msgstr "Escribir en cualquier ranura de almacenamiento" - -#: src/SUMMARY.md:59 -msgid "Storing Arrays" -msgstr "Almacenamiento de Arrays" - -#: src/SUMMARY.md:60 -msgid "Struct as mapping key" -msgstr "Estructura como mapping key" - -#: src/SUMMARY.md:61 -msgid "Hashing" -msgstr "Hashing" - -#: src/SUMMARY.md:62 -msgid "Hash Solidity Compatible" -msgstr "Hash compatible con Solidity" - -#: src/SUMMARY.md:63 -msgid "Optimisations" -msgstr "Optimizaciones" - -#: src/SUMMARY.md:64 -msgid "Storage Optimisations" -msgstr "Optimizaciones de Almacenamiento" - -#: src/SUMMARY.md:65 -msgid "List" -msgstr "Lista" - -#: src/starknet-by-example.md:1 -msgid "# Starknet by Example" -msgstr "# Starknet by Example" - -#: src/starknet-by-example.md:3 -msgid "" -"Starknet By Example is a collection of examples of how to use the Cairo " -"programming language to create smart contracts on Starknet." -msgstr "" -"Starknet By Example es una colección de ejemplos de cómo utilizar el " -"lenguaje de programación de Cairo para crear smart contracts en Starknet." - -#: src/starknet-by-example.md:5 -msgid "" -"Starknet is a permissionless Validity-Rollup that supports general " -"computation. It is currently used as an Ethereum layer-2. Starknet uses the " -"STARK cryptographic proof system to ensure high safety and scalability." -msgstr "" -"Starknet es un Validity-Rollup sin permiso que admite el cálculo general. " -"Actualmente se utiliza como capa 2 de Ethereum. Starknet utiliza el sistema " -"de prueba criptográfica STARK para garantizar una alta seguridad y " -"escalabilidad." - -#: src/starknet-by-example.md:7 -msgid "" -"Starknet smart contracts are written in the Cairo language. Cairo is a " -"Turing-complete programming language designed to write provable programs, " -"abstracting the zk-STARK proof system away from the programmer." -msgstr "" -"Los smart contracts de Starknet están escritos en el lenguaje Cairo. Cairo " -"es un lenguaje de programación Turing completo diseñado para escribir " -"programas demostrables, abstrayendo el sistema de prueba zk-STARK del " -"programador." - -#: src/starknet-by-example.md:9 -msgid "" -"> ⚠️ The examples have not been audited and are not intended for production " -"use.\n" -"> The authors are not responsible for any damages caused by the use of the " -"code provided in this book." -msgstr "" -"> ⚠️ Los ejemplos no han sido auditados y no están pensados para su uso en " -"producción.\n" -"> Los autores no se hacen responsables de los daños causados por el uso del " -"código proporcionado en este libro." - -#: src/starknet-by-example.md:12 -msgid "## For whom is this for?" -msgstr "## ¿A quién va dirigido?" - -#: src/starknet-by-example.md:14 -msgid "" -"Starknet By Example is for anyone who wants to quickly learn how to write " -"smart contracts on Starknet using Cairo with some technical background in " -"programming and blockchain." -msgstr "" -"Starknet By Example es para cualquiera que quiera aprender rápidamente cómo " -"escribir contratos inteligentes en Starknet usando Cairo con cierta " -"experiencia técnica en programación y blockchain." - -#: src/starknet-by-example.md:16 -msgid "" -"The first chapters will give you a basic understanding of the Cairo " -"programming language and how to write, deploy and use smart contracts on " -"Starknet.\n" -"The later chapters will cover more advanced topics and show you how to write " -"more complex smart contracts." -msgstr "" -"Los primeros capítulos le brindarán una comprensión básica del lenguaje de " -"programación Cairo y cómo escribir, implementar y utilizar contratos " -"inteligentes en Starknet. Los capítulos posteriores cubrirán temas más " -"avanzados y le mostrarán cómo escribir contratos inteligentes más complejos." - -#: src/starknet-by-example.md:19 -msgid "## How to use this book?" -msgstr "## ¿Como usar este libro?" - -#: src/starknet-by-example.md:21 -msgid "" -"Each chapter is a standalone example that demonstrates a specific feature " -"or common use case of smart contracts on Starknet. If you are new to Starknet, " -"it is recommended to read the chapters in order." -msgstr "" -"Cada capítulo en un ejemplo independiente que muestra una característica " -"específica o un caso de uso común de un contrato inteligente en Starknet. " -"Si eres nuevo en Starknet, es recomendable que leas los capítulos en orden." - -#: src/starknet-by-example.md:23 -msgid "" -"Most examples contain interfaces and tests that are hidden by default. " -"You can hover over the code blocks and click on the \"Show hidden lines\" " -"(eyes icon) to see the hidden code.\n" -msgstr "" -"La mayoria de los ejemplos contienen interfaces y pruebas que están ocultas por defecto " -"Puedes colocar el cursor sobre los bloques de codígo y darle click en \"Mostrar lineas ocultas\" " -"(icono de ojos) para ver el codígo oculto" - -#: src/starknet-by-example.md:25 -msgid "" -"You can run each example online by using the [Starknet Remix Plugin](https://remix.ethereum.org/?#activate=Starknet)." -msgstr "" -"Puedes ejecutar cada uno de los ejemplos en línea usando [El plugin de Starknet en Remix ](https://remix.ethereum.org/?#activate=Starknet)." - -#: src/starknet-by-example.md:27 -msgid "## Further reading" -msgstr "## Otras lecturas" - -#: src/starknet-by-example.md:29 -msgid "" -"If you want to learn more about the Cairo programming language, you can read " -"the [Cairo Book](https://book.cairo-lang.org).\n" -"If you want to learn more about Starknet, you can read the [Starknet " -"documentation](https://docs.starknet.io/) and the [Starknet Book](https://" -"book.starknet.io)." -msgstr "" -"Si desea obtener más información sobre el lenguaje de programación de Cairo, " -"puede leer el [Cairo Book](https://book.cairo-lang.org). Si desea obtener " -"más información sobre Starknet, puede leer la [Documentación de Starknet]" -"(https://docs.starknet.io/) y el [Starknet Book](https://book.starknet.io)." - -#: src/starknet-by-example.md:32 -msgid "" -"For more resources, check [Awesome Starknet](https://github.com/keep-" -"starknet-strange/awesome-starknet)." -msgstr "" -"Para obtener más recursos, consulte [Awesome Starknet](https://github.com/" -"keep-starknet-strange/awesome-starknet)." - -#: src/starknet-by-example.md:34 -msgid "## Versions" -msgstr "## Versiones" - -#: src/starknet-by-example.md:36 -msgid "The current version of this book uses:" -msgstr "La versión actual de este libro usa:" - -#: src/starknet-by-example.md:38 -msgid "" -"```\n" -"scarb 2.6.3\n" -"```" -msgstr "" -"```\n" -"edition = '2023_11'\n" -"```" - -#: src/starknet-by-example.md:31 src/getting-started/basics/storage.md:34 -#: src/getting-started/basics/constructor.md:27 src/getting-started/basics/variables.md:126 -#: src/getting-started/basics/visibility-mutability.md:75 src/getting-started/basics/counter.md:56 -#: src/getting-started/basics/errors.md:139 src/getting-started/basics/storing-custom-types.md:39 -#: src/getting-started/basics/custom-types-in-entrypoints.md:39 -#: src/getting-started/interacting/interfaces-traits.md:129 -#: src/getting-started/interacting/calling_other_contracts.md:69 -#: src/getting-started/cairo_cheatsheet/felt.md:15 src/getting-started/cairo_cheatsheet/mapping.md:58 -#: src/getting-started/cairo_cheatsheet/arrays.md:42 src/getting-started/cairo_cheatsheet/loop.md:23 -#: src/getting-started/cairo_cheatsheet/match.md:59 src/getting-started/cairo_cheatsheet/tuples.md:18 -#: src/getting-started/cairo_cheatsheet/struct.md:15 -#: src/getting-started/cairo_cheatsheet/type_casting.md:33 src/applications/simple_vault.md:114 -#: src/applications/erc20.md:228 src/applications/constant-product-amm.md:275 -#: src/advanced-concepts/write_to_any_slot.md:58 src/advanced-concepts/storing_arrays.md:105 -#: src/advanced-concepts/struct-mapping-key.md:46 src/advanced-concepts/hash-solidity-compatible.md:46 -#: src/advanced-concepts/optimisations/store_using_packing.md:90 src/advanced-concepts/list.md:139 -msgid "
Last change: 2023-12-07
" -msgstr "
Último cambio: 2023-12-07
" - -#: src/getting-started/basics/introduction.md:1 -msgid "# Basics of Smart Contracts in Cairo" -msgstr "# Conceptos básicos de los Smart Contracts en Cairo" - -#: src/getting-started/basics/introduction.md:3 -msgid "" -"The following chapters will introduce you to Starknet smart contracts and " -"how to write them in Cairo." -msgstr "" -"Los siguientes capítulos le presentarán los smart contracts de Starknet y " -"cómo escribirlos en Cairo." - -#: src/getting-started/basics/introduction.md:5 src/advanced-concepts/optimisations/optimisations.md:5 -msgid "
Last change: 2023-10-12
" -msgstr "
Último cambio: 2023-10-12
" - -#: src/getting-started/basics/storage.md:1 -msgid "# Storage" -msgstr "# Almacenamiento" - -#: src/getting-started/basics/storage.md:3 -msgid "Here's the most minimal contract you can write in Cairo:" -msgstr "Este es el contrato mínimo que puedes redactar en Cairo:" - -#: src/getting-started/basics/storage.md:5 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {}\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {}\n" -"}\n" -"```" - -#: src/getting-started/basics/storage.md:13 -msgid "" -"Storage is a struct annoted with `#[storage]`. Every contract must have one " -"and only one storage.\n" -"It's a key-value store, where each key will be mapped to a storage address " -"of the contract's storage space." -msgstr "" -"El almacenamiento es una estructura (struct) anotada con `#[storage]`. Cada " -"contrato debe tener un único almacenamiento. Es un almacén key-value, donde " -"cada key se asignará a una dirección de almacenamiento del espacio de " -"almacenamiento del contrato." - -#: src/getting-started/basics/storage.md:16 -msgid "" -"You can define [storage variables](./variables.md#storage-variables) in your " -"contract, and then use them to store and retrieve data." -msgstr "" -"Puede definir [variables de storage](./variables.md#storage-variables) en su " -"contrato y luego usarlas para almacenar y recuperar datos." - -#: src/getting-started/basics/storage.md:17 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {\n" -" a: u128,\n" -" b: u8,\n" -" c: u256\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {\n" -" a: u128,\n" -" b: u8,\n" -" c: u256\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/storage.md:29 -msgid "" -"> Actually these two contracts have the same underlying Sierra program.\n" -"> From the compiler's perspective, the storage variables don't exist until " -"they are used." -msgstr "" -"> En realidad estos dos contratos tienen el mismo programa Sierra " -"subyacente.\n" -"> Desde la perspectiva del compilador, las variables de almacenamiento no " -"existen hasta que se utilizan." - -#: src/getting-started/basics/storage.md:32 -msgid "" -"You can also read about [storing custom types](./storing-custom-types.md)" -msgstr "" -"También puede leer sobre [almacenamiento de tipos personalizados](./storing-" -"custom-types.md)" - -#: src/getting-started/basics/constructor.md:1 -msgid "# Constructor" -msgstr "# Constructor" - -#: src/getting-started/basics/constructor.md:3 -msgid "" -"Constructors are a special type of function that runs only once when " -"deploying a contract, and can be used to initialize the state of the " -"contract. Your contract must not have more than one constructor, and that " -"constructor function must be annotated with the `#[constructor]` attribute. " -"Also, a good practice consists in naming that function `constructor`." -msgstr "" -"Los constructores son un tipo especial de función que se ejecuta solo una " -"vez al implementar un contrato y se pueden usar para inicializar el estado " -"del contrato. Su contrato no debe tener más de un constructor, y esa función " -"constructora debe estar anotada con el atributo `#[constructor]`. Además, " -"una buena práctica consiste en denominar a esa función `constructor`." - -#: src/getting-started/basics/constructor.md:5 -msgid "" -"Here's a simple example that demonstrates how to initialize the state of a " -"contract on deployment by defining logic inside a constructor." -msgstr "" -"A continuación se muestra un ejemplo sencillo que demuestra cómo inicializar " -"el estado de un contrato durante la implementación definiendo la lógica " -"dentro de un constructor." - -#: src/getting-started/basics/constructor.md:7 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ExampleConstructor {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" names: LegacyMap::,\n" -" }\n" -"\n" -" // The constructor is decorated with a `#[constructor]` attribute.\n" -" // It is not inside an `impl` block.\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, name: felt252, address: " -"ContractAddress) {\n" -" self.names.write(address, name);\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ExampleConstructor {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" names: LegacyMap::,\n" -" }\n" -"\n" -" // The constructor is decorated with a `#[constructor]` attribute.\n" -" // It is not inside an `impl` block.\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, name: felt252, address: " -"ContractAddress) {\n" -" self.names.write(address, name);\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/constructor.md:25 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/constructor/src/constructor.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/constructor/src/constructor.cairo)." - -#: src/getting-started/basics/variables.md:1 -msgid "# Variables" -msgstr "# Variables" - -#: src/getting-started/basics/variables.md:3 -msgid "There are 3 types of variables in Cairo contracts:" -msgstr "Hay 3 tipos de variables en los contratos de Cairo:" - -#: src/getting-started/basics/variables.md:5 -msgid "" -"- Local\n" -" - declared inside a function\n" -" - not stored on the blockchain\n" -"- Storage\n" -" - declared in the [Storage](./storage.md) of a contract\n" -" - can be accessed from one execution to another\n" -"- Global\n" -" - provides information about the blockchain\n" -" - accessed anywhere, even within library functions" -msgstr "" -"- Local\n" -" - Declarado dentro de una función\n" -" - No almacenado en blockchain\n" -"- Almacenamiento\n" -" - Declarado en el [Almacenamiento](./storage.md) de un contrato\n" -" - Se puede acceder de una ejecución a otra\n" -"- Global\n" -" - Proporciona información sobre la blockchain\n" -" - Se accede desde cualquier lugar, incluso dentro de las funciones de la " -"biblioteca" - -#: src/getting-started/basics/variables.md:15 -msgid "## Local Variables" -msgstr "## Variables Locales" - -#: src/getting-started/basics/variables.md:17 -msgid "" -"Local variables are used and accessed within the scope of a specific " -"function or block of code. They are temporary and exist only for the " -"duration of that particular function or block execution." -msgstr "" -"Las variables locales se utilizan y se accede a ellas dentro del alcance de " -"una función o bloque de código específico. Son temporales y existen solo " -"mientras dure esa función en particular o la ejecución del bloque." - -#: src/getting-started/basics/variables.md:19 -msgid "" -"Local variables are stored in memory and are not stored on the blockchain. " -"This means they cannot be accessed from one execution to another. Local " -"variables are useful for storing temporary data that is relevant only within " -"a specific context. They also make the code more readable by giving names to " -"intermediate values." -msgstr "" -"Las variables locales se almacenan en la memoria y no en la cadena de " -"bloques. Esto significa que no se puede acceder a ellos de una ejecución a " -"otra. Las variables locales son útiles para almacenar datos temporales que " -"son relevantes sólo dentro de un contexto específico. También hacen que el " -"código sea más legible al dar nombres a los valores intermedios." - -#: src/getting-started/basics/variables.md:21 -msgid "Here's a simple example of a contract with only local variables:" -msgstr "Aquí hay un ejemplo simple de un contrato con solo variables locales:" - -#: src/getting-started/basics/variables.md:23 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ILocalVariablesExample {\n" -" fn do_something(self: @TContractState, value: u32) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod LocalVariablesExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl LocalVariablesExample of super::" -"ILocalVariablesExample {\n" -" fn do_something(self: @ContractState, value: u32) -> u32 {\n" -" // This variable is local to the current block. It can't be " -"accessed once it goes out of scope.\n" -" let increment = 10;\n" -"\n" -" {\n" -" // The scope of a code block allows for local variable " -"declaration\n" -" // We can access variables defined in higher scopes.\n" -" let sum = value + increment;\n" -" sum\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ILocalVariablesExample {\n" -" fn do_something(self: @TContractState, value: u32) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod LocalVariablesExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl LocalVariablesExample of super::" -"ILocalVariablesExample {\n" -" fn do_something(self: @ContractState, value: u32) -> u32 {\n" -" // This variable is local to the current block. It can't be " -"accessed once it goes out of scope.\n" -" let increment = 10;\n" -"\n" -" {\n" -" // The scope of a code block allows for local variable " -"declaration\n" -" // We can access variables defined in higher scopes.\n" -" let sum = value + increment;\n" -" sum\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:50 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/local_variables.cairo)." -msgstr "" -"Visite el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " -"o juegue con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/variables/src/local_variables.cairo)." - -#: src/getting-started/basics/variables.md:52 -msgid "## Storage Variables" -msgstr "## Variables de Storage" - -#: src/getting-started/basics/variables.md:54 -msgid "" -"Storage variables are persistent data stored on the blockchain. They can be " -"accessed from one execution to another, allowing the contract to remember " -"and update information over time." -msgstr "" -"Las variables de almacenamiento (storage) son datos persistentes almacenados " -"en la blockchain. Se puede acceder a ellos de una ejecución a otra, lo que " -"permite que el contrato recuerde y actualice la información a lo largo del " -"tiempo." - -#: src/getting-started/basics/variables.md:56 -msgid "" -"To write or update a storage variable, you need to interact with the " -"contract through an external entrypoint by sending a transaction." -msgstr "" -"Para escribir o actualizar una variable de storage, debe interactuar con el " -"contrato a través de un punto de entrada externo mediante el envío de una " -"transacción." - -#: src/getting-started/basics/variables.md:58 -msgid "" -"On the other hand, you can read state variables, for free, without any " -"transaction, simply by interacting with a node." -msgstr "" -"Por otro lado, puedes leer variables de estado, de forma gratuita, sin " -"ninguna transacción, simplemente interactuando con un nodo." - -#: src/getting-started/basics/variables.md:60 -msgid "Here's a simple example of a contract with one storage variable:" -msgstr "" -"A continuación se muestra un ejemplo sencillo de un contrato con una " -"variable de almacenamiento:" - -#: src/getting-started/basics/variables.md:62 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStorageVariableExample {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"#[starknet::contract]\n" -"mod StorageVariablesExample {\n" -" // All storage variables are contained in a struct called Storage\n" -" // annotated with the `#[storage]` attribute\n" -" #[storage]\n" -" struct Storage {\n" -" // Storage variable holding a number\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StorageVariablesExample of super::" -"IStorageVariableExample {\n" -" // Write to storage variables by sending a transaction that calls an " -"external function\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // Read from storage variables without sending transactions\n" -" fn get(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStorageVariableExample {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"#[starknet::contract]\n" -"mod StorageVariablesExample {\n" -" // All storage variables are contained in a struct called Storage\n" -" // annotated with the `#[storage]` attribute\n" -" #[storage]\n" -" struct Storage {\n" -" // Storage variable holding a number\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StorageVariablesExample of super::" -"IStorageVariableExample {\n" -" // Write to storage variables by sending a transaction that calls an " -"external function\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // Read from storage variables without sending transactions\n" -" fn get(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:92 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/storage_variables.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/variables/src/storage_variables." -"cairo)." - -#: src/getting-started/basics/variables.md:94 -msgid "## Global Variables" -msgstr "## Variables Globales" - -#: src/getting-started/basics/variables.md:96 -msgid "" -"Global variables are predefined variables that provide information about the " -"blockchain and the current execution environment. They can be accessed at " -"any time and from anywhere!" -msgstr "" -"Las variables globales son variables predefinidas que proporcionan " -"información sobre la blockchain y el entorno de ejecución actual. ¡Se puede " -"acceder a ellos en cualquier momento y desde cualquier lugar!" - -#: src/getting-started/basics/variables.md:98 -msgid "" -"In Starknet, you can access global variables by using specific functions " -"contained in the starknet core libraries." -msgstr "" -"En Starknet, puede acceder a variables globales utilizando funciones " -"específicas contenidas en las bibliotecas principales de Starknet." - -#: src/getting-started/basics/variables.md:100 -msgid "" -"For example, the `get_caller_address` function returns the address of the " -"caller of the current transaction, and the `get_contract_address` function " -"returns the address of the current contract." -msgstr "" -"Por ejemplo, la función `get_caller_address` devuelve la dirección de la " -"persona que llama de la transacción actual, y la función " -"`get_contract_address` devuelve la dirección del contrato actual." - -#: src/getting-started/basics/variables.md:102 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IGlobalExample {\n" -" fn foo(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod GlobalExample {\n" -" // import the required functions from the starknet core library\n" -" use starknet::get_caller_address;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl GlobalExampleImpl of super::IGlobalExample {\n" -" fn foo(ref self: ContractState) {\n" -" // Call the get_caller_address function to get the sender " -"address\n" -" let caller = get_caller_address();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IGlobalExample {\n" -" fn foo(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod GlobalExample {\n" -" // import the required functions from the starknet core library\n" -" use starknet::get_caller_address;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl GlobalExampleImpl of super::IGlobalExample {\n" -" fn foo(ref self: ContractState) {\n" -" // Call the get_caller_address function to get the sender " -"address\n" -" let caller = get_caller_address();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:125 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/global_variables.cairo)." -msgstr "" -"Visite el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/global_variables.cairo)." - -#: src/getting-started/basics/visibility-mutability.md:1 -msgid "# Visibility and Mutability" -msgstr "# Visibilidad y Mutabilidad" - -#: src/getting-started/basics/visibility-mutability.md:3 -msgid "## Visibility" -msgstr "## Visibilidad" - -#: src/getting-started/basics/visibility-mutability.md:5 -msgid "There are two types of functions in Starknet contracts:" -msgstr "Hay dos tipos de funciones en los contratos Starknet:" - -#: src/getting-started/basics/visibility-mutability.md:7 -msgid "" -"- Functions that are accessible externally and can be called by anyone.\n" -"- Functions that are only accessible internally and can only be called by " -"other functions in the contract." -msgstr "" -"- Funciones a las que se puede acceder externamente y que cualquiera puede " -"llamar.\n" -"- Funciones a las que solo se puede acceder internamente y que solo pueden " -"ser invocadas por otras funciones del contrato." - -#: src/getting-started/basics/visibility-mutability.md:10 -msgid "" -"These functions are also typically divided into two different " -"implementations blocks. The first `impl` block for externally accessible " -"functions is explicitly annotated with an `#[abi(embed_v0)]` attribute. This " -"indicates that all the functions inside this block can be called either as a " -"transaction or as a view function. The second `impl` block for internally " -"accessible functions is not annotated with any attribute, which means that " -"all the functions inside this block are private by default." -msgstr "" -"Estas funciones también suelen dividirse en dos bloques de implementación " -"diferentes. El primer bloque `impl` para funciones accesibles externamente " -"está anotado explícitamente con un atributo `#[abi(embed_v0)]`. Esto indica " -"que todas las funciones dentro de este bloque se pueden llamar como una " -"transacción o como una función de view. El segundo bloque `impl` para " -"funciones accesibles internamente no está anotado con ningún atributo, lo " -"que significa que todas las funciones dentro de este bloque son privadas de " -"forma predeterminada." - -#: src/getting-started/basics/visibility-mutability.md:12 -msgid "## State Mutability" -msgstr "## Mutabilidad del Estado" - -#: src/getting-started/basics/visibility-mutability.md:14 -msgid "" -"Regardless of whether a function is internal or external, it can either " -"modify the contract's state or not. When we declare functions that interact " -"with storage variables inside a smart contract,\n" -"we need to explicitly state that we are accessing the `ContractState` by " -"adding it as the first parameter of the function. This can be done in two " -"different ways:" -msgstr "" -"Independientemente de si una función es interna o externa, puede modificar " -"el estado del contrato o no. Cuando declaramos funciones que interactúan con " -"variables de almacenamiento dentro de un smart contract, debemos indicar " -"explícitamente que estamos accediendo al `ContractState` agregándolo como el " -"primer parámetro de la función. Esto se puede hacer de dos maneras " -"diferentes:" - -#: src/getting-started/basics/visibility-mutability.md:17 -msgid "" -"- If we want our function to be able to mutate the state of the contract, we " -"pass it by reference like this: `ref self: ContractState`.\n" -"- If we want our function to be read-only and not mutate the state of the " -"contract, we pass it by snapshot like this: `self: @ContractState`." -msgstr "" -"- Si queremos que nuestra función pueda mutar el estado del contrato, lo " -"pasamos por referencia así: `ref self: ContractState`.\n" -"- Si queremos que nuestra función sea de solo lectura y no mute el estado " -"del contrato, la pasamos por instantánea como esta: `self: @ContractState`." - -#: src/getting-started/basics/visibility-mutability.md:20 -msgid "" -"Read-only functions, also called view functions, can be directly called " -"without making a transaction. You can interact with them directly through a " -"RPC node to read the contract's state, and they're free to call!\n" -"External functions, that modify the contract's state, on the other side can " -"only be called by making a transaction." -msgstr "" -"Las funciones de solo lectura, también llamadas funciones de visualización, " -"se pueden llamar directamente sin realizar una transacción. Puede " -"interactuar con ellos directamente a través de un nodo RPC para leer el " -"estado del contrato, ¡y pueden llamar libremente! Las funciones externas, " -"que modifican el estado del contrato, por otro lado, solo se pueden llamar " -"realizando una transacción." - -#: src/getting-started/basics/visibility-mutability.md:23 -msgid "" -"Internal functions can't be called externally, but the same principle " -"applies regarding state mutability." -msgstr "" -"Las funciones internas no se pueden llamar externamente, pero se aplica el " -"mismo principio con respecto a la mutabilidad de estado." - -#: src/getting-started/basics/visibility-mutability.md:25 -msgid "Let's take a look at a simple example contract to see these in action:" -msgstr "" -"Echemos un vistazo a un contrato de ejemplo simple para verlos en acción:" - -#: src/getting-started/basics/visibility-mutability.md:27 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExampleContract {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExampleContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -"\n" -" // The `#[abi(embed_v0)]` attribute indicates that all the functions in " -"this implementation can be called externally.\n" -" // Omitting this attribute would make all the functions in this " -"implementation internal.\n" -" #[abi(embed_v0)]\n" -" impl ExampleContract of super::IExampleContract {\n" -" // The `set` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // It can modify the contract's state as it is passed as a " -"reference.\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // The `get` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn get(self: @ContractState) -> u32 {\n" -" // We can call an internal function from any functions within " -"the contract\n" -" PrivateFunctionsTrait::_read_value(self)\n" -" }\n" -" }\n" -"\n" -" // The lack of the `external` attribute indicates that all the functions " -"in this implementation can only be called internally.\n" -" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " -"internal trait allowing us to call internal functions.\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" // The `_read_value` function is outside the implementation that is " -"marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -" // and can only be called from within the contract.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn _read_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExampleContract {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExampleContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -"\n" -" // The `#[abi(embed_v0)]` attribute indicates that all the functions in " -"this implementation can be called externally.\n" -" // Omitting this attribute would make all the functions in this " -"implementation internal.\n" -" #[abi(embed_v0)]\n" -" impl ExampleContract of super::IExampleContract {\n" -" // The `set` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // It can modify the contract's state as it is passed as a " -"reference.\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // The `get` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn get(self: @ContractState) -> u32 {\n" -" // We can call an internal function from any functions within " -"the contract\n" -" PrivateFunctionsTrait::_read_value(self)\n" -" }\n" -" }\n" -"\n" -" // The lack of the `external` attribute indicates that all the functions " -"in this implementation can only be called internally.\n" -" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " -"internal trait allowing us to call internal functions.\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" // The `_read_value` function is outside the implementation that is " -"marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -" // and can only be called from within the contract.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn _read_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/visibility-mutability.md:73 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/visibility/src/visibility.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/visibility/src/visibility.cairo)." - -#: src/getting-started/basics/counter.md:1 -msgid "# Simple Counter" -msgstr "# Counter Sencillo" - -#: src/getting-started/basics/counter.md:3 -msgid "This is a simple counter contract." -msgstr "Este es un contrato de un simple counter." - -#: src/getting-started/basics/counter.md:5 -msgid "Here's how it works:" -msgstr "Así es como trabaja:" - -#: src/getting-started/basics/counter.md:7 -msgid "" -"- The contract has a state variable called 'counter' that is initialized to " -"0.\n" -"\n" -"- When a user calls 'increment', the contract increments the counter by 1.\n" -"\n" -"- When a user calls 'decrement', the contract decrements the counter by 1." -msgstr "" -"- El contrato tiene una variable de estado llamada 'counter' que se " -"inicializa a 0.\n" -"\n" -"- Cuando un usuario llama 'increment', el contrato incrementa el contador en " -"1.\n" -"\n" -"- Cuando un usuario llama 'decrement', el contrato disminuye el contador en " -"1." - -#: src/getting-started/basics/counter.md:13 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISimpleCounter {\n" -" fn get_current_count(self: @TContractState) -> u128;\n" -" fn increment(ref self: TContractState);\n" -" fn decrement(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleCounter {\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter variable\n" -" counter: u128,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128) {\n" -" // Store initial value\n" -" self.counter.write(init_value);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleCounter of super::ISimpleCounter {\n" -" fn get_current_count(self: @ContractState) -> u128 {\n" -" return self.counter.read();\n" -" }\n" -"\n" -" fn increment(ref self: ContractState) {\n" -" // Store counter value + 1\n" -" let counter = self.counter.read() + 1;\n" -" self.counter.write(counter);\n" -" }\n" -" fn decrement(ref self: ContractState) {\n" -" // Store counter value - 1\n" -" let counter = self.counter.read() - 1;\n" -" self.counter.write(counter);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISimpleCounter {\n" -" fn get_current_count(self: @TContractState) -> u128;\n" -" fn increment(ref self: TContractState);\n" -" fn decrement(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleCounter {\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter variable\n" -" counter: u128,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128) {\n" -" // Store initial value\n" -" self.counter.write(init_value);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleCounter of super::ISimpleCounter {\n" -" fn get_current_count(self: @ContractState) -> u128 {\n" -" return self.counter.read();\n" -" }\n" -"\n" -" fn increment(ref self: ContractState) {\n" -" // Store counter value + 1\n" -" let counter = self.counter.read() + 1;\n" -" self.counter.write(counter);\n" -" }\n" -" fn decrement(ref self: ContractState) {\n" -" // Store counter value - 1\n" -" let counter = self.counter.read() - 1;\n" -" self.counter.write(counter);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/counter.md:54 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/counter/src/contracts.cairo)." -msgstr "" -"Visite el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/counter/src/contracts.cairo)." - -#: src/getting-started/basics/mappings.md:1 -msgid "# Mappings" -msgstr "# Mapas" - -#: src/getting-started/basics/mappings.md:3 -msgid "" -"Maps are a key-value data structure used to store data within a smart " -"contract. In Cairo they are implemented using the `LegacyMap` type. It's " -"important to note that the `LegacyMap` type can only be used inside the " -"`Storage` struct of a contract and that it can't be used elsewhere." -msgstr "" -"Los mapas son una estructura de datos de key-value que se utiliza para " -"almacenar datos dentro de un contrato inteligente. En Cairo se implementan " -"utilizando el tipo `LegacyMap`. Es importante tener en cuenta que el tipo " -"`LegacyMap` solo se puede usar dentro de la estructura `Storage` de un " -"contrato y no se puede usar en ningún otro lugar." - -#: src/getting-started/basics/mappings.md:5 -msgid "" -"Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, " -"to map between a key of type `ContractAddress` and value of type `felt252`. " -"The key-value types are specified within angular brackets <>. We write to " -"the map by calling the `write()` method, passing in both the key and value. " -"Similarly, we can read the value associated with a given key by calling the " -"`read()` method and passing in the relevant key." -msgstr "" -"Aquí demostramos cómo usar el tipo `LegacyMap` dentro de un contrato de " -"Cairo, para mapear entre una clave de tipo `ContractAddress` y un valor de " -"tipo `felt252`. Los tipos key-value se especifican entre corchetes angulares " -"<>. Escribimos en el mapa llamando al método `write()`, pasando tanto la " -"clave como el valor. De manera similar, podemos leer el valor asociado con " -"una clave determinada llamando al método `read()` y pasando la clave " -"relevante." - -#: src/getting-started/basics/mappings.md:7 -msgid "Some additional notes:" -msgstr "Algunas notas adicionales:" - -#: src/getting-started/basics/mappings.md:9 -msgid "" -"- More complex key-value mappings are possible, for example we could use " -"`LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an " -"allowance on an ERC20 token contract.\n" -"\n" -"- In mappings, the address of the value at key `k_1,...,k_n` is `h(..." -"h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the Pedersen " -"hash and the final value is taken `mod2251−256`. You can learn more about " -"the contract storage layout in the [Starknet Documentation](https://docs." -"starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-" -"storage/#storage_variables)." -msgstr "" -"- Son posibles asignaciones key-value más complejas; por ejemplo, podríamos " -"usar `LegacyMap::<(ContractAddress, ContractAddress), Felt252>` para crear " -"una asignación en un contrato de token ERC20.\n" -"\n" -"- En las asignaciones, la dirección del valor en la clave `k_1,...,k_n` es " -"`h(...h(h(sn_keccak(nombre_variable),k_1),k_2),...,k_n)` donde `ℎ` es el " -"hash de Pedersen y el valor final se toma `mod2251−256`. Puede obtener más " -"información sobre el diseño de almacenamiento por contrato en la " -"[Documentación de Starknet](https://docs.starknet.io/documentation/" -"architecture_and_concepts/Smart_Contracts/contract-storage/" -"#storage_variables)." - -#: src/getting-started/basics/mappings.md:13 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMapContract {\n" -" fn set(ref self: TContractState, key: ContractAddress, value: felt252);\n" -" fn get(self: @TContractState, key: ContractAddress) -> felt252;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MapContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" // The `LegacyMap` type is only available inside the `Storage` " -"struct.\n" -" map: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl MapContractImpl of super::IMapContract {\n" -" fn set(ref self: ContractState, key: ContractAddress, value: " -"felt252) {\n" -" self.map.write(key, value);\n" -" }\n" -"\n" -" fn get(self: @ContractState, key: ContractAddress) -> felt252 {\n" -" self.map.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMapContract {\n" -" fn set(ref self: TContractState, key: ContractAddress, value: felt252);\n" -" fn get(self: @TContractState, key: ContractAddress) -> felt252;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MapContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" // The `LegacyMap` type is only available inside the `Storage` " -"struct.\n" -" map: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl MapContractImpl of super::IMapContract {\n" -" fn set(ref self: ContractState, key: ContractAddress, value: " -"felt252) {\n" -" self.map.write(key, value);\n" -" }\n" -"\n" -" fn get(self: @ContractState, key: ContractAddress) -> felt252 {\n" -" self.map.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/mappings.md:44 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/mappings/src/mappings.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/mappings/src/mappings.cairo)." - -#: src/getting-started/basics/mappings.md:46 src/components/how_to.md:175 -#: src/components/dependencies.md:504 src/components/collisions.md:121 -msgid "
Last change: 2023-12-17
" -msgstr "
Último cambio: 2023-12-17
" - -#: src/getting-started/basics/errors.md:1 -msgid "# Errors" -msgstr "# Errores" - -#: src/getting-started/basics/errors.md:3 -msgid "" -"Errors can be used to handle validation and other conditions that may occur " -"during the execution of a smart contract.\n" -"If an error is thrown during the execution of a smart contract call, the " -"execution is stopped and any changes made during the transaction are " -"reverted." -msgstr "" -"Los errores se pueden utilizar para manejar la validación y otras " -"condiciones que pueden ocurrir durante la ejecución de un smart contract.\n" -"Si se produce un error durante la ejecución de una llamada de smart " -"contract, la ejecución se detiene y se revierte cualquier cambio realizado " -"durante la transacción." - -#: src/getting-started/basics/errors.md:6 -msgid "To throw an error, use the `assert` or `panic` functions:" -msgstr "Para generar un error, use las funciones `assert` o `panic`:" - -#: src/getting-started/basics/errors.md:8 -msgid "" -"- `assert` is used to validate conditions.\n" -" If the check fails, an error is thrown along with a specified value, often " -"a message.\n" -" It's similar to the `require` statement in Solidity.\n" -"\n" -"- `panic` immediately halt the execution with the given error value.\n" -" It should be used when the condition to check is complex and for internal " -"errors. It's similar to the `revert` statement in Solidity.\n" -" (Use `panic_with_felt252` to be able to directly pass a felt252 as the " -"error value)" -msgstr "" -"- `assert` se utiliza para validar condiciones.\n" -" Si la verificación falla, se genera un error junto con un valor " -"específico, a menudo un mensaje.\n" -" Es similar a la declaración `require` en Solidity.\n" -"\n" -"- `panic` detiene inmediatamente la ejecución con el valor de error dado.\n" -" Debe utilizarse cuando la condición a comprobar es compleja y para " -"errores internos. Es similar a la declaración `revert` en Solidity.\n" -" (Utilice `panic_with_felt252` para poder pasar directamente un fieltro252 " -"como valor de error)" - -#: src/getting-started/basics/errors.md:16 -msgid "Here's a simple example that demonstrates the use of these functions:" -msgstr "Aquí hay un ejemplo simple que demuestra el uso de estas funciones:" - -#: src/getting-started/basics/errors.md:18 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"#[starknet::contract]\n" -"mod ErrorsExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ErrorsExample of super::IErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" // Assert used to validate a condition\n" -" // and abort execution if the condition is not met\n" -" assert(i > 0, 'i must be greater than 0');\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" // Panic used to abort execution directly\n" -" panic_with_felt252('i must not be 0');\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"#[starknet::contract]\n" -"mod ErrorsExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ErrorsExample of super::IErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" // Assert used to validate a condition\n" -" // and abort execution if the condition is not met\n" -" assert(i > 0, 'i must be greater than 0');\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" // Panic used to abort execution directly\n" -" panic_with_felt252('i must not be 0');\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:46 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/simple_errors.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/errors/src/simple_errors.cairo)." - -#: src/getting-started/basics/errors.md:48 -msgid "## Custom errors" -msgstr "## Errores personalizados" - -#: src/getting-started/basics/errors.md:50 -msgid "" -"You can make error handling easier by defining your error codes in a " -"specific module." -msgstr "" -"Puede facilitar el manejo de errores definiendo sus códigos de error en un " -"módulo específico." - -#: src/getting-started/basics/errors.md:52 -msgid "" -"```cairo\n" -"mod Errors {\n" -" const NOT_POSITIVE: felt252 = 'must be greater than 0';\n" -" const NOT_NULL: felt252 = 'must not be null';\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICustomErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CustomErrorsExample {\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CustomErrorsExample of super::ICustomErrorsExample " -"{\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" assert(i > 0, Errors::NOT_POSITIVE);\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" panic_with_felt252(Errors::NOT_NULL);\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"mod Errors {\n" -" const NOT_POSITIVE: felt252 = 'must be greater than 0';\n" -" const NOT_NULL: felt252 = 'must not be null';\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICustomErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CustomErrorsExample {\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CustomErrorsExample of super::ICustomErrorsExample " -"{\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" assert(i > 0, Errors::NOT_POSITIVE);\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" panic_with_felt252(Errors::NOT_NULL);\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:85 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/custom_errors.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/errors/src/custom_errors.cairo)." - -#: src/getting-started/basics/errors.md:87 -msgid "## Vault example" -msgstr "## Ejemplo de Vault" - -#: src/getting-started/basics/errors.md:89 -msgid "" -"Here's another example that demonstrates the use of errors in a more complex " -"contract:" -msgstr "" -"Aquí hay otro ejemplo que demuestra el uso de errores en un contrato más " -"complejo:" - -#: src/getting-started/basics/errors.md:91 -msgid "" -"```cairo\n" -"mod VaultErrors {\n" -" const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance';\n" -"// you can define more errors here\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IVaultErrorsExample {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, amount: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod VaultErrorsExample {\n" -" use super::VaultErrors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" balance: u256,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl VaultErrorsExample of super::IVaultErrorsExample {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -" balance = balance + amount;\n" -" self.balance.write(balance);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -"\n" -" assert(balance >= amount, VaultErrors::INSUFFICIENT_BALANCE);\n" -"\n" -" // Or using panic:\n" -" if (balance >= amount) {\n" -" panic_with_felt252(VaultErrors::INSUFFICIENT_BALANCE);\n" -" }\n" -"\n" -" let balance = balance - amount;\n" -"\n" -" self.balance.write(balance);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"mod VaultErrors {\n" -" const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance';\n" -"// you can define more errors here\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IVaultErrorsExample {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, amount: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod VaultErrorsExample {\n" -" use super::VaultErrors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" balance: u256,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl VaultErrorsExample of super::IVaultErrorsExample {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -" balance = balance + amount;\n" -" self.balance.write(balance);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -"\n" -" assert(balance >= amount, VaultErrors::INSUFFICIENT_BALANCE);\n" -"\n" -" // Or using panic:\n" -" if (balance >= amount) {\n" -" panic_with_felt252(VaultErrors::INSUFFICIENT_BALANCE);\n" -" }\n" -"\n" -" let balance = balance - amount;\n" -"\n" -" self.balance.write(balance);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:137 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/vault_errors.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/errors/src/vault_errors.cairo)." - -#: src/getting-started/basics/events.md:1 -msgid "# Events" -msgstr "# Eventos" - -#: src/getting-started/basics/events.md:3 -msgid "" -"Events are a way to emit data from a contract. All events must be defined in " -"the `Event` enum, which must be annotated with the `#[event]` attribute.\n" -"An event is defined as struct that derives the `#[starknet::Event]` trait. " -"The fields of that struct correspond to the data that will be emitted. An " -"event can be indexed for easy and fast access when querying the data at a " -"later time. Events data can be indexed by adding a `#[key]` attribute to a " -"field member." -msgstr "" -"Los eventos son una forma de emitir datos de un contrato. Todos los eventos " -"deben definirse en la enumeración `Event`, que debe anotarse con el atributo " -"`#[event]`.\n" -"Un evento se define como una estructura que deriva el trait `#[starknet::" -"Event]`. Los campos de esa estructura corresponden a los datos que se " -"emitirán. Un evento se puede indexar para un acceso fácil y rápido al " -"consultar los datos más adelante. Los datos de eventos se pueden indexar " -"agregando un atributo `#[key]` a un miembro de campo." - -#: src/getting-started/basics/events.md:6 -msgid "" -"Here's a simple example of a contract using events that emit an event each " -"time a counter is incremented by the \"increment\" function:" -msgstr "" -"A continuación se muestra un ejemplo simple de un contrato que utiliza " -"eventos que emiten un evento cada vez que la función `increment` incrementa " -"un contador:" - -#: src/getting-started/basics/events.md:8 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IEventCounter {\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod EventCounter {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter value\n" -" counter: u128,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" // The event enum must be annotated with the `#[event]` attribute.\n" -" // It must also derive the `Drop` and `starknet::Event` traits.\n" -" enum Event {\n" -" CounterIncreased: CounterIncreased,\n" -" UserIncreaseCounter: UserIncreaseCounter\n" -" }\n" -"\n" -" // By deriving the `starknet::Event` trait, we indicate to the compiler " -"that\n" -" // this struct will be used when emitting events.\n" -" #[derive(Drop, starknet::Event)]\n" -" struct CounterIncreased {\n" -" amount: u128\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct UserIncreaseCounter {\n" -" // The `#[key]` attribute indicates that this event will be " -"indexed.\n" -" #[key]\n" -" user: ContractAddress,\n" -" new_value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl EventCounter of super::IEventCounter {\n" -" fn increment(ref self: ContractState) {\n" -" let mut counter = self.counter.read();\n" -" counter += 1;\n" -" self.counter.write(counter);\n" -" // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IEventCounter {\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod EventCounter {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter value\n" -" counter: u128,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" // The event enum must be annotated with the `#[event]` attribute.\n" -" // It must also derive the `Drop` and `starknet::Event` traits.\n" -" enum Event {\n" -" CounterIncreased: CounterIncreased,\n" -" UserIncreaseCounter: UserIncreaseCounter\n" -" }\n" -"\n" -" // By deriving the `starknet::Event` trait, we indicate to the compiler " -"that\n" -" // this struct will be used when emitting events.\n" -" #[derive(Drop, starknet::Event)]\n" -" struct CounterIncreased {\n" -" amount: u128\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct UserIncreaseCounter {\n" -" // The `#[key]` attribute indicates that this event will be " -"indexed.\n" -" #[key]\n" -" user: ContractAddress,\n" -" new_value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl EventCounter of super::IEventCounter {\n" -" fn increment(ref self: ContractState) {\n" -" let mut counter = self.counter.read();\n" -" counter += 1;\n" -" self.counter.write(counter);\n" -" // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/events.md:66 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/events/src/counter.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started-getting-started/events/src/counter.cairo)." - -#: src/getting-started/basics/events.md:68 src/getting-started/testing/contract-testing.md:176 -#: src/applications/upgradeable_contract.md:117 -msgid "
Last change: 2023-12-21
" -msgstr "
Último cambio: 2023-12-21
" - -#: src/getting-started/basics/syscalls.md:1 -msgid "# Syscalls" -msgstr "# Llamadas al Sistema" - -#: src/getting-started/basics/syscalls.md:3 -msgid "" -"At the protocol level, the Starknet Operating System (OS) is the program " -"that manages the whole Starknet network." -msgstr "" -"A nivel de protocolo, el sistema operativo (SO) Starknet es el programa que " -"gestiona toda la red Starknet." - -#: src/getting-started/basics/syscalls.md:5 -msgid "" -"Some of the OS functionalities are exposed to smart contracts through the " -"use of syscalls (system calls). Syscalls can be used to get information " -"about the state of the Starknet network, to interact with/deploy contracts, " -"emit events, send messages, and perform other low-level operations." -msgstr "" -"Algunas de las funcionalidades del sistema operativo están expuestas a smart " -"contracts mediante el uso de syscalls (llamadas al sistema). Las llamadas al " -"sistema se pueden utilizar para obtener información sobre el estado de la " -"red Starknet, para interactuar/implementar contratos, emitir eventos, enviar " -"mensajes y realizar otras operaciones de bajo nivel." - -#: src/getting-started/basics/syscalls.md:7 -msgid "" -"Syscalls return a `SyscallResult` which is either `Sucess` of `Failure`, " -"allowing the contract to handle errors." -msgstr "" -"Las llamadas al sistema devuelven un `SyscallResult` que es `Sucess` o " -"`Failure`, lo que permite que el contrato maneje los errores." - -#: src/getting-started/basics/syscalls.md:9 -msgid "Here's the available syscalls:" -msgstr "Aquí están las llamadas al sistema disponibles:" - -#: src/getting-started/basics/syscalls.md:10 -msgid "" -"- [get_block_hash](#get_block_hash)\n" -"- [get_execution_info](#get_execution_info)\n" -"- [call_contract](#call_contract)\n" -"- [deploy](#deploy)\n" -"- [emit_event](#emit_event)\n" -"- [library_call](#library_call)\n" -"- [send_message_to_L1](#send_message_to_L1)\n" -"- [replace_class](#replace_class)\n" -"- [storage_read](#storage_read)\n" -"- [storage_write](#storage_write)" -msgstr "" -"- [get_block_hash](#get_block_hash)\n" -"- [get_execution_info](#get_execution_info)\n" -"- [call_contract](#call_contract)\n" -"- [deploy](#deploy)\n" -"- [emit_event](#emit_event)\n" -"- [library_call](#library_call)\n" -"- [send_message_to_L1](#send_message_to_L1)\n" -"- [replace_class](#replace_class)\n" -"- [storage_read](#storage_read)\n" -"- [storage_write](#storage_write)" - -#: src/getting-started/basics/syscalls.md:20 -msgid "" -msgstr "" - -#: src/getting-started/basics/syscalls.md:22 -msgid "#### get_block_hash" -msgstr "#### get_block_hash" - -#: src/getting-started/basics/syscalls.md:24 -msgid "" -"```cairo\n" -"fn get_block_hash_syscall(block_number: u64) -> SyscallResult\n" -"```" -msgstr "" -"```cairo\n" -"fn get_block_hash_syscall(block_number: u64) -> SyscallResult\n" -"```" - -#: src/getting-started/basics/syscalls.md:28 -msgid "Get the hash of the block number `block_number`." -msgstr "Obtenga el hash del número de bloque `block_number`." - -#: src/getting-started/basics/syscalls.md:30 -msgid "Only within the range `[first_v0_12_0_block, current_block - 10]`." -msgstr "Solo dentro del rango `[first_v0_12_0_block, current_block - 10]`." - -#: src/getting-started/basics/syscalls.md:32 -msgid "#### get_execution_info" -msgstr "#### get_execution_info" - -#: src/getting-started/basics/syscalls.md:34 -msgid "" -"```cairo\n" -"fn get_execution_info_syscall() -> SyscallResult>\n" -"```" -msgstr "" -"```cairo\n" -"fn get_execution_info_syscall() -> SyscallResult>\n" -"```" - -#: src/getting-started/basics/syscalls.md:38 -msgid "" -"Get information about the current execution context.\n" -"The returned `ExecutionInfo` is defined as :" -msgstr "" -"Obtenga información sobre el contexto de ejecución actual.\n" -"La `ExecutionInfo` devuelta se define como:" - -#: src/getting-started/basics/syscalls.md:41 -msgid "" -"```cairo\n" -"#[derive(Copy, Drop, Debug)]\n" -"pub struct ExecutionInfo {\n" -" pub block_info: Box,\n" -" pub tx_info: Box,\n" -" pub caller_address: ContractAddress,\n" -" pub contract_address: ContractAddress,\n" -" pub entry_point_selector: felt252,\n" -"}\n" -"\n" -"#[derive(Copy, Drop, Debug, Serde)]\n" -"pub struct BlockInfo {\n" -" pub block_number: u64,\n" -" pub block_timestamp: u64,\n" -" pub sequencer_address: ContractAddress,\n" -"}\n" -"\n" -"#[derive(Copy, Drop, Debug, Serde)]\n" -"pub struct TxInfo {\n" -" // The version of the transaction. Always fixed (1)\n" -" pub version: felt252,\n" -" // The account contract from which this transaction originates.\n" -" pub account_contract_address: ContractAddress,\n" -" // The max_fee field of the transaction.\n" -" pub max_fee: u128,\n" -" // The signature of the transaction.\n" -" pub signature: Span,\n" -" // The hash of the transaction.\n" -" pub transaction_hash: felt252,\n" -" // The identifier of the chain.\n" -" // This field can be used to prevent replay of testnet transactions on " -"mainnet.\n" -" pub chain_id: felt252,\n" -" // The transaction's nonce.\n" -" pub nonce: felt252,\n" -" // A span of ResourceBounds structs.\n" -" pub resource_bounds: Span,\n" -" // The tip.\n" -" pub tip: u128,\n" -" // If specified, the paymaster should pay for the execution of the tx.\n" -" // The data includes the address of the paymaster sponsoring the " -"transaction, followed by\n" -" // extra data to send to the paymaster.\n" -" pub paymaster_data: Span,\n" -" // The data availability mode for the nonce.\n" -" pub nonce_data_availability_mode: u32,\n" -" // The data availability mode for the account balance from which fee " -"will be taken.\n" -" pub fee_data_availability_mode: u32,\n" -" // If nonempty, will contain the required data for deploying and " -"initializing an account\n" -" // contract: its class hash, address salt and constructor calldata.\n" -" pub account_deployment_data: Span,\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[derive(Copy, Drop, Debug)]\n" -"pub struct ExecutionInfo {\n" -" pub block_info: Box,\n" -" pub tx_info: Box,\n" -" pub caller_address: ContractAddress,\n" -" pub contract_address: ContractAddress,\n" -" pub entry_point_selector: felt252,\n" -"}\n" -"\n" -"#[derive(Copy, Drop, Debug, Serde)]\n" -"pub struct BlockInfo {\n" -" pub block_number: u64,\n" -" pub block_timestamp: u64,\n" -" pub sequencer_address: ContractAddress,\n" -"}\n" -"\n" -"#[derive(Copy, Drop, Debug, Serde)]\n" -"pub struct TxInfo {\n" -" // The version of the transaction. Always fixed (1)\n" -" pub version: felt252,\n" -" // The account contract from which this transaction originates.\n" -" pub account_contract_address: ContractAddress,\n" -" // The max_fee field of the transaction.\n" -" pub max_fee: u128,\n" -" // The signature of the transaction.\n" -" pub signature: Span,\n" -" // The hash of the transaction.\n" -" pub transaction_hash: felt252,\n" -" // The identifier of the chain.\n" -" // This field can be used to prevent replay of testnet transactions on " -"mainnet.\n" -" pub chain_id: felt252,\n" -" // The transaction's nonce.\n" -" pub nonce: felt252,\n" -" // A span of ResourceBounds structs.\n" -" pub resource_bounds: Span,\n" -" // The tip.\n" -" pub tip: u128,\n" -" // If specified, the paymaster should pay for the execution of the tx.\n" -" // The data includes the address of the paymaster sponsoring the " -"transaction, followed by\n" -" // extra data to send to the paymaster.\n" -" pub paymaster_data: Span,\n" -" // The data availability mode for the nonce.\n" -" pub nonce_data_availability_mode: u32,\n" -" // The data availability mode for the account balance from which fee " -"will be taken.\n" -" pub fee_data_availability_mode: u32,\n" -" // If nonempty, will contain the required data for deploying and " -"initializing an account\n" -" // contract: its class hash, address salt and constructor calldata.\n" -" pub account_deployment_data: Span,\n" -"}\n" -"```" - -#: src/getting-started/basics/syscalls.md:93 -msgid "" -"`starknet::info` provides helper functions to access the `ExecutionInfo` " -"fields in a more convenient way:" -msgstr "" -"`starknet::info` proporciona funciones auxiliares para acceder a los campos " -"`ExecutionInfo` de una manera más conveniente:" - -#: src/getting-started/basics/syscalls.md:94 -msgid "" -"- `get_execution_info() -> Box`\n" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" -msgstr "" -"- `get_execution_info() -> Box`\n" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" - -#: src/getting-started/basics/syscalls.md:102 -msgid "#### call_contract" -msgstr "#### call_contract" - -#: src/getting-started/basics/syscalls.md:104 -msgid "" -"```cairo\n" -"fn call_contract_syscall(\n" -" address: ContractAddress, entry_point_selector: felt252, calldata: " -"Span\n" -") -> SyscallResult>\n" -"```" -msgstr "" -"```cairo\n" -"fn call_contract_syscall(\n" -" address: ContractAddress, entry_point_selector: felt252, calldata: " -"Span\n" -") -> SyscallResult>\n" -"```" - -#: src/getting-started/basics/syscalls.md:110 -msgid "" -"Call a contract at `address` with the given `entry_point_selector` and " -"`calldata`.\n" -"Failure can't be caught for this syscall, if the call fails, the whole " -"transaction will revert." -msgstr "" -"Llame a un contrato en la`address` con el `entry_point_selector` y " -"`calldata`proporcionados.\n" -"No se puede detectar una falla en esta llamada al sistema; si la llamada " -"falla, se revertirá toda la transacción." - -#: src/getting-started/basics/syscalls.md:113 -msgid "" -"This is not the recommended way to call a contract. Instead, use the " -"dispatcher generated from the contract interface as shown in the [Calling " -"other contracts](../interacting/calling_other_contracts.md)." -msgstr "" -"Esta no es la forma recomendada de llamar a un contrato. En su lugar, " -"utilice el despachador (dispatcher) generado desde la interfaz del contrato " -"como se muestra en [Llamar a otros contratos] (../interacting/" -"calling_other_contracts.md)." - -#: src/getting-started/basics/syscalls.md:115 -msgid "" -msgstr "" - -#: src/getting-started/basics/syscalls.md:117 -msgid "#### deploy" -msgstr "#### deploy" - -#: src/getting-started/basics/syscalls.md:119 -msgid "" -"```cairo\n" -"fn deploy_syscall(\n" -" class_hash: ClassHash,\n" -" contract_address_salt: felt252,\n" -" calldata: Span,\n" -" deploy_from_zero: bool,\n" -") -> SyscallResult<(ContractAddress, Span::)>\n" -"```" -msgstr "" -"```cairo\n" -"fn deploy_syscall(\n" -" class_hash: ClassHash,\n" -" contract_address_salt: felt252,\n" -" calldata: Span,\n" -" deploy_from_zero: bool,\n" -") -> SyscallResult<(ContractAddress, Span::)>\n" -"```" - -#: src/getting-started/basics/syscalls.md:128 -msgid "" -"Deploy a new contract of the predeclared class `class_hash` with " -"`calldata`.\n" -"The success result is a tuple containing the deployed contract address and " -"the return value of the constructor." -msgstr "" -"Implemente un nuevo contrato de la clase predeclarada `class_hash` con " -"`calldata`.\n" -"El resultado exitoso es una tupla que contiene la dirección del contrato " -"implementado y el valor de retorno del constructor." - -#: src/getting-started/basics/syscalls.md:131 -msgid "" -"`contract_address_salt` and `deploy_from_zero` are used to compute the " -"contract address." -msgstr "" -"`contract_address_salt` y `deploy_from_zero` se utilizan para calcular la " -"dirección del contrato." - -#: src/getting-started/basics/syscalls.md:133 -msgid "" -"Example of the usage of the `deploy` syscall from the [Factory pattern](../" -"interacting/factory.md):" -msgstr "" -"Ejemplo del uso de la llamada al sistema `deploy` del [Factory pattern] (../" -"interacting/factory.md):" - -#: src/getting-started/basics/syscalls.md:135 -msgid "" -"```cairo\n" -"# use starknet::{ContractAddress, ClassHash};\n" -"# \n" -"# #[starknet::interface]\n" -"# trait ICounterFactory {\n" -"# /// Create a new counter contract from stored arguments\n" -"# fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"# \n" -"# /// Create a new counter contract from the given arguments\n" -"# fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"# \n" -"# /// Update the argument\n" -"# fn update_init_value(ref self: TContractState, init_value: u128);\n" -"# \n" -"# /// Update the class hash of the Counter contract to deploy when " -"creating a new counter\n" -"# fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod CounterFactory {\n" -"# use starknet::{ContractAddress, ClassHash};\n" -"# use starknet::syscalls::deploy_syscall;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {\n" -"# /// Store the constructor arguments of the contract to deploy\n" -"# init_value: u128,\n" -"# /// Store the class hash of the contract to deploy\n" -"# counter_class_hash: ClassHash,\n" -"# }\n" -"# \n" -"# #[constructor]\n" -"# fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -"# self.init_value.write(init_value);\n" -"# self.counter_class_hash.write(class_hash);\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"# \n" -"# fn create_counter(ref self: ContractState) -> ContractAddress {\n" -"# self.create_counter_at(self.init_value.read())\n" -"# }\n" -"# \n" -"# fn update_init_value(ref self: ContractState, init_value: u128) {\n" -"# self.init_value.write(init_value);\n" -"# }\n" -"# \n" -"# fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -"# self.counter_class_hash.write(counter_class_hash);\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" -msgstr "" -"```cairo\n" -"# use starknet::{ContractAddress, ClassHash};\n" -"# \n" -"# #[starknet::interface]\n" -"# trait ICounterFactory {\n" -"# /// Create a new counter contract from stored arguments\n" -"# fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"# \n" -"# /// Create a new counter contract from the given arguments\n" -"# fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"# \n" -"# /// Update the argument\n" -"# fn update_init_value(ref self: TContractState, init_value: u128);\n" -"# \n" -"# /// Update the class hash of the Counter contract to deploy when " -"creating a new counter\n" -"# fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod CounterFactory {\n" -"# use starknet::{ContractAddress, ClassHash};\n" -"# use starknet::syscalls::deploy_syscall;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {\n" -"# /// Store the constructor arguments of the contract to deploy\n" -"# init_value: u128,\n" -"# /// Store the class hash of the contract to deploy\n" -"# counter_class_hash: ClassHash,\n" -"# }\n" -"# \n" -"# #[constructor]\n" -"# fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -"# self.init_value.write(init_value);\n" -"# self.counter_class_hash.write(class_hash);\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"# \n" -"# fn create_counter(ref self: ContractState) -> ContractAddress {\n" -"# self.create_counter_at(self.init_value.read())\n" -"# }\n" -"# \n" -"# fn update_init_value(ref self: ContractState, init_value: u128) {\n" -"# self.init_value.write(init_value);\n" -"# }\n" -"# \n" -"# fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -"# self.counter_class_hash.write(counter_class_hash);\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" - -#: src/getting-started/basics/syscalls.md:204 -msgid "#### emit_event" -msgstr "#### emit_event" - -#: src/getting-started/basics/syscalls.md:206 -msgid "" -"```cairo\n" -"fn emit_event_syscall(\n" -" keys: Span, data: Span\n" -") -> SyscallResult<()>\n" -"```" -msgstr "" -"```cairo\n" -"fn emit_event_syscall(\n" -" keys: Span, data: Span\n" -") -> SyscallResult<()>\n" -"```" - -#: src/getting-started/basics/syscalls.md:212 -msgid "Emit an event with the given `keys` and `data`." -msgstr "Emite un evento con las `keys` y los `data` proporcionados." - -#: src/getting-started/basics/syscalls.md:214 -msgid "" -"Example of the usage of the `emit_event` syscall from the [Events](../basics/" -"events.md) chapter:" -msgstr "" -"Ejemplo del uso de la llamada al sistema `emit_event` del capítulo [Eventos]" -"(../basics/events.md):" - -#: src/getting-started/basics/syscalls.md:216 -msgid "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait IEventCounter {\n" -"# fn increment(ref self: TContractState);\n" -"# }\n" -"# #[starknet::contract]\n" -"# mod EventCounter {\n" -"# use starknet::{get_caller_address, ContractAddress};\n" -"# #[storage]\n" -"# struct Storage {\n" -"# // Counter value\n" -"# counter: u128,\n" -"# }\n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# // The event enum must be annotated with the `#[event]` attribute.\n" -"# // It must also derive the `Drop` and `starknet::Event` traits.\n" -"# enum Event {\n" -"# CounterIncreased: CounterIncreased,\n" -"# UserIncreaseCounter: UserIncreaseCounter\n" -"# }\n" -"# \n" -"# // By deriving the `starknet::Event` trait, we indicate to the " -"compiler that\n" -"# // this struct will be used when emitting events.\n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct CounterIncreased {\n" -"# amount: u128\n" -"# }\n" -"# \n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct UserIncreaseCounter {\n" -"# // The `#[key]` attribute indicates that this event will be " -"indexed.\n" -"# #[key]\n" -"# user: ContractAddress,\n" -"# new_value: u128,\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl EventCounter of super::IEventCounter {\n" -"# fn increment(ref self: ContractState) {\n" -"# let mut counter = self.counter.read();\n" -"# counter += 1;\n" -"# self.counter.write(counter);\n" -"# // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" -msgstr "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait IEventCounter {\n" -"# fn increment(ref self: TContractState);\n" -"# }\n" -"# #[starknet::contract]\n" -"# mod EventCounter {\n" -"# use starknet::{get_caller_address, ContractAddress};\n" -"# #[storage]\n" -"# struct Storage {\n" -"# // Counter value\n" -"# counter: u128,\n" -"# }\n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# // The event enum must be annotated with the `#[event]` attribute.\n" -"# // It must also derive the `Drop` and `starknet::Event` traits.\n" -"# enum Event {\n" -"# CounterIncreased: CounterIncreased,\n" -"# UserIncreaseCounter: UserIncreaseCounter\n" -"# }\n" -"# \n" -"# // By deriving the `starknet::Event` trait, we indicate to the " -"compiler that\n" -"# // this struct will be used when emitting events.\n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct CounterIncreased {\n" -"# amount: u128\n" -"# }\n" -"# \n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct UserIncreaseCounter {\n" -"# // The `#[key]` attribute indicates that this event will be " -"indexed.\n" -"# #[key]\n" -"# user: ContractAddress,\n" -"# new_value: u128,\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl EventCounter of super::IEventCounter {\n" -"# fn increment(ref self: ContractState) {\n" -"# let mut counter = self.counter.read();\n" -"# counter += 1;\n" -"# self.counter.write(counter);\n" -"# // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" - -#: src/getting-started/basics/syscalls.md:277 -msgid "" -"\n" -"" -msgstr "" -"\n" -"" - -#: src/getting-started/basics/syscalls.md:289 -msgid "#### library_call" -msgstr "#### library_call" - -#: src/getting-started/basics/syscalls.md:291 -msgid "" -"```cairo\n" -"fn library_call_syscall(\n" -" class_hash: ClassHash, function_selector: felt252, calldata: " -"Span\n" -") -> SyscallResult>\n" -"```" -msgstr "" -"```cairo\n" -"fn library_call_syscall(\n" -" class_hash: ClassHash, function_selector: felt252, calldata: " -"Span\n" -") -> SyscallResult>\n" -"```" - -#: src/getting-started/basics/syscalls.md:297 -msgid "" -"Call the function `function_selector` of the class `class_hash` with " -"`calldata`.\n" -"This is analogous to a delegate call in Ethereum, but only a single class is " -"called." -msgstr "" -"Llame a la función `function_selector` de la clase `class_hash` con " -"`calldata`.\n" -"Esto es análogo a una llamada de delegado en Ethereum, pero solo se llama a " -"una clase." - -#: src/getting-started/basics/syscalls.md:300 -msgid "" -msgstr "" - -#: src/getting-started/basics/syscalls.md:302 -msgid "#### send_message_to_L1" -msgstr "#### send_message_to_L1" - -#: src/getting-started/basics/syscalls.md:304 -msgid "" -"```cairo\n" -"fn send_message_to_l1_syscall(\n" -" to_address: felt252, payload: Span\n" -") -> SyscallResult<()>\n" -"```" -msgstr "" -"```cairo\n" -"fn send_message_to_l1_syscall(\n" -" to_address: felt252, payload: Span\n" -") -> SyscallResult<()>\n" -"```" - -#: src/getting-started/basics/syscalls.md:310 -msgid "" -"Send a message to the L1 contract at `to_address` with the given `payload`." -msgstr "Envíe un mensaje al contrato L1 en `to_address` con la `payload` dada." - -#: src/getting-started/basics/syscalls.md:312 -msgid "" -msgstr "" - -#: src/getting-started/basics/syscalls.md:314 -msgid "#### replace_class" -msgstr "#### replace_class" - -#: src/getting-started/basics/syscalls.md:316 -msgid "" -"```cairo\n" -"fn replace_class_syscall(\n" -" class_hash: ClassHash\n" -") -> SyscallResult<()>\n" -"```" -msgstr "" -"```cairo\n" -"fn replace_class_syscall(\n" -" class_hash: ClassHash\n" -") -> SyscallResult<()>\n" -"```" - -#: src/getting-started/basics/syscalls.md:322 -msgid "Replace the class of the calling contract with the class `class_hash`." -msgstr "Reemplace la clase del contrato de llamada con la clase `class_hash`." - -#: src/getting-started/basics/syscalls.md:324 -msgid "" -"This is used for contract upgrades. Here's an example from the [Upgradeable " -"Contract](../../applications/upgradeable_contract.md):" -msgstr "" -"Esto se utiliza para actualizaciones de contratos. Aquí hay un ejemplo del " -"[Contrato actualizable](../../applications/upgradeable_contract.md):" - -#: src/getting-started/basics/syscalls.md:326 -msgid "" -"```cairo\n" -"# use starknet::class_hash::ClassHash;\n" -"# \n" -"# #[starknet::interface]\n" -"# trait IUpgradeableContract {\n" -"# fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -"# fn version(self: @TContractState) -> u8;\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod UpgradeableContract_V0 {\n" -"# use starknet::class_hash::ClassHash;\n" -"# use starknet::SyscallResultTrait;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {}\n" -"# \n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# enum Event {\n" -"# Upgraded: Upgraded\n" -"# }\n" -"# \n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct Upgraded {\n" -"# implementation: ClassHash\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"# \n" -"# fn version(self: @ContractState) -> u8 {\n" -"# 0\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" -msgstr "" -"```cairo\n" -"# use starknet::class_hash::ClassHash;\n" -"# \n" -"# #[starknet::interface]\n" -"# trait IUpgradeableContract {\n" -"# fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -"# fn version(self: @TContractState) -> u8;\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod UpgradeableContract_V0 {\n" -"# use starknet::class_hash::ClassHash;\n" -"# use starknet::SyscallResultTrait;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {}\n" -"# \n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# enum Event {\n" -"# Upgraded: Upgraded\n" -"# }\n" -"# \n" -"# #[derive(Drop, starknet::Event)]\n" -"# struct Upgraded {\n" -"# implementation: ClassHash\n" -"# }\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"# \n" -"# fn version(self: @ContractState) -> u8 {\n" -"# 0\n" -"# }\n" -"# }\n" -"# }\n" -"# \n" -"# \n" -"```" - -#: src/getting-started/basics/syscalls.md:372 -msgid "" -"The new class code will only be used for future calls to the contract.\n" -"The current transaction containing the `replace_class` syscall will continue " -"to use the old class code. (You can explicitly use the new class code by " -"calling `call_contract` after the `replace_class` syscall in the same " -"transaction)" -msgstr "" -"El nuevo código de clase sólo se utilizará para futuras llamadas al " -"contrato.\n" -"La transacción actual que contiene la llamada al sistema `replace_class` " -"continuará usando el código de clase anterior. (Puede usar explícitamente el " -"nuevo código de clase llamando a `call_contract` después de la llamada al " -"sistema `replace_class` en la misma transacción)" - -#: src/getting-started/basics/syscalls.md:375 -msgid "#### storage_read" -msgstr "#### storage_read" - -#: src/getting-started/basics/syscalls.md:377 -msgid "" -"```cairo\n" -"fn storage_read_syscall(\n" -" address_domain: u32, address: StorageAddress,\n" -") -> SyscallResult\n" -"```" -msgstr "" -"```cairo\n" -"fn storage_read_syscall(\n" -" address_domain: u32, address: StorageAddress,\n" -") -> SyscallResult\n" -"```" - -#: src/getting-started/basics/syscalls.md:383 -msgid "" -"This low-level syscall is used to get the value in the storage of a specific " -"key at `address` in the `address_domain`." -msgstr "" -"Esta llamada al sistema de bajo nivel se utiliza para obtener el valor en el " -"almacenamiento de una clave específica en la`address` en el `address_domain`." - -#: src/getting-started/basics/syscalls.md:385 -msgid "" -"`address_domain` is used to distinguish between data availability modes.\n" -"Currently, only mode `ONCHAIN` (`0`) is supported." -msgstr "" -"`address_domain` se utiliza para distinguir entre modos de disponibilidad de " -"datos.\n" -"Actualmente, solo se admite el modo `ONCHAIN` (`0`)." - -#: src/getting-started/basics/syscalls.md:388 -msgid "#### storage_write" -msgstr "#### storage_write" - -#: src/getting-started/basics/syscalls.md:390 -msgid "" -"```cairo\n" -"fn storage_write_syscall(\n" -" address_domain: u32, address: StorageAddress, value: felt252\n" -") -> SyscallResult<()>\n" -"```" -msgstr "" -"```cairo\n" -"fn storage_write_syscall(\n" -" address_domain: u32, address: StorageAddress, value: felt252\n" -") -> SyscallResult<()>\n" -"```" - -#: src/getting-started/basics/syscalls.md:396 -msgid "" -"Similar to `storage_read`, this low-level syscall is used to write the value " -"`value` in the storage of a specific key at `address` in the " -"`address_domain`." -msgstr "" -"Similar a `storage_read`, esta llamada al sistema de bajo nivel se usa para " -"escribir el valor `value` en el almacenamiento de una clave específica en " -"`address` en el `address_domain`." - -#: src/getting-started/basics/syscalls.md:398 -msgid "## Documentation" -msgstr "## Documentación" - -#: src/getting-started/basics/syscalls.md:400 -msgid "" -"Syscalls are defined in [`starknet::syscall`](https://github.com/starkware-" -"libs/cairo/blob/ec14a5e2c484190ff40811c973a72a53739cedb7/corelib/src/" -"starknet/syscalls.cairo)" -msgstr "" -"Las llamadas al sistema se definen en [`starknet::syscall`](https://github." -"com/starkware-libs/cairo/blob/ec14a5e2c484190ff40811c973a72a53739cedb7/" -"corelib/src/starknet/syscalls.cairo)" - -#: src/getting-started/basics/syscalls.md:402 -msgid "" -"You can also read the [official documentation page](https://docs.starknet.io/" -"documentation/architecture_and_concepts/Smart_Contracts/system-calls-" -"cairo1/) for more details." -msgstr "" -"También puede leer la [página de documentación oficial](https://docs." -"starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-" -"calls-cairo1/) para obtener más detalles." - -#: src/getting-started/basics/syscalls.md:404 -msgid "" -"\n" -"\n" -"
Last change: 2023-12-21
" -msgstr "" -"\n" -"\n" -"
Last change: 2023-12-21
" - -#: src/getting-started/basics/storing-custom-types.md:1 -msgid "# Storing Custom Types" -msgstr "# Almacenamiento de Tipos Personalizados" - -#: src/getting-started/basics/storing-custom-types.md:3 -msgid "" -"While native types can be stored in a contract's storage without any " -"additional work, custom types require a bit more work. This is because at " -"compile time, the compiler does not know how to store custom types in " -"storage. To solve this, we need to implement the `Store` trait for our " -"custom type. Hopefully, we can just derive this trait for our custom type - " -"unless it contains arrays or dictionaries." -msgstr "" -"Si bien los tipos nativos se pueden almacenar en el almacenamiento de un " -"contrato sin ningún trabajo adicional, los tipos personalizados requieren un " -"poco más de trabajo. Esto se debe a que en el momento de la compilación, el " -"compilador no sabe cómo almacenar tipos personalizados en el almacenamiento. " -"Para resolver esto, necesitamos implementar el trait `Store`para nuestro " -"tipo personalizado. Con suerte, podremos derivar este trait para nuestro " -"tipo personalizado, a menos que contenga arrays o diccionarios." - -#: src/getting-started/basics/storing-custom-types.md:5 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoringCustomType {\n" -" fn set_person(ref self: TContractState, person: Person);\n" -"}\n" -"\n" -"// Deriving the starknet::Store trait\n" -"// allows us to store the `Person` struct in the contract's storage.\n" -"#[derive(Drop, Serde, Copy, starknet::Store)]\n" -"struct Person {\n" -" age: u8,\n" -" name: felt252\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoringCustomType {\n" -" use super::Person;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" person: Person\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoringCustomType of super::IStoringCustomType {\n" -" fn set_person(ref self: ContractState, person: Person) {\n" -" self.person.write(person);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoringCustomType {\n" -" fn set_person(ref self: TContractState, person: Person);\n" -"}\n" -"\n" -"// Deriving the starknet::Store trait\n" -"// allows us to store the `Person` struct in the contract's storage.\n" -"#[derive(Drop, Serde, Copy, starknet::Store)]\n" -"struct Person {\n" -" age: u8,\n" -" name: felt252\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoringCustomType {\n" -" use super::Person;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" person: Person\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoringCustomType of super::IStoringCustomType {\n" -" fn set_person(ref self: ContractState, person: Person) {\n" -" self.person.write(person);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/storing-custom-types.md:37 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/storing_custom_types/src/contract.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/storing_custom_types/src/contract.cairo)." - -#: src/getting-started/basics/custom-types-in-entrypoints.md:1 -msgid "# Custom types in entrypoints" -msgstr "# Tipos personalizados en entrypoints" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:3 -msgid "" -"Using custom types in entrypoints requires our type to implement the `Serde` " -"trait. This is because when calling an entrypoint, the input is sent as an " -"array of `felt252` to the entrypoint, and we need to be able to deserialize " -"it into our custom type. Similarly, when returning a custom type from an " -"entrypoint, we need to be able to serialize it into an array of `felt252`.\n" -"Thankfully, we can just derive the `Serde` trait for our custom type." -msgstr "" -"El uso de tipos personalizados en puntos de entrada requiere que nuestro " -"tipo implemente el trait `Serde`. Esto se debe a que cuando se llama a un " -"punto de entrada, la entrada se envía como una matriz de `felt252` al punto " -"de entrada y necesitamos poder deserializarla en nuestro tipo personalizado. " -"De manera similar, al devolver un tipo personalizado desde un punto de " -"entrada, debemos poder serializarlo en una matriz de `felt252`.\n" -"Afortunadamente, podemos derivar el trait `Serde` para nuestro tipo " -"personalizado." - -#: src/getting-started/basics/custom-types-in-entrypoints.md:6 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISerdeCustomType {\n" -" fn person_input(ref self: TContractState, person: SerdeCustomType::" -"Person);\n" -" fn person_output(self: @TContractState) -> SerdeCustomType::Person;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SerdeCustomType {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" // Deriving the `Serde` trait allows us to use\n" -" // the Person type as an entrypoint parameter and return value\n" -" #[derive(Drop, Serde)]\n" -" struct Person {\n" -" age: u8,\n" -" name: felt252\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SerdeCustomType of super::ISerdeCustomType {\n" -" fn person_input(ref self: ContractState, person: Person) {}\n" -"\n" -" fn person_output(self: @ContractState) -> Person {\n" -" Person { age: 10, name: 'Joe' }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISerdeCustomType {\n" -" fn person_input(ref self: TContractState, person: SerdeCustomType::" -"Person);\n" -" fn person_output(self: @TContractState) -> SerdeCustomType::Person;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SerdeCustomType {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" // Deriving the `Serde` trait allows us to use\n" -" // the Person type as an entrypoint parameter and return value\n" -" #[derive(Drop, Serde)]\n" -" struct Person {\n" -" age: u8,\n" -" name: felt252\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SerdeCustomType of super::ISerdeCustomType {\n" -" fn person_input(ref self: ContractState, person: Person) {}\n" -"\n" -" fn person_output(self: @ContractState) -> Person {\n" -" Person { age: 10, name: 'Joe' }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:37 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/custom_type_serde/src/contract.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/custom_type_serde/src/contract.cairo)." - -#: src/getting-started/basics/documentation.md:1 -msgid "# Documentation" -msgstr "# Documentación" - -#: src/getting-started/basics/documentation.md:3 -msgid "" -"It's important to take the time to document your code. It will helps " -"developers and users to understand the contract and its functionalities." -msgstr "" -"Es importante tomarse el tiempo para documentar su código. Ayudará a los " -"desarrolladores y usuarios a comprender el contrato y sus funcionalidades." - -#: src/getting-started/basics/documentation.md:5 -msgid "In Cairo, you can add comments with `//`." -msgstr "En Cairo, puedes agregar comentarios con `//`." - -#: src/getting-started/basics/documentation.md:7 -msgid "### Best Practices:" -msgstr "## Mejores Prácticas:" - -#: src/getting-started/basics/documentation.md:9 -msgid "" -"Since Cairo 1, the community has adopted a [Rust-like documentation style]" -"(https://doc.rust-lang.org/rust-by-example/meta/doc.html)." -msgstr "" -"Desde Cairo 1, la comunidad ha adoptado un [estilo de documentación similar " -"a [Rust-like documentation style](https://doc.rust-lang.org/rust-by-example/" -"meta/doc.html)." - -#: src/getting-started/basics/documentation.md:11 -msgid "### Contract Interface:" -msgstr "## Interfaz de Contrato:" - -#: src/getting-started/basics/documentation.md:13 -msgid "" -"In smart contracts, you will often have a trait that defines the contract's " -"interface (with `#[starknet::interface]`).\n" -"This is the perfect place to include detailed documentation explaining the " -"purpose and functionality of the contract entry points. You can follow this " -"template:" -msgstr "" -"En los smart contracts, a menudo tendrá un trait que define la interfaz del " -"contrato (con `#[starknet::interface]`).\n" -"Este es el lugar perfecto para incluir documentación detallada que explique " -"el propósito y la funcionalidad de los puntos de entrada del contrato. " -"Puedes seguir esta plantilla:" - -#: src/getting-started/basics/documentation.md:16 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IContract {\n" -" /// High-level description of the function\n" -" ///\n" -" /// # Arguments\n" -" ///\n" -" /// * `arg_1` - Description of the argument\n" -" /// * `arg_n` - ...\n" -" ///\n" -" /// # Returns\n" -" ///\n" -" /// High-level description of the return value\n" -" fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IContract {\n" -" /// High-level description of the function\n" -" ///\n" -" /// # Arguments\n" -" ///\n" -" /// * `arg_1` - Description of the argument\n" -" /// * `arg_n` - ...\n" -" ///\n" -" /// # Returns\n" -" ///\n" -" /// High-level description of the return value\n" -" fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return;\n" -"}\n" -"```" - -#: src/getting-started/basics/documentation.md:33 -msgid "" -"Keep in mind that this should not describe the implementation details of the " -"function, but rather the high-level purpose and functionality of the " -"contract from the perspective of a user." -msgstr "" -"Tenga en cuenta que esto no debe describir los detalles de implementación de " -"la función, sino más bien el propósito de alto nivel y la funcionalidad del " -"contrato desde la perspectiva de un usuario." - -#: src/getting-started/basics/documentation.md:35 -msgid "### Implementation Details:" -msgstr "### Detalles de Implementación:" - -#: src/getting-started/basics/documentation.md:37 -msgid "" -"When writing the logic of the contract, you can add comments to describe the " -"technical implementation details of the functions." -msgstr "" -"Al escribir la lógica del contrato, puede agregar comentarios para describir " -"los detalles técnicos de implementación de las funciones." - -#: src/getting-started/basics/documentation.md:39 -msgid "" -"> Avoid over-commenting: Comments should provide additional value and " -"clarity." -msgstr "" -"> Evite comentarios excesivos: Los comentarios deben aportar valor y " -"claridad adicionales." - -#: src/getting-started/basics/documentation.md:41 -msgid "
Last change: 2023-12-05
" -msgstr "
Último cambio: 2023-12-05
" - -#: src/getting-started/interacting/interacting.md:1 -msgid "# Deploy and interact with contracts" -msgstr "# Desplegar contratos e interactuar con ellos" - -#: src/getting-started/interacting/interacting.md:3 -msgid "In this chapter, we will see how to deploy and interact with contracts." -msgstr "" -"En este capítulo, veremos cómo implementar e interactuar con contratos." - -#: src/getting-started/interacting/interacting.md:4 -msgid "
Last change: 2023-10-19
" -msgstr "
Último cambio: 2023-10-19
" - -#: src/getting-started/interacting/interfaces-traits.md:1 -msgid "# Contract interfaces and Traits generation" -msgstr "# Interfaces de Contratos y generación de Traits" - -#: src/getting-started/interacting/interfaces-traits.md:3 -msgid "" -"Contract interfaces define the structure and behavior of a contract, serving " -"as the contract's public ABI. They list all the function signatures that a " -"contract exposes. For a detailed explanation of interfaces, you can refer to " -"the [Cairo Book](https://book.cairo-lang.org/ch99-01-02-a-simple-contract." -"html)." -msgstr "" -"Las interfaces de contrato definen la estructura y el comportamiento de un " -"contrato y sirven como la ABI pública del contrato. Enumeran todas las " -"firmas de funciones que expone un contrato. Para obtener una explicación " -"detallada de las interfaces, puede consultar el [Cairo Book](https://book." -"cairo-lang.org/ch99-01-02-a-simple-contract.html)." - -#: src/getting-started/interacting/interfaces-traits.md:5 -msgid "" -"In cairo, to specify the interface you need to define a trait annotated with " -"`#[starknet::interface]` and then implement that trait in the contract." -msgstr "" -"En Cairo, para especificar la interfaz es necesario definir un trait anotado " -"con `#[starknet::interface]` y luego implementar ese trait en el contrato." - -#: src/getting-started/interacting/interfaces-traits.md:7 -msgid "" -"When a function needs to access the contract state, it must have a `self` " -"parameter of type `ContractState`. This implies that the corresponding " -"function signature in the interface trait must also take a `TContractState` " -"type as a parameter. It's important to note that every function in the " -"contract interface must have this `self` parameter of type `TContractState`." -msgstr "" -"Cuando una función necesita acceder al estado del contrato, debe tener un " -"parámetro `self` de tipo `ContractState`. Esto implica que la firma de " -"función correspondiente en el trait de interfaz también debe tomar un tipo " -"`TContractState` como parámetro. Es importante tener en cuenta que todas las " -"funciones de la interfaz del contrato deben tener este parámetro `self` de " -"tipo `TContractState`." - -#: src/getting-started/interacting/interfaces-traits.md:9 -msgid "" -"You can use the `#[generate_trait]` attribute to implicitly generate the " -"trait for a specific implementation block. This attribute automatically " -"generates a trait with the same functions as the ones in the implemented " -"block, replacing the `self` parameter with a generic `TContractState` " -"parameter. However, you will need to annotate the block with the " -"`#[abi(per_item)]` attribute, and each function with the appropriate " -"attribute depending on whether it's an external function, a constructor or a " -"l1 handler." -msgstr "" -"Puedes utilizar el atributo `#[generate_trait]` para generar implícitamente " -"el trait para un bloque de implementación específico. Este atributo genera " -"automáticamente un trait con las mismas funciones que las del bloque " -"implementado, sustituyendo el parámetro `self` por un parámetro genérico " -"`TContractState`. Sin embargo, tendrás que anotar el bloque con el atributo " -"`#[abi(per_item)]`, y cada función con el atributo apropiado dependiendo de " -"si es una función externa, un constructor o un manejador l1." - -#: src/getting-started/interacting/interfaces-traits.md:11 -msgid "In summary, there's two ways to handle interfaces:" -msgstr "En resumen, hay dos formas de manejar las interfaces:" - -#: src/getting-started/interacting/interfaces-traits.md:13 -msgid "" -"- Explicitly, by defining a trait annoted with `#[starknet::interface]`\n" -"- Implicitly, by using `#[generate_trait]` combined with the " -"#[abi(per_item)]` attributes, and annotating each function inside the " -"implementation block with the appropriate attribute." -msgstr "" -"- Explícitamente, definiendo un trait anotado con `#[starknet::interface]`\n" -"- Implícitamente, usando `#[generate_trait]` combinado con los atributos " -"#[abi(per_item)]` y anotando cada función dentro del bloque de " -"implementación con el atributo apropiado." - -#: src/getting-started/interacting/interfaces-traits.md:16 -msgid "## Explicit interface" -msgstr "## Interfaz explícita" - -#: src/getting-started/interacting/interfaces-traits.md:18 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExplicitInterfaceContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ExplicitInterfaceContract of super::" -"IExplicitInterfaceContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExplicitInterfaceContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ExplicitInterfaceContract of super::" -"IExplicitInterfaceContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:45 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/explicit.cairo)." -msgstr "" -"Juega con este contrato en[Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/explicit.cairo)." - -#: src/getting-started/interacting/interfaces-traits.md:47 -msgid "## Implicit interface" -msgstr "## Interfaz implícita" - -#: src/getting-started/interacting/interfaces-traits.md:49 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ImplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(per_item)]\n" -" #[generate_trait]\n" -" impl ImplicitInterfaceContract of IImplicitInterfaceContract {\n" -" #[external(v0)]\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" #[external(v0)]\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ImplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(per_item)]\n" -" #[generate_trait]\n" -" impl ImplicitInterfaceContract of IImplicitInterfaceContract {\n" -" #[external(v0)]\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" #[external(v0)]\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:73 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit.cairo)." - -#: src/getting-started/interacting/interfaces-traits.md:75 -msgid "" -"> Note: You can import an implicitly generated contract interface with `use " -"contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not " -"be generated automatically." -msgstr "" -"> Nota: Puede importar una interfaz de contrato generada implícitamente con " -"`use contract::{GeneratedContractInterface}`. Sin embargo, el `Dispatcher` " -"no se generará automáticamente." - -#: src/getting-started/interacting/interfaces-traits.md:77 -msgid "## Internal functions" -msgstr "## Funciones internas" - -#: src/getting-started/interacting/interfaces-traits.md:79 -msgid "" -"You can also use `#[generate_trait]` for your internal functions.\n" -"Since this trait is generated in the context of the contract, you can define " -"pure functions as well (functions without the `self` parameter)." -msgstr "" -"También puedes usar `#[generate_trait]` para tus funciones internas.\n" -"Dado que este trait se genera en el contexto del contrato, también puedes " -"definir funciones puras (funciones sin el parámetro `self`)." - -#: src/getting-started/interacting/interfaces-traits.md:82 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IImplicitInternalContract {\n" -" fn add(ref self: TContractState, nb: u32);\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_const(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ImplicitInternalContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalFunctions of InternalFunctionsTrait {\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" fn get_const() -> u32 {\n" -" 42\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.set_value(0);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ImplicitInternalContract of super::" -"IImplicitInternalContract {\n" -" fn add(ref self: ContractState, nb: u32) {\n" -" self.set_value(self.value.read() + nb);\n" -" }\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" fn get_const(self: @ContractState) -> u32 {\n" -" self.get_const()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IImplicitInternalContract {\n" -" fn add(ref self: TContractState, nb: u32);\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_const(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ImplicitInternalContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalFunctions of InternalFunctionsTrait {\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" fn get_const() -> u32 {\n" -" 42\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.set_value(0);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ImplicitInternalContract of super::" -"IImplicitInternalContract {\n" -" fn add(ref self: ContractState, nb: u32) {\n" -" self.set_value(self.value.read() + nb);\n" -" }\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" fn get_const(self: @ContractState) -> u32 {\n" -" self.get_const()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:127 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit_internal." -"cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit_internal." -"cairo)." - -#: src/getting-started/interacting/calling_other_contracts.md:1 -msgid "# Calling other contracts" -msgstr "## Llamar a otros contratos" - -#: src/getting-started/interacting/calling_other_contracts.md:3 -msgid "There are two different ways to call other contracts in Cairo." -msgstr "Hay dos formas diferentes de llamar a otros contratos en Cairo." - -#: src/getting-started/interacting/calling_other_contracts.md:5 -msgid "" -"The easiest way to call other contracts is by using the dispatcher of the " -"contract you want to call.\n" -"You can read more about Dispatchers in the [Cairo Book](https://book.cairo-" -"lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-calls." -"html#contract-dispatcher)" -msgstr "" -"La forma más sencilla de llamar a otros contratos es utilizar el dispatcher " -"del contrato al que desea llamar.\n" -"Puede leer más sobre los dispatcher en el [Libro de El Cairo](https://book." -"cairo-lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-" -"calls.html#contract-dispatcher)" - -#: src/getting-started/interacting/calling_other_contracts.md:8 -msgid "" -"The other way is to use the `starknet::call_contract_syscall` syscall " -"yourself. However, this method is not recommended." -msgstr "" -"La otra forma es utilizar la llamada al sistema `starknet::" -"call_contract_syscall`. Sin embargo, este método no es recomendable." - -#: src/getting-started/interacting/calling_other_contracts.md:10 -msgid "" -"In order to call other contracts using dispatchers, you will need to define " -"the called contract's interface as a trait annotated with the `#[starknet::" -"interface]` attribute, and then import the `IContractDispatcher` and " -"`IContractDispatcherTrait` items in your contract." -msgstr "" -"Para llamar a otros contratos utilizando dispatchers, tendrás que definir la " -"interfaz del contrato llamado como un trait anotado con el atributo " -"`#[starknet::interface]`, y luego importar los elementos " -"`IContractDispatcher` e `IContractDispatcherTrait` en tu contrato." - -#: src/getting-started/interacting/calling_other_contracts.md:12 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Callee {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICalleeImpl of super::ICallee {\n" -" fn set_value(ref self: ContractState, value: u128) -> u128 {\n" -" self.value.write(value);\n" -" value\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Callee {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICalleeImpl of super::ICallee {\n" -" fn set_value(ref self: ContractState, value: u128) -> u128 {\n" -" self.value.write(value);\n" -" value\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/calling_other_contracts.md:34 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x015c3Bb6D0DE26b64FEAF9A8f4655CfADb5c128bF4510398972704ee12775DB1) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/callee.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x015c3Bb6D0DE26b64FEAF9A8f4655CfADb5c128bF4510398972704ee12775DB1) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/callee.cairo)." - -#: src/getting-started/interacting/calling_other_contracts.md:36 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"// We need to have the interface of the callee contract defined\n" -"// so that we can import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICaller {\n" -" fn set_value_from_address(ref self: TContractState, addr: " -"ContractAddress, value: u128);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Caller {\n" -" // We import the Dispatcher of the called contract\n" -" use super::{ICalleeDispatcher, ICalleeDispatcherTrait};\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICallerImpl of super::ICaller {\n" -" fn set_value_from_address(ref self: ContractState, addr: " -"ContractAddress, value: u128) {\n" -" ICalleeDispatcher { contract_address: addr }.set_value(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"// We need to have the interface of the callee contract defined\n" -"// so that we can import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICaller {\n" -" fn set_value_from_address(ref self: TContractState, addr: " -"ContractAddress, value: u128);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Caller {\n" -" // We import the Dispatcher of the called contract\n" -" use super::{ICalleeDispatcher, ICalleeDispatcherTrait};\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICallerImpl of super::ICaller {\n" -" fn set_value_from_address(ref self: ContractState, addr: " -"ContractAddress, value: u128) {\n" -" ICalleeDispatcher { contract_address: addr }.set_value(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/calling_other_contracts.md:68 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x05fa8aF796343d2f22c53C17149386b67B7AC4aB52D9e308Aa507C185aA44778) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/caller.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x05fa8aF796343d2f22c53C17149386b67B7AC4aB52D9e308Aa507C185aA44778) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/caller.cairo)." - -#: src/getting-started/interacting/factory.md:1 -msgid "# Factory Pattern" -msgstr "# Patrón de la Factory" - -#: src/getting-started/interacting/factory.md:3 -msgid "" -"The factory pattern is a well known pattern in object oriented programming. " -"It provides an abstraction on how to instantiate a class. " -msgstr "" -"El patrón de factory es un patrón bien conocido en la programación orientada " -"a objetos. Proporciona una abstracción sobre cómo instanciar una clase. " - -#: src/getting-started/interacting/factory.md:5 -msgid "" -"In the case of smart contracts, we can use this pattern by defining a " -"factory contract that have the sole responsibility of creating and managing " -"other contracts." -msgstr "" -"En el caso de los smart contracts, podemos utilizar este patrón definiendo " -"un contrato de factory que tenga la responsabilidad exclusiva de crear y " -"gestionar otros contratos." - -#: src/getting-started/interacting/factory.md:7 -msgid "## Class hash and contract instance" -msgstr "# Class hash e instancia de contrato" - -#: src/getting-started/interacting/factory.md:9 -msgid "" -"In Starknet, there's a separation between contract's classes and instances. " -"A contract class serves as a blueprint, defined by the underling Cairo " -"bytecode, contract's entrypoints, ABI and Sierra program hash. The contract " -"class is identified by a class hash. When you want to add a new class to the " -"network, you first need to declare it." -msgstr "" -"En Starknet, hay una separación entre las clases de contrato y las " -"instancias. Una clase de contrato sirve como plano, definido por el código " -"de bytes subyacente de Cairo, los puntos de entrada del contrato, la ABI y " -"el hash del programa Sierra. La clase del contrato es identificada por un " -"hash de clase. Cuando se desea agregar una nueva clase a la red, primero es " -"necesario declararla." - -#: src/getting-started/interacting/factory.md:11 -msgid "" -"When deploying a contract, you need to specify the class hash of the " -"contract you want to deploy. Each instance of a contract has their own " -"storage regardless of the class hash." -msgstr "" -"Cuando se despliega un contrato, es necesario especificar el hash de clase " -"del contrato que se desea desplegar. Cada instancia de un contrato tiene su " -"propio almacenamiento independientemente del hash de clase." - -#: src/getting-started/interacting/factory.md:13 -msgid "" -"Using the factory pattern, we can deploy multiple instances of the same " -"contract class and handle upgrades easily." -msgstr "" -"Utilizando el patrón de factory, podemos desplegar múltiples instancias de " -"la misma clase de contrato y manejar las actualizaciones fácilmente." - -#: src/getting-started/interacting/factory.md:15 -msgid "## Minimal example" -msgstr "## Ejemplo mínimo" - -#: src/getting-started/interacting/factory.md:17 -msgid "" -"Here's a minimal example of a factory contract that deploy the " -"`SimpleCounter` contract:" -msgstr "" -"He aquí un ejemplo mínimo de un contrato de factory que despliega el " -"contrato `SimpleCounter`:" - -#: src/getting-started/interacting/factory.md:19 -msgid "" -"```cairo\n" -"use starknet::{ContractAddress, ClassHash};\n" -"\n" -"#[starknet::interface]\n" -"trait ICounterFactory {\n" -" /// Create a new counter contract from stored arguments\n" -" fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"\n" -" /// Create a new counter contract from the given arguments\n" -" fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"\n" -" /// Update the argument\n" -" fn update_init_value(ref self: TContractState, init_value: u128);\n" -"\n" -" /// Update the class hash of the Counter contract to deploy when " -"creating a new counter\n" -" fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CounterFactory {\n" -" use starknet::{ContractAddress, ClassHash};\n" -" use starknet::syscalls::deploy_syscall;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" /// Store the constructor arguments of the contract to deploy\n" -" init_value: u128,\n" -" /// Store the class hash of the contract to deploy\n" -" counter_class_hash: ClassHash,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -" self.init_value.write(init_value);\n" -" self.counter_class_hash.write(class_hash);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"\n" -" fn create_counter(ref self: ContractState) -> ContractAddress {\n" -" self.create_counter_at(self.init_value.read())\n" -" }\n" -"\n" -" fn update_init_value(ref self: ContractState, init_value: u128) {\n" -" self.init_value.write(init_value);\n" -" }\n" -"\n" -" fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -" self.counter_class_hash.write(counter_class_hash);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::{ContractAddress, ClassHash};\n" -"\n" -"#[starknet::interface]\n" -"trait ICounterFactory {\n" -" /// Create a new counter contract from stored arguments\n" -" fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"\n" -" /// Create a new counter contract from the given arguments\n" -" fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"\n" -" /// Update the argument\n" -" fn update_init_value(ref self: TContractState, init_value: u128);\n" -"\n" -" /// Update the class hash of the Counter contract to deploy when " -"creating a new counter\n" -" fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CounterFactory {\n" -" use starknet::{ContractAddress, ClassHash};\n" -" use starknet::syscalls::deploy_syscall;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" /// Store the constructor arguments of the contract to deploy\n" -" init_value: u128,\n" -" /// Store the class hash of the contract to deploy\n" -" counter_class_hash: ClassHash,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -" self.init_value.write(init_value);\n" -" self.counter_class_hash.write(class_hash);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"\n" -" fn create_counter(ref self: ContractState) -> ContractAddress {\n" -" self.create_counter_at(self.init_value.read())\n" -" }\n" -"\n" -" fn update_init_value(ref self: ContractState, init_value: u128) {\n" -" self.init_value.write(init_value);\n" -" }\n" -"\n" -" fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -" self.counter_class_hash.write(counter_class_hash);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/factory.md:86 -msgid "" -"" -msgstr "" -"" - -#: src/getting-started/interacting/factory.md:88 -msgid "" -"This factory can be used to deploy multiple instances of the `SimpleCounter` " -"contract by calling the `create_counter` and `create_counter_at` functions." -msgstr "" -"Esta fábrica se puede utilizar para desplegar múltiples instancias del " -"contrato `SimpleCounter` llamando a las funciones `create_counter` y " -"`create_counter_at`." - -#: src/getting-started/interacting/factory.md:90 -msgid "" -"The `SimpleCounter` class hash is stored inside the factory, and can be " -"upgraded with the `update_counter_class_hash` function which allows to reuse " -"the same factory contract when the `SimpleCounter` contract is upgraded." -msgstr "" -"El hash de la clase `SimpleCounter` se almacena dentro de la fábrica, y se " -"puede actualizar con la función `update_counter_class_hash` que permite " -"reutilizar el mismo contrato de fábrica cuando se actualiza el contrato " -"`SimpleCounter`." - -#: src/getting-started/interacting/factory.md:92 -msgid "" -"This minimal example lacks several useful features such as access control, " -"tracking of deployed contracts, events, ..." -msgstr "" -"Este ejemplo mínimo carece de varias funciones útiles, como el control de " -"acceso, el seguimiento de los contratos desplegados, los eventos, ..." - -#: src/getting-started/interacting/factory.md:94 -msgid "" -"\n" -"\n" -"
Last change: 2023-12-21
" -msgstr "" -"\n" -"\n" -"
Último cambio: 2023-12-21
" - -#: src/getting-started/testing/contract-testing.md:1 -msgid "# Contract Testing" -msgstr "# Testing de Contrato" - -#: src/getting-started/testing/contract-testing.md:3 -msgid "" -"Testing plays a crucial role in software development, especially for smart " -"contracts. In this section, we'll guide you through the basics of testing a " -"smart contract on Starknet with `scarb`." -msgstr "" -"Las pruebas juegan un papel crucial en el desarrollo de software, " -"especialmente para los smart contracts. En esta sección, te guiaremos a " -"través de los conceptos básicos de las pruebas de un smart contracts en " -"Starknet con `scarb`." - -#: src/getting-started/testing/contract-testing.md:5 -msgid "Let's start with a simple smart contract as an example:" -msgstr "Empecemos con un simple contrato inteligente como ejemplo:" - -#: src/getting-started/testing/contract-testing.md:6 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_owner(self: @TContractState) -> ContractAddress;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleContract {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32,\n" -" owner: ContractAddress\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, initial_value: u32) {\n" -" self.value.write(initial_value);\n" -" self.owner.write(get_caller_address());\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleContract of super::ISimpleContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn get_owner(self: @ContractState) -> ContractAddress {\n" -" self.owner.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" assert(self.owner.read() == get_caller_address(), 'Not owner');\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_owner(self: @TContractState) -> ContractAddress;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleContract {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32,\n" -" owner: ContractAddress\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, initial_value: u32) {\n" -" self.value.write(initial_value);\n" -" self.owner.write(get_caller_address());\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleContract of super::ISimpleContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn get_owner(self: @ContractState) -> ContractAddress {\n" -" self.owner.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" assert(self.owner.read() == get_caller_address(), 'Not owner');\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/testing/contract-testing.md:50 -msgid "Now, take a look at the tests for this contract:" -msgstr "Ahora, eche un vistazo a las pruebas de este contrato:" - -#: src/getting-started/testing/contract-testing.md:51 -msgid "" -"```cairo\n" -"#[cfg(test)]\n" -"mod tests {\n" -" // Import the interface and dispatcher to be able to interact with the " -"contract.\n" -" use testing_how_to::contract::{\n" -" ISimpleContract, SimpleContract, ISimpleContractDispatcher, " -"ISimpleContractDispatcherTrait\n" -" };\n" -"\n" -" // Import the deploy syscall to be able to deploy the contract.\n" -" use starknet::class_hash::Felt252TryIntoClassHash;\n" -" use starknet::{\n" -" deploy_syscall, ContractAddress, get_caller_address, " -"get_contract_address,\n" -" contract_address_const\n" -" };\n" -"\n" -" // Use starknet test utils to fake the transaction context.\n" -" use starknet::testing::{set_caller_address, set_contract_address};\n" -"\n" -" // Deploy the contract and return its dispatcher.\n" -" fn deploy(initial_value: u32) -> ISimpleContractDispatcher {\n" -" // Set up constructor arguments.\n" -" let mut calldata = ArrayTrait::new();\n" -" initial_value.serialize(ref calldata);\n" -"\n" -" // Declare and deploy\n" -" let (contract_address, _) = deploy_syscall(\n" -" SimpleContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -" )\n" -" .unwrap();\n" -"\n" -" // Return the dispatcher.\n" -" // The dispatcher allows to interact with the contract based on its " -"interface.\n" -" ISimpleContractDispatcher { contract_address }\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_deploy() {\n" -" let initial_value: u32 = 10;\n" -" let contract = deploy(initial_value);\n" -"\n" -" assert(contract.get_value() == initial_value, 'wrong initial " -"value');\n" -" assert(contract.get_owner() == get_contract_address(), 'wrong " -"owner');\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_as_owner() {\n" -" // Fake the caller address to address 1\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -" assert(contract.get_owner() == owner, 'wrong owner');\n" -"\n" -" // Fake the contract address to address 1\n" -" set_contract_address(owner);\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -"\n" -" assert(contract.get_value() == new_value, 'wrong value');\n" -" }\n" -"\n" -" #[test]\n" -" #[should_panic]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_not_owner() {\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -"\n" -" let not_owner = contract_address_const::<2>();\n" -" set_contract_address(not_owner);\n" -"\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[cfg(test)]\n" -"mod tests {\n" -" // Import the interface and dispatcher to be able to interact with the " -"contract.\n" -" use testing_how_to::contract::{\n" -" ISimpleContract, SimpleContract, ISimpleContractDispatcher, " -"ISimpleContractDispatcherTrait\n" -" };\n" -"\n" -" // Import the deploy syscall to be able to deploy the contract.\n" -" use starknet::class_hash::Felt252TryIntoClassHash;\n" -" use starknet::{\n" -" deploy_syscall, ContractAddress, get_caller_address, " -"get_contract_address,\n" -" contract_address_const\n" -" };\n" -"\n" -" // Use starknet test utils to fake the transaction context.\n" -" use starknet::testing::{set_caller_address, set_contract_address};\n" -"\n" -" // Deploy the contract and return its dispatcher.\n" -" fn deploy(initial_value: u32) -> ISimpleContractDispatcher {\n" -" // Set up constructor arguments.\n" -" let mut calldata = ArrayTrait::new();\n" -" initial_value.serialize(ref calldata);\n" -"\n" -" // Declare and deploy\n" -" let (contract_address, _) = deploy_syscall(\n" -" SimpleContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -" )\n" -" .unwrap();\n" -"\n" -" // Return the dispatcher.\n" -" // The dispatcher allows to interact with the contract based on its " -"interface.\n" -" ISimpleContractDispatcher { contract_address }\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_deploy() {\n" -" let initial_value: u32 = 10;\n" -" let contract = deploy(initial_value);\n" -"\n" -" assert(contract.get_value() == initial_value, 'wrong initial " -"value');\n" -" assert(contract.get_owner() == get_contract_address(), 'wrong " -"owner');\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_as_owner() {\n" -" // Fake the caller address to address 1\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -" assert(contract.get_owner() == owner, 'wrong owner');\n" -"\n" -" // Fake the contract address to address 1\n" -" set_contract_address(owner);\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -"\n" -" assert(contract.get_value() == new_value, 'wrong value');\n" -" }\n" -"\n" -" #[test]\n" -" #[should_panic]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_not_owner() {\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -"\n" -" let not_owner = contract_address_const::<2>();\n" -" set_contract_address(not_owner);\n" -"\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/testing/contract-testing.md:132 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/testing_how_to/src/lib.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/testing_how_to/src/lib.cairo)." - -#: src/getting-started/testing/contract-testing.md:134 -msgid "" -"To define our test, we use scarb, which allows us to create a separate " -"module guarded with `#[cfg(test)]`. This ensures that the test module is " -"only compiled when running tests using `scarb test`." -msgstr "" -"Para definir nuestro test, usamos scarb, que nos permite crear un módulo " -"separado protegido con `#[cfg(test)]`. Esto asegura que el módulo de prueba " -"sólo se compila cuando se ejecutan pruebas utilizando `scarb test`." - -#: src/getting-started/testing/contract-testing.md:136 -msgid "" -"Each test is defined as a function with the `#[test]` attribute. You can " -"also check if a test panics using the `#[should_panic]` attribute." -msgstr "" -"Cada prueba se define como una función con el atributo `#[test]`. También " -"puede comprobar si una prueba entra en pánico utilizando el atributo " -"`#[should_panic]`." - -#: src/getting-started/testing/contract-testing.md:138 -msgid "" -"As we are in the context of a smart contract, it's essential to set up the " -"gas limit. You do this by using the `#[available_gas(X)]` attribute to " -"specify the gas limit for a test. This is also a great way to ensure that " -"your contract's features stay under a certain gas limit!" -msgstr "" -"Como estamos en el contexto de un smart contract, es esencial establecer el " -"límite de gas. Esto se hace utilizando el atributo `#[available_gas(X)]` " -"para especificar el límite de gas para una prueba. ¡Esta es también una gran " -"manera de asegurar que las funciones de tu contrato se mantienen por debajo " -"de un cierto límite de gas!" - -#: src/getting-started/testing/contract-testing.md:140 -msgid "> Note: The term \"gas\" here refers to Sierra gas, not L1 gas" -msgstr ">Nota: El término \"gas\" se refiere aquí al gas Sierra, no al gas L1" - -#: src/getting-started/testing/contract-testing.md:142 -msgid "Now, let's move on to the testing process:" -msgstr "Pasemos ahora al proceso de prueba:" - -#: src/getting-started/testing/contract-testing.md:143 -msgid "" -"- Use the `deploy` function logic to declare and deploy your contract.\n" -"- Use `assert` to verify that the contract behaves as expected in the given " -"context." -msgstr "" -"- Utilice la lógica de la función `deploy` para declarar e implementar su " -"contrato.\n" -"- Utilice `assert` para verificar que el contrato se comporta como se espera " -"en el contexto dado." - -#: src/getting-started/testing/contract-testing.md:146 -msgid "" -"To make testing more convenient, the `testing` module of the corelib " -"provides some helpful functions:" -msgstr "" -"Para que las pruebas resulten más cómodas, el módulo `testing` de corelib " -"proporciona algunas funciones útiles:" - -#: src/getting-started/testing/contract-testing.md:147 -msgid "" -"- `set_caller_address(address: ContractAddress)`\n" -"- `set_contract_address(address: ContractAddress)`\n" -"- `set_block_number(block_number: u64)`\n" -"- `set_block_timestamp(block_timestamp: u64)`\n" -"- `set_account_contract_address(address: ContractAddress)`\n" -"- `set_max_fee(fee: u128)`" -msgstr "" -"- `set_caller_address(address: ContractAddress)`\n" -"- `set_contract_address(address: ContractAddress)`\n" -"- `set_block_number(block_number: u64)`\n" -"- `set_block_timestamp(block_timestamp: u64)`\n" -"- `set_account_contract_address(address: ContractAddress)`\n" -"- `set_max_fee(fee: u128)`" - -#: src/getting-started/testing/contract-testing.md:154 -msgid "" -"You may also need the `info` module from the corelib, which allows you to " -"access information about the current execution context (see [syscalls](../" -"basics/syscalls.md)):" -msgstr "" -"Es posible que también necesite el módulo `info` de corelib, que le permite " -"acceder a información sobre el contexto de ejecución actual (consulte " -"[syscalls](../basics/syscalls.md)):" - -#: src/getting-started/testing/contract-testing.md:155 -msgid "" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" -msgstr "" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" - -#: src/getting-started/testing/contract-testing.md:163 -msgid "" -"You can found the full list of functions in the [Starknet Corelib repo]" -"(https://github.com/starkware-libs/cairo/tree/main/corelib/src/starknet).\n" -"You can also find a detailled explaination of testing in cairo in the [Cairo " -"book - Chapter 9](https://book.cairo-lang.org/ch09-01-how-to-write-tests." -"html)." -msgstr "" -"Puede encontrar la lista completa de funciones en el [repositorio de " -"Starknet Corelib](https://github.com/starkware-libs/cairo/tree/main/corelib/" -"src/starknet).\n" -"También puede encontrar una explicación detallada de las pruebas en Cairo en " -"el [Libro de Cairo - Capítulo 9](https://book.cairo-lang.org/ch09-01-how-to-" -"write-tests.html)." - -#: src/getting-started/testing/contract-testing.md:166 -msgid "## Starknet Foundry" -msgstr "## Starknet Foundry" - -#: src/getting-started/testing/contract-testing.md:168 -msgid "" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:170 -msgid "" -"Starknet Foundry is a powerful toolkit for developing smart contracts on " -"Starknet. It offers support for testing Starknet smart contracts on top of " -"`scarb` with the `Forge` tool." -msgstr "" -"Starknet Foundry es un potente conjunto de herramientas para el desarrollo " -"de contratos inteligentes en Starknet. Ofrece soporte para probar contratos " -"inteligentes Starknet sobre `scarb` con la herramienta `Forge`." - -#: src/getting-started/testing/contract-testing.md:172 -msgid "" -"Testing with `snforge` is similar to the process we just described but " -"simplified. Moreover, additional features are on the way, including " -"cheatcodes or parallel tests execution. We highly recommend exploring " -"Starknet Foundry and incorporating it into your projects." -msgstr "" -"Probar con `snforge` es similar al proceso que acabamos de describir, pero " -"simplificado. Además, hay características adicionales en camino, incluyendo " -"cheatcodes o ejecución de pruebas en paralelo. Recomendamos encarecidamente " -"explorar Starknet Foundry e incorporarlo a tus proyectos." - -#: src/getting-started/testing/contract-testing.md:174 -msgid "" -"For more detailed information about testing contracts with Starknet Foundry, " -"check out the [Starknet Foundry Book - Testing Contracts](https://foundry-rs." -"github.io/starknet-foundry/testing/contracts.html)." -msgstr "" -"Si desea información más detallada sobre los contratos de pruebas con " -"Starknet Foundry, consulte el [Starknet Foundry Book - Testing Contracts]" -"(https://foundry-rs.github.io/starknet-foundry/testing/contracts.html)." - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:1 -msgid "# Cairo Cheatsheet" -msgstr "# Hoja de ruta de Cairo" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:3 -msgid "" -"This chapter aims to provide a quick reference for the most common Cairo " -"constructs." -msgstr "" -"Este capítulo pretende ofrecer una referencia rápida para las construcciones " -"más comunes de Cairo." - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:5 -msgid "
Last change: 2023-10-31
" -msgstr "
Último cambio: 2023-10-31
" - -#: src/getting-started/cairo_cheatsheet/felt.md:1 -msgid "# Felt252" -msgstr "# Felt252" - -#: src/getting-started/cairo_cheatsheet/felt.md:3 -msgid "" -"Felt252 is a fundamental data type in Cairo from which all other data types " -"are derived.\n" -"Felt252 can also be used to store short-string representations with a " -"maximum length of 31 characters." -msgstr "" -"Felt252 es un tipo de datos fundamental en Cairo del que se derivan todos " -"los demás tipos de datos.\n" -"Felt252 también se puede utilizar para almacenar representaciones de cadenas " -"cortas con una longitud máxima de 31 caracteres." - -#: src/getting-started/cairo_cheatsheet/felt.md:6 src/getting-started/cairo_cheatsheet/arrays.md:20 -#: src/advanced-concepts/hash-solidity-compatible.md:5 -msgid "For example:" -msgstr "Por ejemplo:" - -#: src/getting-started/cairo_cheatsheet/felt.md:8 -msgid "" -"```cairo\n" -" let felt: felt252 = 100;\n" -" let felt_as_str = 'Hello Starknet!';\n" -"\n" -" let felt = felt + felt_as_str;\n" -"```" -msgstr "" -"```cairo\n" -" let felt: felt252 = 100;\n" -" let felt_as_str = 'Hello Starknet!';\n" -"\n" -" let felt = felt + felt_as_str;\n" -"```" - -#: src/getting-started/cairo_cheatsheet/mapping.md:1 -msgid "# Mapping" -msgstr "# Mapping" - -#: src/getting-started/cairo_cheatsheet/mapping.md:3 -msgid "" -"The ```LegacyMap``` type can be used to represent a collection of key-value." -msgstr "" -"El tipo ```LegacyMap``` se puede utilizar para representar una colección de " -"key-value." - -#: src/getting-started/cairo_cheatsheet/mapping.md:5 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMappingExample {\n" -" fn register_user(ref self: TContractState, student_add: ContractAddress, " -"studentName: felt252);\n" -" fn record_student_score(\n" -" ref self: TContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" );\n" -" fn view_student_name(self: @TContractState, student_add: " -"ContractAddress) -> felt252;\n" -" fn view_student_score(\n" -" self: @TContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MappingContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" students_name: LegacyMap::,\n" -" students_result_record: LegacyMap::<(ContractAddress, felt252), " -"u16>,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl External of super::IMappingExample {\n" -" fn register_user(\n" -" ref self: ContractState, student_add: ContractAddress, " -"studentName: felt252\n" -" ) {\n" -" self.students_name.write(student_add, studentName);\n" -" }\n" -"\n" -" fn record_student_score(\n" -" ref self: ContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" ) {\n" -" self.students_result_record.write((student_add, subject), " -"score);\n" -" }\n" -"\n" -" fn view_student_name(self: @ContractState, student_add: " -"ContractAddress) -> felt252 {\n" -" self.students_name.read(student_add)\n" -" }\n" -"\n" -" fn view_student_score(\n" -" self: @ContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16 {\n" -" // for a 2D mapping its important to take note of the amount of " -"brackets being used.\n" -" self.students_result_record.read((student_add, subject))\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMappingExample {\n" -" fn register_user(ref self: TContractState, student_add: ContractAddress, " -"studentName: felt252);\n" -" fn record_student_score(\n" -" ref self: TContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" );\n" -" fn view_student_name(self: @TContractState, student_add: " -"ContractAddress) -> felt252;\n" -" fn view_student_score(\n" -" self: @TContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MappingContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" students_name: LegacyMap::,\n" -" students_result_record: LegacyMap::<(ContractAddress, felt252), " -"u16>,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl External of super::IMappingExample {\n" -" fn register_user(\n" -" ref self: ContractState, student_add: ContractAddress, " -"studentName: felt252\n" -" ) {\n" -" self.students_name.write(student_add, studentName);\n" -" }\n" -"\n" -" fn record_student_score(\n" -" ref self: ContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" ) {\n" -" self.students_result_record.write((student_add, subject), " -"score);\n" -" }\n" -"\n" -" fn view_student_name(self: @ContractState, student_add: " -"ContractAddress) -> felt252 {\n" -" self.students_name.read(student_add)\n" -" }\n" -"\n" -" fn view_student_score(\n" -" self: @ContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16 {\n" -" // for a 2D mapping its important to take note of the amount of " -"brackets being used.\n" -" self.students_result_record.read((student_add, subject))\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/arrays.md:1 -msgid "# Arrays" -msgstr "# Arrays" - -#: src/getting-started/cairo_cheatsheet/arrays.md:3 -msgid "" -"Arrays are collections of elements of the same type.\n" -"The possible operations on arrays are defined with the `array::ArrayTrait` " -"of the corelib:" -msgstr "" -"Los arrays son colecciones de elementos del mismo tipo.\n" -"Las posibles operaciones sobre arrays se definen con el `array::ArrayTrait` " -"de corelib:" - -#: src/getting-started/cairo_cheatsheet/arrays.md:6 -msgid "" -"```cairo\n" -"trait ArrayTrait {\n" -" fn new() -> Array;\n" -" fn append(ref self: Array, value: T);\n" -" fn pop_front(ref self: Array) -> Option nopanic;\n" -" fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic;\n" -" fn get(self: @Array, index: usize) -> Option>;\n" -" fn at(self: @Array, index: usize) -> @T;\n" -" fn len(self: @Array) -> usize;\n" -" fn is_empty(self: @Array) -> bool;\n" -" fn span(self: @Array) -> Span;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait ArrayTrait {\n" -" fn new() -> Array;\n" -" fn append(ref self: Array, value: T);\n" -" fn pop_front(ref self: Array) -> Option nopanic;\n" -" fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic;\n" -" fn get(self: @Array, index: usize) -> Option>;\n" -" fn at(self: @Array, index: usize) -> @T;\n" -" fn len(self: @Array) -> usize;\n" -" fn is_empty(self: @Array) -> bool;\n" -" fn span(self: @Array) -> Span;\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/arrays.md:22 -msgid "" -"```cairo\n" -"fn array() -> bool {\n" -" let mut arr = ArrayTrait::::new();\n" -" arr.append(10);\n" -" arr.append(20);\n" -" arr.append(30);\n" -"\n" -" assert(arr.len() == 3, 'array length should be 3');\n" -"\n" -" let first_value = arr.pop_front().unwrap();\n" -" assert(first_value == 10, 'first value should match');\n" -"\n" -" let second_value = *arr.at(0);\n" -" assert(second_value == 20, 'second value should match');\n" -"\n" -" // Returns true if an array is empty, then false if it isn't.\n" -" arr.is_empty()\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"fn array() -> bool {\n" -" let mut arr = ArrayTrait::::new();\n" -" arr.append(10);\n" -" arr.append(20);\n" -" arr.append(30);\n" -"\n" -" assert(arr.len() == 3, 'array length should be 3');\n" -"\n" -" let first_value = arr.pop_front().unwrap();\n" -" assert(first_value == 10, 'first value should match');\n" -"\n" -" let second_value = *arr.at(0);\n" -" assert(second_value == 20, 'second value should match');\n" -"\n" -" // Returns true if an array is empty, then false if it isn't.\n" -" arr.is_empty()\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/loop.md:1 -msgid "# Loop" -msgstr "# Loop" - -#: src/getting-started/cairo_cheatsheet/loop.md:3 -msgid "" -"A loop specifies a block of code that will run repetitively until a halting " -"condition is encountered.\n" -"For example:" -msgstr "" -"Un bucle especifica un bloque de código que se ejecutará repetitivamente " -"hasta que se encuentre una condición de detención.\n" -"Por ejemplo:" - -#: src/getting-started/cairo_cheatsheet/loop.md:6 -msgid "" -"```cairo\n" -" let mut arr = ArrayTrait::new();\n" -"\n" -" // Same as ~ while (i < 10) arr.append(i++);\n" -" let mut i: u32 = 0;\n" -" let limit = 10;\n" -" loop {\n" -" if i == limit {\n" -" break;\n" -" };\n" -"\n" -" arr.append(i);\n" -"\n" -" i += 1;\n" -" };\n" -"```" -msgstr "" -"```cairo\n" -" let mut arr = ArrayTrait::new();\n" -"\n" -" // Same as ~ while (i < 10) arr.append(i++);\n" -" let mut i: u32 = 0;\n" -" let limit = 10;\n" -" loop {\n" -" if i == limit {\n" -" break;\n" -" };\n" -"\n" -" arr.append(i);\n" -"\n" -" i += 1;\n" -" };\n" -"```" - -#: src/getting-started/cairo_cheatsheet/match.md:1 -msgid "# Match" -msgstr "# Match" - -#: src/getting-started/cairo_cheatsheet/match.md:3 -msgid "" -"The `match` expression in Cairo allows us to control the flow of our code " -"by comparing a `felt252` data type or an enum against various patterns and then " -"running specific code based on the pattern that matches.\n" -"For example:" -msgstr "" -"La expresión `match` en Cairo nos permite controlar el flujo de nuestro " -"código comparando un tipo de datos sentido o una enumeración con varios " -"patrones y luego ejecutando código específico basado en el patrón que " -"coincide.\n" -"Por ejemplo:" - -#: src/getting-started/cairo_cheatsheet/match.md:6 -msgid "" -"```cairo\n" -"#[derive(Drop, Serde)]\n" -"enum Colour {\n" -" Red,\n" -" Blue,\n" -" Green,\n" -" Orange,\n" -" Black\n" -"}\n" -"\n" -"#[derive(Drop, Serde)]\n" -"enum Coin {\n" -" Penny,\n" -" Nickel,\n" -" Dime,\n" -" Quarter,\n" -"}\n" -"\n" -"fn value_in_cents(coin: Coin) -> felt252 {\n" -" match coin {\n" -" Coin::Penny => 1,\n" -" Coin::Nickel => 5,\n" -" Coin::Dime => 10,\n" -" Coin::Quarter => 25,\n" -" }\n" -"}\n" -"\n" -"fn specified_colour(colour: Colour) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match colour {\n" -" Colour::Red => { response = 'You passed in Red'; },\n" -" Colour::Blue => { response = 'You passed in Blue'; },\n" -" Colour::Green => { response = 'You passed in Green'; },\n" -" Colour::Orange => { response = 'You passed in Orange'; },\n" -" Colour::Black => { response = 'You passed in Black'; },\n" -" };\n" -"\n" -" response\n" -"}\n" -"\n" -"fn quiz(num: felt252) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match num {\n" -" 0 => { response = 'You failed' },\n" -" _ => { response = 'You Passed' },\n" -" };\n" -"\n" -" response\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[derive(Drop, Serde)]\n" -"enum Colour {\n" -" Red,\n" -" Blue,\n" -" Green,\n" -" Orange,\n" -" Black\n" -"}\n" -"\n" -"#[derive(Drop, Serde)]\n" -"enum Coin {\n" -" Penny,\n" -" Nickel,\n" -" Dime,\n" -" Quarter,\n" -"}\n" -"\n" -"fn value_in_cents(coin: Coin) -> felt252 {\n" -" match coin {\n" -" Coin::Penny => 1,\n" -" Coin::Nickel => 5,\n" -" Coin::Dime => 10,\n" -" Coin::Quarter => 25,\n" -" }\n" -"}\n" -"\n" -"fn specified_colour(colour: Colour) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match colour {\n" -" Colour::Red => { response = 'You passed in Red'; },\n" -" Colour::Blue => { response = 'You passed in Blue'; },\n" -" Colour::Green => { response = 'You passed in Green'; },\n" -" Colour::Orange => { response = 'You passed in Orange'; },\n" -" Colour::Black => { response = 'You passed in Black'; },\n" -" };\n" -"\n" -" response\n" -"}\n" -"\n" -"fn quiz(num: felt252) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match num {\n" -" 0 => { response = 'You failed' },\n" -" _ => { response = 'You Passed' },\n" -" };\n" -"\n" -" response\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/tuples.md:1 -msgid "# Tuples" -msgstr "# Tuples" - -#: src/getting-started/cairo_cheatsheet/tuples.md:3 -msgid "" -"Tuples is a data type to group a fixed number of items of potentially " -"different types into a single compound structure. Unlike arrays, tuples have " -"a set length and can contain elements of varying types. Once a tuple is " -"created, its size cannot change.\n" -"For example:" -msgstr "" -"Las Tuplas es un tipo de datos para agrupar un número fijo de elementos de " -"tipos potencialmente diferentes en una única estructura compuesta. A " -"diferencia de las arrays, las tuplas tienen una longitud determinada y " -"pueden contener elementos de distintos tipos. Una vez creada una tupla, su " -"tamaño no puede cambiar.\n" -"Por ejemplo:" - -#: src/getting-started/cairo_cheatsheet/tuples.md:6 -msgid "" -"```cairo\n" -" let address = \"0x000\";\n" -" let age = 20;\n" -" let active = true;\n" -"\n" -" // Create tuple\n" -" let user_tuple = (address, age, active);\n" -"\n" -" // Access tuple\n" -" let (address, age, active) = stored_tuple;\n" -"```" -msgstr "" -"```cairo\n" -" let address = \"0x000\";\n" -" let age = 20;\n" -" let active = true;\n" -"\n" -" // Create tuple\n" -" let user_tuple = (address, age, active);\n" -"\n" -" // Access tuple\n" -" let (address, age, active) = stored_tuple;\n" -"```" - -#: src/getting-started/cairo_cheatsheet/struct.md:1 -msgid "# Struct" -msgstr "# Struct" - -#: src/getting-started/cairo_cheatsheet/struct.md:3 -msgid "" -"A struct is a data type similar to tuple. Like tuples they can be used to " -"hold data of different types.\n" -"For example:" -msgstr "" -"Una estructura es un tipo de datos similar a una tupla. Al igual que las " -"tuplas, se pueden utilizar para contener datos de diferentes tipos.Por " -"ejemplo:" - -#: src/getting-started/cairo_cheatsheet/struct.md:6 -msgid "" -"```cairo\n" -"// With Store, you can store Data's structs in the storage part of " -"contracts.\n" -"#[derive(Drop, starknet::Store)]\n" -"struct Data {\n" -" address: starknet::ContractAddress,\n" -" age: u8\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"// With Store, you can store Data's structs in the storage part of " -"contracts.\n" -"#[derive(Drop, starknet::Store)]\n" -"struct Data {\n" -" address: starknet::ContractAddress,\n" -" age: u8\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:1 -msgid "# Type casting" -msgstr "# Conversión de Tipos" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:3 -msgid "" -"Cairo supports the conversion from one scalar types to another by using the " -"into and try_into methods.\n" -"`traits::Into` is used for conversion from a smaller data type to a larger " -"data type, while `traits::TryInto` is used when converting from a larger to " -"a smaller type that might not fit. \n" -"For example:" -msgstr "" -"Cairo admite la conversión de un tipo escalar a otro mediante el uso de los " -"métodos into y try_into.\n" -"`traits::Into` se usa para la conversión de un tipo de datos más pequeño a " -"un tipo de datos más grande, mientras que `traits::TryInto` se usa para " -"convertir de un tipo más grande a uno más pequeño que podría no encajar.\n" -"Por ejemplo:" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:7 -msgid "" -"```cairo\n" -" let a_number: u32 = 15;\n" -" let my_felt252 = 15;\n" -"\n" -" // Since a u32 might not fit in a u8 and a u16, we need to use " -"try_into,\n" -" // then unwrap the Option type thats returned.\n" -" let new_u8: u8 = a_number.try_into().unwrap();\n" -" let new_u16: u16 = a_number.try_into().unwrap();\n" -"\n" -" // since new_u32 is the of the same type (u32) as rand_number, we can " -"directly assign them,\n" -" // or use the .into() method.\n" -" let new_u32: u32 = a_number;\n" -"\n" -" // When typecasting from a smaller size to an equal or larger size we " -"use the .into() method.\n" -" // Note: u64 and u128 are larger than u32, so a u32 type will always fit " -"into them.\n" -" let new_u64: u64 = a_number.into();\n" -" let new_u128: u128 = a_number.into();\n" -"\n" -" // Since a felt252 is smaller than a u256, we can use the into() method\n" -" let new_u256: u256 = my_felt252.into();\n" -" let new_felt252: felt252 = new_u16.into();\n" -"\n" -" // Note: usize is smaller than felt252, so we use try_into\n" -" let new_usize: usize = my_felt252.try_into().unwrap();\n" -"```" -msgstr "" -"```cairo\n" -" let a_number: u32 = 15;\n" -" let my_felt252 = 15;\n" -"\n" -" // Since a u32 might not fit in a u8 and a u16, we need to use " -"try_into,\n" -" // then unwrap the Option type thats returned.\n" -" let new_u8: u8 = a_number.try_into().unwrap();\n" -" let new_u16: u16 = a_number.try_into().unwrap();\n" -"\n" -" // since new_u32 is the of the same type (u32) as rand_number, we can " -"directly assign them,\n" -" // or use the .into() method.\n" -" let new_u32: u32 = a_number;\n" -"\n" -" // When typecasting from a smaller size to an equal or larger size we " -"use the .into() method.\n" -" // Note: u64 and u128 are larger than u32, so a u32 type will always fit " -"into them.\n" -" let new_u64: u64 = a_number.into();\n" -" let new_u128: u128 = a_number.into();\n" -"\n" -" // Since a felt252 is smaller than a u256, we can use the into() method\n" -" let new_u256: u256 = my_felt252.into();\n" -" let new_felt252: felt252 = new_u16.into();\n" -"\n" -" // Note: usize is smaller than felt252, so we use try_into\n" -" let new_usize: usize = my_felt252.try_into().unwrap();\n" -"```" - -#: src/components/how_to.md:1 -msgid "# Components How-To" -msgstr "# Cómo hacer Componentes" - -#: src/components/how_to.md:3 -msgid "" -"Components are like modular addons that can be snapped into contracts to add " -"reusable logic, storage, and events.\n" -"They are used to separate the core logic from common functionalities, " -"simplifying the contract's code and making it easier to read and maintain.\n" -"It also reduces the risk of bugs and vulnerabilities by using well-tested " -"components." -msgstr "" -"Los componentes son como complementos modulares que se pueden integrar en " -"contratos para agregar lógica, almacenamiento y eventos reutilizables.\n" -"Se utilizan para separar la lógica central de las funcionalidades comunes, " -"simplificando el código del contrato y haciéndolo más fácil de leer y " -"mantener.\n" -"También reduce el riesgo de errores y vulnerabilidades mediante el uso de " -"componentes bien probados." - -#: src/components/how_to.md:7 -msgid "Key characteristics:" -msgstr "Caracteristicas claves:" - -#: src/components/how_to.md:8 -msgid "" -"- Modularity: Easily pluggable into multiple contracts.\n" -"- Reusable Logic: Encapsulates specific functionalities.\n" -"- Not Standalone: Cannot be declared or deployed independently." -msgstr "" -"- Modularidad: Fácilmente conectable a múltiples contratos.\n" -"- Lógica Reutilizable: Encapsula funcionalidades específicas.\n" -"- No autónomo: no se puede declarar ni implementar de forma independiente." - -#: src/components/how_to.md:12 -msgid "## How to create a component" -msgstr "## Cómo crear un componente" - -#: src/components/how_to.md:14 -msgid "" -"The following example shows a simple `Switchable` component that can be used " -"to add a switch that can be either on or off.\n" -"It contains a storage variable `switchable_value`, a function `switch` and " -"an event `Switch`." -msgstr "" -"El siguiente ejemplo muestra un componente `Switchable` simple que se puede " -"usar para agregar un interruptor que puede estar encendido o apagado.\n" -"Contiene una variable de almacenamiento `switchable_value`, una función " -"`switch` y un evento `Switch`." - -#: src/components/how_to.md:17 -msgid "" -"> It is a good practice to prefix the component storage variables with the " -"component name to [avoid collisions](./collisions.md)." -msgstr "" -"> Es una buena práctica anteponer las variables de almacenamiento del " -"componente con el nombre del componente para [evitar colisiones] (./" -"collisions.md)." - -#: src/components/how_to.md:19 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchable {\n" -" fn is_on(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod switchable_component {\n" -" #[storage]\n" -" struct Storage {\n" -" switchable_value: bool,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct SwitchEvent {}\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchEvent: SwitchEvent,\n" -" }\n" -"\n" -" #[embeddable_as(Switchable)]\n" -" impl SwitchableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ISwitchable> {\n" -" fn is_on(self: @ComponentState) -> bool {\n" -" self.switchable_value.read()\n" -" }\n" -"\n" -" fn switch(ref self: ComponentState) {\n" -" self.switchable_value.write(!self.switchable_value.read());\n" -" self.emit(Event::SwitchEvent(SwitchEvent {}));\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl SwitchableInternalImpl<\n" -" TContractState, +HasComponent\n" -" > of SwitchableInternalTrait {\n" -" fn _off(ref self: ComponentState) {\n" -" self.switchable_value.write(false);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchable {\n" -" fn is_on(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod switchable_component {\n" -" #[storage]\n" -" struct Storage {\n" -" switchable_value: bool,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct SwitchEvent {}\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchEvent: SwitchEvent,\n" -" }\n" -"\n" -" #[embeddable_as(Switchable)]\n" -" impl SwitchableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ISwitchable> {\n" -" fn is_on(self: @ComponentState) -> bool {\n" -" self.switchable_value.read()\n" -" }\n" -"\n" -" fn switch(ref self: ComponentState) {\n" -" self.switchable_value.write(!self.switchable_value.read());\n" -" self.emit(Event::SwitchEvent(SwitchEvent {}));\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl SwitchableInternalImpl<\n" -" TContractState, +HasComponent\n" -" > of SwitchableInternalTrait {\n" -" fn _off(ref self: ComponentState) {\n" -" self.switchable_value.write(false);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/components/how_to.md:67 -msgid "" -"A component in itself is really similar to a contract, it *can* also have:" -msgstr "" -"Un componente en sí mismo es muy similar a un contrato, *puede* también " -"tener:" - -#: src/components/how_to.md:68 -msgid "" -"- An interface defining entrypoints " -"(`ISwitchableComponent`)\n" -"- A Storage struct\n" -"- Events\n" -"- Internal functions" -msgstr "" -"- Una interfaz que define puntos de entrada " -"(`ISwitchableComponent`)\n" -"- Una estructura de Storage\n" -"- Eventos\n" -"- Funciones internas" - -#: src/components/how_to.md:73 -msgid "" -"It don't have a constructor, but you can create a `_init` internal function " -"and call it from the contract's constructor. In the previous example, the " -"`_off` function is used this way." -msgstr "" -"No tiene constructor, pero puedes crear una función interna `_init` y " -"llamarla desde el constructor del contrato. En el ejemplo anterior, la " -"función `_off` se usa de esta manera." - -#: src/components/how_to.md:75 -msgid "" -"> It's currently not possible to use the same component multiple times in " -"the same contract.\n" -"> This is a known limitation that may be lifted in the future.\n" -"> \n" -"> For now, you can view components as an implementation of a specific " -"interface/feature (`Ownable`, `Upgradeable`, ... `~able`).\n" -"> This is why we called it `Switchable` and not `Switch`; The contract *is " -"switchable*, not *has a switch*." -msgstr "" -"> Actualmente no es posible utilizar el mismo componente varias veces en el " -"mismo contrato.\n" -"> Esta es una limitación conocida que puede eliminarse en el futuro.\n" -">\n" -"> Por ahora, puede ver los componentes como una implementación de una " -"interfaz/función específica (`Ownable`, `Upgradeable`, ... `~able`).\n" -"> Por eso lo llamamos `Switchable` y no `Switch`; El contrato *es " -"switchable*, no *tiene un switch*." - -#: src/components/how_to.md:81 -msgid "## How to use a component" -msgstr "## Cómo utilizar un componente" - -#: src/components/how_to.md:83 -msgid "" -"Now that we have a component, we can use it in a contract.\n" -"The following contract incorporates the `Switchable` component:" -msgstr "" -"Ahora que tenemos un componente, podemos usarlo en un contrato.\n" -"El siguiente contrato incorpora el componente `Switchable`:" - -#: src/components/how_to.md:86 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod SwitchContract {\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use components::switchable::switchable_component::" -"SwitchableInternalTrait;\n" -"# use components::switchable::ISwitchable;\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use super::SwitchContract;\n" -"# \n" -"# fn STATE() -> SwitchContract::ContractState {\n" -"# SwitchContract::contract_state_for_testing()\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let state = STATE();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_switch() {\n" -"# let mut state = STATE();\n" -"# \n" -"# state.switch();\n" -"# assert(state.is_on() == true, 'The switch should be on');\n" -"# \n" -"# state.switch();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_value() {\n" -"# let mut state = STATE();\n" -"# assert(state.is_on() == state.switch.switchable_value.read(), " -"'Wrong value');\n" -"# \n" -"# state.switch.switch();\n" -"# assert(state.is_on() == state.switch.switchable_value.read(), " -"'Wrong value');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_internal_off() {\n" -"# let mut state = STATE();\n" -"# \n" -"# state.switch._off();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# \n" -"# state.switch();\n" -"# state.switch._off();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod SwitchContract {\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use components::switchable::switchable_component::" -"SwitchableInternalTrait;\n" -"# use components::switchable::ISwitchable;\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use super::SwitchContract;\n" -"# \n" -"# fn STATE() -> SwitchContract::ContractState {\n" -"# SwitchContract::contract_state_for_testing()\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let state = STATE();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_switch() {\n" -"# let mut state = STATE();\n" -"# \n" -"# state.switch();\n" -"# assert(state.is_on() == true, 'The switch should be on');\n" -"# \n" -"# state.switch();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_value() {\n" -"# let mut state = STATE();\n" -"# assert(state.is_on() == state.switch.switchable_value.read(), " -"'Wrong value');\n" -"# \n" -"# state.switch.switch();\n" -"# assert(state.is_on() == state.switch.switchable_value.read(), " -"'Wrong value');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_internal_off() {\n" -"# let mut state = STATE();\n" -"# \n" -"# state.switch._off();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# \n" -"# state.switch();\n" -"# state.switch._off();\n" -"# assert(state.is_on() == false, 'The switch should be off');\n" -"# }\n" -"# }\n" -"```" - -#: src/components/how_to.md:171 -msgid "## Deep dive into components" -msgstr "## Profundización en los componentes" - -#: src/components/how_to.md:173 -msgid "" -"You can find more in-depth information about components in the [Cairo book - " -"Components](https://book.cairo-lang.org/ch99-01-05-00-components.html)." -msgstr "" -"Puede encontrar información más detallada sobre los componentes en el [Cairo " -"book - Components](https://book.cairo-lang.org/ch99-01-05-00-components." -"html)." - -#: src/components/dependencies.md:1 -msgid "# Components Dependencies" -msgstr "# Dependencias de Componentes" - -#: src/components/dependencies.md:3 -msgid "" -"A component with a dependency on a trait T can be used in a contract as long " -"as the contract implements the trait T." -msgstr "" -"Un componente que depende de un trait T se puede utilizar en un contrato " -"siempre que el contrato implemente el trait T." - -#: src/components/dependencies.md:5 -msgid "We will use a new `Countable` component as an example:" -msgstr "Usaremos un nuevo componente `Countable` como ejemplo:" - -#: src/components/dependencies.md:7 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICountable {\n" -" fn get(self: @TContractState) -> u32;\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod countable_component {\n" -" #[storage]\n" -" struct Storage {\n" -" countable_value: u32,\n" -" }\n" -"\n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" self.countable_value.write(self.countable_value.read() + 1);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICountable {\n" -" fn get(self: @TContractState) -> u32;\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod countable_component {\n" -" #[storage]\n" -" struct Storage {\n" -" countable_value: u32,\n" -" }\n" -"\n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" self.countable_value.write(self.countable_value.read() + 1);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/components/dependencies.md:36 -msgid "" -"We want to add a way to enable or disable the counter, in a way that calling " -"`increment` on a disabled counter will not increment the counter.\n" -"But we don't want to add this switch logic to the `Countable` component " -"itself.\n" -"We instead add the trait `Switchable` as a dependency to the `Countable` " -"component." -msgstr "" -"Queremos agregar una forma de habilitar o deshabilitar el contador, de " -"manera que llamar a `increment` en un contador deshabilitado no incremente " -"el contador.\n" -"Pero no queremos agregar esta lógica de cambio al componente`Countable`.\n" -"En su lugar, agregamos el trait `Switchable` como una dependencia del " -"componente `Countable`." - -#: src/components/dependencies.md:40 -msgid "#### Implementation of the trait in the contract" -msgstr "#### Implementación del trait en el contrato" - -#: src/components/dependencies.md:42 -msgid "We first define the `ISwitchable` trait:" -msgstr "Primero definimos el trait `ISwitchable`:" - -#: src/components/dependencies.md:44 -msgid "" -"```cairo\n" -"trait ISwitchable {\n" -" fn is_on(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait ISwitchable {\n" -" fn is_on(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"```" - -#: src/components/dependencies.md:51 -msgid "" -"Then we can modify the implementation of the `Countable` component to depend " -"on the `ISwitchable` trait:" -msgstr "" -"Luego podemos modificar la implementación del componente `Countable` para " -"que dependa del rasgo `ISwitchable`:" - -#: src/components/dependencies.md:53 -msgid "" -"```cairo\n" -"# #[starknet::component]\n" -"# mod countable_component {\n" -"# use components::countable::ICountable;\n" -"# use components::switchable::ISwitchable;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {\n" -"# countable_value: u32,\n" -"# }\n" -"# \n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState, +HasComponent, " -"+ISwitchable\n" -" > of ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" if (self.get_contract().is_on()) {\n" -" self.countable_value.write(self.countable_value.read() + " -"1);\n" -" }\n" -" }\n" -" }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"# #[starknet::component]\n" -"# mod countable_component {\n" -"# use components::countable::ICountable;\n" -"# use components::switchable::ISwitchable;\n" -"# \n" -"# #[storage]\n" -"# struct Storage {\n" -"# countable_value: u32,\n" -"# }\n" -"# \n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState, +HasComponent, " -"+ISwitchable\n" -" > of ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" if (self.get_contract().is_on()) {\n" -" self.countable_value.write(self.countable_value.read() + " -"1);\n" -" }\n" -" }\n" -" }\n" -"# }\n" -"```" - -#: src/components/dependencies.md:81 -msgid "" -"A contract that uses the `Countable` component must implement the " -"`ISwitchable` trait:" -msgstr "" -"Un contrato que utilice el componente `Countable` debe implementar el trait " -"`ISwitchable`:" - -#: src/components/dependencies.md:83 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_dep_switch::countable_component;\n" -" use components::switchable::ISwitchable;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" switch: bool\n" -" }\n" -"\n" -" // Implementation of the dependency:\n" -" #[abi(embed_v0)]\n" -" impl Switchable of ISwitchable {\n" -" fn switch(ref self: ContractState) {\n" -" self.switch.write(!self.switch.read());\n" -" }\n" -"\n" -" fn is_on(self: @ContractState) -> bool {\n" -" self.switch.read()\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch.write(false);\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 6, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_dep_switch::countable_component;\n" -" use components::switchable::ISwitchable;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" switch: bool\n" -" }\n" -"\n" -" // Implementation of the dependency:\n" -" #[abi(embed_v0)]\n" -" impl Switchable of ISwitchable {\n" -" fn switch(ref self: ContractState) {\n" -" self.switch.write(!self.switch.read());\n" -" }\n" -"\n" -" fn is_on(self: @ContractState) -> bool {\n" -" self.switch.read()\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch.write(false);\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 6, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" - -#: src/components/dependencies.md:201 -msgid "#### Implementation of the trait in another component" -msgstr "#### Implementación del trait en otro componente" - -#: src/components/dependencies.md:203 -msgid "" -"In the previous example, we implemented the `ISwitchable` trait in the " -"contract." -msgstr "" -"En el ejemplo anterior, implementamos el rasgo `ISwitchable` en el contrato." - -#: src/components/dependencies.md:205 -msgid "" -"We already implemented a [`Switchable`](./how_to.md) component that provide " -"an implementation of the `ISwitchable` trait.\n" -"By using the `Switchable` component in a contract, we embed the " -"implementation of the `ISwitchable` trait in the contract and resolve the " -"dependency on the `ISwitchable` trait." -msgstr "" -"Ya hemos implementado un componente [`Switchable`](./how_to.md) que " -"proporciona una implementación del trait `ISwitchable`.\n" -"Al utilizar el componente `Switchable` en un contrato, incrustamos la " -"implementación del trait `ISwitchable` en el contrato y resolvemos la " -"dependencia del trait `ISwitchable`." - -#: src/components/dependencies.md:208 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_dep_switch::countable_component;\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(3000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 6, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_dep_switch::countable_component;\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(3000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 6, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" - -#: src/components/dependencies.md:320 -msgid "#### Dependency on other components internal functions" -msgstr "#### Dependencia de funciones internas de otros componentes" - -#: src/components/dependencies.md:322 -msgid "" -"The previous example shows how to use the `ISwitchable` trait implementation " -"from the `Switchable` component inside the `Countable` component by " -"embedding the implementation in the contract.\n" -"However, suppose we would like to turn off the switch after each increment. " -"There's no `set` function in the `ISwitchable` trait, so we can't do it " -"directly." -msgstr "" -"El ejemplo anterior muestra cómo utilizar la implementación del rasgo " -"`ISwitchable` del componente `Switchable` dentro del componente `Countable` " -"incrustando la implementación en el contrato.\n" -"Sin embargo, supongamos que queremos apagar el interruptor después de cada " -"incremento. No hay función `set` en el trait `ISwitchable`, así que no " -"podemos hacerlo directamente." - -#: src/components/dependencies.md:325 -msgid "" -"But the Switchable component implements the internal function `_off` from " -"the `SwitchableInternalTrait` that set the switch to `false`.\n" -"We can't embed `SwitchableInternalImpl`, but we can add `switchable::" -"HasComponent` as a dependency inside `CountableImpl`." -msgstr "" -"Pero el componente Switchable implementa la función interna `_off` del " -"`SwitchableInternalTrait` que establece el interruptor a `false`.\n" -"No podemos incrustar `SwitchableInternalImpl`, pero podemos añadir " -"`switchable::HasComponent` como dependencia dentro de " -"`CountableImpl`." - -#: src/components/dependencies.md:328 -msgid "" -"We make the `Countable` component depend on the `Switchable` component.\n" -"This will allow to do `switchable::ComponentState` -> " -"`TContractState` -> `countable::ComponentState` and access " -"the internal functions of the `Switchable` component inside the `Countable` " -"component:" -msgstr "" -"Hacemos que el componente `Countable` dependa del componente `Switchable`.\n" -"Esto permitirá hacer `switchable::ComponentState` -> " -"`TContractState` -> `countable::ComponentState` y acceder a " -"las funciones internas del componente `Switchable` dentro del componente " -"`Countable`:" - -#: src/components/dependencies.md:331 -msgid "" -"```cairo\n" -"#[starknet::component]\n" -"mod countable_component {\n" -" use components::countable::ICountable;\n" -" use components::switchable::ISwitchable;\n" -"\n" -" // Explicitly depends on a component and not a trait\n" -" use components::switchable::switchable_component;\n" -" use switchable_component::{SwitchableInternalImpl, " -"SwitchableInternalTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" countable_value: u32,\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl GetSwitchable<\n" -" TContractState,\n" -" +HasComponent,\n" -" +switchable_component::HasComponent,\n" -" +Drop\n" -" > of GetSwitchableTrait {\n" -" fn get_switchable(\n" -" self: @ComponentState\n" -" ) -> @switchable_component::ComponentState {\n" -" let contract = self.get_contract();\n" -" switchable_component::HasComponent::::" -"get_component(contract)\n" -" }\n" -"\n" -" fn get_switchable_mut(\n" -" ref self: ComponentState\n" -" ) -> switchable_component::ComponentState {\n" -" let mut contract = self.get_contract_mut();\n" -" switchable_component::HasComponent::::" -"get_component_mut(ref contract)\n" -" }\n" -" }\n" -"\n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState,\n" -" +HasComponent,\n" -" +ISwitchable,\n" -" +switchable_component::HasComponent,\n" -" +Drop\n" -" > of ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" if (self.get_contract().is_on()) {\n" -" self.countable_value.write(self.countable_value.read() + " -"1);\n" -"\n" -" // use the switchable component internal function\n" -" let mut switch = self.get_switchable_mut();\n" -" switch._off();\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::component]\n" -"mod countable_component {\n" -" use components::countable::ICountable;\n" -" use components::switchable::ISwitchable;\n" -"\n" -" // Explicitly depends on a component and not a trait\n" -" use components::switchable::switchable_component;\n" -" use switchable_component::{SwitchableInternalImpl, " -"SwitchableInternalTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" countable_value: u32,\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl GetSwitchable<\n" -" TContractState,\n" -" +HasComponent,\n" -" +switchable_component::HasComponent,\n" -" +Drop\n" -" > of GetSwitchableTrait {\n" -" fn get_switchable(\n" -" self: @ComponentState\n" -" ) -> @switchable_component::ComponentState {\n" -" let contract = self.get_contract();\n" -" switchable_component::HasComponent::::" -"get_component(contract)\n" -" }\n" -"\n" -" fn get_switchable_mut(\n" -" ref self: ComponentState\n" -" ) -> switchable_component::ComponentState {\n" -" let mut contract = self.get_contract_mut();\n" -" switchable_component::HasComponent::::" -"get_component_mut(ref contract)\n" -" }\n" -" }\n" -"\n" -" #[embeddable_as(Countable)]\n" -" impl CountableImpl<\n" -" TContractState,\n" -" +HasComponent,\n" -" +ISwitchable,\n" -" +switchable_component::HasComponent,\n" -" +Drop\n" -" > of ICountable> {\n" -" fn get(self: @ComponentState) -> u32 {\n" -" self.countable_value.read()\n" -" }\n" -"\n" -" fn increment(ref self: ComponentState) {\n" -" if (self.get_contract().is_on()) {\n" -" self.countable_value.write(self.countable_value.read() + " -"1);\n" -"\n" -" // use the switchable component internal function\n" -" let mut switch = self.get_switchable_mut();\n" -" switch._off();\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/components/dependencies.md:393 -msgid "" -"The contract remains the same that the previous example, but the " -"implementation of the `Countable` component is different:" -msgstr "" -"El contrato sigue siendo el mismo que en el ejemplo anterior, pero la " -"implementación del componente `Countable` es diferente:" - -#: src/components/dependencies.md:394 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_internal_dep_switch::" -"countable_component;\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# \n" -"# // The counter turned the switch off.\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(3000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment(); // off\n" -"# counter.increment(); // off\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod CountableContract {\n" -" use components_dependencies::countable_internal_dep_switch::" -"countable_component;\n" -" use components::switchable::switchable_component;\n" -"\n" -" component!(path: countable_component, storage: counter, event: " -"CountableEvent);\n" -" component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CountableImpl = countable_component::Countable;\n" -" #[abi(embed_v0)]\n" -" impl SwitchableImpl = switchable_component::Switchable;\n" -" impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" counter: countable_component::Storage,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" CountableEvent: countable_component::Event,\n" -" SwitchableEvent: switchable_component::Event,\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::CountableContract;\n" -"# use components::countable::{ICountable, ICountableDispatcher, " -"ICountableDispatcherTrait};\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ICountableDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# CountableContract::TEST_CLASS_HASH.try_into().unwrap(), 0, " -"array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (ICountableDispatcher { contract_address }, ISwitchableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# assert(counter.get() == 0, 'Counter != 0');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_off() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 0, 'Counter incremented');\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_increment_switch_on() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# assert(switch.is_on() == true, 'Switch != true');\n" -"# \n" -"# counter.increment();\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# \n" -"# // The counter turned the switch off.\n" -"# assert(switch.is_on() == false, 'Switch != false');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(3000000)]\n" -"# fn test_increment_multiple_switches() {\n" -"# let (mut counter, mut switch) = deploy();\n" -"# \n" -"# switch.switch();\n" -"# \n" -"# counter.increment();\n" -"# counter.increment(); // off\n" -"# counter.increment(); // off\n" -"# assert(counter.get() == 1, 'Counter did not increment');\n" -"# \n" -"# switch.switch();\n" -"# counter.increment();\n" -"# switch.switch();\n" -"# counter.increment();\n" -"# counter.increment();\n" -"# assert(counter.get() == 3, 'Counter did not increment');\n" -"# }\n" -"# }\n" -"```" - -#: src/components/collisions.md:1 -msgid "# Component-Contract Storage Collisions" -msgstr "# Colisiones Componente-Contrato de Almacenamiento" - -#: src/components/collisions.md:3 -msgid "Components can declare their own storage variables." -msgstr "" -"Los componentes pueden declarar sus propias variables de almacenamiento." - -#: src/components/collisions.md:5 -msgid "" -"When a contract use a component, the component storage is merged with the " -"contract storage.\n" -"The storage layout is only determined by the variables names, so variables " -"with the same name will collide." -msgstr "" -"Cuando un contrato utiliza un componente, el almacenamiento del componente " -"se fusiona con el almacenamiento del contrato.\n" -"La disposición del almacenamiento sólo está determinada por los nombres de " -"las variables, por lo que las variables con el mismo nombre colisionarán." - -#: src/components/collisions.md:8 -msgid "" -"> In a future release, the `#[substorage(v1)]` will determine the storage " -"layout based on the component as well, so collisions will be avoided." -msgstr "" -"> En una futura versión, el `#[substorage(v1)]` determinará la disposición " -"del almacenamiento basándose también en el componente, por lo que se " -"evitarán colisiones." - -#: src/components/collisions.md:10 -msgid "" -"A good practice is to prefix the component storage variables with the " -"component name, as shown in the [Switchable component example](./how_to.md)." -msgstr "" -"Una buena práctica es anteponer a las variables de almacenamiento del " -"componente el nombre del componente, como se muestra en el [Ejemplo de " -"componente conmutable](./how_to.md)." - -#: src/components/collisions.md:12 -msgid "#### Example" -msgstr "#### Ejemplo" - -#: src/components/collisions.md:14 -msgid "" -"Here's an example of a collision on the `switchable_value` storage variable " -"of the `Switchable` component." -msgstr "" -"He aquí un ejemplo de colisión en la variable de almacenamiento " -"`switchable_value` del componente `Switchable`." - -#: src/components/collisions.md:16 -msgid "Interface:" -msgstr "Interface:" - -#: src/components/collisions.md:17 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchCollision {\n" -" fn set(ref self: TContractState, value: bool);\n" -" fn get(ref self: TContractState) -> bool;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchCollision {\n" -" fn set(ref self: TContractState, value: bool);\n" -" fn get(ref self: TContractState) -> bool;\n" -"}\n" -"```" - -#: src/components/collisions.md:25 -msgid "" -"Here's the storage of the contract (you can expand the code snippet to see " -"the full contract):" -msgstr "" -"Aquí tienes el almacenamiento del contrato (puedes ampliar el fragmento de " -"código para ver el contrato completo):" - -#: src/components/collisions.md:26 -msgid "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait ISwitchCollision {\n" -"# fn set(ref self: TContractState, value: bool);\n" -"# fn get(ref self: TContractState) -> bool;\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod SwitchCollisionContract {\n" -"# use components::switchable::switchable_component;\n" -"# \n" -"# component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl SwitchableImpl = switchable_component::" -"Switchable;\n" -"# impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"# \n" -" #[storage]\n" -" struct Storage {\n" -" switchable_value: bool,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage,\n" -" }\n" -"# \n" -"# #[constructor]\n" -"# fn constructor(ref self: ContractState) {\n" -"# self.switch._off();\n" -"# }\n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# enum Event {\n" -"# SwitchableEvent: switchable_component::Event,\n" -"# }\n" -"# \n" -"# #[external(v0)]\n" -"# impl SwitchCollisionContract of super::ISwitchCollision " -"{\n" -"# fn set(ref self: ContractState, value: bool) {\n" -"# self.switchable_value.write(value);\n" -"# }\n" -"# \n" -"# fn get(ref self: ContractState) -> bool {\n" -"# self.switchable_value.read()\n" -"# }\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait ISwitchCollision {\n" -"# fn set(ref self: TContractState, value: bool);\n" -"# fn get(ref self: TContractState) -> bool;\n" -"# }\n" -"# \n" -"# #[starknet::contract]\n" -"# mod SwitchCollisionContract {\n" -"# use components::switchable::switchable_component;\n" -"# \n" -"# component!(path: switchable_component, storage: switch, event: " -"SwitchableEvent);\n" -"# \n" -"# #[abi(embed_v0)]\n" -"# impl SwitchableImpl = switchable_component::" -"Switchable;\n" -"# impl SwitchableInternalImpl = switchable_component::" -"SwitchableInternalImpl;\n" -"# \n" -" #[storage]\n" -" struct Storage {\n" -" switchable_value: bool,\n" -" #[substorage(v0)]\n" -" switch: switchable_component::Storage,\n" -" }\n" -"# \n" -"# #[constructor]\n" -"# fn constructor(ref self: ContractState) {\n" -"# self.switch._off();\n" -"# }\n" -"# \n" -"# #[event]\n" -"# #[derive(Drop, starknet::Event)]\n" -"# enum Event {\n" -"# SwitchableEvent: switchable_component::Event,\n" -"# }\n" -"# \n" -"# #[external(v0)]\n" -"# impl SwitchCollisionContract of super::ISwitchCollision " -"{\n" -"# fn set(ref self: ContractState, value: bool) {\n" -"# self.switchable_value.write(value);\n" -"# }\n" -"# \n" -"# fn get(ref self: ContractState) -> bool {\n" -"# self.switchable_value.read()\n" -"# }\n" -"# }\n" -"# }\n" -"```" - -#: src/components/collisions.md:74 -msgid "" -"Both the contract and the component have a `switchable_value` storage " -"variable, so they collide:" -msgstr "" -"Tanto el contrato como el componente tienen una variable de almacenamiento " -"`switchable_value`, por lo que colisionan:" - -#: src/components/collisions.md:76 -msgid "" -"```cairo\n" -"# mod switch_collision_tests {\n" -"# use components::switchable::switchable_component::" -"SwitchableInternalTrait;\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use components::contracts::switch_collision::{\n" -"# SwitchCollisionContract, ISwitchCollisionDispatcher, " -"ISwitchCollisionDispatcherTrait\n" -"# };\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ISwitchCollisionDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# SwitchCollisionContract::TEST_CLASS_HASH.try_into().unwrap(), " -"0, array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (\n" -"# ISwitchCollisionDispatcher { contract_address },\n" -"# ISwitchableDispatcher { contract_address },\n" -"# )\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -" fn test_collision() {\n" -" let (mut contract, mut contract_iswitch) = deploy();\n" -"\n" -" assert(contract.get() == false, 'value !off');\n" -" assert(contract_iswitch.is_on() == false, 'switch !off');\n" -"\n" -" contract_iswitch.switch();\n" -" assert(contract_iswitch.is_on() == true, 'switch !on');\n" -" assert(contract.get() == true, 'value !on');\n" -"\n" -" // `collision` between component storage 'value' and contract " -"storage 'value'\n" -" assert(contract.get() == contract_iswitch.is_on(), 'value != " -"switch');\n" -"\n" -" contract.set(false);\n" -" assert(contract.get() == contract_iswitch.is_on(), 'value != " -"switch');\n" -" }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"# mod switch_collision_tests {\n" -"# use components::switchable::switchable_component::" -"SwitchableInternalTrait;\n" -"# use components::switchable::{ISwitchable, ISwitchableDispatcher, " -"ISwitchableDispatcherTrait};\n" -"# \n" -"# use components::contracts::switch_collision::{\n" -"# SwitchCollisionContract, ISwitchCollisionDispatcher, " -"ISwitchCollisionDispatcherTrait\n" -"# };\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (ISwitchCollisionDispatcher, ISwitchableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# SwitchCollisionContract::TEST_CLASS_HASH.try_into().unwrap(), " -"0, array![].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (\n" -"# ISwitchCollisionDispatcher { contract_address },\n" -"# ISwitchableDispatcher { contract_address },\n" -"# )\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -" fn test_collision() {\n" -" let (mut contract, mut contract_iswitch) = deploy();\n" -"\n" -" assert(contract.get() == false, 'value !off');\n" -" assert(contract_iswitch.is_on() == false, 'switch !off');\n" -"\n" -" contract_iswitch.switch();\n" -" assert(contract_iswitch.is_on() == true, 'switch !on');\n" -" assert(contract.get() == true, 'value !on');\n" -"\n" -" // `collision` between component storage 'value' and contract " -"storage 'value'\n" -" assert(contract.get() == contract_iswitch.is_on(), 'value != " -"switch');\n" -"\n" -" contract.set(false);\n" -" assert(contract.get() == contract_iswitch.is_on(), 'value != " -"switch');\n" -" }\n" -"# }\n" -"```" - -#: src/components/ownable.md:1 -msgid "# Ownable" -msgstr "# Ownable" - -#: src/components/ownable.md:3 -msgid "" -"The following `Ownable` component is a simple component that allows the " -"contract to set an owner and provides a `_assert_is_owner` function that can " -"be used to ensure that the caller is the owner." -msgstr "" -"El siguiente componente `Ownable` es un componente simple que permite al " -"contrato establecer un propietario y proporciona una función " -"`_assert_is_owner` que se puede utilizar para asegurarse de que el llamante " -"es el propietario." - -#: src/components/ownable.md:5 -msgid "" -"It can also be used to renounce ownership of a contract, meaning that no one " -"will be able to satisfy the `_assert_is_owner` function." -msgstr "" -"También se puede utilizar para renunciar a la propiedad de un contrato, lo " -"que significa que nadie podrá satisfacer la función `_assert_is_owner`." - -#: src/components/ownable.md:7 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IOwnable {\n" -" fn owner(self: @TContractState) -> ContractAddress;\n" -" fn transfer_ownership(ref self: TContractState, new: ContractAddress);\n" -" fn renounce_ownership(ref self: TContractState);\n" -"}\n" -"\n" -"mod Errors {\n" -" const UNAUTHORIZED: felt252 = 'Not owner';\n" -" const ZERO_ADDRESS_OWNER: felt252 = 'Owner cannot be zero';\n" -" const ZERO_ADDRESS_CALLER: felt252 = 'Caller cannot be zero';\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod ownable_component {\n" -" use starknet::{ContractAddress, get_caller_address};\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" ownable_owner: ContractAddress,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct OwnershipTransferredEvent {\n" -" previous: ContractAddress,\n" -" new: ContractAddress\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct OwnershipRenouncedEvent {\n" -" previous: ContractAddress\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" OwnershipTransferredEvent: OwnershipTransferredEvent,\n" -" OwnershipRenouncedEvent: OwnershipRenouncedEvent\n" -" }\n" -"\n" -" #[embeddable_as(Ownable)]\n" -" impl OwnableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::IOwnable> {\n" -" fn owner(self: @ComponentState) -> ContractAddress " -"{\n" -" self.ownable_owner.read()\n" -" }\n" -"\n" -" fn transfer_ownership(ref self: ComponentState, new: " -"ContractAddress) {\n" -" self._assert_only_owner();\n" -" self._transfer_ownership(new);\n" -" }\n" -"\n" -" fn renounce_ownership(ref self: ComponentState) {\n" -" self._assert_only_owner();\n" -" self._renounce_ownership();\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl OwnableInternalImpl<\n" -" TContractState, +HasComponent\n" -" > of OwnableInternalTrait {\n" -" fn _assert_only_owner(self: @ComponentState) {\n" -" let caller = get_caller_address();\n" -" assert(caller.is_non_zero(), Errors::ZERO_ADDRESS_CALLER);\n" -" assert(caller == self.ownable_owner.read(), Errors::" -"UNAUTHORIZED);\n" -" }\n" -"\n" -" fn _init(ref self: ComponentState, owner: " -"ContractAddress) {\n" -" assert(owner.is_non_zero(), Errors::ZERO_ADDRESS_OWNER);\n" -" self.ownable_owner.write(owner);\n" -" }\n" -"\n" -" fn _transfer_ownership(ref self: ComponentState, " -"new: ContractAddress) {\n" -" assert(new.is_non_zero(), Errors::ZERO_ADDRESS_OWNER);\n" -" let previous = self.ownable_owner.read();\n" -" self.ownable_owner.write(new);\n" -" self\n" -" .emit(\n" -" Event::" -"OwnershipTransferredEvent(OwnershipTransferredEvent { previous, new })\n" -" );\n" -" }\n" -"\n" -" fn _renounce_ownership(ref self: ComponentState) {\n" -" let previous = self.ownable_owner.read();\n" -" self.ownable_owner.write(Zeroable::zero());\n" -" self.emit(Event::OwnershipRenouncedEvent(OwnershipRenouncedEvent " -"{ previous }));\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IOwnable {\n" -" fn owner(self: @TContractState) -> ContractAddress;\n" -" fn transfer_ownership(ref self: TContractState, new: ContractAddress);\n" -" fn renounce_ownership(ref self: TContractState);\n" -"}\n" -"\n" -"mod Errors {\n" -" const UNAUTHORIZED: felt252 = 'Not owner';\n" -" const ZERO_ADDRESS_OWNER: felt252 = 'Owner cannot be zero';\n" -" const ZERO_ADDRESS_CALLER: felt252 = 'Caller cannot be zero';\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod ownable_component {\n" -" use starknet::{ContractAddress, get_caller_address};\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" ownable_owner: ContractAddress,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct OwnershipTransferredEvent {\n" -" previous: ContractAddress,\n" -" new: ContractAddress\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct OwnershipRenouncedEvent {\n" -" previous: ContractAddress\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" OwnershipTransferredEvent: OwnershipTransferredEvent,\n" -" OwnershipRenouncedEvent: OwnershipRenouncedEvent\n" -" }\n" -"\n" -" #[embeddable_as(Ownable)]\n" -" impl OwnableImpl<\n" -" TContractState, +HasComponent\n" -" > of super::IOwnable> {\n" -" fn owner(self: @ComponentState) -> ContractAddress " -"{\n" -" self.ownable_owner.read()\n" -" }\n" -"\n" -" fn transfer_ownership(ref self: ComponentState, new: " -"ContractAddress) {\n" -" self._assert_only_owner();\n" -" self._transfer_ownership(new);\n" -" }\n" -"\n" -" fn renounce_ownership(ref self: ComponentState) {\n" -" self._assert_only_owner();\n" -" self._renounce_ownership();\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl OwnableInternalImpl<\n" -" TContractState, +HasComponent\n" -" > of OwnableInternalTrait {\n" -" fn _assert_only_owner(self: @ComponentState) {\n" -" let caller = get_caller_address();\n" -" assert(caller.is_non_zero(), Errors::ZERO_ADDRESS_CALLER);\n" -" assert(caller == self.ownable_owner.read(), Errors::" -"UNAUTHORIZED);\n" -" }\n" -"\n" -" fn _init(ref self: ComponentState, owner: " -"ContractAddress) {\n" -" assert(owner.is_non_zero(), Errors::ZERO_ADDRESS_OWNER);\n" -" self.ownable_owner.write(owner);\n" -" }\n" -"\n" -" fn _transfer_ownership(ref self: ComponentState, " -"new: ContractAddress) {\n" -" assert(new.is_non_zero(), Errors::ZERO_ADDRESS_OWNER);\n" -" let previous = self.ownable_owner.read();\n" -" self.ownable_owner.write(new);\n" -" self\n" -" .emit(\n" -" Event::" -"OwnershipTransferredEvent(OwnershipTransferredEvent { previous, new })\n" -" );\n" -" }\n" -"\n" -" fn _renounce_ownership(ref self: ComponentState) {\n" -" let previous = self.ownable_owner.read();\n" -" self.ownable_owner.write(Zeroable::zero());\n" -" self.emit(Event::OwnershipRenouncedEvent(OwnershipRenouncedEvent " -"{ previous }));\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/components/ownable.md:104 -msgid "A mock contract that uses the `Ownable` component:" -msgstr "Un contrato simulado que utiliza el componente `Ownable`:" - -#: src/components/ownable.md:106 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IOwned {\n" -" fn do_something(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod OwnedContract {\n" -" use components::ownable::IOwnable;\n" -" use components::ownable::ownable_component::OwnableInternalTrait;\n" -" use components::ownable::ownable_component;\n" -"\n" -" component!(path: ownable_component, storage: ownable, event: " -"OwnableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl OwnableImpl = ownable_component::Ownable;\n" -" impl OwnableInternalImpl = ownable_component::" -"OwnableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" ownable: ownable_component::Storage,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.ownable._init(starknet::get_caller_address());\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" OwnableEvent: ownable_component::Event,\n" -" }\n" -"\n" -" #[external(v0)]\n" -" impl Owned of super::IOwned {\n" -" fn do_something(ref self: ContractState) {\n" -" self.ownable._assert_only_owner();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::{OwnedContract, IOwnedDispatcher, IOwnedDispatcherTrait};\n" -"# use components::ownable::{IOwnable, IOwnableDispatcher, " -"IOwnableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# \n" -"# use starknet::{contract_address_const, ContractAddress};\n" -"# use starknet::testing::{set_caller_address, set_contract_address};\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (IOwnedDispatcher, IOwnableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# OwnedContract::TEST_CLASS_HASH.try_into().unwrap(), 0, array!" -"[].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (IOwnedDispatcher { contract_address }, IOwnableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let owner = contract_address_const::<'owner'>();\n" -"# set_contract_address(owner);\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# assert(ownable.owner() == owner, 'wrong_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_wrong_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# let not_owner = contract_address_const::<'not_owner'>();\n" -"# assert(ownable.owner() != not_owner, 'wrong_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_do_something() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, _) = deploy();\n" -"# \n" -"# contract.do_something();\n" -"# // Should not panic\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_do_something_not_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, _) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# contract.do_something();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_transfer_ownership() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (contract, ownable) = deploy();\n" -"# \n" -"# let new_owner = contract_address_const::<'new_owner'>();\n" -"# ownable.transfer_ownership(new_owner);\n" -"# \n" -"# assert(ownable.owner() == new_owner, 'wrong_owner');\n" -"# \n" -"# set_contract_address(new_owner);\n" -"# contract.do_something();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_transfer_ownership_not_owner() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# ownable.transfer_ownership(contract_address_const::" -"<'new_owner'>());\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_transfer_ownership_zero_error() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# ownable.transfer_ownership(Zeroable::zero());\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_renounce_ownership() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# ownable.renounce_ownership();\n" -"# assert(ownable.owner() == Zeroable::zero(), 'not_zero_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_renounce_ownership_not_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# ownable.renounce_ownership();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_renounce_ownership_previous_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, ownable) = deploy();\n" -"# \n" -"# ownable.renounce_ownership();\n" -"# \n" -"# contract.do_something();\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IOwned {\n" -" fn do_something(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod OwnedContract {\n" -" use components::ownable::IOwnable;\n" -" use components::ownable::ownable_component::OwnableInternalTrait;\n" -" use components::ownable::ownable_component;\n" -"\n" -" component!(path: ownable_component, storage: ownable, event: " -"OwnableEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl OwnableImpl = ownable_component::Ownable;\n" -" impl OwnableInternalImpl = ownable_component::" -"OwnableInternalImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" ownable: ownable_component::Storage,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.ownable._init(starknet::get_caller_address());\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" OwnableEvent: ownable_component::Event,\n" -" }\n" -"\n" -" #[external(v0)]\n" -" impl Owned of super::IOwned {\n" -" fn do_something(ref self: ContractState) {\n" -" self.ownable._assert_only_owner();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::{OwnedContract, IOwnedDispatcher, IOwnedDispatcherTrait};\n" -"# use components::ownable::{IOwnable, IOwnableDispatcher, " -"IOwnableDispatcherTrait};\n" -"# \n" -"# use core::starknet::storage::StorageMemberAccessTrait;\n" -"# \n" -"# use starknet::{contract_address_const, ContractAddress};\n" -"# use starknet::testing::{set_caller_address, set_contract_address};\n" -"# use starknet::deploy_syscall;\n" -"# \n" -"# fn deploy() -> (IOwnedDispatcher, IOwnableDispatcher) {\n" -"# let (contract_address, _) = deploy_syscall(\n" -"# OwnedContract::TEST_CLASS_HASH.try_into().unwrap(), 0, array!" -"[].span(), false\n" -"# )\n" -"# .unwrap();\n" -"# \n" -"# (IOwnedDispatcher { contract_address }, IOwnableDispatcher " -"{ contract_address },)\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_init() {\n" -"# let owner = contract_address_const::<'owner'>();\n" -"# set_contract_address(owner);\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# assert(ownable.owner() == owner, 'wrong_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_wrong_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# let not_owner = contract_address_const::<'not_owner'>();\n" -"# assert(ownable.owner() != not_owner, 'wrong_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_do_something() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, _) = deploy();\n" -"# \n" -"# contract.do_something();\n" -"# // Should not panic\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_do_something_not_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, _) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# contract.do_something();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_transfer_ownership() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (contract, ownable) = deploy();\n" -"# \n" -"# let new_owner = contract_address_const::<'new_owner'>();\n" -"# ownable.transfer_ownership(new_owner);\n" -"# \n" -"# assert(ownable.owner() == new_owner, 'wrong_owner');\n" -"# \n" -"# set_contract_address(new_owner);\n" -"# contract.do_something();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_transfer_ownership_not_owner() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# ownable.transfer_ownership(contract_address_const::" -"<'new_owner'>());\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_transfer_ownership_zero_error() {\n" -"# set_contract_address(contract_address_const::<'initial'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# ownable.transfer_ownership(Zeroable::zero());\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# fn test_renounce_ownership() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# ownable.renounce_ownership();\n" -"# assert(ownable.owner() == Zeroable::zero(), 'not_zero_owner');\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_renounce_ownership_not_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (_, ownable) = deploy();\n" -"# \n" -"# set_contract_address(contract_address_const::<'not_owner'>());\n" -"# ownable.renounce_ownership();\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(2000000)]\n" -"# #[should_panic]\n" -"# fn test_renounce_ownership_previous_owner() {\n" -"# set_contract_address(contract_address_const::<'owner'>());\n" -"# let (contract, ownable) = deploy();\n" -"# \n" -"# ownable.renounce_ownership();\n" -"# \n" -"# contract.do_something();\n" -"# }\n" -"# }\n" -"```" - -#: src/components/ownable.md:282 src/advanced-concepts/hashing.md:133 -msgid "
Last change: 2024-01-05
" -msgstr "
Última modificación: 2024-01-05
" - -#: src/applications/upgradeable_contract.md:1 -msgid "# Upgradeable Contract" -msgstr "# Contratos Actualizables" - -#: src/applications/upgradeable_contract.md:3 -msgid "" -"In Starknet, contracts are divided into two parts: contract classes and " -"contract\n" -"instances. This division follows a similar concept used in object-oriented\n" -"programming languages, where we distinguish between the definition and " -"implementation\n" -"of objects." -msgstr "" -"En Starknet, los contratos se dividen en dos partes: clases de contratos e " -"instancias de contratos.\n" -"Esta división sigue un concepto similar al utilizado en los lenguajes de " -"programación orientados a objetos, en los que se distingue entre definición " -"e implementación de objetos." - -#: src/applications/upgradeable_contract.md:8 -msgid "" -"A contract class is the definition of a contract: it specifies how the " -"contract\n" -"behaves. It contains essential information like the Cairo byte code, hint\n" -"information, entry point names, and everything that defines its semantics\n" -"unambiguously." -msgstr "" -"Una clase de contrato es la definición de un contrato: especifica cómo se " -"comporta el contrato.\n" -"Contiene información esencial como el código de bytes de Cairo, información " -"de pistas,\n" -"nombres de puntos de entrada y todo lo que define su semántica\n" -"sin ambigüedades." - -#: src/applications/upgradeable_contract.md:13 -msgid "" -"To identify different contract classes, Starknet assigns a unique identifier " -"to each\n" -"class: the class hash. A contract instance is a deployed contract that " -"corresponds to\n" -"a specific contract class. Think of it as an instance of an object in " -"languages like\n" -"Java." -msgstr "" -"Para identificar las diferentes clases de contratos, Starknet asigna un " -"identificador único a cada clase: el hash de la clase. Una instancia de " -"contrato es un contrato desplegado que corresponde a una clase de contrato " -"específica. Piense en ello como una instancia de un objeto en lenguajes como " -"Java." - -#: src/applications/upgradeable_contract.md:18 -msgid "" -"Each class is identified by its class hash, which is analogous to a class " -"name in an object-oriented programming language. A contract instance is a " -"deployed contract corresponding to a class." -msgstr "" -"Cada clase se identifica por su hash de clase, que es análogo a un nombre de " -"clase en un lenguaje de programación orientado a objetos. Una instancia de " -"contrato es un contrato desplegado correspondiente a una clase." - -#: src/applications/upgradeable_contract.md:20 -msgid "" -"You can upgrade a deployed contract to a newer version by calling the " -"`replace_class_syscall` function. By using this function, you can update the " -"class hash associated with a deployed contract, effectively upgrading its " -"implementation. However, this will not modify the contract's storage, so all " -"the data stored in the contract will remain the same." -msgstr "" -"Puedes actualizar un contrato desplegado a una versión más reciente llamando " -"a la función `replace_class_syscall`. Usando esta función, puedes actualizar " -"el hash de clase asociado con un contrato desplegado, actualizando " -"efectivamente su implementación. Sin embargo, esto no modificará el " -"almacenamiento del contrato, por lo que todos los datos almacenados en el " -"contrato seguirán siendo los mismos." - -#: src/applications/upgradeable_contract.md:22 -msgid "" -"To illustrate this concept, let's consider an example with two contracts: " -"`UpgradeableContract_V0`, and `UpgradeableContract_V1`.\n" -"Start by deploying `UpgradeableContract_V0` as the initial version. Next, " -"send a transaction that invokes the `upgrade` function, with the class hash " -"of `UpgradeableContract_V1` as parameter to upgrade the class hash of the " -"deployed contract to the `UpgradeableContract_V1` one. Then, call the " -"`version` method on the contract to see that the contract was upgraded to " -"the V1 version." -msgstr "" -"Para ilustrar este concepto, consideremos un ejemplo con dos contratos: " -"Contrato Actualizable V0 y Contrato Actualizable V1.\n" -"Comience desplegando `UpgradeableContract_V0` como versión inicial. A " -"continuación, envía una transacción que invoque a la función `upgrade`, con " -"el hash de clase del `UpgradeableContract_V1` como parámetro para actualizar " -"el hash de clase del contrato desplegado al del `UpgradeableContract_V1`. " -"Luego, llama al método `version` en el contrato para ver que el contrato fue " -"actualizado a la versión V1." - -#: src/applications/upgradeable_contract.md:25 -msgid "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V0 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 0\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V0 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 0\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/upgradeable_contract.md:68 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x005300003ade5d10447d941a42d48b7141074cd8bade2b16520684896a5090ea) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v0.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x005300003ade5d10447d941a42d48b7141074cd8bade2b16520684896a5090ea) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v0.cairo)." - -#: src/applications/upgradeable_contract.md:71 -msgid "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V1 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 1\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V1 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract " -"{\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 1\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/upgradeable_contract.md:114 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x017c86152badd1d665b9836571bd6b0a484f028748aa13d9b2d5d9c9192fafc6) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v1.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x017c86152badd1d665b9836571bd6b0a484f028748aa13d9b2d5d9c9192fafc6) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v1.cairo)." - -#: src/applications/simple_vault.md:1 -msgid "# Simple Defi Vault" -msgstr "# Simple Defi Vault" - -#: src/applications/simple_vault.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example Vault](https://" -"solidity-by-example.org/defi/vault/).\n" -"Here's how it works:" -msgstr "" -"Se trata de la adaptación cairota de la [Solidity by example Vault](https://" -"solidity-by-example.org/defi/vault/).\n" -"Funciona de la siguiente manera:" - -#: src/applications/simple_vault.md:6 -msgid "" -"- When a user deposits a token, the contract calculates the amount of shares " -"to mint.\n" -"\n" -"- When a user withdraws, the contract burns their shares, calculates the " -"yield, and withdraw both the yield and the initial amount of token deposited." -msgstr "" -"- Cuando un usuario deposita un token, el contrato calcula la cantidad de " -"acciones a acuñar.\n" -"\n" -"- Cuando un usuario retira, el contrato quema sus acciones, calcula el " -"rendimiento y retira tanto el rendimiento como la cantidad inicial de token " -"depositada." - -#: src/applications/simple_vault.md:10 -msgid "" -"```cairo\n" -"use starknet::{ContractAddress};\n" -"\n" -"// In order to make contract calls within our Vault,\n" -"// we need to have the interface of the remote ERC20 contract defined to " -"import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn name(self: @TContractState) -> felt252;\n" -" fn symbol(self: @TContractState) -> felt252;\n" -" fn decimals(self: @TContractState) -> u8;\n" -" fn total_supply(self: @TContractState) -> u256;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> u256;\n" -" fn allowance(self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress) -> u256;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, " -"amount: u256) -> bool;\n" -" fn transfer_from(\n" -" ref self: TContractState, sender: ContractAddress, recipient: " -"ContractAddress, amount: u256\n" -" ) -> bool;\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"u256) -> bool;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleVault {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, shares: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleVault {\n" -" use super::{IERC20Dispatcher, IERC20DispatcherTrait};\n" -" use starknet::{ContractAddress, get_caller_address, " -"get_contract_address};\n" -" #[storage]\n" -" struct Storage {\n" -" token: IERC20Dispatcher,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, token: ContractAddress) {\n" -" self.token.write(IERC20Dispatcher { contract_address: token });\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, shares: u256) " -"{\n" -" self.total_supply.write(self.total_supply.read() + shares);\n" -" self.balance_of.write(to, self.balance_of.read(to) + shares);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, shares: " -"u256) {\n" -" self.total_supply.write(self.total_supply.read() - shares);\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"shares);\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleVault of super::ISimpleVault {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" // a = amount\n" -" // B = balance of token before deposit\n" -" // T = total supply\n" -" // s = shares to mint\n" -" //\n" -" // (T + s) / T = (a + B) / B \n" -" //\n" -" // s = aT / B\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let mut shares = 0;\n" -" if self.total_supply.read() == 0 {\n" -" shares = amount;\n" -" } else {\n" -" let balance = self.token.read().balance_of(this);\n" -" shares = (amount * self.total_supply.read()) / balance;\n" -" }\n" -"\n" -" PrivateFunctions::_mint(ref self, caller, shares);\n" -" self.token.read().transfer_from(caller, this, amount);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, shares: u256) {\n" -" // a = amount\n" -" // B = balance of token before withdraw\n" -" // T = total supply\n" -" // s = shares to burn\n" -" //\n" -" // (T - s) / T = (B - a) / B \n" -" //\n" -" // a = sB / T\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let balance = self.token.read().balance_of(this);\n" -" let amount = (shares * balance) / self.total_supply.read();\n" -" PrivateFunctions::_burn(ref self, caller, shares);\n" -" self.token.read().transfer(caller, amount);\n" -" }\n" -" }\n" -"}\n" -"\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::{ContractAddress};\n" -"\n" -"// In order to make contract calls within our Vault,\n" -"// we need to have the interface of the remote ERC20 contract defined to " -"import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn name(self: @TContractState) -> felt252;\n" -" fn symbol(self: @TContractState) -> felt252;\n" -" fn decimals(self: @TContractState) -> u8;\n" -" fn total_supply(self: @TContractState) -> u256;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> u256;\n" -" fn allowance(self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress) -> u256;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, " -"amount: u256) -> bool;\n" -" fn transfer_from(\n" -" ref self: TContractState, sender: ContractAddress, recipient: " -"ContractAddress, amount: u256\n" -" ) -> bool;\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"u256) -> bool;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleVault {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, shares: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleVault {\n" -" use super::{IERC20Dispatcher, IERC20DispatcherTrait};\n" -" use starknet::{ContractAddress, get_caller_address, " -"get_contract_address};\n" -" #[storage]\n" -" struct Storage {\n" -" token: IERC20Dispatcher,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, token: ContractAddress) {\n" -" self.token.write(IERC20Dispatcher { contract_address: token });\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, shares: u256) " -"{\n" -" self.total_supply.write(self.total_supply.read() + shares);\n" -" self.balance_of.write(to, self.balance_of.read(to) + shares);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, shares: " -"u256) {\n" -" self.total_supply.write(self.total_supply.read() - shares);\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"shares);\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleVault of super::ISimpleVault {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" // a = amount\n" -" // B = balance of token before deposit\n" -" // T = total supply\n" -" // s = shares to mint\n" -" //\n" -" // (T + s) / T = (a + B) / B \n" -" //\n" -" // s = aT / B\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let mut shares = 0;\n" -" if self.total_supply.read() == 0 {\n" -" shares = amount;\n" -" } else {\n" -" let balance = self.token.read().balance_of(this);\n" -" shares = (amount * self.total_supply.read()) / balance;\n" -" }\n" -"\n" -" PrivateFunctions::_mint(ref self, caller, shares);\n" -" self.token.read().transfer_from(caller, this, amount);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, shares: u256) {\n" -" // a = amount\n" -" // B = balance of token before withdraw\n" -" // T = total supply\n" -" // s = shares to burn\n" -" //\n" -" // (T - s) / T = (B - a) / B \n" -" //\n" -" // a = sB / T\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let balance = self.token.read().balance_of(this);\n" -" let amount = (shares * balance) / self.total_supply.read();\n" -" PrivateFunctions::_burn(ref self, caller, shares);\n" -" self.token.read().transfer(caller, amount);\n" -" }\n" -" }\n" -"}\n" -"\n" -"```" - -#: src/applications/simple_vault.md:113 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/simple_vault/src/simple_vault.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/simple_vault/src/simple_vault.cairo)." - -#: src/applications/erc20.md:1 -msgid "# ERC20 Token" -msgstr "# Token ERC20" - -#: src/applications/erc20.md:3 -msgid "" -"Contracts that follow the [ERC20 Standard](https://eips.ethereum.org/EIPS/" -"eip-20) are called ERC20 tokens. They are used to represent fungible assets." -msgstr "" -"Los contratos que siguen el [Standard ERC20](https://eips.ethereum.org/EIPS/" -"eip-20) se denominan tokens ERC20. Se utilizan para representar activos " -"fungibles." - -#: src/applications/erc20.md:5 -msgid "" -"To create an ERC20 conctract, it must implement the following interface:" -msgstr "Para crear un contrato ERC20, debe implementar la siguiente interfaz:" - -#: src/applications/erc20.md:7 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn get_name(self: @TContractState) -> felt252;\n" -" fn get_symbol(self: @TContractState) -> felt252;\n" -" fn get_decimals(self: @TContractState) -> u8;\n" -" fn get_total_supply(self: @TContractState) -> felt252;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> " -"felt252;\n" -" fn allowance(\n" -" self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, " -"amount: felt252);\n" -" fn transfer_from(\n" -" ref self: TContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" );\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"felt252);\n" -" fn increase_allowance(ref self: TContractState, spender: " -"ContractAddress, added_value: felt252);\n" -" fn decrease_allowance(\n" -" ref self: TContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" );\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn get_name(self: @TContractState) -> felt252;\n" -" fn get_symbol(self: @TContractState) -> felt252;\n" -" fn get_decimals(self: @TContractState) -> u8;\n" -" fn get_total_supply(self: @TContractState) -> felt252;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> " -"felt252;\n" -" fn allowance(\n" -" self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, " -"amount: felt252);\n" -" fn transfer_from(\n" -" ref self: TContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" );\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"felt252);\n" -" fn increase_allowance(ref self: TContractState, spender: " -"ContractAddress, added_value: felt252);\n" -" fn decrease_allowance(\n" -" ref self: TContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" );\n" -"}\n" -"```" - -#: src/applications/erc20.md:33 -msgid "" -"In Starknet, function names should be written in *snake_case*. This is not " -"the case in Solidity, where function names are written in *camelCase*.\n" -"The Starknet ERC20 interface is therefore slightly different from the " -"Solidity ERC20 interface." -msgstr "" -"En Starknet, los nombres de las funciones deben escribirse en *snake_case*. " -"Este no es el caso en Solidity, donde los nombres de las funciones se " -"escriben en *camelCase*.\n" -"Por lo tanto, la interfaz ERC20 de Starknet es ligeramente diferente de la " -"interfaz ERC20 de Solidity." - -#: src/applications/erc20.md:36 -msgid "Here's an implementation of the ERC20 interface in Cairo:" -msgstr "He aquí una implementación de la interfaz ERC20 en Cairo:" - -#: src/applications/erc20.md:38 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod erc20 {\n" -" use zeroable::Zeroable;\n" -" use starknet::get_caller_address;\n" -" use starknet::contract_address_const;\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" name: felt252,\n" -" symbol: felt252,\n" -" decimals: u8,\n" -" total_supply: felt252,\n" -" balances: LegacyMap::,\n" -" allowances: LegacyMap::<(ContractAddress, ContractAddress), " -"felt252>,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Transfer: Transfer,\n" -" Approval: Approval,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Transfer {\n" -" from: ContractAddress,\n" -" to: ContractAddress,\n" -" value: felt252,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Approval {\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" value: felt252,\n" -" }\n" -"\n" -" mod Errors {\n" -" const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0';\n" -" const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0';\n" -" const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0';\n" -" const TRANSFER_TO_ZERO: felt252 = 'ERC20: transfer to 0';\n" -" const BURN_FROM_ZERO: felt252 = 'ERC20: burn from 0';\n" -" const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0';\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState,\n" -" recipient: ContractAddress,\n" -" name: felt252,\n" -" decimals: u8,\n" -" initial_supply: felt252,\n" -" symbol: felt252\n" -" ) {\n" -" self.name.write(name);\n" -" self.symbol.write(symbol);\n" -" self.decimals.write(decimals);\n" -" self.mint(recipient, initial_supply);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl IERC20Impl of super::IERC20 {\n" -" fn get_name(self: @ContractState) -> felt252 {\n" -" self.name.read()\n" -" }\n" -"\n" -" fn get_symbol(self: @ContractState) -> felt252 {\n" -" self.symbol.read()\n" -" }\n" -"\n" -" fn get_decimals(self: @ContractState) -> u8 {\n" -" self.decimals.read()\n" -" }\n" -"\n" -" fn get_total_supply(self: @ContractState) -> felt252 {\n" -" self.total_supply.read()\n" -" }\n" -"\n" -" fn balance_of(self: @ContractState, account: ContractAddress) -> " -"felt252 {\n" -" self.balances.read(account)\n" -" }\n" -"\n" -" fn allowance(\n" -" self: @ContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252 {\n" -" self.allowances.read((owner, spender))\n" -" }\n" -"\n" -" fn transfer(ref self: ContractState, recipient: ContractAddress, " -"amount: felt252) {\n" -" let sender = get_caller_address();\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn transfer_from(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self.spend_allowance(sender, caller, amount);\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn approve(ref self: ContractState, spender: ContractAddress, " -"amount: felt252) {\n" -" let caller = get_caller_address();\n" -" self.approve_helper(caller, spender, amount);\n" -" }\n" -"\n" -" fn increase_allowance(\n" -" ref self: ContractState, spender: ContractAddress, added_value: " -"felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"+ added_value\n" -" );\n" -" }\n" -"\n" -" fn decrease_allowance(\n" -" ref self: ContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"- subtracted_value\n" -" );\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalImpl of InternalTrait {\n" -" fn _transfer(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(sender.is_non_zero(), Errors::TRANSFER_FROM_ZERO);\n" -" assert(recipient.is_non_zero(), Errors::TRANSFER_TO_ZERO);\n" -" self.balances.write(sender, self.balances.read(sender) - " -"amount);\n" -" self.balances.write(recipient, self.balances.read(recipient) + " -"amount);\n" -" self.emit(Transfer { from: sender, to: recipient, value: " -"amount });\n" -" }\n" -"\n" -" fn spend_allowance(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let allowance = self.allowances.read((owner, spender));\n" -" self.allowances.write((owner, spender), allowance - amount);\n" -" }\n" -"\n" -" fn approve_helper(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(spender.is_non_zero(), Errors::APPROVE_TO_ZERO);\n" -" self.allowances.write((owner, spender), amount);\n" -" self.emit(Approval { owner, spender, value: amount });\n" -" }\n" -"\n" -" fn mint(ref self: ContractState, recipient: ContractAddress, amount: " -"felt252) {\n" -" assert(recipient.is_non_zero(), Errors::MINT_TO_ZERO);\n" -" let supply = self.total_supply.read() + amount; // What can go " -"wrong here?\n" -" self.total_supply.write(supply);\n" -" let balance = self.balances.read(recipient) + amount;\n" -" self.balances.write(recipient, amount);\n" -" self\n" -" .emit(\n" -" Event::Transfer(\n" -" Transfer {\n" -" from: contract_address_const::<0>(), to: " -"recipient, value: amount\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod erc20 {\n" -" use zeroable::Zeroable;\n" -" use starknet::get_caller_address;\n" -" use starknet::contract_address_const;\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" name: felt252,\n" -" symbol: felt252,\n" -" decimals: u8,\n" -" total_supply: felt252,\n" -" balances: LegacyMap::,\n" -" allowances: LegacyMap::<(ContractAddress, ContractAddress), " -"felt252>,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Transfer: Transfer,\n" -" Approval: Approval,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Transfer {\n" -" from: ContractAddress,\n" -" to: ContractAddress,\n" -" value: felt252,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Approval {\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" value: felt252,\n" -" }\n" -"\n" -" mod Errors {\n" -" const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0';\n" -" const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0';\n" -" const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0';\n" -" const TRANSFER_TO_ZERO: felt252 = 'ERC20: transfer to 0';\n" -" const BURN_FROM_ZERO: felt252 = 'ERC20: burn from 0';\n" -" const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0';\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState,\n" -" recipient: ContractAddress,\n" -" name: felt252,\n" -" decimals: u8,\n" -" initial_supply: felt252,\n" -" symbol: felt252\n" -" ) {\n" -" self.name.write(name);\n" -" self.symbol.write(symbol);\n" -" self.decimals.write(decimals);\n" -" self.mint(recipient, initial_supply);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl IERC20Impl of super::IERC20 {\n" -" fn get_name(self: @ContractState) -> felt252 {\n" -" self.name.read()\n" -" }\n" -"\n" -" fn get_symbol(self: @ContractState) -> felt252 {\n" -" self.symbol.read()\n" -" }\n" -"\n" -" fn get_decimals(self: @ContractState) -> u8 {\n" -" self.decimals.read()\n" -" }\n" -"\n" -" fn get_total_supply(self: @ContractState) -> felt252 {\n" -" self.total_supply.read()\n" -" }\n" -"\n" -" fn balance_of(self: @ContractState, account: ContractAddress) -> " -"felt252 {\n" -" self.balances.read(account)\n" -" }\n" -"\n" -" fn allowance(\n" -" self: @ContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252 {\n" -" self.allowances.read((owner, spender))\n" -" }\n" -"\n" -" fn transfer(ref self: ContractState, recipient: ContractAddress, " -"amount: felt252) {\n" -" let sender = get_caller_address();\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn transfer_from(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self.spend_allowance(sender, caller, amount);\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn approve(ref self: ContractState, spender: ContractAddress, " -"amount: felt252) {\n" -" let caller = get_caller_address();\n" -" self.approve_helper(caller, spender, amount);\n" -" }\n" -"\n" -" fn increase_allowance(\n" -" ref self: ContractState, spender: ContractAddress, added_value: " -"felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"+ added_value\n" -" );\n" -" }\n" -"\n" -" fn decrease_allowance(\n" -" ref self: ContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"- subtracted_value\n" -" );\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalImpl of InternalTrait {\n" -" fn _transfer(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(sender.is_non_zero(), Errors::TRANSFER_FROM_ZERO);\n" -" assert(recipient.is_non_zero(), Errors::TRANSFER_TO_ZERO);\n" -" self.balances.write(sender, self.balances.read(sender) - " -"amount);\n" -" self.balances.write(recipient, self.balances.read(recipient) + " -"amount);\n" -" self.emit(Transfer { from: sender, to: recipient, value: " -"amount });\n" -" }\n" -"\n" -" fn spend_allowance(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let allowance = self.allowances.read((owner, spender));\n" -" self.allowances.write((owner, spender), allowance - amount);\n" -" }\n" -"\n" -" fn approve_helper(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(spender.is_non_zero(), Errors::APPROVE_TO_ZERO);\n" -" self.allowances.write((owner, spender), amount);\n" -" self.emit(Approval { owner, spender, value: amount });\n" -" }\n" -"\n" -" fn mint(ref self: ContractState, recipient: ContractAddress, amount: " -"felt252) {\n" -" assert(recipient.is_non_zero(), Errors::MINT_TO_ZERO);\n" -" let supply = self.total_supply.read() + amount; // What can go " -"wrong here?\n" -" self.total_supply.write(supply);\n" -" let balance = self.balances.read(recipient) + amount;\n" -" self.balances.write(recipient, amount);\n" -" self\n" -" .emit(\n" -" Event::Transfer(\n" -" Transfer {\n" -" from: contract_address_const::<0>(), to: " -"recipient, value: amount\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/erc20.md:224 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/erc20/src/token.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/erc20/src/token.cairo)." - -#: src/applications/erc20.md:226 -msgid "" -"There's several other implementations, such as the [Open Zeppelin](https://" -"docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the [Cairo By Example]" -"(https://cairo-by-example.com/examples/erc20/) ones." -msgstr "" -"Existen otras implementaciones, como la [Open Zeppelin](https://docs." -"openzeppelin.com/contracts-cairo/0.7.0/erc20) o la [Cairo By Example]" -"(https://cairo-by-example.com/examples/erc20/)." - -#: src/applications/constant-product-amm.md:1 -msgid "# Constant Product AMM" -msgstr "# AMM de Producto Constante" - -#: src/applications/constant-product-amm.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example Constant Product " -"AMM](https://solidity-by-example.org/defi/constant-product-amm/)." -msgstr "" -"Se trata de la adaptación cairota de la [Solidez por ejemplo Producto " -"Constante AMM](https://solidity-by-example.org/defi/constant-product-amm/)." - -#: src/applications/constant-product-amm.md:5 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IConstantProductAmm {\n" -" fn swap(ref self: TContractState, token_in: ContractAddress, amount_in: " -"u256) -> u256;\n" -" fn add_liquidity(ref self: TContractState, amount0: u256, amount1: u256) " -"-> u256;\n" -" fn remove_liquidity(ref self: TContractState, shares: u256) -> (u256, " -"u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ConstantProductAmm {\n" -" use core::traits::Into;\n" -" use openzeppelin::token::erc20::interface::{IERC20Dispatcher, " -"IERC20DispatcherTrait};\n" -" use starknet::{\n" -" ContractAddress, get_caller_address, get_contract_address, " -"contract_address_const\n" -" };\n" -" use integer::u256_sqrt;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" token0: IERC20Dispatcher,\n" -" token1: IERC20Dispatcher,\n" -" reserve0: u256,\n" -" reserve1: u256,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap::,\n" -" // Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -" // E.g. 3 = 0.3%\n" -" fee: u16,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState, token0: ContractAddress, token1: " -"ContractAddress, fee: u16\n" -" ) {\n" -" // assert(fee <= 1000, 'fee > 1000');\n" -" self.token0.write(IERC20Dispatcher { contract_address: token0 });\n" -" self.token1.write(IERC20Dispatcher { contract_address: token1 });\n" -" self.fee.write(fee);\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, amount: u256) " -"{\n" -" self.balance_of.write(to, self.balance_of.read(to) + amount);\n" -" self.total_supply.write(self.total_supply.read() + amount);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, amount: " -"u256) {\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"amount);\n" -" self.total_supply.write(self.total_supply.read() - amount);\n" -" }\n" -"\n" -" fn _update(ref self: ContractState, reserve0: u256, reserve1: u256) " -"{\n" -" self.reserve0.write(reserve0);\n" -" self.reserve1.write(reserve1);\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn select_token(self: @ContractState, token: ContractAddress) -> " -"bool {\n" -" assert(\n" -" token == self.token0.read().contract_address\n" -" || token == self.token1.read().contract_address,\n" -" 'invalid token'\n" -" );\n" -" token == self.token0.read().contract_address\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn min(x: u256, y: u256) -> u256 {\n" -" if (x <= y) {\n" -" x\n" -" } else {\n" -" y\n" -" }\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ConstantProductAmm of super::IConstantProductAmm {\n" -" fn swap(ref self: ContractState, token_in: ContractAddress, " -"amount_in: u256) -> u256 {\n" -" assert(amount_in > 0, 'amount in = 0');\n" -" let is_token0: bool = self.select_token(token_in);\n" -"\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" let (\n" -" token_in, token_out, reserve_in, reserve_out\n" -" ): (IERC20Dispatcher, IERC20Dispatcher, u256, u256) =\n" -" if (is_token0) {\n" -" (token0, token1, reserve0, reserve1)\n" -" } else {\n" -" (token1, token0, reserve1, reserve0)\n" -" };\n" -"\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" token_in.transfer_from(caller, this, amount_in);\n" -"\n" -" // How much dy for dx?\n" -" // xy = k\n" -" // (x + dx)(y - dy) = k\n" -" // y - dy = k / (x + dx)\n" -" // y - k / (x + dx) = dy\n" -" // y - xy / (x + dx) = dy\n" -" // (yx + ydx - xy) / (x + dx) = dy\n" -" // ydx / (x + dx) = dy\n" -"\n" -" let amount_in_with_fee = (amount_in * (1000 - self.fee.read()." -"into()) / 1000);\n" -" let amount_out = (reserve_out * amount_in_with_fee) / " -"(reserve_in + amount_in_with_fee);\n" -"\n" -" token_out.transfer(caller, amount_out);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" amount_out\n" -" }\n" -"\n" -" fn add_liquidity(ref self: ContractState, amount0: u256, amount1: " -"u256) -> u256 {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" token0.transfer_from(caller, this, amount0);\n" -" token1.transfer_from(caller, this, amount1);\n" -"\n" -" // How much dx, dy to add?\n" -" //\n" -" // xy = k\n" -" // (x + dx)(y + dy) = k'\n" -" //\n" -" // No price change, before and after adding liquidity\n" -" // x / y = (x + dx) / (y + dy)\n" -" //\n" -" // x(y + dy) = y(x + dx)\n" -" // x * dy = y * dx\n" -" //\n" -" // x / y = dx / dy\n" -" // dy = y / x * dx\n" -"\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" if (reserve0 > 0 || reserve1 > 0) {\n" -" assert(reserve0 * amount1 == reserve1 * amount0, 'x / y != " -"dx / dy');\n" -" }\n" -"\n" -" // How much shares to mint?\n" -" //\n" -" // f(x, y) = value of liquidity\n" -" // We will define f(x, y) = sqrt(xy)\n" -" //\n" -" // L0 = f(x, y)\n" -" // L1 = f(x + dx, y + dy)\n" -" // T = total shares\n" -" // s = shares to mint\n" -" //\n" -" // Total shares should increase proportional to increase in " -"liquidity\n" -" // L1 / L0 = (T + s) / T\n" -" //\n" -" // L1 * T = L0 * (T + s)\n" -" //\n" -" // (L1 - L0) * T / L0 = s\n" -"\n" -" // Claim\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -" //\n" -" // Proof\n" -" // --- Equation 1 ---\n" -" // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // dx / dy = x / y so replace dy = dx * y / x\n" -" //\n" -" // --- Equation 2 ---\n" -" // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // Multiply by sqrt(x) / sqrt(x)\n" -" // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - sqrt(x^2y)) / " -"sqrt(x^2y)\n" -" // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(y)sqrt(x^2))\n" -" // sqrt(y) on top and bottom cancels out\n" -" //\n" -" // --- Equation 3 ---\n" -" // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(x^2)\n" -" // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -" // = ((x + dx) - x) / x\n" -" // = dx / x\n" -" // Since dx / dy = x / y,\n" -" // dx / x = dy / y\n" -" //\n" -" // Finally\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let shares = if (total_supply == 0) {\n" -" u256_sqrt(amount0 * amount1).into()\n" -" } else {\n" -" PrivateFunctions::min(\n" -" amount0 * total_supply / reserve0, amount1 * " -"total_supply / reserve1\n" -" )\n" -" };\n" -" assert(shares > 0, 'shares = 0');\n" -" self._mint(caller, shares);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" shares\n" -" }\n" -"\n" -" fn remove_liquidity(ref self: ContractState, shares: u256) -> (u256, " -"u256) {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" // Claim\n" -" // dx, dy = amount of liquidity to remove\n" -" // dx = s / T * x\n" -" // dy = s / T * y\n" -" //\n" -" // Proof\n" -" // Let's find dx, dy such that\n" -" // v / L = s / T\n" -" //\n" -" // where\n" -" // v = f(dx, dy) = sqrt(dxdy)\n" -" // L = total liquidity = sqrt(xy)\n" -" // s = shares\n" -" // T = total supply\n" -" //\n" -" // --- Equation 1 ---\n" -" // v = s / T * L\n" -" // sqrt(dxdy) = s / T * sqrt(xy)\n" -" //\n" -" // Amount of liquidity to remove must not change price so\n" -" // dx / dy = x / y\n" -" //\n" -" // replace dy = dx * y / x\n" -" // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -" //\n" -" // Divide both sides of Equation 1 with sqrt(y / x)\n" -" // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -" // = s / T * sqrt(x^2) = s / T * x\n" -" //\n" -" // Likewise\n" -" // dy = s / T * y\n" -"\n" -" // bal0 >= reserve0\n" -" // bal1 >= reserve1\n" -" let (bal0, bal1): (u256, u256) = (token0.balance_of(this), " -"token1.balance_of(this));\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let (amount0, amount1): (u256, u256) = (\n" -" (shares * bal0) / total_supply, (shares * bal1) / " -"total_supply\n" -" );\n" -" assert(amount0 > 0 && amount1 > 0, 'amount0 or amount1 = 0');\n" -"\n" -" self._burn(caller, shares);\n" -" self._update(bal0 - amount0, bal1 - amount1);\n" -"\n" -" token0.transfer(caller, amount0);\n" -" token1.transfer(caller, amount1);\n" -" (amount0, amount1)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IConstantProductAmm {\n" -" fn swap(ref self: TContractState, token_in: ContractAddress, amount_in: " -"u256) -> u256;\n" -" fn add_liquidity(ref self: TContractState, amount0: u256, amount1: u256) " -"-> u256;\n" -" fn remove_liquidity(ref self: TContractState, shares: u256) -> (u256, " -"u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ConstantProductAmm {\n" -" use core::traits::Into;\n" -" use openzeppelin::token::erc20::interface::{IERC20Dispatcher, " -"IERC20DispatcherTrait};\n" -" use starknet::{\n" -" ContractAddress, get_caller_address, get_contract_address, " -"contract_address_const\n" -" };\n" -" use integer::u256_sqrt;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" token0: IERC20Dispatcher,\n" -" token1: IERC20Dispatcher,\n" -" reserve0: u256,\n" -" reserve1: u256,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap::,\n" -" // Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -" // E.g. 3 = 0.3%\n" -" fee: u16,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState, token0: ContractAddress, token1: " -"ContractAddress, fee: u16\n" -" ) {\n" -" // assert(fee <= 1000, 'fee > 1000');\n" -" self.token0.write(IERC20Dispatcher { contract_address: token0 });\n" -" self.token1.write(IERC20Dispatcher { contract_address: token1 });\n" -" self.fee.write(fee);\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, amount: u256) " -"{\n" -" self.balance_of.write(to, self.balance_of.read(to) + amount);\n" -" self.total_supply.write(self.total_supply.read() + amount);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, amount: " -"u256) {\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"amount);\n" -" self.total_supply.write(self.total_supply.read() - amount);\n" -" }\n" -"\n" -" fn _update(ref self: ContractState, reserve0: u256, reserve1: u256) " -"{\n" -" self.reserve0.write(reserve0);\n" -" self.reserve1.write(reserve1);\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn select_token(self: @ContractState, token: ContractAddress) -> " -"bool {\n" -" assert(\n" -" token == self.token0.read().contract_address\n" -" || token == self.token1.read().contract_address,\n" -" 'invalid token'\n" -" );\n" -" token == self.token0.read().contract_address\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn min(x: u256, y: u256) -> u256 {\n" -" if (x <= y) {\n" -" x\n" -" } else {\n" -" y\n" -" }\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ConstantProductAmm of super::IConstantProductAmm {\n" -" fn swap(ref self: ContractState, token_in: ContractAddress, " -"amount_in: u256) -> u256 {\n" -" assert(amount_in > 0, 'amount in = 0');\n" -" let is_token0: bool = self.select_token(token_in);\n" -"\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" let (\n" -" token_in, token_out, reserve_in, reserve_out\n" -" ): (IERC20Dispatcher, IERC20Dispatcher, u256, u256) =\n" -" if (is_token0) {\n" -" (token0, token1, reserve0, reserve1)\n" -" } else {\n" -" (token1, token0, reserve1, reserve0)\n" -" };\n" -"\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" token_in.transfer_from(caller, this, amount_in);\n" -"\n" -" // How much dy for dx?\n" -" // xy = k\n" -" // (x + dx)(y - dy) = k\n" -" // y - dy = k / (x + dx)\n" -" // y - k / (x + dx) = dy\n" -" // y - xy / (x + dx) = dy\n" -" // (yx + ydx - xy) / (x + dx) = dy\n" -" // ydx / (x + dx) = dy\n" -"\n" -" let amount_in_with_fee = (amount_in * (1000 - self.fee.read()." -"into()) / 1000);\n" -" let amount_out = (reserve_out * amount_in_with_fee) / " -"(reserve_in + amount_in_with_fee);\n" -"\n" -" token_out.transfer(caller, amount_out);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" amount_out\n" -" }\n" -"\n" -" fn add_liquidity(ref self: ContractState, amount0: u256, amount1: " -"u256) -> u256 {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" token0.transfer_from(caller, this, amount0);\n" -" token1.transfer_from(caller, this, amount1);\n" -"\n" -" // How much dx, dy to add?\n" -" //\n" -" // xy = k\n" -" // (x + dx)(y + dy) = k'\n" -" //\n" -" // No price change, before and after adding liquidity\n" -" // x / y = (x + dx) / (y + dy)\n" -" //\n" -" // x(y + dy) = y(x + dx)\n" -" // x * dy = y * dx\n" -" //\n" -" // x / y = dx / dy\n" -" // dy = y / x * dx\n" -"\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" if (reserve0 > 0 || reserve1 > 0) {\n" -" assert(reserve0 * amount1 == reserve1 * amount0, 'x / y != " -"dx / dy');\n" -" }\n" -"\n" -" // How much shares to mint?\n" -" //\n" -" // f(x, y) = value of liquidity\n" -" // We will define f(x, y) = sqrt(xy)\n" -" //\n" -" // L0 = f(x, y)\n" -" // L1 = f(x + dx, y + dy)\n" -" // T = total shares\n" -" // s = shares to mint\n" -" //\n" -" // Total shares should increase proportional to increase in " -"liquidity\n" -" // L1 / L0 = (T + s) / T\n" -" //\n" -" // L1 * T = L0 * (T + s)\n" -" //\n" -" // (L1 - L0) * T / L0 = s\n" -"\n" -" // Claim\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -" //\n" -" // Proof\n" -" // --- Equation 1 ---\n" -" // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // dx / dy = x / y so replace dy = dx * y / x\n" -" //\n" -" // --- Equation 2 ---\n" -" // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // Multiply by sqrt(x) / sqrt(x)\n" -" // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - sqrt(x^2y)) / " -"sqrt(x^2y)\n" -" // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(y)sqrt(x^2))\n" -" // sqrt(y) on top and bottom cancels out\n" -" //\n" -" // --- Equation 3 ---\n" -" // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(x^2)\n" -" // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -" // = ((x + dx) - x) / x\n" -" // = dx / x\n" -" // Since dx / dy = x / y,\n" -" // dx / x = dy / y\n" -" //\n" -" // Finally\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let shares = if (total_supply == 0) {\n" -" u256_sqrt(amount0 * amount1).into()\n" -" } else {\n" -" PrivateFunctions::min(\n" -" amount0 * total_supply / reserve0, amount1 * " -"total_supply / reserve1\n" -" )\n" -" };\n" -" assert(shares > 0, 'shares = 0');\n" -" self._mint(caller, shares);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" shares\n" -" }\n" -"\n" -" fn remove_liquidity(ref self: ContractState, shares: u256) -> (u256, " -"u256) {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" // Claim\n" -" // dx, dy = amount of liquidity to remove\n" -" // dx = s / T * x\n" -" // dy = s / T * y\n" -" //\n" -" // Proof\n" -" // Let's find dx, dy such that\n" -" // v / L = s / T\n" -" //\n" -" // where\n" -" // v = f(dx, dy) = sqrt(dxdy)\n" -" // L = total liquidity = sqrt(xy)\n" -" // s = shares\n" -" // T = total supply\n" -" //\n" -" // --- Equation 1 ---\n" -" // v = s / T * L\n" -" // sqrt(dxdy) = s / T * sqrt(xy)\n" -" //\n" -" // Amount of liquidity to remove must not change price so\n" -" // dx / dy = x / y\n" -" //\n" -" // replace dy = dx * y / x\n" -" // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -" //\n" -" // Divide both sides of Equation 1 with sqrt(y / x)\n" -" // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -" // = s / T * sqrt(x^2) = s / T * x\n" -" //\n" -" // Likewise\n" -" // dy = s / T * y\n" -"\n" -" // bal0 >= reserve0\n" -" // bal1 >= reserve1\n" -" let (bal0, bal1): (u256, u256) = (token0.balance_of(this), " -"token1.balance_of(this));\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let (amount0, amount1): (u256, u256) = (\n" -" (shares * bal0) / total_supply, (shares * bal1) / " -"total_supply\n" -" );\n" -" assert(amount0 > 0 && amount1 > 0, 'amount0 or amount1 = 0');\n" -"\n" -" self._burn(caller, shares);\n" -" self._update(bal0 - amount0, bal1 - amount1);\n" -"\n" -" token0.transfer(caller, amount0);\n" -" token1.transfer(caller, amount1);\n" -" (amount0, amount1)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/constant-product-amm.md:274 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/constant_product_amm/src/" -"constant_product_amm.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/constant_product_amm/src/" -"constant_product_amm.cairo)." - -#: src/advanced-concepts/write_to_any_slot.md:1 -msgid "# Writing to any storage slot" -msgstr "# Escribir en cualquier ranura de almacenamiento" - -#: src/advanced-concepts/write_to_any_slot.md:3 -msgid "" -"On Starknet, a contract's storage is a map with 2^251 slots, where each slot " -"is a felt which is initialized to 0.\n" -"The address of storage variables is computed at compile time using the " -"formula: `storage variable address := pedersen(keccak(variable name), " -"keys)`. Interactions with storage variables are commonly performed using the " -"`self.var.read()` and `self.var.write()` functions." -msgstr "" -"En Starknet, el almacenamiento de un contrato es un mapa con 2^251 ranuras, " -"donde cada ranura es un fieltro que se inicializa a 0.\n" -"La dirección de las variables de almacenamiento se calcula en tiempo de " -"compilación mediante la fórmula `dirección de variable de almacenamiento := " -"pedersen(keccak(nombre de variable), keys)`. Las interacciones con las " -"variables de almacenamiento se realizan normalmente utilizando las funciones " -"`self.var.read()` y `self.var.write()`." - -#: src/advanced-concepts/write_to_any_slot.md:6 -msgid "" -"Nevertheless, we can use the `storage_write_syscall` and " -"`storage_read_syscall` syscalls, to write to and read from any storage " -"slot.\n" -"This is useful when writing to storage variables that are not known at " -"compile time, or to ensure that even if the contract is upgraded and the " -"computation method of storage variable addresses changes, they remain " -"accessible." -msgstr "" -"Sin embargo, podemos usar las llamadas al sistema `storage_write_syscall` y " -"`storage_read_syscall`, para escribir y leer desde cualquier ranura de " -"almacenamiento.\n" -"Esto es útil cuando se escribe en variables de almacenamiento que no se " -"conocen en tiempo de compilación, o para asegurarse de que incluso si el " -"contrato se actualiza y el método de cálculo de las direcciones de las " -"variables de almacenamiento cambia, siguen siendo accesibles." - -#: src/advanced-concepts/write_to_any_slot.md:9 -msgid "" -"In the following example, we use the Poseidon hash function to compute the " -"address of a storage variable. Poseidon is a ZK-friendly hash function that " -"is cheaper and faster than Pedersen, making it an excellent choice for " -"onchain computations. Once the address is computed, we use the storage " -"syscalls to interact with it." -msgstr "" -"En el siguiente ejemplo, utilizamos la función hash Poseidon para calcular " -"la dirección de una variable de almacenamiento. Poseidon es una función hash " -"compatible con ZK que es más barata y rápida que Pedersen, lo que la " -"convierte en una excelente elección para cálculos en cadena. Una vez " -"calculada la dirección, utilizamos las llamadas al sistema de almacenamiento " -"para interactuar con ella." - -#: src/advanced-concepts/write_to_any_slot.md:11 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IWriteToAnySlots {\n" -" fn write_slot(ref self: TContractState, value: u32);\n" -" fn read_slot(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod WriteToAnySlot {\n" -" use starknet::syscalls::{storage_read_syscall, storage_write_syscall};\n" -" use starknet::SyscallResultTrait;\n" -" use poseidon::poseidon_hash_span;\n" -" use starknet::storage_access::Felt252TryIntoStorageAddress;\n" -" use starknet::StorageAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" const SLOT_NAME: felt252 = 'test_slot';\n" -"\n" -" #[abi(embed_v0)]\n" -" impl WriteToAnySlot of super::IWriteToAnySlots {\n" -" fn write_slot(ref self: ContractState, value: u32) {\n" -" storage_write_syscall(0, get_address_from_name(SLOT_NAME), value." -"into());\n" -" }\n" -"\n" -" fn read_slot(self: @ContractState) -> u32 {\n" -" storage_read_syscall(0, get_address_from_name(SLOT_NAME))\n" -" .unwrap_syscall()\n" -" .try_into()\n" -" .unwrap()\n" -" }\n" -" }\n" -" fn get_address_from_name(variable_name: felt252) -> StorageAddress {\n" -" let mut data: Array = ArrayTrait::new();\n" -" data.append(variable_name);\n" -" let hashed_name: felt252 = poseidon_hash_span(data.span());\n" -" let MASK_250: u256 = " -"0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n" -" // By taking the 250 least significant bits of the hash output, we " -"get a valid 250bits storage address.\n" -" let result: felt252 = (hashed_name.into() & MASK_250).try_into()." -"unwrap();\n" -" let result: StorageAddress = result.try_into().unwrap();\n" -" result\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IWriteToAnySlots {\n" -" fn write_slot(ref self: TContractState, value: u32);\n" -" fn read_slot(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod WriteToAnySlot {\n" -" use starknet::syscalls::{storage_read_syscall, storage_write_syscall};\n" -" use starknet::SyscallResultTrait;\n" -" use poseidon::poseidon_hash_span;\n" -" use starknet::storage_access::Felt252TryIntoStorageAddress;\n" -" use starknet::StorageAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" const SLOT_NAME: felt252 = 'test_slot';\n" -"\n" -" #[abi(embed_v0)]\n" -" impl WriteToAnySlot of super::IWriteToAnySlots {\n" -" fn write_slot(ref self: ContractState, value: u32) {\n" -" storage_write_syscall(0, get_address_from_name(SLOT_NAME), value." -"into());\n" -" }\n" -"\n" -" fn read_slot(self: @ContractState) -> u32 {\n" -" storage_read_syscall(0, get_address_from_name(SLOT_NAME))\n" -" .unwrap_syscall()\n" -" .try_into()\n" -" .unwrap()\n" -" }\n" -" }\n" -" fn get_address_from_name(variable_name: felt252) -> StorageAddress {\n" -" let mut data: Array = ArrayTrait::new();\n" -" data.append(variable_name);\n" -" let hashed_name: felt252 = poseidon_hash_span(data.span());\n" -" let MASK_250: u256 = " -"0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n" -" // By taking the 250 least significant bits of the hash output, we " -"get a valid 250bits storage address.\n" -" let result: felt252 = (hashed_name.into() & MASK_250).try_into()." -"unwrap();\n" -" let result: StorageAddress = result.try_into().unwrap();\n" -" result\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/write_to_any_slot.md:56 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x033943CB781A4E63C9dcE0A1A09eAa3b617AA43CC61637C08c043a67f3fe0087) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/write_to_any_slot/src/contract.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x033943CB781A4E63C9dcE0A1A09eAa3b617AA43CC61637C08c043a67f3fe0087) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/write_to_any_slot/src/contract.cairo)." - -#: src/advanced-concepts/storing_arrays.md:1 -msgid "# Storing Arrays" -msgstr "# Almacenamiento de Arrays" - -#: src/advanced-concepts/storing_arrays.md:3 -msgid "" -"On Starknet, complex values (e.g., tuples or structs), are stored in a " -"continuous segment starting from the address of the storage variable. There " -"is a 256 field elements limitation to the maximal size of a complex storage " -"value, meaning that to store arrays of more than 255 elements in storage, we " -"would need to split it into segments of size `n <= 255` and store these " -"segments in multiple storage addresses. There is currently no native support " -"for storing arrays in Cairo, so you will need to write your own " -"implementation of the `Store` trait for the type of array you wish to store." -msgstr "" -"En Starknet, los valores complejos (por ejemplo, tuplas o structs), se " -"almacenan en un segmento continuo a partir de la dirección de la variable de " -"almacenamiento. Hay una limitación de 256 elementos de campo para el tamaño " -"máximo de un valor de almacenamiento complejo, lo que significa que para " -"almacenar matrices de más de 255 elementos en el almacenamiento, " -"necesitaríamos dividirlo en segmentos de tamaño `n <= 255` y almacenar estos " -"segmentos en múltiples direcciones de almacenamiento. Actualmente no hay " -"soporte nativo para almacenar arrays en Cairo, por lo que necesitarás " -"escribir tu propia implementación del rasgo `Store` para el tipo de array " -"que desees almacenar." - -#: src/advanced-concepts/storing_arrays.md:5 -msgid "" -"> Note: While storing arrays in storage is possible, it is not always " -"recommended, as the read and write operations can get very costly. For " -"example, reading an array of size `n` requires `n` storage reads, and " -"writing to an array of size `n` requires `n` storage writes. If you only " -"need to access a single element of the array at a time, it is recommended to " -"use a `LegacyMap` and store the length in another variable instead." -msgstr "" -"> Nota: Aunque es posible almacenar arrays, no siempre es recomendable, ya " -"que las operaciones de lectura y escritura pueden ser muy costosas. Por " -"ejemplo, leer un array de tamaño `n` requiere `n` lecturas de " -"almacenamiento, y escribir en un array de tamaño `n` requiere `n` escrituras " -"de almacenamiento. Si sólo necesitas acceder a un único elemento del array " -"cada vez, se recomienda utilizar un `LegacyMap` y almacenar la longitud en " -"otra variable." - -#: src/advanced-concepts/storing_arrays.md:7 -msgid "" -"The following example demonstrates how to write a simple implementation of " -"the `StorageAccess` trait for the `Array` type, allowing us to " -"store arrays of up to 255 `felt252` elements." -msgstr "" -"El siguiente ejemplo muestra cómo escribir una implementación sencilla del " -"trait `StorageAccess` para el tipo `Array`, permitiéndonos " -"almacenar arrays de hasta 255 elementos `felt252`." - -#: src/advanced-concepts/storing_arrays.md:9 -msgid "" -"```cairo\n" -"impl StoreFelt252Array of Store> {\n" -" fn read(address_domain: u32, base: StorageBaseAddress) -> " -"SyscallResult> {\n" -" StoreFelt252Array::read_at_offset(address_domain, base, 0)\n" -" }\n" -"\n" -" fn write(\n" -" address_domain: u32, base: StorageBaseAddress, value: " -"Array\n" -" ) -> SyscallResult<()> {\n" -" StoreFelt252Array::write_at_offset(address_domain, base, 0, value)\n" -" }\n" -"\n" -" fn read_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8\n" -" ) -> SyscallResult> {\n" -" let mut arr: Array = ArrayTrait::new();\n" -"\n" -" // Read the stored array's length. If the length is superior to 255, " -"the read will fail.\n" -" let len: u8 = Store::::read_at_offset(address_domain, base, " -"offset)\n" -" .expect('Storage Span too large');\n" -" offset += 1;\n" -"\n" -" // Sequentially read all stored elements and append them to the " -"array.\n" -" let exit = len + offset;\n" -" loop {\n" -" if offset >= exit {\n" -" break;\n" -" }\n" -"\n" -" let value = Store::::read_at_offset(address_domain, " -"base, offset).unwrap();\n" -" arr.append(value);\n" -" offset += Store::::size();\n" -" };\n" -"\n" -" // Return the array.\n" -" Result::Ok(arr)\n" -" }\n" -"\n" -" fn write_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8, mut " -"value: Array\n" -" ) -> SyscallResult<()> {\n" -" // // Store the length of the array in the first storage slot.\n" -" let len: u8 = value.len().try_into().expect('Storage - Span too " -"large');\n" -" Store::::write_at_offset(address_domain, base, offset, len);\n" -" offset += 1;\n" -"\n" -" // Store the array elements sequentially\n" -" loop {\n" -" match value.pop_front() {\n" -" Option::Some(element) => {\n" -" Store::::write_at_offset(address_domain, base, " -"offset, element);\n" -" offset += Store::::size();\n" -" },\n" -" Option::None(_) => { break Result::Ok(()); }\n" -" };\n" -" }\n" -" }\n" -"\n" -" fn size() -> u8 {\n" -" 255 * Store::::size()\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"impl StoreFelt252Array of Store> {\n" -" fn read(address_domain: u32, base: StorageBaseAddress) -> " -"SyscallResult> {\n" -" StoreFelt252Array::read_at_offset(address_domain, base, 0)\n" -" }\n" -"\n" -" fn write(\n" -" address_domain: u32, base: StorageBaseAddress, value: " -"Array\n" -" ) -> SyscallResult<()> {\n" -" StoreFelt252Array::write_at_offset(address_domain, base, 0, value)\n" -" }\n" -"\n" -" fn read_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8\n" -" ) -> SyscallResult> {\n" -" let mut arr: Array = ArrayTrait::new();\n" -"\n" -" // Read the stored array's length. If the length is superior to 255, " -"the read will fail.\n" -" let len: u8 = Store::::read_at_offset(address_domain, base, " -"offset)\n" -" .expect('Storage Span too large');\n" -" offset += 1;\n" -"\n" -" // Sequentially read all stored elements and append them to the " -"array.\n" -" let exit = len + offset;\n" -" loop {\n" -" if offset >= exit {\n" -" break;\n" -" }\n" -"\n" -" let value = Store::::read_at_offset(address_domain, " -"base, offset).unwrap();\n" -" arr.append(value);\n" -" offset += Store::::size();\n" -" };\n" -"\n" -" // Return the array.\n" -" Result::Ok(arr)\n" -" }\n" -"\n" -" fn write_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8, mut " -"value: Array\n" -" ) -> SyscallResult<()> {\n" -" // // Store the length of the array in the first storage slot.\n" -" let len: u8 = value.len().try_into().expect('Storage - Span too " -"large');\n" -" Store::::write_at_offset(address_domain, base, offset, len);\n" -" offset += 1;\n" -"\n" -" // Store the array elements sequentially\n" -" loop {\n" -" match value.pop_front() {\n" -" Option::Some(element) => {\n" -" Store::::write_at_offset(address_domain, base, " -"offset, element);\n" -" offset += Store::::size();\n" -" },\n" -" Option::None(_) => { break Result::Ok(()); }\n" -" };\n" -" }\n" -" }\n" -"\n" -" fn size() -> u8 {\n" -" 255 * Store::::size()\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/storing_arrays.md:73 -msgid "" -"You can then import this implementation in your contract and use it to store " -"arrays in storage:" -msgstr "" -"A continuación, puede importar esta implementación en su contrato y " -"utilizarla para almacenar arrays en el almacenamiento:" - -#: src/advanced-concepts/storing_arrays.md:75 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoreArrayContract {\n" -" fn store_array(ref self: TContractState, arr: Array);\n" -" fn read_array(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoreArrayContract {\n" -" use super::StoreFelt252Array;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" arr: Array\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoreArrayImpl of super::IStoreArrayContract {\n" -" fn store_array(ref self: ContractState, arr: Array) {\n" -" self.arr.write(arr);\n" -" }\n" -"\n" -" fn read_array(self: @ContractState) -> Array {\n" -" self.arr.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoreArrayContract {\n" -" fn store_array(ref self: TContractState, arr: Array);\n" -" fn read_array(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoreArrayContract {\n" -" use super::StoreFelt252Array;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" arr: Array\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoreArrayImpl of super::IStoreArrayContract {\n" -" fn store_array(ref self: ContractState, arr: Array) {\n" -" self.arr.write(arr);\n" -" }\n" -"\n" -" fn read_array(self: @ContractState) -> Array {\n" -" self.arr.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/storing_arrays.md:103 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x008F8069a3Fcd7691Db46Dc3b6F9D2C0436f9200E861330957Fd780A3595da86) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/storing_arrays/src/contract.cairo)." -msgstr "" -"Visita el contrato en [Voyager](https://goerli.voyager.online/" -"contract/0x008F8069a3Fcd7691Db46Dc3b6F9D2C0436f9200E861330957Fd780A3595da86) " -"o juega con él en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/storing_arrays/src/contract.cairo)." - -#: src/advanced-concepts/struct-mapping-key.md:1 -msgid "# Structs as mapping keys" -msgstr "# Estructuras como mapping keys" - -#: src/advanced-concepts/struct-mapping-key.md:3 -msgid "" -"In order to use structs as mapping keys, you can use `#[derive(Hash)]` on " -"the struct definition. This will automatically generate a hash function for " -"the struct that can be used to represent the struct as a key in a " -"`LegacyMap`." -msgstr "" -"Para utilizar estructuras como mapping keys, puede utilizar " -"`#[derive(Hash)]` en la definición de la estructura. Esto generará " -"automáticamente una función hash para la estructura que se puede utilizar " -"para representar la estructura como una key en un `LegacyMap`." - -#: src/advanced-concepts/struct-mapping-key.md:5 -msgid "" -"Consider the following example in which we would like to use an object of\n" -"type `Pet` as a key in a `LegacyMap`. The `Pet` struct has three fields: " -"`name`, `age` and `owner`. We consider that the combination of these three " -"fields uniquely identifies a pet." -msgstr "" -"Consideremos el siguiente ejemplo en el que queremos utilizar un objeto de " -"tipo `Pet` como clave en un `LegacyMap`. La estructura `Pet` tiene tres " -"campos: `nombre`, `edad` y `propietario`. Consideramos que la combinación de " -"estos tres campos identifica de forma única a una mascota." - -#: src/advanced-concepts/struct-mapping-key.md:8 -msgid "" -"```cairo\n" -"#[derive(Copy, Drop, Serde, Hash)]\n" -"struct Pet {\n" -" name: felt252,\n" -" age: u8,\n" -" owner: felt252,\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IPetRegistry {\n" -" fn register_pet(ref self: TContractState, key: Pet, timestamp: u64);\n" -" fn get_registration_date(self: @TContractState, key: Pet) -> u64;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod PetRegistry {\n" -" use hash::{HashStateTrait, Hash};\n" -" use super::Pet;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" registration_time: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl PetRegistry of super::IPetRegistry {\n" -" fn register_pet(ref self: ContractState, key: Pet, timestamp: u64) " -"{\n" -" self.registration_time.write(key, timestamp);\n" -" }\n" -"\n" -" fn get_registration_date(self: @ContractState, key: Pet) -> u64 {\n" -" self.registration_time.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[derive(Copy, Drop, Serde, Hash)]\n" -"struct Pet {\n" -" name: felt252,\n" -" age: u8,\n" -" owner: felt252,\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IPetRegistry {\n" -" fn register_pet(ref self: TContractState, key: Pet, timestamp: u64);\n" -" fn get_registration_date(self: @TContractState, key: Pet) -> u64;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod PetRegistry {\n" -" use hash::{HashStateTrait, Hash};\n" -" use super::Pet;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" registration_time: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl PetRegistry of super::IPetRegistry {\n" -" fn register_pet(ref self: ContractState, key: Pet, timestamp: u64) " -"{\n" -" self.registration_time.write(key, timestamp);\n" -" }\n" -"\n" -" fn get_registration_date(self: @ContractState, key: Pet) -> u64 {\n" -" self.registration_time.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/struct-mapping-key.md:45 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/struct_as_mapping_key/src/contract." -"cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/struct_as_mapping_key/src/contract." -"cairo)." - -#: src/advanced-concepts/hashing.md:1 -msgid "# Hashing" -msgstr "# Hashing" - -#: src/advanced-concepts/hashing.md:3 -msgid "" -"Hashing is a cryptographic technique that allows you to transform a variable " -"length input into a fixed length output.\n" -"The resulting output is called a hash and it's completely different from the " -"input.\n" -"Hash functions are deterministic, meaning that the same input will always " -"produce the same output." -msgstr "" -"El hash es una técnica criptográfica que permite transformar una entrada de " -"longitud variable en una salida de longitud fija.\n" -"La salida resultante se llama hash y es completamente diferente de la " -"entrada.\n" -"Las funciones hash son deterministas, lo que significa que la misma entrada " -"siempre producirá la misma salida." - -#: src/advanced-concepts/hashing.md:7 -msgid "" -"The two hash functions provided by the Cairo library are `Poseidon` and " -"`Pedersen`.\n" -"Pedersen hashes were used in the past (but still used in some scenario for " -"backward compatibility) while Poseidon hashes are the standard nowadays " -"since they were designed to be very efficient for Zero Knowledge proof " -"systems." -msgstr "" -"Las dos funciones hash proporcionadas por la librería Cairo son `Poseidon` y " -"`Pedersen`.\n" -"Los hashes Pedersen se usaban en el pasado (pero todavía se usan en algunos " -"escenarios por compatibilidad con versiones anteriores) mientras que los " -"hashes Poseidon son el estándar hoy en día ya que fueron diseñados para ser " -"muy eficientes para sistemas de Zero Knowledge proof." - -#: src/advanced-concepts/hashing.md:10 -msgid "" -"In Cairo it's possible to hash all the types that can be converted to " -"`felt252` since they implement natively the `Hash` trait. It's also possible " -"to hash more complex types like structs by deriving the Hash trait with the " -"attribute `#[derive(Hash)]` but only if all the struct's fields are " -"themselves hashable." -msgstr "" -"En Cairo es posible hacer hash de todos los tipos que se pueden convertir a " -"`felt252` ya que implementan nativamente el trait `Hash`. También es posible " -"hacer hash de tipos más complejos como structs derivando el rasgo Hash con " -"el atributo `#[derive(Hash)]` pero sólo si todos los campos del struct son a " -"su vez hashables." - -#: src/advanced-concepts/hashing.md:12 -msgid "" -"You first need to initialize a hash state with the `new` method of the " -"`HashStateTrait` and then you can update it with the `update` method. You " -"can accumulate multiple updates. Then, the `finalize` method returns the " -"final hash value as a `felt252`." -msgstr "" -"Primero necesitas inicializar un estado hash con el método `new` del " -"`HashStateTrait` y luego puedes actualizarlo con el método `update`. Puedes " -"acumular múltiples actualizaciones. A continuación, el método `finalize` " -"devuelve el valor hash final como un `felt252`." - -#: src/advanced-concepts/hashing.md:14 -msgid "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait IHashTrait {\n" -"# fn save_user_with_poseidon(\n" -"# ref self: T, id: felt252, username: felt252, password: felt252\n" -"# ) -> felt252;\n" -"# fn save_user_with_pedersen(\n" -"# ref self: T, id: felt252, username: felt252, password: felt252\n" -"# ) -> felt252;\n" -"# }\n" -"# \n" -"#[starknet::contract]\n" -"mod HashTraits {\n" -" use core::hash::{HashStateTrait, HashStateExTrait};\n" -" use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" user_hash_poseidon: felt252,\n" -" user_hash_pedersen: felt252,\n" -" }\n" -"\n" -" #[derive(Drop, Hash)]\n" -" struct LoginDetails {\n" -" username: felt252,\n" -" password: felt252,\n" -" }\n" -"\n" -" #[derive(Drop, Hash)]\n" -" struct UserDetails {\n" -" id: felt252,\n" -" login: LoginDetails,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl HashTrait of super::IHashTrait {\n" -" fn save_user_with_poseidon(\n" -" ref self: ContractState, id: felt252, username: felt252, " -"password: felt252\n" -" ) -> felt252 {\n" -" let login = LoginDetails { username, password };\n" -" let user = UserDetails { id, login };\n" -"\n" -" let poseidon_hash = PoseidonTrait::new().update_with(user)." -"finalize();\n" -"\n" -" self.user_hash_poseidon.write(poseidon_hash);\n" -" poseidon_hash\n" -" }\n" -"\n" -" fn save_user_with_pedersen(\n" -" ref self: ContractState, id: felt252, username: felt252, " -"password: felt252\n" -" ) -> felt252 {\n" -" let login = LoginDetails { username, password };\n" -" let user = UserDetails { id, login };\n" -"\n" -" let pedersen_hash = PedersenTrait::new(0).update_with(user)." -"finalize();\n" -"\n" -" self.user_hash_pedersen.write(pedersen_hash);\n" -" pedersen_hash\n" -" }\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::{HashTraits, IHashTraitDispatcher, " -"IHashTraitDispatcherTrait};\n" -"# \n" -"# use core::hash::{HashStateTrait, HashStateExTrait};\n" -"# use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait};\n" -"# use starknet::{deploy_syscall};\n" -"# \n" -"# use debug::PrintTrait;\n" -"# \n" -"# fn deploy() -> IHashTraitDispatcher {\n" -"# let mut calldata = ArrayTrait::new();\n" -"# let (address, _) = deploy_syscall(\n" -"# HashTraits::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -"# )\n" -"# .unwrap();\n" -"# IHashTraitDispatcher { contract_address: address }\n" -"# }\n" -"# \n" -"# \n" -"# #[test]\n" -"# #[available_gas(20000000)]\n" -"# fn test_pedersen_hash() {\n" -"# let mut contract = deploy();\n" -"# \n" -"# let id = 0x1;\n" -"# let username = 'A.stark';\n" -"# let password = 'password.stark';\n" -"# let test_hash = contract.save_user_with_pedersen(id, username, " -"password);\n" -"# \n" -"# assert(\n" -"# test_hash == " -"0x6da4b4d0489989f5483d179643dafb3405b0e3b883a6c8efe5beb824ba9055a,\n" -"# 'Incorrect hash output'\n" -"# );\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(20000000)]\n" -"# fn test_poseidon_hash() {\n" -"# let mut contract = deploy();\n" -"# \n" -"# let id = 0x1;\n" -"# let username = 'A.stark';\n" -"# let password = 'password.stark';\n" -"# \n" -"# let test_hash = contract.save_user_with_poseidon(id, username, " -"password);\n" -"# \n" -"# test_hash.print();\n" -"# \n" -"# assert(\n" -"# test_hash == " -"0x4d165e1d398ae4864854518d3c58c3d7a21ed9c1f8f3618fbb0031d208aab7b,\n" -"# 'Incorrect hash output'\n" -"# );\n" -"# }\n" -"# }\n" -"```" -msgstr "" -"```cairo\n" -"# #[starknet::interface]\n" -"# trait IHashTrait {\n" -"# fn save_user_with_poseidon(\n" -"# ref self: T, id: felt252, username: felt252, password: felt252\n" -"# ) -> felt252;\n" -"# fn save_user_with_pedersen(\n" -"# ref self: T, id: felt252, username: felt252, password: felt252\n" -"# ) -> felt252;\n" -"# }\n" -"# \n" -"#[starknet::contract]\n" -"mod HashTraits {\n" -" use core::hash::{HashStateTrait, HashStateExTrait};\n" -" use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" user_hash_poseidon: felt252,\n" -" user_hash_pedersen: felt252,\n" -" }\n" -"\n" -" #[derive(Drop, Hash)]\n" -" struct LoginDetails {\n" -" username: felt252,\n" -" password: felt252,\n" -" }\n" -"\n" -" #[derive(Drop, Hash)]\n" -" struct UserDetails {\n" -" id: felt252,\n" -" login: LoginDetails,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl HashTrait of super::IHashTrait {\n" -" fn save_user_with_poseidon(\n" -" ref self: ContractState, id: felt252, username: felt252, " -"password: felt252\n" -" ) -> felt252 {\n" -" let login = LoginDetails { username, password };\n" -" let user = UserDetails { id, login };\n" -"\n" -" let poseidon_hash = PoseidonTrait::new().update_with(user)." -"finalize();\n" -"\n" -" self.user_hash_poseidon.write(poseidon_hash);\n" -" poseidon_hash\n" -" }\n" -"\n" -" fn save_user_with_pedersen(\n" -" ref self: ContractState, id: felt252, username: felt252, " -"password: felt252\n" -" ) -> felt252 {\n" -" let login = LoginDetails { username, password };\n" -" let user = UserDetails { id, login };\n" -"\n" -" let pedersen_hash = PedersenTrait::new(0).update_with(user)." -"finalize();\n" -"\n" -" self.user_hash_pedersen.write(pedersen_hash);\n" -" pedersen_hash\n" -" }\n" -" }\n" -"}\n" -"# \n" -"# #[cfg(test)]\n" -"# mod tests {\n" -"# use super::{HashTraits, IHashTraitDispatcher, " -"IHashTraitDispatcherTrait};\n" -"# \n" -"# use core::hash::{HashStateTrait, HashStateExTrait};\n" -"# use core::{pedersen::PedersenTrait, poseidon::PoseidonTrait};\n" -"# use starknet::{deploy_syscall};\n" -"# \n" -"# use debug::PrintTrait;\n" -"# \n" -"# fn deploy() -> IHashTraitDispatcher {\n" -"# let mut calldata = ArrayTrait::new();\n" -"# let (address, _) = deploy_syscall(\n" -"# HashTraits::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -"# )\n" -"# .unwrap();\n" -"# IHashTraitDispatcher { contract_address: address }\n" -"# }\n" -"# \n" -"# \n" -"# #[test]\n" -"# #[available_gas(20000000)]\n" -"# fn test_pedersen_hash() {\n" -"# let mut contract = deploy();\n" -"# \n" -"# let id = 0x1;\n" -"# let username = 'A.stark';\n" -"# let password = 'password.stark';\n" -"# let test_hash = contract.save_user_with_pedersen(id, username, " -"password);\n" -"# \n" -"# assert(\n" -"# test_hash == " -"0x6da4b4d0489989f5483d179643dafb3405b0e3b883a6c8efe5beb824ba9055a,\n" -"# 'Incorrect hash output'\n" -"# );\n" -"# }\n" -"# \n" -"# #[test]\n" -"# #[available_gas(20000000)]\n" -"# fn test_poseidon_hash() {\n" -"# let mut contract = deploy();\n" -"# \n" -"# let id = 0x1;\n" -"# let username = 'A.stark';\n" -"# let password = 'password.stark';\n" -"# \n" -"# let test_hash = contract.save_user_with_poseidon(id, username, " -"password);\n" -"# \n" -"# test_hash.print();\n" -"# \n" -"# assert(\n" -"# test_hash == " -"0x4d165e1d398ae4864854518d3c58c3d7a21ed9c1f8f3618fbb0031d208aab7b,\n" -"# 'Incorrect hash output'\n" -"# );\n" -"# }\n" -"# }\n" -"```" - -#: src/advanced-concepts/hash-solidity-compatible.md:1 -msgid "# Hash Solidity Compatible" -msgstr "# Hash compatible con Solidity" - -#: src/advanced-concepts/hash-solidity-compatible.md:3 -msgid "" -"This contract demonstrates Keccak hashing in Cairo to match Solidity's " -"keccak256. While both use Keccak, their endianness differs: Cairo is little-" -"endian, Solidity big-endian. The contract achieves compatibility by hashing " -"in big-endian using `keccak_u256s_be_inputs`, and reversing the bytes of the " -"result with `u128_byte_reverse`." -msgstr "" -"Este contrato demuestra el hashing Keccak en Cairo para que coincida con el " -"keccak256 de Solidity. Mientras que ambos usan Keccak, su endianness " -"difiere: Cairo es little-endian, Solidity big-endian. El contrato consigue " -"la compatibilidad haciendo hashing en big-endian usando " -"`keccak_u256s_be_inputs`, e invirtiendo los bytes del resultado con " -"`u128_byte_reverse`." - -#: src/advanced-concepts/hash-solidity-compatible.md:7 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISolidityHashExample {\n" -" fn hash_data(ref self: TContractState, input_data: Span) -> u256;\n" -"}\n" -"\n" -"\n" -"#[starknet::contract]\n" -"mod SolidityHashExample {\n" -" use keccak::{keccak_u256s_be_inputs};\n" -" use array::Span;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SolidityHashExample of super::ISolidityHashExample " -"{\n" -" fn hash_data(ref self: ContractState, input_data: Span) -> " -"u256 {\n" -" let hashed = keccak_u256s_be_inputs(input_data);\n" -"\n" -" // Split the hashed value into two 128-bit segments\n" -" let low: u128 = hashed.low;\n" -" let high: u128 = hashed.high;\n" -"\n" -" // Reverse each 128-bit segment\n" -" let reversed_low = integer::u128_byte_reverse(low);\n" -" let reversed_high = integer::u128_byte_reverse(high);\n" -"\n" -" // Reverse merge the reversed segments back into a u256 value\n" -" let compatible_hash = u256 { low: reversed_high, high: " -"reversed_low };\n" -"\n" -" compatible_hash\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISolidityHashExample {\n" -" fn hash_data(ref self: TContractState, input_data: Span) -> u256;\n" -"}\n" -"\n" -"\n" -"#[starknet::contract]\n" -"mod SolidityHashExample {\n" -" use keccak::{keccak_u256s_be_inputs};\n" -" use array::Span;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SolidityHashExample of super::ISolidityHashExample " -"{\n" -" fn hash_data(ref self: ContractState, input_data: Span) -> " -"u256 {\n" -" let hashed = keccak_u256s_be_inputs(input_data);\n" -"\n" -" // Split the hashed value into two 128-bit segments\n" -" let low: u128 = hashed.low;\n" -" let high: u128 = hashed.high;\n" -"\n" -" // Reverse each 128-bit segment\n" -" let reversed_low = integer::u128_byte_reverse(low);\n" -" let reversed_high = integer::u128_byte_reverse(high);\n" -"\n" -" // Reverse merge the reversed segments back into a u256 value\n" -" let compatible_hash = u256 { low: reversed_high, high: " -"reversed_low };\n" -"\n" -" compatible_hash\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/hash-solidity-compatible.md:44 -msgid "" -"Play with the contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/hash_solidity_compatible/src/contract." -"cairo)." -msgstr "" -"Juega con el contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/hash_solidity_compatible/src/contract." -"cairo)." - -#: src/advanced-concepts/optimisations/optimisations.md:1 -msgid "# Optimisations " -msgstr "# Optimizaciones " - -#: src/advanced-concepts/optimisations/optimisations.md:3 -msgid "A collection of optimisation patterns to save gas and steps." -msgstr "Una colección de patrones de optimización para ahorrar gas y pasos." - -#: src/advanced-concepts/optimisations/store_using_packing.md:1 -msgid "# Storage optimisation " -msgstr "# Optimización del Storage " - -#: src/advanced-concepts/optimisations/store_using_packing.md:3 -msgid "" -"A smart contract has a limited amount of **storage slots**. Each slot can " -"store a single `felt252` value.\n" -"Writing to a storage slot has a cost, so we want to use as few storage slots " -"as possible." -msgstr "" -"Un contrato inteligente tiene una cantidad limitada de **ranuras de " -"almacenamiento**. Cada ranura puede almacenar un único valor `felt252`. \n" -"Escribir en una ranura de almacenamiento tiene un coste, por lo que queremos " -"utilizar el menor número posible de ranuras de almacenamiento." - -#: src/advanced-concepts/optimisations/store_using_packing.md:6 -msgid "" -"In Cairo, every type is derived from the `felt252` type, which uses 252 bits " -"to store a value.\n" -"This design is quite simple, but it does have a drawback: it is not storage " -"efficient. For example, if we want to store a `u8` value, we need to use an " -"entire slot, even though we only need 8 bits." -msgstr "" -"En Cairo, cada tipo deriva del tipo `felt252`, que utiliza 252 bits para " -"almacenar un valor.\n" -"Este diseño es bastante simple, pero tiene un inconveniente: no es eficiente " -"en almacenamiento. Por ejemplo, si queremos almacenar un valor `u8`, " -"necesitamos usar un slot entero, aunque sólo necesitemos 8 bits." - -#: src/advanced-concepts/optimisations/store_using_packing.md:9 -msgid "## Packing" -msgstr "## Packing" - -#: src/advanced-concepts/optimisations/store_using_packing.md:11 -msgid "" -"When storing multiple values, we can use a technique called **packing**. " -"Packing is a technique that allows us to store multiple values in a single " -"felt value. This is done by using the bits of the felt value to store " -"multiple values." -msgstr "" -"Cuando almacenamos múltiples valores, podemos utilizar una técnica llamada " -"**packing**. El empaquetado es una técnica que nos permite almacenar " -"múltiples valores en un único valor de felt. Esto se hace utilizando los " -"bits del valor de felt para almacenar múltiples valores." - -#: src/advanced-concepts/optimisations/store_using_packing.md:13 -msgid "" -"For example, if we want to store two `u8` values, we can use the first 8 " -"bits of the felt value to store the first `u8` value, and the last 8 bits to " -"store the second `u8` value. This way, we can store two `u8` values in a " -"single felt value." -msgstr "" -"Por ejemplo, si queremos almacenar dos valores `u8`, podemos utilizar los " -"primeros 8 bits del valor de felt para almacenar el primer valor `u8`, y los " -"últimos 8 bits para almacenar el segundo valor `u8`. De esta forma, podemos " -"almacenar dos valores `u8` en un único valor de felt." - -#: src/advanced-concepts/optimisations/store_using_packing.md:15 -msgid "" -"Cairo provides a built-in store using packing that you can use with the " -"`StorePacking` trait." -msgstr "" -"Cairo proporciona un almacén incorporado que usa empaquetado que puedes usar " -"con el trait `StorePacking`." - -#: src/advanced-concepts/optimisations/store_using_packing.md:17 -msgid "" -"```cairo\n" -"trait StorePacking {\n" -" fn pack(value: T) -> PackedT;\n" -" fn unpack(value: PackedT) -> T;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait StorePacking {\n" -" fn pack(value: T) -> PackedT;\n" -" fn unpack(value: PackedT) -> T;\n" -"}\n" -"```" - -#: src/advanced-concepts/optimisations/store_using_packing.md:24 -msgid "" -"This allows to store the type `T` by first packing it into the type " -"`PackedT` with the `pack` function, and then storing the `PackedT` value " -"with it's `Store` implementation. When reading the value, we first retrieve " -"the `PackedT` value, and then unpack it into the type `T` using the `unpack` " -"function." -msgstr "" -"Esto permite almacenar el tipo `T` empaquetándolo primero en el tipo " -"`PackedT` con la función `pack`, y luego almacenando el valor `PackedT` con " -"su implementación `Store`. Al leer el valor, primero recuperamos el valor " -"`PackedT`, y luego lo desempaquetamos en el tipo `T` utilizando la función " -"`unpack`." - -#: src/advanced-concepts/optimisations/store_using_packing.md:26 -msgid "" -"Here's an example of storing a `Time` struct with two `u8` values using the " -"`StorePacking` trait:" -msgstr "" -"He aquí un ejemplo de almacenamiento de una estructura `Time` con dos " -"valores `u8` utilizando el trait `StorePacking`:" - -#: src/advanced-concepts/optimisations/store_using_packing.md:28 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ITime {\n" -" fn set(ref self: TContractState, value: TimeContract::Time);\n" -" fn get(self: @TContractState) -> TimeContract::Time;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod TimeContract {\n" -" use starknet::storage_access::StorePacking;\n" -" use integer::{\n" -" U8IntoFelt252, Felt252TryIntoU16, U16DivRem, u16_as_non_zero, " -"U16IntoFelt252,\n" -" Felt252TryIntoU8\n" -" };\n" -" use traits::{Into, TryInto, DivRem};\n" -" use option::OptionTrait;\n" -" use serde::Serde;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" time: Time\n" -" }\n" -"\n" -" #[derive(Copy, Serde, Drop)]\n" -" struct Time {\n" -" hour: u8,\n" -" minute: u8\n" -" }\n" -"\n" -" impl TimePackable of StorePacking {\n" -" fn pack(value: Time) -> felt252 {\n" -" let msb: felt252 = 256 * value.hour.into();\n" -" let lsb: felt252 = value.minute.into();\n" -" return msb + lsb;\n" -" }\n" -" fn unpack(value: felt252) -> Time {\n" -" let value: u16 = value.try_into().unwrap();\n" -" let (q, r) = U16DivRem::div_rem(value, u16_as_non_zero(256));\n" -" let hour: u8 = Into::::into(q).try_into()." -"unwrap();\n" -" let minute: u8 = Into::::into(r).try_into()." -"unwrap();\n" -" return Time { hour, minute };\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl TimeContract of super::ITime {\n" -" fn set(ref self: ContractState, value: Time) {\n" -" // This will call the pack method of the TimePackable trait\n" -" // and store the resulting felt252\n" -" self.time.write(value);\n" -" }\n" -" fn get(self: @ContractState) -> Time {\n" -" // This will read the felt252 value from storage\n" -" // and return the result of the unpack method of the " -"TimePackable trait\n" -" return self.time.read();\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ITime {\n" -" fn set(ref self: TContractState, value: TimeContract::Time);\n" -" fn get(self: @TContractState) -> TimeContract::Time;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod TimeContract {\n" -" use starknet::storage_access::StorePacking;\n" -" use integer::{\n" -" U8IntoFelt252, Felt252TryIntoU16, U16DivRem, u16_as_non_zero, " -"U16IntoFelt252,\n" -" Felt252TryIntoU8\n" -" };\n" -" use traits::{Into, TryInto, DivRem};\n" -" use option::OptionTrait;\n" -" use serde::Serde;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" time: Time\n" -" }\n" -"\n" -" #[derive(Copy, Serde, Drop)]\n" -" struct Time {\n" -" hour: u8,\n" -" minute: u8\n" -" }\n" -"\n" -" impl TimePackable of StorePacking {\n" -" fn pack(value: Time) -> felt252 {\n" -" let msb: felt252 = 256 * value.hour.into();\n" -" let lsb: felt252 = value.minute.into();\n" -" return msb + lsb;\n" -" }\n" -" fn unpack(value: felt252) -> Time {\n" -" let value: u16 = value.try_into().unwrap();\n" -" let (q, r) = U16DivRem::div_rem(value, u16_as_non_zero(256));\n" -" let hour: u8 = Into::::into(q).try_into()." -"unwrap();\n" -" let minute: u8 = Into::::into(r).try_into()." -"unwrap();\n" -" return Time { hour, minute };\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl TimeContract of super::ITime {\n" -" fn set(ref self: ContractState, value: Time) {\n" -" // This will call the pack method of the TimePackable trait\n" -" // and store the resulting felt252\n" -" self.time.write(value);\n" -" }\n" -" fn get(self: @ContractState) -> Time {\n" -" // This will read the felt252 value from storage\n" -" // and return the result of the unpack method of the " -"TimePackable trait\n" -" return self.time.read();\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/optimisations/store_using_packing.md:88 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet-cairo1-compiler&url=https://github.com/NethermindEth/" -"StarknetByExample/blob/main/listings/advanced-concepts/store_using_packing/" -"src/contract.cairo)." -msgstr "" -"Juega con este contrato en [Remix](https://remix.ethereum.org/?" -"#activate=Starknet-cairo1-compiler&url=https://github.com/NethermindEth/" -"StarknetByExample/blob/main/listings/advanced-concepts/store_using_packing/" -"src/contract.cairo)." - -#: src/advanced-concepts/list.md:1 -msgid "# List" -msgstr "# Lista" - -#: src/advanced-concepts/list.md:3 -msgid "" -"By default, there is no list type supported in Cairo, but you can use " -"Alexandria. You can refer to the [Alexandria documentation](https://github." -"com/keep-starknet-strange/alexandria/tree/main/src/storage) for more details." -msgstr "" -"Por defecto, no hay ningún tipo de lista soportado en Cairo, pero puedes " -"usar Alexandria. Puede consultar la [documentación de Alexandria](https://" -"github.com/keep-starknet-strange/alexandria/tree/main/src/storage) para más " -"detalles." - -#: src/advanced-concepts/list.md:5 -msgid "## What is `List`?" -msgstr "## ¿Qué es `List`?" - -#: src/advanced-concepts/list.md:7 -msgid "An ordered sequence of values that can be used in Starknet storage:" -msgstr "" -"Una secuencia ordenada de valores que puede utilizarse en el storage de " -"Starknet:" - -#: src/advanced-concepts/list.md:9 -msgid "" -"```cairo\n" -"#[storage]\n" -"stuct Storage {\n" -" amounts: List\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[storage]\n" -"stuct Storage {\n" -" amounts: List\n" -"}\n" -"```" - -#: src/advanced-concepts/list.md:16 -msgid "### Interface" -msgstr "### Interface" - -#: src/advanced-concepts/list.md:18 -msgid "" -"```cairo\n" -"trait ListTrait {\n" -" fn len(self: @List) -> u32;\n" -" fn is_empty(self: @List) -> bool;\n" -" fn append(ref self: List, value: T) -> u32;\n" -" fn get(self: @List, index: u32) -> Option;\n" -" fn set(ref self: List, index: u32, value: T);\n" -" fn pop_front(ref self: List) -> Option;\n" -" fn array(self: @List) -> Array;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait ListTrait {\n" -" fn len(self: @List) -> u32;\n" -" fn is_empty(self: @List) -> bool;\n" -" fn append(ref self: List, value: T) -> u32;\n" -" fn get(self: @List, index: u32) -> Option;\n" -" fn set(ref self: List, index: u32, value: T);\n" -" fn pop_front(ref self: List) -> Option;\n" -" fn array(self: @List) -> Array;\n" -"}\n" -"```" - -#: src/advanced-concepts/list.md:30 -msgid "" -"`List` also implements `IndexView` so you can use the familiar bracket " -"notation to access its members:" -msgstr "" -"`List` también implementa `IndexView` para que puedas utilizar la notación " -"familiar de corchetes para acceder a sus miembros:" - -#: src/advanced-concepts/list.md:32 -msgid "" -"```cairo\n" -"let second = self.amounts.read()[1];\n" -"```" -msgstr "" -"```cairo\n" -"let second = self.amounts.read()[1];\n" -"```" - -#: src/advanced-concepts/list.md:36 -msgid "" -"Note that unlike `get`, using this bracket notation panics when accessing an " -"out of bounds index." -msgstr "" -"Tenga en cuenta que, a diferencia de `get`, el uso de esta notación de " -"corchetes entra en pánico cuando se accede a un índice fuera de los límites." - -#: src/advanced-concepts/list.md:38 -msgid "### Support for custom types" -msgstr "### Compatibilidad con tipos personalizados" - -#: src/advanced-concepts/list.md:40 -msgid "" -"`List` supports most of the corelib types out of the box. If you want to " -"store a your own custom type in a `List`, it has to implement the `Store` " -"trait. You can have the compiler derive it for you using the " -"`#[derive(starknet::Store)]` attribute." -msgstr "" -"`List` soporta la mayoría de los tipos de corelib. Si quieres almacenar un " -"tipo personalizado en una `List`, tiene que implementar el trait `Store`. " -"Puedes hacer que el compilador lo derive por ti usando el atributo " -"`#[derive(starknet::Store)]`." - -#: src/advanced-concepts/list.md:42 -msgid "### Caveats" -msgstr "### Advertencias" - -#: src/advanced-concepts/list.md:44 -msgid "There are two idiosyncacies you should be aware of when using `List`" -msgstr "Hay dos particularidades que debe tener en cuenta al utilizar `List`" - -#: src/advanced-concepts/list.md:46 -msgid "" -"1. The `append` operation costs 2 storage writes - one for the value itself " -"and another one for updating the List's length\n" -"2. Due to a compiler limitation, it is not possible to use mutating " -"operations with a single inline statement. For example, `self.amounts.read()." -"append(42);` will not work. You have to do it in 2 steps:" -msgstr "" -"1. La operación `append` cuesta 2 escrituras de almacenamiento - una para el " -"valor en sí y otra para actualizar la longitud de la Lista\n" -"2. Debido a una limitación del compilador, no es posible utilizar " -"operaciones de mutación con una única sentencia inline. Por ejemplo, `self." -"amounts.read().append(42);` no funcionará. Tienes que hacerlo en 2 pasos:" - -#: src/advanced-concepts/list.md:49 -msgid "" -"```cairo\n" -"let mut amounts = self.amounts.read();\n" -"amounts.append(42);\n" -"```" -msgstr "" -"```cairo\n" -"let mut amounts = self.amounts.read();\n" -"amounts.append(42);\n" -"```" - -#: src/advanced-concepts/list.md:54 -msgid "### Dependencies" -msgstr "### Dependencias" - -#: src/advanced-concepts/list.md:56 -msgid "Update your project dependencies by in the `Scarb.toml` file:" -msgstr "Actualice las dependencias de su proyecto en el archivo `Scarb.toml`:" - -#: src/advanced-concepts/list.md:57 -msgid "" -"```cairo\n" -"[dependencies]\n" -"(...)\n" -"alexandria_storage = { git = \"https://github.com/keep-starknet-strange/" -"alexandria.git\" }\n" -"```" -msgstr "" -"```cairo\n" -"[dependencies]\n" -"(...)\n" -"alexandria_storage = { git = \"https://github.com/keep-starknet-strange/" -"alexandria.git\" }\n" -"```" - -#: src/advanced-concepts/list.md:63 -msgid "" -"For example, let's use `List` to create a contract that tracks a list of " -"amounts and tasks:" -msgstr "" -"Por ejemplo, utilicemos `List` para crear un contrato que realice el " -"seguimiento de una lista de importes y tareas:" - -#: src/advanced-concepts/list.md:65 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IListExample {\n" -" fn add_in_amount(ref self: TContractState, number: u128);\n" -" fn add_in_task(ref self: TContractState, description: felt252, status: " -"felt252);\n" -" fn is_empty_list(self: @TContractState) -> bool;\n" -" fn list_length(self: @TContractState) -> u32;\n" -" fn get_from_index(self: @TContractState, index: u32) -> u128;\n" -" fn set_from_index(ref self: TContractState, index: u32, number: u128);\n" -" fn pop_front_list(ref self: TContractState);\n" -" fn array_conversion(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ListExample {\n" -" use alexandria_storage::list::{List, ListTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" amounts: List,\n" -" tasks: List\n" -" }\n" -"\n" -" #[derive(Copy, Drop, Serde, starknet::Store)]\n" -" struct Task {\n" -" description: felt252,\n" -" status: felt252\n" -" }\n" -"\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ListExample of super::IListExample {\n" -" fn add_in_amount(ref self: ContractState, number: u128) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.append(number);\n" -" }\n" -"\n" -" fn add_in_task(ref self: ContractState, description: felt252, " -"status: felt252) {\n" -" let new_task = Task { description: description, status: " -"status };\n" -" let mut current_tasks_list = self.tasks.read();\n" -" current_tasks_list.append(new_task);\n" -" }\n" -"\n" -" fn is_empty_list(self: @ContractState) -> bool {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.is_empty()\n" -" }\n" -"\n" -" fn list_length(self: @ContractState) -> u32 {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.len()\n" -" }\n" -"\n" -" fn get_from_index(self: @ContractState, index: u32) -> u128 {\n" -" self.amounts.read()[index]\n" -" }\n" -"\n" -" fn set_from_index(ref self: ContractState, index: u32, number: u128) " -"{\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.set(index, number);\n" -" }\n" -"\n" -" fn pop_front_list(ref self: ContractState) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.pop_front();\n" -" }\n" -"\n" -" fn array_conversion(self: @ContractState) -> Array {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.array()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IListExample {\n" -" fn add_in_amount(ref self: TContractState, number: u128);\n" -" fn add_in_task(ref self: TContractState, description: felt252, status: " -"felt252);\n" -" fn is_empty_list(self: @TContractState) -> bool;\n" -" fn list_length(self: @TContractState) -> u32;\n" -" fn get_from_index(self: @TContractState, index: u32) -> u128;\n" -" fn set_from_index(ref self: TContractState, index: u32, number: u128);\n" -" fn pop_front_list(ref self: TContractState);\n" -" fn array_conversion(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ListExample {\n" -" use alexandria_storage::list::{List, ListTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" amount: List,\n" -" tasks: List\n" -" }\n" -"\n" -" #[derive(Copy, Drop, Serde, starknet::Store)]\n" -" struct Task {\n" -" description: felt252,\n" -" status: felt252\n" -" }\n" -"\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ListExample of super::IListExample {\n" -" fn add_in_amount(ref self: ContractState, number: u128) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.append(number);\n" -" }\n" -"\n" -" fn add_in_task(ref self: ContractState, description: felt252, " -"status: felt252) {\n" -" let new_task = Task { description: description, status: " -"status };\n" -" let mut current_tasks_list = self.tasks.read();\n" -" current_tasks_list.append(new_task);\n" -" }\n" -"\n" -" fn is_empty_list(self: @ContractState) -> bool {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.is_empty()\n" -" }\n" -"\n" -" fn list_length(self: @ContractState) -> u32 {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.len()\n" -" }\n" -"\n" -" fn get_from_index(self: @ContractState, index: u32) -> u128 {\n" -" self.amounts.read()[index]\n" -" }\n" -"\n" -" fn set_from_index(ref self: ContractState, index: u32, number: u128) " -"{\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.set(index, number);\n" -" }\n" -"\n" -" fn pop_front_list(ref self: ContractState) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.pop_front();\n" -" }\n" -"\n" -" fn array_conversion(self: @ContractState) -> Array {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.array()\n" -" }\n" -" }\n" -"}\n" -"```" - -#~ msgid "Summary" -#~ msgstr "Resumen" - -#~ msgid "" -#~ "// The constructor is decorated with a `#[constructor]` attribute.\n" -#~ " // It is not inside an `impl` block.\n" -#~ msgstr "" -#~ "// The constructor is decorated with a `#[constructor]` attribute.\n" -#~ " // It is not inside an `impl` block.\n" - -#~ msgid "Local" -#~ msgstr "Local" - -#~ msgid "declared inside a function" -#~ msgstr "declarado dentro de una función" - -#~ msgid "not stored on the blockchain" -#~ msgstr "no almacenado en la blockchain" - -#~ msgid "declared in the [Storage](./storage.md) of a contract" -#~ msgstr "declarado en el [Storage](./storage.md) de un contrato" - -#~ msgid "can be accessed from one execution to another" -#~ msgstr "se puede acceder de una ejecución a otra" - -#~ msgid "Global" -#~ msgstr "Global" - -#~ msgid "provides information about the blockchain" -#~ msgstr "proporciona información sobre la blockchain" - -#~ msgid "accessed anywhere, even within library functions" -#~ msgstr "" -#~ "se puede acceder desde cualquier lugar, incluso dentro de las funciones " -#~ "de la librería" - -#~ msgid "" -#~ "// This variable is local to the current block. It can't be accessed once " -#~ "it goes out of scope.\n" -#~ msgstr "" -#~ "// This variable is local to the current block. It can't be accessed once " -#~ "it goes out of scope.\n" - -#~ msgid "" -#~ "// The scope of a code block allows for local variable declaration\n" -#~ " // We can access variables defined in higher scopes.\n" -#~ msgstr "" -#~ "// The scope of a code block allows for local variable declaration\n" -#~ " // We can access variables defined in higher scopes.\n" - -#~ msgid "" -#~ "// All storage variables are contained in a struct called Storage\n" -#~ " // annotated with the `#[storage]` attribute\n" -#~ msgstr "" -#~ "// All storage variables are contained in a struct called Storage\n" -#~ " // annotated with the `#[storage]` attribute\n" - -#~ msgid "// Storage variable holding a number\n" -#~ msgstr "// Storage variable holding a number\n" - -#~ msgid "" -#~ "// Write to storage variables by sending a transaction that calls an " -#~ "external function\n" -#~ msgstr "" -#~ "// Write to storage variables by sending a transaction that calls an " -#~ "external function\n" - -#~ msgid "// Read from storage variables without sending transactions\n" -#~ msgstr "// Read from storage variables without sending transactions\n" - -#~ msgid "// import the required functions from the starknet core library\n" -#~ msgstr "// import the required functions from the starknet core library\n" - -#~ msgid "// Call the get_caller_address function to get the sender address\n" -#~ msgstr "// Call the get_caller_address function to get the sender address\n" - -#~ msgid "// ...\n" -#~ msgstr "// ...\n" - -#~ msgid "" -#~ "Functions that are accessible externally and can be called by anyone." -#~ msgstr "" -#~ "Funciones a las que se puede acceder externamente y que cualquiera puede " -#~ "llamar." - -#~ msgid "" -#~ "If we want our function to be able to mutate the state of the contract, " -#~ "we pass it by reference like this: `ref self: ContractState`." -#~ msgstr "" -#~ "Si queremos que nuestra función pueda mutar el estado del contrato, lo " -#~ "pasamos por referencia así: `ref self: ContractState`." - -#~ msgid "" -#~ "// The `#[abi(embed_v0)]` attribute indicates that all the functions in this " -#~ "implementation can be called externally.\n" -#~ " // Omitting this attribute would make all the functions in this " -#~ "implementation internal.\n" -#~ msgstr "" -#~ "// The `#[abi(embed_v0)]` attribute indicates that all the functions in this " -#~ "implementation can be called externally.\n" -#~ " // Omitting this attribute would make all the functions in this " -#~ "implementation internal.\n" - -#~ msgid "" -#~ "// The `set` function can be called externally because it is written " -#~ "inside an implementation marked as `#[abi(embed_v0)]`.\n" -#~ " // It can modify the contract's state as it is passed as a " -#~ "reference.\n" -#~ msgstr "" -#~ "// The `set` function can be called externally because it is written " -#~ "inside an implementation marked as `#[abi(embed_v0)]`.\n" -#~ " // It can modify the contract's state as it is passed as a " -#~ "reference.\n" - -#~ msgid "" -#~ "// The `get` function can be called externally because it is written " -#~ "inside an implementation marked as `#[abi(embed_v0)]`.\n" -#~ " // However, it can't modify the contract's state, as it is passed as a " -#~ "snapshot: it is only a \"view\" function.\n" -#~ msgstr "" -#~ "// The `get` function can be called externally because it is written " -#~ "inside an implementation marked as `#[abi(embed_v0)]`.\n" -#~ " // However, it can't modify the contract's state, as it is passed as a " -#~ "snapshot: it is only a \"view\" function.\n" - -#~ msgid "" -#~ "// We can call an internal function from any functions within the " -#~ "contract\n" -#~ msgstr "" -#~ "// We can call an internal function from any functions within the " -#~ "contract\n" - -#~ msgid "" -#~ "// The lack of the `external` attribute indicates that all the functions " -#~ "in this implementation can only be called internally.\n" -#~ " // We name the trait `PrivateFunctionsTrait` to indicate that it is " -#~ "an internal trait allowing us to call internal functions.\n" -#~ msgstr "" -#~ "// The lack of the `external` attribute indicates that all the functions " -#~ "in this implementation can only be called internally.\n" -#~ " // We name the trait `PrivateFunctionsTrait` to indicate that it is " -#~ "an internal trait allowing us to call internal functions.\n" - -#~ msgid "" -#~ "// The `_read_value` function is outside the implementation that is " -#~ "marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -#~ " // and can only be called from within the contract.\n" -#~ " // However, it can't modify the contract's state, as it is passed as a " -#~ "snapshot: it is only a \"view\" function.\n" -#~ msgstr "" -#~ "// The `_read_value` function is outside the implementation that is " -#~ "marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -#~ " // and can only be called from within the contract.\n" -#~ " // However, it can't modify the contract's state, as it is passed as a " -#~ "snapshot: it is only a \"view\" function.\n" - -#~ msgid "" -#~ "The contract has a state variable called 'counter' that is initialized to " -#~ "0." -#~ msgstr "" -#~ "El contrato tiene una variable de estado llamada 'counter' que se " -#~ "inicializa a 0." - -#~ msgid "" -#~ "When a user calls 'increment', the contract increments the counter by 1." -#~ msgstr "" -#~ "Cuando un usuario llama a 'increment', el contrato incrementa el contador " -#~ "en 1." - -#~ msgid "" -#~ "When a user calls 'decrement', the contract decrements the counter by 1." -#~ msgstr "" -#~ "Cuando un usuario llama a 'decrement', el contrato disminuye el contador " -#~ "en 1." - -#~ msgid "// Counter variable\n" -#~ msgstr "// Counter variable\n" - -#~ msgid "// Store initial value\n" -#~ msgstr "// Store initial value\n" - -#~ msgid "// Store counter value + 1\n" -#~ msgstr "// Store counter value + 1\n" - -#~ msgid "// Store counter value - 1\n" -#~ msgstr "// Store counter value - 1\n" - -#~ msgid "" -#~ "More complex key-value mappings are possible, for example we could use " -#~ "`LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an " -#~ "allowance on an ERC20 token contract." -#~ msgstr "" -#~ "Son posibles asignaciones de key-value más complejas; por ejemplo, " -#~ "podríamos usar `LegacyMap::<(ContractAddress, ContractAddress), Felt252>` " -#~ "para crear una asignación en un contrato de token ERC20." - -#~ msgid "" -#~ "// The `LegacyMap` type is only available inside the `Storage` struct.\n" -#~ msgstr "" -#~ "// The `LegacyMap` type is only available inside the `Storage` struct.\n" - -#~ msgid "" -#~ "`assert` is used to validate conditions. If the check fails, an error is " -#~ "thrown along with a specified value, often a message. It's similar to the " -#~ "`require` statement in Solidity." -#~ msgstr "" -#~ "`assert` se utiliza para validar condiciones. Si la verificación falla, " -#~ "se genera un error junto con un valor específico, a menudo un mensaje. Es " -#~ "similar a la declaración `require` en Solidity." - -#~ msgid "" -#~ "// Assert used to validate a condition\n" -#~ " // and abort execution if the condition is not met\n" -#~ msgstr "" -#~ "// Assert used to validate a condition\n" -#~ " // and abort execution if the condition is not met\n" - -#~ msgid "// Panic used to abort execution directly\n" -#~ msgstr "// Panic used to abort execution directly\n" - -#~ msgid "// you can define more errors here\n" -#~ msgstr "// you can define more errors here\n" - -#~ msgid "// Or using panic:\n" -#~ msgstr "// Or using panic:\n" - -#~ msgid "// Counter value\n" -#~ msgstr "// Counter value\n" - -#~ msgid "" -#~ "// The event enum must be annotated with the `#[event]` attribute.\n" -#~ " // It must also derive the `Drop` and `starknet::Event` traits.\n" -#~ msgstr "" -#~ "// The event enum must be annotated with the `#[event]` attribute.\n" -#~ " // It must also derive the `Drop` and `starknet::Event` traits.\n" - -#~ msgid "" -#~ "// By deriving the `starknet::Event` trait, we indicate to the compiler " -#~ "that\n" -#~ " // this struct will be used when emitting events.\n" -#~ msgstr "" -#~ "// By deriving the `starknet::Event` trait, we indicate to the compiler " -#~ "that\n" -#~ " // this struct will be used when emitting events.\n" - -#~ msgid "" -#~ "// The `#[key]` attribute indicates that this event will be indexed.\n" -#~ msgstr "" -#~ "// The `#[key]` attribute indicates that this event will be indexed.\n" - -#~ msgid "" -#~ "// Deriving the starknet::Store trait\n" -#~ "// allows us to store the `Person` struct in the contract's storage.\n" -#~ msgstr "" -#~ "// Deriving the starknet::Store trait\n" -#~ "// allows us to store the `Person` struct in the contract's storage.\n" - -#~ msgid "" -#~ "// Deriving the `Serde` trait allows us to use\n" -#~ " // the Person type as an entrypoint parameter and return value\n" -#~ msgstr "" -#~ "// Deriving the `Serde` trait allows us to use\n" -#~ " // the Person type as an entrypoint parameter and return value\n" - -#~ msgid "" -#~ "Explicitly, by defining a trait annoted with `#[starknet::interface]`" -#~ msgstr "" -#~ "Explícitamente, definiendo un trait anotado con `#[starknet::interface]`" - -#~ msgid "" -#~ "// We need to have the interface of the callee contract defined\n" -#~ "// so that we can import the Dispatcher.\n" -#~ msgstr "" -#~ "// We need to have the interface of the callee contract defined\n" -#~ "// so that we can import the Dispatcher.\n" - -#~ msgid "// We import the Dispatcher of the called contract\n" -#~ msgstr "// We import the Dispatcher of the called contract\n" - -#~ msgid "/// Create a new counter contract from stored arguments\n" -#~ msgstr "/// Create a new counter contract from stored arguments\n" - -#~ msgid "/// Create a new counter contract from the given arguments\n" -#~ msgstr "/// Create a new counter contract from the given arguments\n" - -#~ msgid "/// Update the argument\n" -#~ msgstr "/// Update the argument\n" - -#~ msgid "" -#~ "/// Update the class hash of the Counter contract to deploy when creating " -#~ "a new counter\n" -#~ msgstr "" -#~ "/// Update the class hash of the Counter contract to deploy when creating " -#~ "a new counter\n" - -#~ msgid "/// Store the constructor arguments of the contract to deploy\n" -#~ msgstr "/// Store the constructor arguments of the contract to deploy\n" - -#~ msgid "/// Store the class hash of the contract to deploy\n" -#~ msgstr "/// Store the class hash of the contract to deploy\n" - -#~ msgid "// Contructor arguments\n" -#~ msgstr "// Contructor arguments\n" - -#~ msgid "// Contract deployment\n" -#~ msgstr "// Contract deployment\n" - -#~ msgid "" -#~ "// Import the interface and dispatcher to be able to interact with the " -#~ "contract.\n" -#~ msgstr "" -#~ "// Import the interface and dispatcher to be able to interact with the " -#~ "contract.\n" - -#~ msgid "// Import the deploy syscall to be able to deploy the contract.\n" -#~ msgstr "// Import the deploy syscall to be able to deploy the contract.\n" - -#~ msgid "// Use starknet test utils to fake the transaction context.\n" -#~ msgstr "// Use starknet test utils to fake the transaction context.\n" - -#~ msgid "// Deploy the contract and return its dispatcher.\n" -#~ msgstr "// Deploy the contract and return its dispatcher.\n" - -#~ msgid "// Set up constructor arguments.\n" -#~ msgstr "// Set up constructor arguments.\n" - -#~ msgid "// Declare and deploy\n" -#~ msgstr "// Declare and deploy\n" - -#~ msgid "" -#~ "// Return the dispatcher.\n" -#~ " // The dispatcher allows to interact with the contract based on " -#~ "its interface.\n" -#~ msgstr "" -#~ "// Return the dispatcher.\n" -#~ " // The dispatcher allows to interact with the contract based on " -#~ "its interface.\n" - -#~ msgid "// Fake the caller address to address 1\n" -#~ msgstr "// Fake the caller address to address 1\n" - -#~ msgid "// Fake the contract address to address 1\n" -#~ msgstr "// Fake the contract address to address 1\n" - -#~ msgid "Use the `deploy` function logic to declare and deploy your contract." -#~ msgstr "" -#~ "Utilice la lógica de la función `deploy` para declarar y desplegar su " -#~ "contrato." - -#~ msgid "`set_caller_address(address: ContractAddress)`" -#~ msgstr "`set_caller_address(address: ContractAddress)`" - -#~ msgid "`set_contract_address(address: ContractAddress)`" -#~ msgstr "`set_contract_address(address: ContractAddress)`" - -#~ msgid "`set_block_timestamp(block_timestamp: u64)`" -#~ msgstr "`set_block_timestamp(block_timestamp: u64)`" - -#~ msgid "`set_account_contract_address(address: ContractAddress)`" -#~ msgstr "`set_account_contract_address(address: ContractAddress)`" - -#~ msgid "`set_max_fee(fee: u128)`" -#~ msgstr "`set_max_fee(fee: u128)`" - -#~ msgid "`get_caller_address() -> ContractAddress`" -#~ msgstr "`get_caller_address() -> ContractAddress`" - -#~ msgid "`get_contract_address() -> ContractAddress`" -#~ msgstr "`get_contract_address() -> ContractAddress`" - -#~ msgid "`get_block_info() -> Box`" -#~ msgstr "`get_block_info() -> Box`" - -#~ msgid "`get_tx_info() -> Box`" -#~ msgstr "`get_tx_info() -> Box`" - -#~ msgid "`get_block_timestamp() -> u64`" -#~ msgstr "`get_block_timestamp() -> u64`" - -#~ msgid "`get_block_number() -> u64`" -#~ msgstr "`get_block_number() -> u64`" - -#~ msgid "" -#~ "// for a 2D mapping its important to take note of the amount of brackets " -#~ "being used.\n" -#~ msgstr "" -#~ "// for a 2D mapping its important to take note of the amount of brackets " -#~ "being used.\n" - -#~ msgid "// Returns true if an array is empty, then false if it isn't.\n" -#~ msgstr "// Returns true if an array is empty, then false if it isn't.\n" - -#~ msgid "// Same as ~ while (i < 10) arr.append(i++);\n" -#~ msgstr "// Same as ~ while (i < 10) arr.append(i++);\n" - -#~ msgid "\"0x000\"" -#~ msgstr "\"0x000\"" - -#~ msgid "// Create tuple\n" -#~ msgstr "// Create tuple\n" - -#~ msgid "// Access tuple\n" -#~ msgstr "// Access tuple\n" - -#~ msgid "" -#~ "// With Store, you can store Data's structs in the storage part of " -#~ "contracts.\n" -#~ msgstr "" -#~ "// With Store, you can store Data's structs in the storage part of " -#~ "contracts.\n" - -#~ msgid "" -#~ "// Since a u32 might not fit in a u8 and a u16, we need to use try_into,\n" -#~ " // then unwrap the Option type thats returned.\n" -#~ msgstr "" -#~ "// Since a u32 might not fit in a u8 and a u16, we need to use try_into,\n" -#~ " // then unwrap the Option type thats returned.\n" - -#~ msgid "" -#~ "// since new_u32 is the of the same type (u32) as rand_number, we can " -#~ "directly assign them,\n" -#~ " // or use the .into() method.\n" -#~ msgstr "" -#~ "// since new_u32 is the of the same type (u32) as rand_number, we can " -#~ "directly assign them,\n" -#~ " // or use the .into() method.\n" - -#~ msgid "" -#~ "// When typecasting from a smaller size to an equal or larger size we use " -#~ "the .into() method.\n" -#~ " // Note: u64 and u128 are larger than u32, so a u32 type will always " -#~ "fit into them.\n" -#~ msgstr "" -#~ "// When typecasting from a smaller size to an equal or larger size we use " -#~ "the .into() method.\n" -#~ " // Note: u64 and u128 are larger than u32, so a u32 type will always " -#~ "fit into them.\n" - -#~ msgid "" -#~ "// Since a felt252 is smaller than a u256, we can use the into() method\n" -#~ msgstr "" -#~ "// Since a felt252 is smaller than a u256, we can use the into() method\n" - -#~ msgid "// Note: usize is smaller than felt252, so we use try_into\n" -#~ msgstr "// Note: usize is smaller than felt252, so we use try_into\n" - -#~ msgid "Modularity: Easily pluggable into multiple contracts." -#~ msgstr "Modularidad: Fácilmente conectable a múltiples contratos." - -#~ msgid "Reusable Logic: Encapsulates specific functionalities." -#~ msgstr "Lógica Reutilizable: Encapsula funcionalidades específicas." - -#~ msgid "Not Standalone: Cannot be declared or deployed independently." -#~ msgstr "" -#~ "No independiente: No se puede declarar ni implementar de forma " -#~ "independiente." - -#~ msgid "A Storage struct" -#~ msgstr "Una struct de Storage" - -#~ msgid "" -#~ "// This is needed to be able to use internal functions of the switch " -#~ "component.\n" -#~ msgstr "" -#~ "// This is needed to be able to use internal functions of the switch " -#~ "component.\n" - -#~ msgid "" -#~ "When a user deposits a token, the contract calculates the amount of " -#~ "shares to mint." -#~ msgstr "" -#~ "Cuando un usuario deposita un token, el contrato calcula la cantidad de " -#~ "acciones a acuñar." - -#~ msgid "" -#~ "// In order to make contract calls within our Vault,\n" -#~ "// we need to have the interface of the remote ERC20 contract defined to " -#~ "import the Dispatcher.\n" -#~ msgstr "" -#~ "// In order to make contract calls within our Vault,\n" -#~ "// we need to have the interface of the remote ERC20 contract defined to " -#~ "import the Dispatcher.\n" - -#~ msgid "" -#~ "// a = amount\n" -#~ " // B = balance of token before deposit\n" -#~ " // T = total supply\n" -#~ " // s = shares to mint\n" -#~ " //\n" -#~ " // (T + s) / T = (a + B) / B \n" -#~ " //\n" -#~ " // s = aT / B\n" -#~ msgstr "" -#~ "// a = amount\n" -#~ " // B = balance of token before deposit\n" -#~ " // T = total supply\n" -#~ " // s = shares to mint\n" -#~ " //\n" -#~ " // (T + s) / T = (a + B) / B \n" -#~ " //\n" -#~ " // s = aT / B\n" - -#~ msgid "" -#~ "// a = amount\n" -#~ " // B = balance of token before withdraw\n" -#~ " // T = total supply\n" -#~ " // s = shares to burn\n" -#~ " //\n" -#~ " // (T - s) / T = (B - a) / B \n" -#~ " //\n" -#~ " // a = sB / T\n" -#~ msgstr "" -#~ "// a = amount\n" -#~ " // B = balance of token before withdraw\n" -#~ " // T = total supply\n" -#~ " // s = shares to burn\n" -#~ " //\n" -#~ " // (T - s) / T = (B - a) / B \n" -#~ " //\n" -#~ " // a = sB / T\n" - -#~ msgid "// What can go wrong here?\n" -#~ msgstr "// What can go wrong here?\n" - -#~ msgid "" -#~ "// Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -#~ " // E.g. 3 = 0.3%\n" -#~ msgstr "" -#~ "// Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -#~ " // E.g. 3 = 0.3%\n" - -#~ msgid "// assert(fee <= 1000, 'fee > 1000');\n" -#~ msgstr "// assert(fee <= 1000, 'fee > 1000');\n" - -#~ msgid "" -#~ "// How much dy for dx?\n" -#~ " // xy = k\n" -#~ " // (x + dx)(y - dy) = k\n" -#~ " // y - dy = k / (x + dx)\n" -#~ " // y - k / (x + dx) = dy\n" -#~ " // y - xy / (x + dx) = dy\n" -#~ " // (yx + ydx - xy) / (x + dx) = dy\n" -#~ " // ydx / (x + dx) = dy\n" -#~ msgstr "" -#~ "// How much dy for dx?\n" -#~ " // xy = k\n" -#~ " // (x + dx)(y - dy) = k\n" -#~ " // y - dy = k / (x + dx)\n" -#~ " // y - k / (x + dx) = dy\n" -#~ " // y - xy / (x + dx) = dy\n" -#~ " // (yx + ydx - xy) / (x + dx) = dy\n" -#~ " // ydx / (x + dx) = dy\n" - -#~ msgid "" -#~ "// How much dx, dy to add?\n" -#~ " //\n" -#~ " // xy = k\n" -#~ " // (x + dx)(y + dy) = k'\n" -#~ " //\n" -#~ " // No price change, before and after adding liquidity\n" -#~ " // x / y = (x + dx) / (y + dy)\n" -#~ " //\n" -#~ " // x(y + dy) = y(x + dx)\n" -#~ " // x * dy = y * dx\n" -#~ " //\n" -#~ " // x / y = dx / dy\n" -#~ " // dy = y / x * dx\n" -#~ msgstr "" -#~ "// How much dx, dy to add?\n" -#~ " //\n" -#~ " // xy = k\n" -#~ " // (x + dx)(y + dy) = k'\n" -#~ " //\n" -#~ " // No price change, before and after adding liquidity\n" -#~ " // x / y = (x + dx) / (y + dy)\n" -#~ " //\n" -#~ " // x(y + dy) = y(x + dx)\n" -#~ " // x * dy = y * dx\n" -#~ " //\n" -#~ " // x / y = dx / dy\n" -#~ " // dy = y / x * dx\n" - -#~ msgid "" -#~ "// How much shares to mint?\n" -#~ " //\n" -#~ " // f(x, y) = value of liquidity\n" -#~ " // We will define f(x, y) = sqrt(xy)\n" -#~ " //\n" -#~ " // L0 = f(x, y)\n" -#~ " // L1 = f(x + dx, y + dy)\n" -#~ " // T = total shares\n" -#~ " // s = shares to mint\n" -#~ " //\n" -#~ " // Total shares should increase proportional to increase in " -#~ "liquidity\n" -#~ " // L1 / L0 = (T + s) / T\n" -#~ " //\n" -#~ " // L1 * T = L0 * (T + s)\n" -#~ " //\n" -#~ " // (L1 - L0) * T / L0 = s\n" -#~ msgstr "" -#~ "// How much shares to mint?\n" -#~ " //\n" -#~ " // f(x, y) = value of liquidity\n" -#~ " // We will define f(x, y) = sqrt(xy)\n" -#~ " //\n" -#~ " // L0 = f(x, y)\n" -#~ " // L1 = f(x + dx, y + dy)\n" -#~ " // T = total shares\n" -#~ " // s = shares to mint\n" -#~ " //\n" -#~ " // Total shares should increase proportional to increase in " -#~ "liquidity\n" -#~ " // L1 / L0 = (T + s) / T\n" -#~ " //\n" -#~ " // L1 * T = L0 * (T + s)\n" -#~ " //\n" -#~ " // (L1 - L0) * T / L0 = s\n" - -#~ msgid "" -#~ "// Claim\n" -#~ " // (L1 - L0) / L0 = dx / x = dy / y\n" -#~ " //\n" -#~ " // Proof\n" -#~ " // --- Equation 1 ---\n" -#~ " // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -#~ "sqrt(xy)\n" -#~ " //\n" -#~ " // dx / dy = x / y so replace dy = dx * y / x\n" -#~ " //\n" -#~ " // --- Equation 2 ---\n" -#~ " // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -#~ "sqrt(xy)\n" -#~ " //\n" -#~ " // Multiply by sqrt(x) / sqrt(x)\n" -#~ " // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - " -#~ "sqrt(x^2y)) / sqrt(x^2y)\n" -#~ " // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - " -#~ "sqrt(x^2)) / (sqrt(y)sqrt(x^2))\n" -#~ " // sqrt(y) on top and bottom cancels out\n" -#~ " //\n" -#~ " // --- Equation 3 ---\n" -#~ " // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -#~ "(sqrt(x^2)\n" -#~ " // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -#~ " // = ((x + dx) - x) / x\n" -#~ " // = dx / x\n" -#~ " // Since dx / dy = x / y,\n" -#~ " // dx / x = dy / y\n" -#~ " //\n" -#~ " // Finally\n" -#~ " // (L1 - L0) / L0 = dx / x = dy / y\n" -#~ msgstr "" -#~ "// Claim\n" -#~ " // (L1 - L0) / L0 = dx / x = dy / y\n" -#~ " //\n" -#~ " // Proof\n" -#~ " // --- Equation 1 ---\n" -#~ " // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -#~ "sqrt(xy)\n" -#~ " //\n" -#~ " // dx / dy = x / y so replace dy = dx * y / x\n" -#~ " //\n" -#~ " // --- Equation 2 ---\n" -#~ " // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -#~ "sqrt(xy)\n" -#~ " //\n" -#~ " // Multiply by sqrt(x) / sqrt(x)\n" -#~ " // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - " -#~ "sqrt(x^2y)) / sqrt(x^2y)\n" -#~ " // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - " -#~ "sqrt(x^2)) / (sqrt(y)sqrt(x^2))\n" -#~ " // sqrt(y) on top and bottom cancels out\n" -#~ " //\n" -#~ " // --- Equation 3 ---\n" -#~ " // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -#~ "(sqrt(x^2)\n" -#~ " // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -#~ " // = ((x + dx) - x) / x\n" -#~ " // = dx / x\n" -#~ " // Since dx / dy = x / y,\n" -#~ " // dx / x = dy / y\n" -#~ " //\n" -#~ " // Finally\n" -#~ " // (L1 - L0) / L0 = dx / x = dy / y\n" - -#~ msgid "" -#~ "// Claim\n" -#~ " // dx, dy = amount of liquidity to remove\n" -#~ " // dx = s / T * x\n" -#~ " // dy = s / T * y\n" -#~ " //\n" -#~ " // Proof\n" -#~ " // Let's find dx, dy such that\n" -#~ " // v / L = s / T\n" -#~ " //\n" -#~ " // where\n" -#~ " // v = f(dx, dy) = sqrt(dxdy)\n" -#~ " // L = total liquidity = sqrt(xy)\n" -#~ " // s = shares\n" -#~ " // T = total supply\n" -#~ " //\n" -#~ " // --- Equation 1 ---\n" -#~ " // v = s / T * L\n" -#~ " // sqrt(dxdy) = s / T * sqrt(xy)\n" -#~ " //\n" -#~ " // Amount of liquidity to remove must not change price so\n" -#~ " // dx / dy = x / y\n" -#~ " //\n" -#~ " // replace dy = dx * y / x\n" -#~ " // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -#~ " //\n" -#~ " // Divide both sides of Equation 1 with sqrt(y / x)\n" -#~ " // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -#~ " // = s / T * sqrt(x^2) = s / T * x\n" -#~ " //\n" -#~ " // Likewise\n" -#~ " // dy = s / T * y\n" -#~ msgstr "" -#~ "// Claim\n" -#~ " // dx, dy = amount of liquidity to remove\n" -#~ " // dx = s / T * x\n" -#~ " // dy = s / T * y\n" -#~ " //\n" -#~ " // Proof\n" -#~ " // Let's find dx, dy such that\n" -#~ " // v / L = s / T\n" -#~ " //\n" -#~ " // where\n" -#~ " // v = f(dx, dy) = sqrt(dxdy)\n" -#~ " // L = total liquidity = sqrt(xy)\n" -#~ " // s = shares\n" -#~ " // T = total supply\n" -#~ " //\n" -#~ " // --- Equation 1 ---\n" -#~ " // v = s / T * L\n" -#~ " // sqrt(dxdy) = s / T * sqrt(xy)\n" -#~ " //\n" -#~ " // Amount of liquidity to remove must not change price so\n" -#~ " // dx / dy = x / y\n" -#~ " //\n" -#~ " // replace dy = dx * y / x\n" -#~ " // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -#~ " //\n" -#~ " // Divide both sides of Equation 1 with sqrt(y / x)\n" -#~ " // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -#~ " // = s / T * sqrt(x^2) = s / T * x\n" -#~ " //\n" -#~ " // Likewise\n" -#~ " // dy = s / T * y\n" - -#~ msgid "" -#~ "// bal0 >= reserve0\n" -#~ " // bal1 >= reserve1\n" -#~ msgstr "" -#~ "// bal0 >= reserve0\n" -#~ " // bal1 >= reserve1\n" - -#~ msgid "" -#~ "// By taking the 250 least significant bits of the hash output, we get a " -#~ "valid 250bits storage address.\n" -#~ msgstr "" -#~ "// By taking the 250 least significant bits of the hash output, we get a " -#~ "valid 250bits storage address.\n" - -#~ msgid "" -#~ "// Read the stored array's length. If the length is superior to 255, the " -#~ "read will fail.\n" -#~ msgstr "" -#~ "// Read the stored array's length. If the length is superior to 255, the " -#~ "read will fail.\n" - -#~ msgid "" -#~ "// Sequentially read all stored elements and append them to the array.\n" -#~ msgstr "" -#~ "// Sequentially read all stored elements and append them to the array.\n" - -#~ msgid "// Return the array.\n" -#~ msgstr "// Return the array.\n" - -#~ msgid "// // Store the length of the array in the first storage slot.\n" -#~ msgstr "// // Store the length of the array in the first storage slot.\n" - -#~ msgid "// Store the array elements sequentially\n" -#~ msgstr "// Store the array elements sequentially\n" - -#~ msgid "// Split the hashed value into two 128-bit segments\n" -#~ msgstr "// Split the hashed value into two 128-bit segments\n" - -#~ msgid "// Reverse each 128-bit segment\n" -#~ msgstr "// Reverse each 128-bit segment\n" - -#~ msgid "// Reverse merge the reversed segments back into a u256 value\n" -#~ msgstr "// Reverse merge the reversed segments back into a u256 value\n" - -#~ msgid "" -#~ "// This will call the pack method of the TimePackable trait\n" -#~ " // and store the resulting felt252\n" -#~ msgstr "" -#~ "// This will call the pack method of the TimePackable trait\n" -#~ " // and store the resulting felt252\n" - -#~ msgid "" -#~ "// This will read the felt252 value from storage\n" -#~ " // and return the result of the unpack method of the " -#~ "TimePackable trait\n" -#~ msgstr "" -#~ "// This will read the felt252 value from storage\n" -#~ " // and return the result of the unpack method of the " -#~ "TimePackable trait\n" - -#~ msgid "" -#~ "The `append` operation costs 2 storage writes - one for the value itself " -#~ "and another one for updating the List's length" -#~ msgstr "" -#~ "La operación `append` cuesta 2 escrituras de storage - una para el valor " -#~ "en sí y otra para actualizar la longitud de la Lista" - -#~ msgid "Here's a list of other resources that you might find useful:" -#~ msgstr "Aquí hay una lista de otros recursos que pueden resultarle útiles:" - -#~ msgid "" -#~ "[Starklings](https://github.com/shramee/starklings-cairo1): An " -#~ "interactive tutorial to get you up and running with Cairo v1 and Starknet " -#~ msgstr "" -#~ "[Starklings](https://github.com/shramee/starklings-cairo1): Un tutorial " -#~ "interactivo para empezar a utilizar Cairo v1 y Starknet " - -#~ msgid "" -#~ "[Cairopractice](https://cairopractice.com/): A blog with a series of " -#~ "articles about Cairo and Starknet" -#~ msgstr "" -#~ "[Cairopractice](https://cairopractice.com/): Un blog con una serie de " -#~ "artículos sobre Cairo y Starknet" - -#~ msgid "" -#~ "[Cairo by example](https://cairo-by-example.com/): An introduction to " -#~ "Cairo, with simple examples" -#~ msgstr "" -#~ "[Cairo by example](https://cairo-by-example.com/): Una introducción a " -#~ "Cairo, con ejemplos sencillos" diff --git a/po/messages.po b/po/messages.po deleted file mode 100644 index d1c1848f..00000000 --- a/po/messages.po +++ /dev/null @@ -1,2228 +0,0 @@ - -msgid "" -msgstr "" -"Project-Id-Version: Starknet by Example\n" -"POT-Creation-Date: 2023-12-06T10:11:16Z\n" -"PO-Revision-Date: \n" -"Last-Translator: \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Language: en\n" -"Plural-Forms: nplurals=1; plural=0;\n" - -#: src/SUMMARY.md:1 -msgid "Summary" -msgstr "" - -#: src/SUMMARY.md:3 -msgid "Introduction" -msgstr "" - -#: src/SUMMARY.md:6 -msgid "Getting Started" -msgstr "" - -#: src/SUMMARY.md:8 -msgid "Basics of a Starknet contract" -msgstr "" - -#: src/SUMMARY.md:9 src/getting-started/basics/storage.md:1 src/getting-started/basics/variables.md:8 -msgid "Storage" -msgstr "" - -#: src/SUMMARY.md:10 src/getting-started/basics/constructor.md:1 -msgid "Constructor" -msgstr "" - -#: src/SUMMARY.md:11 src/getting-started/basics/variables.md:1 -msgid "Variables" -msgstr "" - -#: src/SUMMARY.md:12 src/getting-started/basics/visibility-mutability.md:1 -msgid "Visibility and Mutability" -msgstr "" - -#: src/SUMMARY.md:13 -msgid "Counter Example" -msgstr "" - -#: src/SUMMARY.md:14 src/getting-started/basics/mappings.md:1 -msgid "Mappings" -msgstr "" - -#: src/SUMMARY.md:15 src/getting-started/basics/errors.md:1 -msgid "Errors" -msgstr "" - -#: src/SUMMARY.md:16 src/getting-started/basics/events.md:1 -msgid "Events" -msgstr "" - -#: src/SUMMARY.md:17 src/getting-started/basics/storing-custom-types.md:1 -msgid "Storing Custom Types" -msgstr "" - -#: src/SUMMARY.md:18 src/getting-started/basics/custom-types-in-entrypoints.md:1 -msgid "Custom types in entrypoints" -msgstr "" - -#: src/SUMMARY.md:19 src/getting-started/basics/documentation.md:1 -msgid "Documentation" -msgstr "" - -#: src/SUMMARY.md:20 src/getting-started/interacting/interacting.md:1 -msgid "Deploy and interact with contracts" -msgstr "" - -#: src/SUMMARY.md:21 src/getting-started/interacting/interfaces-traits.md:1 -msgid "Contract interfaces and Traits generation" -msgstr "" - -#: src/SUMMARY.md:22 src/getting-started/interacting/calling_other_contracts.md:1 -msgid "Calling other contracts" -msgstr "" - -#: src/SUMMARY.md:23 -msgid "Factory pattern" -msgstr "" - -#: src/SUMMARY.md:24 -msgid "Testing contracts" -msgstr "" - -#: src/SUMMARY.md:25 -msgid "Cairo cheatsheet" -msgstr "" - -#: src/SUMMARY.md:26 -msgid "Felt" -msgstr "" - -#: src/SUMMARY.md:27 -msgid "LegacyMap" -msgstr "" - -#: src/SUMMARY.md:28 src/getting-started/cairo_cheatsheet/arrays.md:1 -msgid "Arrays" -msgstr "" - -#: src/SUMMARY.md:29 src/getting-started/cairo_cheatsheet/loop.md:1 -msgid "Loop" -msgstr "" - -#: src/SUMMARY.md:30 src/getting-started/cairo_cheatsheet/match.md:1 -msgid "Match" -msgstr "" - -#: src/SUMMARY.md:31 src/getting-started/cairo_cheatsheet/tuples.md:1 -msgid "Tuples" -msgstr "" - -#: src/SUMMARY.md:32 src/getting-started/cairo_cheatsheet/struct.md:1 -msgid "Struct" -msgstr "" - -#: src/SUMMARY.md:33 src/getting-started/cairo_cheatsheet/type_casting.md:1 -msgid "Type casting" -msgstr "" - -#: src/SUMMARY.md:36 -msgid "Applications examples" -msgstr "" - -#: src/SUMMARY.md:37 src/applications/upgradeable_contract.md:1 -msgid "Upgradeable Contract" -msgstr "" - -#: src/SUMMARY.md:38 -msgid "Defi Vault" -msgstr "" - -#: src/SUMMARY.md:39 src/applications/erc20.md:1 -msgid "ERC20 Token" -msgstr "" - -#: src/SUMMARY.md:40 src/applications/constant-product-amm.md:1 -msgid "Constant Product AMM" -msgstr "" - -#: src/SUMMARY.md:43 -msgid "Advanced concepts" -msgstr "" - -#: src/SUMMARY.md:44 src/advanced-concepts/write_to_any_slot.md:1 -msgid "Writing to any storage slot" -msgstr "" - -#: src/SUMMARY.md:45 src/advanced-concepts/storing_arrays.md:1 -msgid "Storing Arrays" -msgstr "" - -#: src/SUMMARY.md:46 -msgid "Struct as mapping key" -msgstr "" - -#: src/SUMMARY.md:47 src/advanced-concepts/hash-solidity-compatible.md:1 -msgid "Hash Solidity Compatible" -msgstr "" - -#: src/SUMMARY.md:48 src/advanced-concepts/optimisations/optimisations.md:1 -msgid "Optimisations" -msgstr "" - -#: src/SUMMARY.md:49 -msgid "Storage Optimisations" -msgstr "" - -#: src/SUMMARY.md:50 src/advanced-concepts/list.md:1 -msgid "List" -msgstr "" - -#: src/starknet-by-example.md:1 -msgid "Starknet by Example" -msgstr "" - -#: src/starknet-by-example.md:3 -msgid "" -"Starknet By Example is a collection of examples of how to use the Cairo " -"programming language to create smart contracts on Starknet." -msgstr "" - -#: src/starknet-by-example.md:5 -msgid "" -"Starknet is a permissionless Validity-Rollup that supports general " -"computation. It is currently used as an Ethereum layer-2. Starknet use the " -"STARK cryptographic proof system to ensure high safety and scalability." -msgstr "" - -#: src/starknet-by-example.md:7 -msgid "" -"Starknet smart contracts are written in the Cairo language. Cairo is a " -"Turing-complete programming language designed to write provable programs, " -"abstracting the zk-STARK proof system away from the programmer." -msgstr "" - -#: src/starknet-by-example.md:9 -msgid "The current version of this book use `scarb 2.3.1`" -msgstr "" - -#: src/starknet-by-example.md:11 -msgid "For whom is this for?" -msgstr "" - -#: src/starknet-by-example.md:13 -msgid "" -"Starknet By Example is for anyone who wants to quickly learn how to write " -"smart contracts on Starknet using Cairo with some technical background in " -"programming and blockchain." -msgstr "" - -#: src/starknet-by-example.md:15 -msgid "" -"The first chapters will give you a basic understanding of the Cairo " -"programming language and how to write, deploy and use smart contracts on " -"Starknet. The later chapters will cover more advanced topics and show you " -"how to write more complex smart contracts." -msgstr "" - -#: src/starknet-by-example.md:18 -msgid "Further reading" -msgstr "" - -#: src/starknet-by-example.md:20 -msgid "" -"If you want to learn more about the Cairo programming language, you can read " -"the [Cairo Book](https://book.cairo-lang.org). If you want to learn more " -"about Starknet, you can read the [Starknet " -"documentation](https://docs.starknet.io/) and the [Starknet " -"Book](https://book.starknet.io)." -msgstr "" - -#: src/starknet-by-example.md:23 -msgid "Here's a list of other resources that you might find useful:" -msgstr "" - -#: src/starknet-by-example.md:24 -msgid "" -"[Starklings](https://github.com/shramee/starklings-cairo1): An interactive " -"tutorial to get you up and running with Cairo v1 and Starknet " -msgstr "" - -#: src/starknet-by-example.md:25 -msgid "" -"[Cairopractice](https://cairopractice.com/): A blog with a series of " -"articles about Cairo and Starknet" -msgstr "" - -#: src/starknet-by-example.md:26 -msgid "" -"[Cairo by example](https://cairo-by-example.com/): An introduction to Cairo, " -"with simple examples" -msgstr "" - -#: src/getting-started/basics/introduction.md:1 -msgid "Basics of Smart Contracts in Cairo" -msgstr "" - -#: src/getting-started/basics/introduction.md:3 -msgid "" -"The following chapters will introduce you to Starknet smart contracts and " -"how to write them in Cairo." -msgstr "" - -#: src/getting-started/basics/storage.md:3 -msgid "Here's the most minimal contract you can write in Cairo:" -msgstr "" - -#: src/getting-started/basics/storage.md:13 -msgid "" -"Storage is a struct annoted with `#[storage]`. Every contract must have one " -"and only one storage. It's a key-value store, where each key will be mapped " -"to a storage address of the contract's storage space." -msgstr "" - -#: src/getting-started/basics/storage.md:16 -msgid "" -"You can define [storage variables](./variables.md#storage-variables) in your " -"contract, and then use them to store and retrieve data." -msgstr "" - -#: src/getting-started/basics/storage.md:29 -msgid "" -"Actually these two contracts have the same underlying Sierra program. From " -"the compiler's perspective, the storage variables don't exist until they are " -"used." -msgstr "" - -#: src/getting-started/basics/storage.md:32 -msgid "You can also read about [storing custom types](./storing-custom-types.md)" -msgstr "" - -#: src/getting-started/basics/constructor.md:3 -msgid "" -"Constructors are a special type of function that runs only once when " -"deploying a contract, and can be used to initialize the state of the " -"contract. Your contract must not have more than one constructor, and that " -"constructor function must be annotated with the `#[constructor]` attribute. " -"Also, a good practice consists in naming that function `constructor`." -msgstr "" - -#: src/getting-started/basics/constructor.md:5 -msgid "" -"Here's a simple example that demonstrates how to initialize the state of a " -"contract on deployment by defining logic inside a constructor." -msgstr "" - -#: src/getting-started/basics/constructor.md:17 -msgid "" -"// The constructor is decorated with a `#[constructor]` attribute.\n" -" // It is not inside an `impl` block.\n" -msgstr "" - -#: src/getting-started/basics/constructor.md:25 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/constructor/src/constructor.cairo)." -msgstr "" - -#: src/getting-started/basics/variables.md:3 -msgid "There are 3 types of variables in Cairo contracts:" -msgstr "" - -#: src/getting-started/basics/variables.md:5 -msgid "Local" -msgstr "" - -#: src/getting-started/basics/variables.md:6 -msgid "declared inside a function" -msgstr "" - -#: src/getting-started/basics/variables.md:7 -msgid "not stored on the blockchain" -msgstr "" - -#: src/getting-started/basics/variables.md:9 -msgid "declared in the [Storage](./storage.md) of a contract" -msgstr "" - -#: src/getting-started/basics/variables.md:10 -msgid "can be accessed from one execution to another" -msgstr "" - -#: src/getting-started/basics/variables.md:11 -msgid "Global" -msgstr "" - -#: src/getting-started/basics/variables.md:12 -msgid "provides information about the blockchain" -msgstr "" - -#: src/getting-started/basics/variables.md:13 -msgid "accessed anywhere, even within library functions" -msgstr "" - -#: src/getting-started/basics/variables.md:15 -msgid "Local Variables" -msgstr "" - -#: src/getting-started/basics/variables.md:17 -msgid "" -"Local variables are used and accessed within the scope of a specific " -"function or block of code. They are temporary and exist only for the " -"duration of that particular function or block execution." -msgstr "" - -#: src/getting-started/basics/variables.md:19 -msgid "" -"Local variables are stored in memory and are not stored on the blockchain. " -"This means they cannot be accessed from one execution to another. Local " -"variables are useful for storing temporary data that is relevant only within " -"a specific context. They also make the code more readable by giving names to " -"intermediate values." -msgstr "" - -#: src/getting-started/basics/variables.md:21 -msgid "Here's a simple example of a contract with only local variables:" -msgstr "" - -#: src/getting-started/basics/variables.md:37 -msgid "" -"// This variable is local to the current block. It can't be accessed once it " -"goes out of scope.\n" -msgstr "" - -#: src/getting-started/basics/variables.md:41 -msgid "" -"// The scope of a code block allows for local variable declaration\n" -" // We can access variables defined in higher scopes.\n" -msgstr "" - -#: src/getting-started/basics/variables.md:50 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/variables/src/local_variables.cairo)." -msgstr "" - -#: src/getting-started/basics/variables.md:52 -msgid "Storage Variables" -msgstr "" - -#: src/getting-started/basics/variables.md:54 -msgid "" -"Storage variables are persistent data stored on the blockchain. They can be " -"accessed from one execution to another, allowing the contract to remember " -"and update information over time." -msgstr "" - -#: src/getting-started/basics/variables.md:56 -msgid "" -"To write or update a storage variable, you need to interact with the " -"contract through an external entrypoint by sending a transaction." -msgstr "" - -#: src/getting-started/basics/variables.md:58 -msgid "" -"On the other hand, you can read state variables, for free, without any " -"transaction, simply by interacting with a node." -msgstr "" - -#: src/getting-started/basics/variables.md:60 -msgid "Here's a simple example of a contract with one storage variable:" -msgstr "" - -#: src/getting-started/basics/variables.md:70 -msgid "" -"// All storage variables are contained in a struct called Storage\n" -" // annotated with the `#[storage]` attribute\n" -msgstr "" - -#: src/getting-started/basics/variables.md:74 -msgid "// Storage variable holding a number\n" -msgstr "" - -#: src/getting-started/basics/variables.md:80 -msgid "" -"// Write to storage variables by sending a transaction that calls an " -"external function\n" -msgstr "" - -#: src/getting-started/basics/variables.md:85 -msgid "// Read from storage variables without sending transactions\n" -msgstr "" - -#: src/getting-started/basics/variables.md:92 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/variables/src/storage_variables.cairo)." -msgstr "" - -#: src/getting-started/basics/variables.md:94 -msgid "Global Variables" -msgstr "" - -#: src/getting-started/basics/variables.md:96 -msgid "" -"Global variables are predefined variables that provide information about the " -"blockchain and the current execution environment. They can be accessed at " -"any time and from anywhere!" -msgstr "" - -#: src/getting-started/basics/variables.md:98 -msgid "" -"In Starknet, you can access global variables by using specific functions " -"contained in the starknet core libraries." -msgstr "" - -#: src/getting-started/basics/variables.md:100 -msgid "" -"For example, the `get_caller_address` function returns the address of the " -"caller of the current transaction, and the `get_contract_address` function " -"returns the address of the current contract." -msgstr "" - -#: src/getting-started/basics/variables.md:109 -msgid "// import the required functions from the starknet core library\n" -msgstr "" - -#: src/getting-started/basics/variables.md:118 -msgid "// Call the get_caller_address function to get the sender address\n" -msgstr "" - -#: src/getting-started/basics/variables.md:120 -msgid "// ...\n" -msgstr "" - -#: src/getting-started/basics/variables.md:125 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/variables/src/global_variables.cairo)." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:3 -msgid "Visibility" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:5 -msgid "There are two types of functions in Starknet contracts:" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:7 -msgid "Functions that are accessible externally and can be called by anyone." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:8 -msgid "" -"Functions that are only accessible internally and can only be called by " -"other functions in the contract." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:10 -msgid "" -"These functions are also typically divided into two different " -"implementations blocks. The first `impl` block for externally accessible " -"functions is explicitly annotated with an `#[abi(embed_v0)]` attribute. This " -"indicates that all the functions inside this block can be called either as a " -"transaction or as a view function. The second `impl` block for internally " -"accessible functions is not annotated with any attribute, which means that " -"all the functions inside this block are private by default." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:12 -msgid "State Mutability" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:14 -msgid "" -"Regardless of whether a function is internal or external, it can either " -"modify the contract's state or not. When we declare functions that interact " -"with storage variables inside a smart contract, we need to explicitly state " -"that we are accessing the `ContractState` by adding it as the first " -"parameter of the function. This can be done in two different ways:" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:17 -msgid "" -"If we want our function to be able to mutate the state of the contract, we " -"pass it by reference like this: `ref self: ContractState`." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:18 -msgid "" -"If we want our function to be read-only and not mutate the state of the " -"contract, we pass it by snapshot like this: `self: @ContractState`." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:20 -msgid "" -"Read-only functions, also called view functions, can be directly called " -"without making a transaction. You can interact with them directly through a " -"RPC node to read the contract's state, and they're free to call! External " -"functions, that modify the contract's state, on the other side can only be " -"called by making a transaction." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:23 -msgid "" -"Internal functions can't be called externally, but the same principle " -"applies regarding state mutability." -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:25 -msgid "Let's take a look at a simple example contract to see these in action:" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:42 -msgid "" -"// The `#[abi(embed_v0)]` attribute indicates that all the functions in this " -"implementation can be called externally.\n" -" // Omitting this attribute would make all the functions in this " -"implementation internal.\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:46 -msgid "" -"// The `set` function can be called externally because it is written inside " -"an implementation marked as `#[abi(embed_v0)]`.\n" -" // It can modify the contract's state as it is passed as a " -"reference.\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:52 -msgid "" -"// The `get` function can be called externally because it is written inside " -"an implementation marked as `#[abi(embed_v0)]`.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:55 -msgid "" -"// We can call an internal function from any functions within the contract\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:60 -msgid "" -"// The lack of the `external` attribute indicates that all the functions in " -"this implementation can only be called internally.\n" -" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " -"internal trait allowing us to call internal functions.\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:64 -msgid "" -"// The `_read_value` function is outside the implementation that is marked " -"as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -" // and can only be called from within the contract.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -msgstr "" - -#: src/getting-started/basics/visibility-mutability.md:73 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/visibility/src/visibility.cairo)." -msgstr "" - -#: src/getting-started/basics/counter.md:1 -msgid "Simple Counter" -msgstr "" - -#: src/getting-started/basics/counter.md:3 -msgid "This is a simple counter contract." -msgstr "" - -#: src/getting-started/basics/counter.md:5 -msgid "Here's how it works:" -msgstr "" - -#: src/getting-started/basics/counter.md:7 -msgid "" -"The contract has a state variable called 'counter' that is initialized to 0." -msgstr "" - -#: src/getting-started/basics/counter.md:9 -msgid "When a user calls 'increment', the contract increments the counter by 1." -msgstr "" - -#: src/getting-started/basics/counter.md:11 -msgid "When a user calls 'decrement', the contract decrements the counter by 1." -msgstr "" - -#: src/getting-started/basics/counter.md:25 -msgid "// Counter variable\n" -msgstr "" - -#: src/getting-started/basics/counter.md:31 -msgid "// Store initial value\n" -msgstr "" - -#: src/getting-started/basics/counter.md:42 -msgid "// Store counter value + 1\n" -msgstr "" - -#: src/getting-started/basics/counter.md:47 -msgid "// Store counter value - 1\n" -msgstr "" - -#: src/getting-started/basics/counter.md:54 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/counter/src/contracts.cairo)." -msgstr "" - -#: src/getting-started/basics/mappings.md:3 -msgid "" -"Maps are a key-value data structure used to store data within a smart " -"contract. In Cairo they are implemented using the `LegacyMap` type. It's " -"important to note that the `LegacyMap` type can only be used inside the " -"`Storage` struct of a contract and that it can't be used elsewhere." -msgstr "" - -#: src/getting-started/basics/mappings.md:5 -msgid "" -"Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, " -"to map between a key of type `ContractAddress` and value of type `felt252`. " -"The key-value types are specified within angular brackets \\<\\>. We write " -"to the map by calling the `write()` method, passing in both the key and " -"value. Similarly, we can read the value associated with a given key by " -"calling the `read()` method and passing in the relevant key." -msgstr "" - -#: src/getting-started/basics/mappings.md:7 -msgid "Some additional notes:" -msgstr "" - -#: src/getting-started/basics/mappings.md:9 -msgid "" -"More complex key-value mappings are possible, for example we could use " -"`LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an " -"allowance on an ERC20 token contract." -msgstr "" - -#: src/getting-started/basics/mappings.md:11 -msgid "" -"In mappings, the address of the value at key `k_1,...,k_n` is " -"`h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the " -"Pedersen hash and the final value is taken `mod2251−256`. You can learn more " -"about the contract storage layout in the [Starknet " -"Documentation](https://docs.starknet.io/documentation/architecture_and_concepts/Contracts/contract-storage/#storage_variables)." -msgstr "" - -#: src/getting-started/basics/mappings.md:28 -msgid "// The `LegacyMap` type is only available inside the `Storage` struct.\n" -msgstr "" - -#: src/getting-started/basics/mappings.md:44 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/mappings/src/mappings.cairo)." -msgstr "" - -#: src/getting-started/basics/errors.md:3 -msgid "" -"Errors can be used to handle validation and other conditions that may occur " -"during the execution of a smart contract. If an error is thrown during the " -"execution of a smart contract call, the execution is stopped and any changes " -"made during the transaction are reverted." -msgstr "" - -#: src/getting-started/basics/errors.md:6 -msgid "To throw an error, use the `assert` or `panic` functions:" -msgstr "" - -#: src/getting-started/basics/errors.md:8 -msgid "" -"`assert` is used to validate conditions. If the check fails, an error is " -"thrown along with a specified value, often a message. It's similar to the " -"`require` statement in Solidity." -msgstr "" - -#: src/getting-started/basics/errors.md:12 -msgid "" -"`panic` immediately halt the execution with the given error value. It should " -"be used when the condition to check is complex and for internal errors. It's " -"similar to the `revert` statement in Solidity. (Use `panic_with_felt252` to " -"be able to directly pass a felt252 as the error value)" -msgstr "" - -#: src/getting-started/basics/errors.md:16 -msgid "Here's a simple example that demonstrates the use of these functions:" -msgstr "" - -#: src/getting-started/basics/errors.md:32 -msgid "" -"// Assert used to validate a condition\n" -" // and abort execution if the condition is not met\n" -msgstr "" - -#: src/getting-started/basics/errors.md:39 -msgid "// Panic used to abort execution directly\n" -msgstr "" - -#: src/getting-started/basics/errors.md:46 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/errors/src/simple_errors.cairo)." -msgstr "" - -#: src/getting-started/basics/errors.md:48 -msgid "Custom errors" -msgstr "" - -#: src/getting-started/basics/errors.md:50 -msgid "" -"You can make error handling easier by defining your error codes in a " -"specific module." -msgstr "" - -#: src/getting-started/basics/errors.md:85 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/errors/src/custom_errors.cairo)." -msgstr "" - -#: src/getting-started/basics/errors.md:87 -msgid "Vault example" -msgstr "" - -#: src/getting-started/basics/errors.md:89 -msgid "" -"Here's another example that demonstrates the use of errors in a more complex " -"contract:" -msgstr "" - -#: src/getting-started/basics/errors.md:93 -msgid "// you can define more errors here\n" -msgstr "" - -#: src/getting-started/basics/errors.md:125 -msgid "// Or using panic:\n" -msgstr "" - -#: src/getting-started/basics/errors.md:137 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/errors/src/vault_errors.cairo)." -msgstr "" - -#: src/getting-started/basics/events.md:3 -msgid "" -"Events are a way to emit data from a contract. All events must be defined in " -"the `Event` enum, which must be annotated with the `#[event]` attribute. An " -"event is defined as struct that derives the `#[starknet::Event]` trait. The " -"fields of that struct correspond to the data that will be emitted. An event " -"can be indexed for easy and fast access when querying the data at a later " -"time. Events data can be indexed by adding a `#[key]` attribute to a field " -"member." -msgstr "" - -#: src/getting-started/basics/events.md:6 -msgid "" -"Here's a simple example of a contract using events that emit an event each " -"time a counter is incremented by the \"increment\" function:" -msgstr "" - -#: src/getting-started/basics/events.md:18 -msgid "// Counter value\n" -msgstr "" - -#: src/getting-started/basics/events.md:24 -msgid "" -"// The event enum must be annotated with the `#[event]` attribute.\n" -" // It must also derive the `Drop` and `starknet::Event` traits.\n" -msgstr "" - -#: src/getting-started/basics/events.md:31 -msgid "" -"// By deriving the `starknet::Event` trait, we indicate to the compiler " -"that\n" -" // this struct will be used when emitting events.\n" -msgstr "" - -#: src/getting-started/basics/events.md:40 -msgid "// The `#[key]` attribute indicates that this event will be indexed.\n" -msgstr "" - -#: src/getting-started/basics/events.md:52 -msgid "// Emit event\n" -msgstr "" - -#: src/getting-started/basics/events.md:66 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/events/src/counter.cairo)." -msgstr "" - -#: src/getting-started/basics/storing-custom-types.md:3 -msgid "" -"While native types can be stored in a contract's storage without any " -"additional work, custom types require a bit more work. This is because at " -"compile time, the compiler does not know how to store custom types in " -"storage. To solve this, we need to implement the `Store` trait for our " -"custom type. Hopefully, we can just derive this trait for our custom type - " -"unless it contains arrays or dictionaries." -msgstr "" - -#: src/getting-started/basics/storing-custom-types.md:10 -msgid "" -"// Deriving the starknet::Store trait\n" -"// allows us to store the `Person` struct in the contract's storage.\n" -msgstr "" - -#: src/getting-started/basics/storing-custom-types.md:37 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/storing_custom_types/src/contract.cairo)." -msgstr "" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:3 -msgid "" -"Using custom types in entrypoints requires our type to implement the `Serde` " -"trait. This is because when calling an entrypoint, the input is sent as an " -"array of `felt252` to the entrypoint, and we need to be able to deserialize " -"it into our custom type. Similarly, when returning a custom type from an " -"entrypoint, we need to be able to serialize it into an array of `felt252`. " -"Thankfully, we can just derive the `Serde` trait for our custom type." -msgstr "" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:18 -msgid "" -"// Deriving the `Serde` trait allows us to use\n" -" // the Person type as an entrypoint parameter and return value\n" -msgstr "" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:37 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/custom_type_serde/src/contract.cairo)." -msgstr "" - -#: src/getting-started/basics/documentation.md:3 -msgid "" -"It's important to take the time to document your code. It will helps " -"developers and users to understand the contract and its functionalities." -msgstr "" - -#: src/getting-started/basics/documentation.md:5 -msgid "In Cairo, you can add comments with `//`." -msgstr "" - -#: src/getting-started/basics/documentation.md:7 -msgid "Best Practices:" -msgstr "" - -#: src/getting-started/basics/documentation.md:9 -msgid "" -"Since Cairo 1, the community has adopted a [Rust-like documentation " -"style](https://doc.rust-lang.org/rust-by-example/meta/doc.html)." -msgstr "" - -#: src/getting-started/basics/documentation.md:11 -msgid "Contract Interface:" -msgstr "" - -#: src/getting-started/basics/documentation.md:13 -msgid "" -"In smart contracts, you will often have a trait that defines the contract's " -"interface (with `#[starknet::interface]`). This is the perfect place to " -"include detailed documentation explaining the purpose and functionality of " -"the contract entry points. You can follow this template:" -msgstr "" - -#: src/getting-started/basics/documentation.md:19 -msgid "" -"/// High-level description of the function\n" -" ///\n" -" /// # Arguments\n" -" ///\n" -" /// * `arg_1` - Description of the argument\n" -" /// * `arg_n` - ...\n" -" ///\n" -" /// # Returns\n" -" ///\n" -" /// High-level description of the return value\n" -msgstr "" - -#: src/getting-started/basics/documentation.md:33 -msgid "" -"Keep in mind that this should not describe the implementation details of the " -"function, but rather the high-level purpose and functionality of the " -"contract from the perspective of a user." -msgstr "" - -#: src/getting-started/basics/documentation.md:35 -msgid "Implementation Details:" -msgstr "" - -#: src/getting-started/basics/documentation.md:37 -msgid "" -"When writing the logic of the contract, you can add comments to describe the " -"technical implementation details of the functions." -msgstr "" - -#: src/getting-started/basics/documentation.md:39 -msgid "" -"Avoid over-commenting: Comments should provide additional value and clarity." -msgstr "" - -#: src/getting-started/interacting/interacting.md:3 -msgid "In this chapter, we will see how to deploy and interact with contracts." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:3 -msgid "" -"Contract interfaces define the structure and behavior of a contract, serving " -"as the contract's public ABI. They list all the function signatures that a " -"contract exposes. For a detailed explanation of interfaces, you can refer to " -"the [Cairo " -"Book](https://book.cairo-lang.org/ch99-01-02-a-simple-contract.html)." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:5 -msgid "" -"In cairo, to specify the interface you need to define a trait annotated with " -"`#[starknet::interface]` and then implement that trait in the contract." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:7 -msgid "" -"When a function needs to access the contract state, it must have a `self` " -"parameter of type `ContractState`. This implies that the corresponding " -"function signature in the interface trait must also take a `TContractState` " -"type as a parameter. It's important to note that every function in the " -"contract interface must have this `self` parameter of type `TContractState`." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:9 -msgid "" -"You can use the `#[generate_trait]` attribute to implicitly generate the " -"trait for a specific implementation block. This attribute automatically " -"generates a trait with the same functions as the ones in the implemented " -"block, replacing the `self` parameter with a generic `TContractState` " -"parameter. However, you will need to annotate the block with the " -"`#[abi(per_item)]` attribute, and each function with the appropriate " -"attribute depending on whether it's an external function, a constructor or a " -"l1 handler." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:11 -msgid "In summary, there's two ways to handle interfaces:" -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:13 -msgid "Explicitly, by defining a trait annoted with `#[starknet::interface]`" -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:14 -msgid "" -"Implicitly, by using `#[generate_trait]` combined with the " -"#\\[abi(per_item)\\]\\` attributes, and annotating each function inside the " -"implementation block with the appropriate attribute." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:16 -msgid "Explicit interface" -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:45 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/interfaces_traits/src/explicit.cairo)." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:47 -msgid "Implicit interface" -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:73 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/interfaces_traits/src/implicit.cairo)." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:75 -msgid "" -"Note: You can import an implicitly generated contract interface with `use " -"contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not " -"be generated automatically." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:77 -msgid "Internal functions" -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:79 -msgid "" -"You can also use `#[generate_trait]` for your internal functions. Since this " -"trait is generated in the context of the contract, you can define pure " -"functions as well (functions without the `self` parameter)." -msgstr "" - -#: src/getting-started/interacting/interfaces-traits.md:127 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/interfaces_traits/src/implicit_internal.cairo)." -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:3 -msgid "There are two different ways to call other contracts in Cairo." -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:5 -msgid "" -"The easiest way to call other contracts is by using the dispatcher of the " -"contract you want to call. You can read more about Dispatchers in the [Cairo " -"Book](https://book.cairo-lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-calls.html#contract-dispatcher)" -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:8 -msgid "" -"The other way is to use the `starknet::call_contract_syscall` syscall " -"yourself. However, this method is not recommended." -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:10 -msgid "" -"In order to call other contracts using dispatchers, you will need to define " -"the called contract's interface as a trait annotated with the " -"`#[starknet::interface]` attribute, and then import the " -"`IContractDispatcher` and `IContractDispatcherTrait` items in your contract." -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:34 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x015c3Bb6D0DE26b64FEAF9A8f4655CfADb5c128bF4510398972704ee12775DB1) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/calling_other_contracts/src/callee.cairo)." -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:38 -msgid "" -"// We need to have the interface of the callee contract defined\n" -"// so that we can import the Dispatcher.\n" -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:53 -msgid "// We import the Dispatcher of the called contract\n" -msgstr "" - -#: src/getting-started/interacting/calling_other_contracts.md:68 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x05fa8aF796343d2f22c53C17149386b67B7AC4aB52D9e308Aa507C185aA44778) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/calling_other_contracts/src/caller.cairo)." -msgstr "" - -#: src/getting-started/interacting/factory.md:1 -msgid "Factory Pattern" -msgstr "" - -#: src/getting-started/interacting/factory.md:3 -msgid "" -"The factory pattern is a well known pattern in object oriented programming. " -"It provides an abstraction on how to instantiate a class. " -msgstr "" - -#: src/getting-started/interacting/factory.md:5 -msgid "" -"In the case of smart contracts, we can use this pattern by defining a " -"factory contract that have the sole responsibility of creating and managing " -"other contracts." -msgstr "" - -#: src/getting-started/interacting/factory.md:7 -msgid "Class hash and contract instance" -msgstr "" - -#: src/getting-started/interacting/factory.md:9 -msgid "" -"In Starknet, there's a separation between contract's classes and instances. " -"A contract class serves as a blueprint, defined by the underling Cairo " -"bytecode, contract's entrypoints, ABI and Sierra program hash. The contract " -"class is identified by a class hash. When you want to add a new class to the " -"network, you first need to declare it." -msgstr "" - -#: src/getting-started/interacting/factory.md:11 -msgid "" -"When deploying a contract, you need to specify the class hash of the " -"contract you want to deploy. Each instance of a contract has their own " -"storage regardless of the class hash." -msgstr "" - -#: src/getting-started/interacting/factory.md:13 -msgid "" -"Using the factory pattern, we can deploy multiple instances of the same " -"contract class and handle upgrades easily." -msgstr "" - -#: src/getting-started/interacting/factory.md:15 -msgid "Minimal example" -msgstr "" - -#: src/getting-started/interacting/factory.md:17 -msgid "" -"Here's a minimal example of a factory contract that deploy the " -"`SimpleCounter` contract:" -msgstr "" - -#: src/getting-started/interacting/factory.md:24 -msgid "/// Create a new counter contract from stored arguments\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:27 -msgid "/// Create a new counter contract from the given arguments\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:30 -msgid "/// Update the argument\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:33 -msgid "" -"/// Update the class hash of the Counter contract to deploy when creating a " -"new counter\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:44 -msgid "/// Store the constructor arguments of the contract to deploy\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:46 -msgid "/// Store the class hash of the contract to deploy\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:59 -msgid "// Contructor arguments\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:62 -msgid "// Contract deployment\n" -msgstr "" - -#: src/getting-started/interacting/factory.md:88 -msgid "" -"This factory can be used to deploy multiple instances of the `SimpleCounter` " -"contract by calling the `create_counter` and `create_counter_at` functions." -msgstr "" - -#: src/getting-started/interacting/factory.md:90 -msgid "" -"The `SimpleCounter` class hash is stored inside the factory, and can be " -"upgraded with the `update_counter_class_hash` function which allows to reuse " -"the same factory contract when the `SimpleCounter` contract is upgraded." -msgstr "" - -#: src/getting-started/interacting/factory.md:92 -msgid "" -"This minimal example lacks several useful features such as access control, " -"tracking of deployed contracts, events, ..." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:1 -msgid "Contract Testing" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:3 -msgid "" -"Testing plays a crucial role in software development, especially for smart " -"contracts. In this section, we'll guide you through the basics of testing a " -"smart contract on Starknet with `scarb`." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:5 -msgid "Let's start with a simple smart contract as an example:" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:50 -msgid "Now, take a look at the tests for this contract:" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:54 -msgid "" -"// Import the interface and dispatcher to be able to interact with the " -"contract.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:59 -msgid "// Import the deploy syscall to be able to deploy the contract.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:66 -msgid "// Use starknet test utils to fake the transaction context.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:69 -msgid "// Deploy the contract and return its dispatcher.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:71 -msgid "// Set up constructor arguments.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:75 -msgid "// Declare and deploy\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:81 -msgid "" -"// Return the dispatcher.\n" -" // The dispatcher allows to interact with the contract based on its " -"interface.\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:99 -msgid "// Fake the caller address to address 1\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:106 -msgid "// Fake the contract address to address 1\n" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:132 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/getting-started-getting-started/testing/src/lib.cairo)." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:134 -msgid "" -"To define our test, we use scarb, which allows us to create a separate " -"module guarded with `#[cfg(test)]`. This ensures that the test module is " -"only compiled when running tests using `scarb test`." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:136 -msgid "" -"Each test is defined as a function with the `#[test]` attribute. You can " -"also check if a test panics using the `#[should_panic]` attribute." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:138 -msgid "" -"As we are in the context of a smart contract, it's essential to set up the " -"gas limit. You do this by using the `#[available_gas(X)]` attribute to " -"specify the gas limit for a test. This is also a great way to ensure that " -"your contract's features stay under a certain gas limit!" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:140 -msgid "Note: The term \"gas\" here refers to Sierra gas, not L1 gas" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:142 -msgid "Now, let's move on to the testing process:" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:143 -msgid "Use the `deploy` function logic to declare and deploy your contract." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:144 -msgid "" -"Use `assert` to verify that the contract behaves as expected in the given " -"context." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:146 -msgid "" -"To make testing more convenient, the `testing` module of the corelib " -"provides some helpful functions:" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:147 -msgid "`set_caller_address(address: ContractAddress)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:148 -msgid "`set_contract_address(address: ContractAddress)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:149 -msgid "`set_block_number(block_number: u64)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:150 -msgid "`set_block_timestamp(block_timestamp: u64)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:151 -msgid "`set_account_contract_address(address: ContractAddress)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:152 -msgid "`set_max_fee(fee: u128)`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:154 -msgid "" -"You may also need the `info` module from the corelib, which allows you to " -"access information about the current transaction context:" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:155 -msgid "`get_caller_address() -> ContractAddress`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:156 -msgid "`get_contract_address() -> ContractAddress`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:157 -msgid "`get_block_info() -> Box`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:158 -msgid "`get_tx_info() -> Box`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:159 -msgid "`get_block_timestamp() -> u64`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:160 -msgid "`get_block_number() -> u64`" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:163 -msgid "" -"You can found the full list of functions in the [Starknet Corelib " -"repo](https://github.com/starkware-libs/cairo/tree/main/corelib/src/starknet). " -"You can also find a detailled explaination of testing in cairo in the [Cairo " -"book - Chapter " -"8](https://book.cairo-lang.org/ch08-01-how-to-write-tests.html)." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:166 -msgid "Starknet Foundry" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:170 -msgid "" -"Starknet Foundry is a powerful toolkit for developing smart contracts on " -"Starknet. It offers support for testing Starknet smart contracts on top of " -"`scarb` with the `Forge` tool." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:172 -msgid "" -"Testing with `snforge` is similar to the process we just described but " -"simplified. Moreover, additional features are on the way, including " -"cheatcodes or parallel tests execution. We highly recommend exploring " -"Starknet Foundry and incorporating it into your projects." -msgstr "" - -#: src/getting-started/testing/contract-testing.md:174 -msgid "" -"For more detailed information about testing contracts with Starknet Foundry, " -"check out the [Starknet Foundry Book - Testing " -"Contracts](https://foundry-rs.github.io/starknet-foundry/testing/contracts.html)." -msgstr "" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:1 -msgid "Cairo Cheatsheet" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:3 -msgid "" -"This chapter aims to provide a quick reference for the most common Cairo " -"constructs." -msgstr "" - -#: src/getting-started/cairo_cheatsheet/felt.md:1 -msgid "Felt252" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/felt.md:3 -msgid "" -"Felt252 is a fundamental data type in Cairo from which all other data types " -"are derived. Felt252 can also be used to store short-string representations " -"with a maximum length of 31 characters." -msgstr "" - -#: src/getting-started/cairo_cheatsheet/felt.md:6 src/getting-started/cairo_cheatsheet/arrays.md:20 -#: src/advanced-concepts/hash-solidity-compatible.md:5 -msgid "For example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/mapping.md:1 -msgid "Mapping" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/mapping.md:3 -msgid "The `LegacyMap` type can be used to represent a collection of key-value." -msgstr "" - -#: src/getting-started/cairo_cheatsheet/mapping.md:51 -msgid "" -"// for a 2D mapping its important to take note of the amount of brackets " -"being used.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/arrays.md:3 -msgid "" -"Arrays are collections of elements of the same type. The possible operations " -"on arrays are defined with the `array::ArrayTrait` of the corelib:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/arrays.md:37 -msgid "// Returns true if an array is empty, then false if it isn't.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/loop.md:3 -msgid "" -"A loop specifies a block of code that will run repetitively until a halting " -"condition is encountered. For example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/loop.md:9 -msgid "// Same as ~ while (i < 10) arr.append(i++);\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/match.md:3 -msgid "" -"The `match` expression in Cairo allows us to control the flow of our code " -"by comparing a `felt252` data type or an enum against various patterns and then " -"running specific code based on the pattern that matches. For example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/tuples.md:3 -msgid "" -"Tuples is a data type to group a fixed number of items of potentially " -"different types into a single compound structure. Unlike arrays, tuples have " -"a set length and can contain elements of varying types. Once a tuple is " -"created, its size cannot change. For example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/tuples.md:7 -msgid "\"0x000\"" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/tuples.md:11 -msgid "// Create tuple\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/tuples.md:14 -msgid "// Access tuple\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/struct.md:3 -msgid "" -"A struct is a data type similar to tuple. Like tuples they can be used to " -"hold data of different types. For example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/struct.md:7 -msgid "" -"// With Store, you can store Data's structs in the storage part of " -"contracts.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:3 -msgid "" -"Cairo supports the conversion from one scalar types to another by using the " -"into and try_into methods. `traits::Into` is used for conversion from a " -"smaller data type to a larger data type, while `traits::TryInto` is used " -"when converting from a larger to a smaller type that might not fit. For " -"example:" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:11 -msgid "" -"// Since a u32 might not fit in a u8 and a u16, we need to use try_into,\n" -" // then unwrap the Option type thats returned.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:16 -msgid "" -"// since new_u32 is the of the same type (u32) as rand_number, we can " -"directly assign them,\n" -" // or use the .into() method.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:20 -msgid "" -"// When typecasting from a smaller size to an equal or larger size we use " -"the .into() method.\n" -" // Note: u64 and u128 are larger than u32, so a u32 type will always fit " -"into them.\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:25 -msgid "// Since a felt252 is smaller than a u256, we can use the into() method\n" -msgstr "" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:29 -msgid "// Note: usize is smaller than felt252, so we use try_into\n" -msgstr "" - -#: src/applications/upgradeable_contract.md:3 -msgid "" -"In Starknet, contracts are divided into two parts: contract classes and " -"contract instances. This division follows a similar concept used in " -"object-oriented programming languages, where we distinguish between the " -"definition and implementation of objects." -msgstr "" - -#: src/applications/upgradeable_contract.md:8 -msgid "" -"A contract class is the definition of a contract: it specifies how the " -"contract behaves. It contains essential information like the Cairo byte " -"code, hint information, entry point names, and everything that defines its " -"semantics unambiguously." -msgstr "" - -#: src/applications/upgradeable_contract.md:13 -msgid "" -"To identify different contract classes, Starknet assigns a unique identifier " -"to each class: the class hash. A contract instance is a deployed contract " -"that corresponds to a specific contract class. Think of it as an instance of " -"an object in languages like Java." -msgstr "" - -#: src/applications/upgradeable_contract.md:18 -msgid "" -"Each class is identified by its class hash, which is analogous to a class " -"name in an object-oriented programming language. A contract instance is a " -"deployed contract corresponding to a class." -msgstr "" - -#: src/applications/upgradeable_contract.md:20 -msgid "" -"You can upgrade a deployed contract to a newer version by calling the " -"`replace_class_syscall` function. By using this function, you can update the " -"class hash associated with a deployed contract, effectively upgrading its " -"implementation. However, this will not modify the contract's storage, so all " -"the data stored in the contract will remain the same." -msgstr "" - -#: src/applications/upgradeable_contract.md:22 -msgid "" -"To illustrate this concept, let's consider an example with two contracts: " -"`UpgradeableContract_V0`, and `UpgradeableContract_V1`. Start by deploying " -"`UpgradeableContract_V0` as the initial version. Next, send a transaction " -"that invokes the `upgrade` function, with the class hash of " -"`UpgradeableContract_V1` as parameter to upgrade the class hash of the " -"deployed contract to the `UpgradeableContract_V1` one. Then, call the " -"`version` method on the contract to see that the contract was upgraded to " -"the V1 version." -msgstr "" - -#: src/applications/upgradeable_contract.md:68 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x005300003ade5d10447d941a42d48b7141074cd8bade2b16520684896a5090ea) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/applications-applications/upgradeable_contract/src/upgradeable_contract_v0.cairo)." -msgstr "" - -#: src/applications/upgradeable_contract.md:114 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x017c86152badd1d665b9836571bd6b0a484f028748aa13d9b2d5d9c9192fafc6) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/applications-applications/upgradeable_contract/src/upgradeable_contract_v1.cairo)." -msgstr "" - -#: src/applications/simple_vault.md:1 -msgid "Simple Defi Vault" -msgstr "" - -#: src/applications/simple_vault.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example " -"Vault](https://solidity-by-example.org/defi/vault/). Here's how it works:" -msgstr "" - -#: src/applications/simple_vault.md:6 -msgid "" -"When a user deposits a token, the contract calculates the amount of shares " -"to mint." -msgstr "" - -#: src/applications/simple_vault.md:8 -msgid "" -"When a user withdraws, the contract burns their shares, calculates the " -"yield, and withdraw both the yield and the initial amount of token deposited." -msgstr "" - -#: src/applications/simple_vault.md:12 -msgid "" -"// In order to make contract calls within our Vault,\n" -"// we need to have the interface of the remote ERC20 contract defined to " -"import the Dispatcher.\n" -msgstr "" - -#: src/applications/simple_vault.md:68 -msgid "" -"// a = amount\n" -" // B = balance of token before deposit\n" -" // T = total supply\n" -" // s = shares to mint\n" -" //\n" -" // (T + s) / T = (a + B) / B \n" -" //\n" -" // s = aT / B\n" -msgstr "" - -#: src/applications/simple_vault.md:92 -msgid "" -"// a = amount\n" -" // B = balance of token before withdraw\n" -" // T = total supply\n" -" // s = shares to burn\n" -" //\n" -" // (T - s) / T = (B - a) / B \n" -" //\n" -" // a = sB / T\n" -msgstr "" - -#: src/applications/simple_vault.md:113 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/applications-applications/simple_vault/src/simple_vault.cairo)." -msgstr "" - -#: src/applications/erc20.md:3 -msgid "" -"Contracts that follow the [ERC20 " -"Standard](https://eips.ethereum.org/EIPS/eip-20) are called ERC20 tokens. " -"They are used to represent fungible assets." -msgstr "" - -#: src/applications/erc20.md:5 -msgid "To create an ERC20 conctract, it must implement the following interface:" -msgstr "" - -#: src/applications/erc20.md:33 -msgid "" -"In Starknet, function names should be written in _snake_case_. This is not " -"the case in Solidity, where function names are written in _camelCase_. The " -"Starknet ERC20 interface is therefore slightly different from the Solidity " -"ERC20 interface." -msgstr "" - -#: src/applications/erc20.md:36 -msgid "Here's an implementation of the ERC20 interface in Cairo:" -msgstr "" - -#: src/applications/erc20.md:207 -msgid "// What can go wrong here?\n" -msgstr "" - -#: src/applications/erc20.md:224 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/applications-applications/erc20/src/token.cairo)." -msgstr "" - -#: src/applications/erc20.md:226 -msgid "" -"There's several other implementations, such as the [Open " -"Zeppelin](https://docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the " -"[Cairo By Example](https://cairo-by-example.com/examples/erc20/) ones." -msgstr "" - -#: src/applications/constant-product-amm.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example Constant Product " -"AMM](https://solidity-by-example.org/defi/constant-product-amm/)." -msgstr "" - -#: src/applications/constant-product-amm.md:32 -msgid "" -"// Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -" // E.g. 3 = 0.3%\n" -msgstr "" - -#: src/applications/constant-product-amm.md:41 -msgid "// assert(fee <= 1000, 'fee > 1000');\n" -msgstr "" - -#: src/applications/constant-product-amm.md:107 -msgid "" -"// How much dy for dx?\n" -" // xy = k\n" -" // (x + dx)(y - dy) = k\n" -" // y - dy = k / (x + dx)\n" -" // y - k / (x + dx) = dy\n" -" // y - xy / (x + dx) = dy\n" -" // (yx + ydx - xy) / (x + dx) = dy\n" -" // ydx / (x + dx) = dy\n" -msgstr "" - -#: src/applications/constant-product-amm.md:135 -msgid "" -"// How much dx, dy to add?\n" -" //\n" -" // xy = k\n" -" // (x + dx)(y + dy) = k'\n" -" //\n" -" // No price change, before and after adding liquidity\n" -" // x / y = (x + dx) / (y + dy)\n" -" //\n" -" // x(y + dy) = y(x + dx)\n" -" // x * dy = y * dx\n" -" //\n" -" // x / y = dx / dy\n" -" // dy = y / x * dx\n" -msgstr "" - -#: src/applications/constant-product-amm.md:154 -msgid "" -"// How much shares to mint?\n" -" //\n" -" // f(x, y) = value of liquidity\n" -" // We will define f(x, y) = sqrt(xy)\n" -" //\n" -" // L0 = f(x, y)\n" -" // L1 = f(x + dx, y + dy)\n" -" // T = total shares\n" -" // s = shares to mint\n" -" //\n" -" // Total shares should increase proportional to increase in " -"liquidity\n" -" // L1 / L0 = (T + s) / T\n" -" //\n" -" // L1 * T = L0 * (T + s)\n" -" //\n" -" // (L1 - L0) * T / L0 = s\n" -msgstr "" - -#: src/applications/constant-product-amm.md:171 -msgid "" -"// Claim\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -" //\n" -" // Proof\n" -" // --- Equation 1 ---\n" -" // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // dx / dy = x / y so replace dy = dx * y / x\n" -" //\n" -" // --- Equation 2 ---\n" -" // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // Multiply by sqrt(x) / sqrt(x)\n" -" // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - sqrt(x^2y)) / " -"sqrt(x^2y)\n" -" // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(y)sqrt(x^2))\n" -" // sqrt(y) on top and bottom cancels out\n" -" //\n" -" // --- Equation 3 ---\n" -" // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(x^2)\n" -" // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -" // = ((x + dx) - x) / x\n" -" // = dx / x\n" -" // Since dx / dy = x / y,\n" -" // dx / x = dy / y\n" -" //\n" -" // Finally\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -msgstr "" - -#: src/applications/constant-product-amm.md:221 -msgid "" -"// Claim\n" -" // dx, dy = amount of liquidity to remove\n" -" // dx = s / T * x\n" -" // dy = s / T * y\n" -" //\n" -" // Proof\n" -" // Let's find dx, dy such that\n" -" // v / L = s / T\n" -" //\n" -" // where\n" -" // v = f(dx, dy) = sqrt(dxdy)\n" -" // L = total liquidity = sqrt(xy)\n" -" // s = shares\n" -" // T = total supply\n" -" //\n" -" // --- Equation 1 ---\n" -" // v = s / T * L\n" -" // sqrt(dxdy) = s / T * sqrt(xy)\n" -" //\n" -" // Amount of liquidity to remove must not change price so\n" -" // dx / dy = x / y\n" -" //\n" -" // replace dy = dx * y / x\n" -" // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -" //\n" -" // Divide both sides of Equation 1 with sqrt(y / x)\n" -" // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -" // = s / T * sqrt(x^2) = s / T * x\n" -" //\n" -" // Likewise\n" -" // dy = s / T * y\n" -msgstr "" - -#: src/applications/constant-product-amm.md:253 -msgid "" -"// bal0 >= reserve0\n" -" // bal1 >= reserve1\n" -msgstr "" - -#: src/applications/constant-product-amm.md:274 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/applications-applications/constant_product_amm/src/constant_product_amm.cairo)." -msgstr "" - -#: src/advanced-concepts/write_to_any_slot.md:3 -msgid "" -"On Starknet, a contract's storage is a map with 2^251 slots, where each slot " -"is a felt which is initialized to 0. The address of storage variables is " -"computed at compile time using the formula: `storage variable address := " -"pedersen(keccak(variable name), keys)`. Interactions with storage variables " -"are commonly performed using the `self.var.read()` and `self.var.write()` " -"functions." -msgstr "" - -#: src/advanced-concepts/write_to_any_slot.md:6 -msgid "" -"Nevertheless, we can use the `storage_write_syscall` and " -"`storage_read_syscall` syscalls, to write to and read from any storage slot. " -"This is useful when writing to storage variables that are not known at " -"compile time, or to ensure that even if the contract is upgraded and the " -"computation method of storage variable addresses changes, they remain " -"accessible." -msgstr "" - -#: src/advanced-concepts/write_to_any_slot.md:9 -msgid "" -"In the following example, we use the Poseidon hash function to compute the " -"address of a storage variable. Poseidon is a ZK-friendly hash function that " -"is cheaper and faster than Pedersen, making it an excellent choice for " -"onchain computations. Once the address is computed, we use the storage " -"syscalls to interact with it." -msgstr "" - -#: src/advanced-concepts/write_to_any_slot.md:49 -msgid "" -"// By taking the 250 least significant bits of the hash output, we get a " -"valid 250bits storage address.\n" -msgstr "" - -#: src/advanced-concepts/write_to_any_slot.md:56 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x033943CB781A4E63C9dcE0A1A09eAa3b617AA43CC61637C08c043a67f3fe0087) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts-advanced-concepts/write_to_any_slot/src/contract.cairo)." -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:3 -msgid "" -"On Starknet, complex values (e.g., tuples or structs), are stored in a " -"continuous segment starting from the address of the storage variable. There " -"is a 256 field elements limitation to the maximal size of a complex storage " -"value, meaning that to store arrays of more than 255 elements in storage, we " -"would need to split it into segments of size `n <= 255` and store these " -"segments in multiple storage addresses. There is currently no native support " -"for storing arrays in Cairo, so you will need to write your own " -"implementation of the `Store` trait for the type of array you wish to store." -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:5 -msgid "" -"Note: While storing arrays in storage is possible, it is not always " -"recommended, as the read and write operations can get very costly. For " -"example, reading an array of size `n` requires `n` storage reads, and " -"writing to an array of size `n` requires `n` storage writes. If you only " -"need to access a single element of the array at a time, it is recommended to " -"use a `LegacyMap` and store the length in another variable instead." -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:7 -msgid "" -"The following example demonstrates how to write a simple implementation of " -"the `StorageAccess` trait for the `Array` type, allowing us to " -"store arrays of up to 255 `felt252` elements." -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:26 -msgid "" -"// Read the stored array's length. If the length is superior to 255, the " -"read will fail.\n" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:31 -msgid "// Sequentially read all stored elements and append them to the array.\n" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:43 -msgid "// Return the array.\n" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:50 -msgid "// // Store the length of the array in the first storage slot.\n" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:55 -msgid "// Store the array elements sequentially\n" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:73 -msgid "" -"You can then import this implementation in your contract and use it to store " -"arrays in storage:" -msgstr "" - -#: src/advanced-concepts/storing_arrays.md:103 -msgid "" -"Visit contract on " -"[Voyager](https://goerli.voyager.online/contract/0x008F8069a3Fcd7691Db46Dc3b6F9D2C0436f9200E861330957Fd780A3595da86) " -"or play with it in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts-advanced-concepts/storing_arrays/src/contract.cairo)." -msgstr "" - -#: src/advanced-concepts/struct-mapping-key.md:1 -msgid "Structs as mapping keys" -msgstr "" - -#: src/advanced-concepts/struct-mapping-key.md:3 -msgid "" -"In order to use structs as mapping keys, you can use `#[derive(Hash)]` on " -"the struct definition. This will automatically generate a hash function for " -"the struct that can be used to represent the struct as a key in a " -"`LegacyMap`." -msgstr "" - -#: src/advanced-concepts/struct-mapping-key.md:5 -msgid "" -"Consider the following example in which we would like to use an object of " -"type `Pet` as a key in a `LegacyMap`. The `Pet` struct has three fields: " -"`name`, `age` and `owner`. We consider that the combination of these three " -"fields uniquely identifies a pet." -msgstr "" - -#: src/advanced-concepts/struct-mapping-key.md:45 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts-advanced-concepts/struct_as_mapping_key/src/contract.cairo)." -msgstr "" - -#: src/advanced-concepts/hash-solidity-compatible.md:3 -msgid "" -"This contract demonstrates Keccak hashing in Cairo to match Solidity's " -"keccak256. While both use Keccak, their endianness differs: Cairo is " -"little-endian, Solidity big-endian. The contract achieves compatibility by " -"hashing in big-endian using `keccak_u256s_be_inputs`, and reversing the " -"bytes of the result with `u128_byte_reverse`." -msgstr "" - -#: src/advanced-concepts/hash-solidity-compatible.md:27 -msgid "// Split the hashed value into two 128-bit segments\n" -msgstr "" - -#: src/advanced-concepts/hash-solidity-compatible.md:31 -msgid "// Reverse each 128-bit segment\n" -msgstr "" - -#: src/advanced-concepts/hash-solidity-compatible.md:35 -msgid "// Reverse merge the reversed segments back into a u256 value\n" -msgstr "" - -#: src/advanced-concepts/hash-solidity-compatible.md:44 -msgid "" -"Play with the contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts-advanced-concepts/hash_solidity_compatible/src/contract.cairo)." -msgstr "" - -#: src/advanced-concepts/optimisations/optimisations.md:3 -msgid "A collection of optimisation patterns to save gas and steps." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:1 -msgid "Storage optimisation" -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:3 -msgid "" -"A smart contract has a limited amount of **storage slots**. Each slot can " -"store a single `felt252` value. Writing to a storage slot has a cost, so we " -"want to use as few storage slots as possible." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:6 -msgid "" -"In Cairo, every type is derived from the `felt252` type, which uses 252 bits " -"to store a value. This design is quite simple, but it does have a drawback: " -"it is not storage efficient. For example, if we want to store a `u8` value, " -"we need to use an entire slot, even though we only need 8 bits." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:9 -msgid "Packing" -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:11 -msgid "" -"When storing multiple values, we can use a technique called **packing**. " -"Packing is a technique that allows us to store multiple values in a single " -"felt value. This is done by using the bits of the felt value to store " -"multiple values." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:13 -msgid "" -"For example, if we want to store two `u8` values, we can use the first 8 " -"bits of the felt value to store the first `u8` value, and the last 8 bits to " -"store the second `u8` value. This way, we can store two `u8` values in a " -"single felt value." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:15 -msgid "" -"Cairo provides a built-in store using packing that you can use with the " -"`StorePacking` trait." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:24 -msgid "" -"This allows to store the type `T` by first packing it into the type " -"`PackedT` with the `pack` function, and then storing the `PackedT` value " -"with it's `Store` implementation. When reading the value, we first retrieve " -"the `PackedT` value, and then unpack it into the type `T` using the `unpack` " -"function." -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:26 -msgid "" -"Here's an example of storing a `Time` struct with two `u8` values using the " -"`StorePacking` trait:" -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:75 -msgid "" -"// This will call the pack method of the TimePackable trait\n" -" // and store the resulting felt252\n" -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:80 -msgid "" -"// This will read the felt252 value from storage\n" -" // and return the result of the unpack method of the " -"TimePackable trait\n" -msgstr "" - -#: src/advanced-concepts/optimisations/store_using_packing.md:88 -msgid "" -"Play with this contract in " -"[Remix](https://remix.ethereum.org/?#activate=Starknet-cairo1-compiler&url=https://github.com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts-advanced-concepts/store_using_packing/src/contract.cairo)." -msgstr "" - -#: src/advanced-concepts/list.md:3 -msgid "" -"By default, there is no list type supported in Cairo, but you can use " -"Alexandria. You can refer to the [Alexandria " -"documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/src/storage) " -"for more details." -msgstr "" - -#: src/advanced-concepts/list.md:5 -msgid "What is `List`?" -msgstr "" - -#: src/advanced-concepts/list.md:7 -msgid "An ordered sequence of values that can be used in Starknet storage:" -msgstr "" - -#: src/advanced-concepts/list.md:16 -msgid "Interface" -msgstr "" - -#: src/advanced-concepts/list.md:30 -msgid "" -"`List` also implements `IndexView` so you can use the familiar bracket " -"notation to access its members:" -msgstr "" - -#: src/advanced-concepts/list.md:36 -msgid "" -"Note that unlike `get`, using this bracket notation panics when accessing an " -"out of bounds index." -msgstr "" - -#: src/advanced-concepts/list.md:38 -msgid "Support for custom types" -msgstr "" - -#: src/advanced-concepts/list.md:40 -msgid "" -"`List` supports most of the corelib types out of the box. If you want to " -"store a your own custom type in a `List`, it has to implement the `Store` " -"trait. You can have the compiler derive it for you using the " -"`#[derive(starknet::Store)]` attribute." -msgstr "" - -#: src/advanced-concepts/list.md:42 -msgid "Caveats" -msgstr "" - -#: src/advanced-concepts/list.md:44 -msgid "There are two idiosyncacies you should be aware of when using `List`" -msgstr "" - -#: src/advanced-concepts/list.md:46 -msgid "" -"The `append` operation costs 2 storage writes - one for the value itself and " -"another one for updating the List's length" -msgstr "" - -#: src/advanced-concepts/list.md:47 -msgid "" -"Due to a compiler limitation, it is not possible to use mutating operations " -"with a single inline statement. For example, " -"`self.amounts.read().append(42);` will not work. You have to do it in 2 " -"steps:" -msgstr "" - -#: src/advanced-concepts/list.md:54 -msgid "Dependencies" -msgstr "" - -#: src/advanced-concepts/list.md:56 -msgid "Update your project dependencies by in the `Scarb.toml` file:" -msgstr "" - -#: src/advanced-concepts/list.md:60 -msgid "\"https://github.com/keep-starknet-strange/alexandria.git\"" -msgstr "" - -#: src/advanced-concepts/list.md:63 -msgid "" -"For example, let's use `List` to create a contract that tracks a list of " -"amounts and tasks:" -msgstr "" - diff --git a/po/zh-cn.po b/po/zh-cn.po deleted file mode 100644 index de215af4..00000000 --- a/po/zh-cn.po +++ /dev/null @@ -1,7124 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: Starknet by Example\n" -"POT-Creation-Date: \n" -"PO-Revision-Date: 2023-12-08 14:49+0900\n" -"Last-Translator: StarknetAstro \n" -"Language-Team: Language zh-cn\n" -"Language: zh_CN\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Poedit 3.4.1\n" - -#: src/SUMMARY.md:3 -msgid "Introduction" -msgstr "介绍" - -#: src/SUMMARY.md:6 -msgid "Getting Started" -msgstr "入门" - -#: src/SUMMARY.md:8 -msgid "Basics of a Starknet contract" -msgstr "Starknet合约的基本内容" - -#: src/SUMMARY.md:9 -msgid "Storage" -msgstr "存储" - -#: src/SUMMARY.md:10 -msgid "Constructor" -msgstr "构造函数" - -#: src/SUMMARY.md:11 -msgid "Variables" -msgstr "变量" - -#: src/SUMMARY.md:12 -msgid "Visibility and Mutability" -msgstr "可见性和可变性" - -#: src/SUMMARY.md:13 -msgid "Counter Example" -msgstr "计数器示例" - -#: src/SUMMARY.md:14 -msgid "Mappings" -msgstr "映射" - -#: src/SUMMARY.md:15 -msgid "Errors" -msgstr "错误" - -#: src/SUMMARY.md:16 -msgid "Events" -msgstr "事件" - -#: src/SUMMARY.md:17 -msgid "Storing Custom Types" -msgstr "存储自定义类型" - -#: src/SUMMARY.md:18 -msgid "Custom types in entrypoints" -msgstr "入口点中的自定义类型" - -#: src/SUMMARY.md:19 -msgid "Documentation" -msgstr "文档" - -#: src/SUMMARY.md:20 -msgid "Deploy and interact with contracts" -msgstr "部署合约并与合约交互" - -#: src/SUMMARY.md:21 -msgid "Contract interfaces and Traits generation" -msgstr "合约接口和Trait生成" - -#: src/SUMMARY.md:22 -msgid "Calling other contracts" -msgstr "调用其他合约" - -#: src/SUMMARY.md:23 -msgid "Factory pattern" -msgstr "工厂模式" - -#: src/SUMMARY.md:24 -msgid "Testing contracts" -msgstr "测试合约" - -#: src/SUMMARY.md:25 -msgid "Cairo cheatsheet" -msgstr "Cairo cheatsheet" - -#: src/SUMMARY.md:26 -msgid "Felt" -msgstr "Felt" - -#: src/SUMMARY.md:27 -msgid "LegacyMap" -msgstr "LegacyMap" - -#: src/SUMMARY.md:28 -msgid "Arrays" -msgstr "数组" - -#: src/SUMMARY.md:29 -msgid "Loop" -msgstr "循环" - -#: src/SUMMARY.md:30 -msgid "Match" -msgstr "匹配" - -#: src/SUMMARY.md:31 -msgid "Tuples" -msgstr "元组" - -#: src/SUMMARY.md:32 -msgid "Struct" -msgstr "结构体" - -#: src/SUMMARY.md:33 -msgid "Type casting" -msgstr "类型转换" - -#: src/SUMMARY.md:35 -msgid "Components" -msgstr "" - -#: src/SUMMARY.md:36 -msgid "Components How-To" -msgstr "" - -#: src/SUMMARY.md:39 -msgid "Applications" -msgstr "应用" - -#: src/SUMMARY.md:40 -msgid "Upgradeable Contract" -msgstr "可升级合约" - -#: src/SUMMARY.md:41 -msgid "Defi Vault" -msgstr "Defi Vault" - -#: src/SUMMARY.md:42 -msgid "ERC20 Token" -msgstr "ERC20 代币" - -#: src/SUMMARY.md:43 -msgid "Constant Product AMM" -msgstr "恒定产品 AMM" - -#: src/SUMMARY.md:46 -msgid "Advanced concepts" -msgstr "高级概念" - -#: src/SUMMARY.md:47 -msgid "Writing to any storage slot" -msgstr "写入任何存储槽" - -#: src/SUMMARY.md:48 -msgid "Storing Arrays" -msgstr "存储数组" - -#: src/SUMMARY.md:49 -msgid "Struct as mapping key" -msgstr "结构体作为映射键" - -#: src/SUMMARY.md:50 -msgid "Hash Solidity Compatible" -msgstr "兼容Hash Solidity" - -#: src/SUMMARY.md:51 -msgid "Optimisations" -msgstr "优化" - -#: src/SUMMARY.md:52 -msgid "Storage Optimisations" -msgstr "存储优化" - -#: src/SUMMARY.md:53 -msgid "List" -msgstr "列表" - -#: src/starknet-by-example.md:1 -msgid "# Starknet by Example" -msgstr "# Starknet by Example" - -#: src/starknet-by-example.md:3 -msgid "" -"Starknet By Example is a collection of examples of how to use the Cairo " -"programming language to create smart contracts on Starknet." -msgstr "" -"Starknet By Example是如何使用Cairo编程语言在Starknet上创建智能合约的范例集。\n" -"中文版由 [StarknetAstro](https://twitter.com/StarkNetAstroCN) 社区翻译。" - -#: src/starknet-by-example.md:5 -msgid "" -"Starknet is a permissionless Validity-Rollup that supports general " -"computation. It is currently used as an Ethereum layer-2. Starknet use the " -"STARK cryptographic proof system to ensure high safety and scalability." -msgstr "" -"Starknet是一种支持通用计算的无权限Validity-Rollup。它目前被用作以太坊的第二" -"层。Starknet 使用 STARK 加密证明系统来确保高安全性和可扩展性。" - -#: src/starknet-by-example.md:7 -msgid "" -"Starknet smart contracts are written in the Cairo language. Cairo is a Turing-" -"complete programming language designed to write provable programs, " -"abstracting the zk-STARK proof system away from the programmer." -msgstr "" -"Starknet智能合约是用Cairo语言编写的。Cairo语言是一种图灵完备的编程语言,旨在编" -"写可证明的程序,将 zk-STARK 证明系统从程序员手中抽象出来。" - -#: src/starknet-by-example.md:9 -msgid "The current version of this book use:" -msgstr "本书当前版本使用:" - -#: src/starknet-by-example.md:10 -msgid "" -"```\n" -"scarb 2.3.1\n" -"```" -msgstr "" -"```\n" -"scarb 2.3.1\n" -"```" - -#: src/starknet-by-example.md:14 -msgid "" -"> ⚠️ The examples have not been audited and are not intended for production " -"use.\n" -"> The authors are not responsible for any damages caused by the use of the " -"code provided in this book." -msgstr "" - -#: src/starknet-by-example.md:17 -msgid "## For whom is this for?" -msgstr "## 谁该读这本书?" - -#: src/starknet-by-example.md:19 -msgid "" -"Starknet By Example is for anyone who wants to quickly learn how to write " -"smart contracts on Starknet using Cairo with some technical background in " -"programming and blockchain." -msgstr "" -"Starknet By Example适合想要快速学习如何使用 Cairo 在 Starknet 上编写智能合约," -"并具有一定编程和区块链技术背景的人。" - -#: src/starknet-by-example.md:21 -msgid "" -"The first chapters will give you a basic understanding of the Cairo " -"programming language and how to write, deploy and use smart contracts on " -"Starknet.\n" -"The later chapters will cover more advanced topics and show you how to write " -"more complex smart contracts." -msgstr "" -"前几章将让你基本了解Cairo编程语言,以及如何在Starknet编写、部署和使用智能合" -"约。\n" -"后面的章节将涉及更高级的主题,并向你展示如何编写更复杂的智能合约。" - -#: src/starknet-by-example.md:24 -msgid "## Further reading" -msgstr "## 进一步阅读" - -#: src/starknet-by-example.md:26 -msgid "" -"If you want to learn more about the Cairo programming language, you can read " -"the [Cairo Book](https://book.cairo-lang.org).\n" -"If you want to learn more about Starknet, you can read the [Starknet " -"documentation](https://docs.starknet.io/) and the [Starknet Book](https://" -"book.starknet.io)." -msgstr "" -"如果你想进一步了解 Cairo 编程语言,可以阅读[Cairo Book](https://book.cairo-" -"lang.org/zh-cn/index.html)。\n" -"如果你想进一步了解星网,可以阅读[Starknet documentation](https://docs." -"starknet.io/) 和[Starknet Book](https://book.starknet.io/zh-cn/index.html)。" - -#: src/starknet-by-example.md:29 -msgid "" -"For more resources, check [Awesome Starknet](https://github.com/keep-starknet-" -"strange/awesome-starknet)." -msgstr "" - -#: src/starknet-by-example.md:31 src/getting-started/basics/storage.md:34 -#: src/getting-started/basics/constructor.md:27 src/getting-started/basics/variables.md:126 -#: src/getting-started/basics/visibility-mutability.md:75 src/getting-started/basics/counter.md:56 -#: src/getting-started/basics/mappings.md:46 src/getting-started/basics/errors.md:139 -#: src/getting-started/basics/events.md:68 src/getting-started/basics/storing-custom-types.md:39 -#: src/getting-started/basics/custom-types-in-entrypoints.md:39 -#: src/getting-started/interacting/interfaces-traits.md:129 -#: src/getting-started/interacting/calling_other_contracts.md:69 -#: src/getting-started/testing/contract-testing.md:176 src/getting-started/cairo_cheatsheet/felt.md:15 -#: src/getting-started/cairo_cheatsheet/mapping.md:58 -#: src/getting-started/cairo_cheatsheet/arrays.md:42 src/getting-started/cairo_cheatsheet/loop.md:23 -#: src/getting-started/cairo_cheatsheet/match.md:59 src/getting-started/cairo_cheatsheet/tuples.md:18 -#: src/getting-started/cairo_cheatsheet/struct.md:15 -#: src/getting-started/cairo_cheatsheet/type_casting.md:33 src/components/how_to.md:114 -#: src/applications/upgradeable_contract.md:117 src/applications/simple_vault.md:114 -#: src/applications/erc20.md:228 src/applications/constant-product-amm.md:275 -#: src/advanced-concepts/write_to_any_slot.md:58 src/advanced-concepts/storing_arrays.md:105 -#: src/advanced-concepts/struct-mapping-key.md:46 src/advanced-concepts/hash-solidity-compatible.md:46 -#: src/advanced-concepts/optimisations/store_using_packing.md:90 src/advanced-concepts/list.md:139 -msgid "
Last change: 2023-12-07
" -msgstr "
Last change: 2023-12-07
" - -#: src/getting-started/basics/introduction.md:1 -msgid "# Basics of Smart Contracts in Cairo" -msgstr "# Cairo的智能合约基础知识" - -#: src/getting-started/basics/introduction.md:3 -msgid "" -"The following chapters will introduce you to Starknet smart contracts and how " -"to write them in Cairo." -msgstr "以下章节将向你介绍Starknet智能合约以及如何用Cairo编写这些合约。" - -#: src/getting-started/basics/introduction.md:5 src/advanced-concepts/optimisations/optimisations.md:5 -msgid "
Last change: 2023-10-12
" -msgstr "
Last change: 2023-10-12
" - -#: src/getting-started/basics/storage.md:1 -msgid "# Storage" -msgstr "# 存储" - -#: src/getting-started/basics/storage.md:3 -msgid "Here's the most minimal contract you can write in Cairo:" -msgstr "这是您用Cairo能写的最简短的合约:" - -#: src/getting-started/basics/storage.md:5 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {}\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {}\n" -"}\n" -"```" - -#: src/getting-started/basics/storage.md:13 -msgid "" -"Storage is a struct annoted with `#[storage]`. Every contract must have one " -"and only one storage.\n" -"It's a key-value store, where each key will be mapped to a storage address of " -"the contract's storage space." -msgstr "" -"存储是一个结构体,用 `#[storage]`标注。每个合约必须有且仅有一个存储空间。\n" -"它是一个键值存储空间,其中每个键都将映射到合约存储空间的存储地址。" - -#: src/getting-started/basics/storage.md:16 -msgid "" -"You can define [storage variables](./variables.md#storage-variables) in your " -"contract, and then use them to store and retrieve data." -msgstr "" -"您可以在合约中定义 [存储变量](./variables.md#storage-variables),然后使用它" -"们来存储和检索数据。" - -#: src/getting-started/basics/storage.md:17 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {\n" -" a: u128,\n" -" b: u8,\n" -" c: u256\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod Contract {\n" -" #[storage]\n" -" struct Storage {\n" -" a: u128,\n" -" b: u8,\n" -" c: u256\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/storage.md:29 -msgid "" -"> Actually these two contracts have the same underlying Sierra program.\n" -"> From the compiler's perspective, the storage variables don't exist until " -"they are used." -msgstr "" -"> 实际上,这两个合约的底层 Sierra 程序是一样的。\n" -"> 从编译器的角度来看,存储变量在使用之前是不存在的。" - -#: src/getting-started/basics/storage.md:32 -msgid "" -"You can also read about [storing custom types](./storing-custom-types.md)" -msgstr "您还可以阅读有关 [存储自定义类型](./storing-custom-types.md) 的内容。" - -#: src/getting-started/basics/constructor.md:1 -msgid "# Constructor" -msgstr "# 构造函数" - -#: src/getting-started/basics/constructor.md:3 -msgid "" -"Constructors are a special type of function that runs only once when " -"deploying a contract, and can be used to initialize the state of the " -"contract. Your contract must not have more than one constructor, and that " -"constructor function must be annotated with the `#[constructor]` attribute. " -"Also, a good practice consists in naming that function `constructor`." -msgstr "" -"构造函数是一种特殊类型的函数,只在部署合约时运行一次,可用于初始化合约的状态。" -"你的合约不能有一个以上的构造函数,而且构造函数必须使用 `#[constructor]` 属性注" -"释。此外,一个好的做法是将该函数命名为 `constructor`。" - -#: src/getting-started/basics/constructor.md:5 -msgid "" -"Here's a simple example that demonstrates how to initialize the state of a " -"contract on deployment by defining logic inside a constructor." -msgstr "" -"下面是一个简单的示例,演示如何通过在构造函数中定义逻辑,在部署时初始化合约的状" -"态。" - -#: src/getting-started/basics/constructor.md:7 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ExampleConstructor {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" names: LegacyMap::,\n" -" }\n" -"\n" -" // The constructor is decorated with a `#[constructor]` attribute.\n" -" // It is not inside an `impl` block.\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, name: felt252, address: " -"ContractAddress) {\n" -" self.names.write(address, name);\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ExampleConstructor {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" names: LegacyMap::,\n" -" }\n" -"\n" -" // The constructor is decorated with a `#[constructor]` attribute.\n" -" // It is not inside an `impl` block.\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, name: felt252, address: " -"ContractAddress) {\n" -" self.names.write(address, name);\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/constructor.md:25 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/constructor/src/constructor.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " -"上的合约,或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/constructor/src/constructor.cairo) 中尝试" -"它。" - -#: src/getting-started/basics/variables.md:1 -msgid "# Variables" -msgstr "# 变量" - -#: src/getting-started/basics/variables.md:3 -msgid "There are 3 types of variables in Cairo contracts:" -msgstr "Cairo合约中有 3 种变量:" - -#: src/getting-started/basics/variables.md:5 -msgid "" -"- Local\n" -" - declared inside a function\n" -" - not stored on the blockchain\n" -"- Storage\n" -" - declared in the [Storage](./storage.md) of a contract\n" -" - can be accessed from one execution to another\n" -"- Global\n" -" - provides information about the blockchain\n" -" - accessed anywhere, even within library functions" -msgstr "" -"- 局部\n" -" - 在函数中声明\n" -" - 不存储在区块链中\n" -"- 存储\n" -" - 在合约的 [Storage](./storage.md) 中声明\n" -" - 可从一个执行过程访问到另一个执行过程\n" -"- 全局\n" -" - 提供有关区块链的信息\n" -" - 可在任何地方访问,甚至在库函数中" - -#: src/getting-started/basics/variables.md:15 -msgid "## Local Variables" -msgstr "## 局部变量" - -#: src/getting-started/basics/variables.md:17 -msgid "" -"Local variables are used and accessed within the scope of a specific function " -"or block of code. They are temporary and exist only for the duration of that " -"particular function or block execution." -msgstr "" -"局部变量在特定函数或代码块的范围内使用和访问。它们是临时的,只在特定函数或代码" -"块执行期间存在。" - -#: src/getting-started/basics/variables.md:19 -msgid "" -"Local variables are stored in memory and are not stored on the blockchain. " -"This means they cannot be accessed from one execution to another. Local " -"variables are useful for storing temporary data that is relevant only within " -"a specific context. They also make the code more readable by giving names to " -"intermediate values." -msgstr "" -"局部变量存储在内存中,不会存储在区块链上。这就意味着在执行过程中无法访问它们。" -"局部变量可用于存储仅在特定上下文中相关的临时数据。通过为中间值命名,它们还能使" -"代码更具可读性。" - -#: src/getting-started/basics/variables.md:21 -msgid "Here's a simple example of a contract with only local variables:" -msgstr "下面是一个只有局部变量的简单合约示例:" - -#: src/getting-started/basics/variables.md:23 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ILocalVariablesExample {\n" -" fn do_something(self: @TContractState, value: u32) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod LocalVariablesExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl LocalVariablesExample of super::" -"ILocalVariablesExample {\n" -" fn do_something(self: @ContractState, value: u32) -> u32 {\n" -" // This variable is local to the current block. It can't be " -"accessed once it goes out of scope.\n" -" let increment = 10;\n" -"\n" -" {\n" -" // The scope of a code block allows for local variable " -"declaration\n" -" // We can access variables defined in higher scopes.\n" -" let sum = value + increment;\n" -" sum\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ILocalVariablesExample {\n" -" fn do_something(self: @TContractState, value: u32) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod LocalVariablesExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl LocalVariablesExample of super::" -"ILocalVariablesExample {\n" -" fn do_something(self: @ContractState, value: u32) -> u32 {\n" -" // This variable is local to the current block. It can't be " -"accessed once it goes out of scope.\n" -" let increment = 10;\n" -"\n" -" {\n" -" // The scope of a code block allows for local variable " -"declaration\n" -" // We can access variables defined in higher scopes.\n" -" let sum = value + increment;\n" -" sum\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:50 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/local_variables.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " -"上的合约,或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/local_variables.cairo) 中尝试" -"它。" - -#: src/getting-started/basics/variables.md:52 -msgid "## Storage Variables" -msgstr "## 存储用变量" - -#: src/getting-started/basics/variables.md:54 -msgid "" -"Storage variables are persistent data stored on the blockchain. They can be " -"accessed from one execution to another, allowing the contract to remember and " -"update information over time." -msgstr "" -"存储变量是存储在区块链上的持久数据。它们可以在不同的执行过程中被访问,从而使合" -"约能够保存和更新信息。" - -#: src/getting-started/basics/variables.md:56 -msgid "" -"To write or update a storage variable, you need to interact with the contract " -"through an external entrypoint by sending a transaction." -msgstr "要写入或更新存储变量,需要通过外部入口点发送交易与合约交互。" - -#: src/getting-started/basics/variables.md:58 -msgid "" -"On the other hand, you can read state variables, for free, without any " -"transaction, simply by interacting with a node." -msgstr "另一方面,只需与节点交互,就可以免费读取状态变量,无需发出任何交易。" - -#: src/getting-started/basics/variables.md:60 -msgid "Here's a simple example of a contract with one storage variable:" -msgstr "下面是一个带有一个存储变量的简单合约示例:" - -#: src/getting-started/basics/variables.md:62 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStorageVariableExample {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"#[starknet::contract]\n" -"mod StorageVariablesExample {\n" -" // All storage variables are contained in a struct called Storage\n" -" // annotated with the `#[storage]` attribute\n" -" #[storage]\n" -" struct Storage {\n" -" // Storage variable holding a number\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StorageVariablesExample of super::" -"IStorageVariableExample {\n" -" // Write to storage variables by sending a transaction that calls an " -"external function\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // Read from storage variables without sending transactions\n" -" fn get(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStorageVariableExample {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"#[starknet::contract]\n" -"mod StorageVariablesExample {\n" -" // All storage variables are contained in a struct called Storage\n" -" // annotated with the `#[storage]` attribute\n" -" #[storage]\n" -" struct Storage {\n" -" // Storage variable holding a number\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StorageVariablesExample of super::" -"IStorageVariableExample {\n" -" // Write to storage variables by sending a transaction that calls an " -"external function\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // Read from storage variables without sending transactions\n" -" fn get(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:92 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/storage_variables.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " -"上的合约,或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/storage_variables.cairo)中尝" -"试它。" - -#: src/getting-started/basics/variables.md:94 -msgid "## Global Variables" -msgstr "## 全局变量" - -#: src/getting-started/basics/variables.md:96 -msgid "" -"Global variables are predefined variables that provide information about the " -"blockchain and the current execution environment. They can be accessed at any " -"time and from anywhere!" -msgstr "" -"全局变量是预定义变量,可提供有关区块链和当前执行环境的信息。可以随时随地访问它" -"们!" - -#: src/getting-started/basics/variables.md:98 -msgid "" -"In Starknet, you can access global variables by using specific functions " -"contained in the starknet core libraries." -msgstr "" -"在 Starknet 中,您可以通过使用 starknet 核心库中的特定函数来访问全局变量。" - -#: src/getting-started/basics/variables.md:100 -msgid "" -"For example, the `get_caller_address` function returns the address of the " -"caller of the current transaction, and the `get_contract_address` function " -"returns the address of the current contract." -msgstr "" -"例如,`get_caller_address`函数返回当前事务的调用者地址,`get_contract_address`" -"函数返回当前合约的地址。" - -#: src/getting-started/basics/variables.md:102 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IGlobalExample {\n" -" fn foo(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod GlobalExample {\n" -" // import the required functions from the starknet core library\n" -" use starknet::get_caller_address;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl GlobalExampleImpl of super::IGlobalExample {\n" -" fn foo(ref self: ContractState) {\n" -" // Call the get_caller_address function to get the sender " -"address\n" -" let caller = get_caller_address();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IGlobalExample {\n" -" fn foo(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod GlobalExample {\n" -" // import the required functions from the starknet core library\n" -" use starknet::get_caller_address;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl GlobalExampleImpl of super::IGlobalExample {\n" -" fn foo(ref self: ContractState) {\n" -" // Call the get_caller_address function to get the sender " -"address\n" -" let caller = get_caller_address();\n" -" // ...\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/variables.md:125 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/global_variables.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F)上" -"的合约,或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/variables/src/global_variables.cairo) 中尝" -"试它。" - -#: src/getting-started/basics/visibility-mutability.md:1 -msgid "# Visibility and Mutability" -msgstr "# 可见性和可变性" - -#: src/getting-started/basics/visibility-mutability.md:3 -msgid "## Visibility" -msgstr "## 可见性" - -#: src/getting-started/basics/visibility-mutability.md:5 -msgid "There are two types of functions in Starknet contracts:" -msgstr "Starknet合约有两种功能:" - -#: src/getting-started/basics/visibility-mutability.md:7 -msgid "" -"- Functions that are accessible externally and can be called by anyone.\n" -"- Functions that are only accessible internally and can only be called by " -"other functions in the contract." -msgstr "" -"- 外部可访问、任何人都可调用的函数。\n" -"- 只能在内部访问的函数,只能被合约中的其他函数调用。" - -#: src/getting-started/basics/visibility-mutability.md:10 -msgid "" -"These functions are also typically divided into two different implementations " -"blocks. The first `impl` block for externally accessible functions is " -"explicitly annotated with an `#[abi(embed_v0)]` attribute. This indicates " -"that all the functions inside this block can be called either as a " -"transaction or as a view function. The second `impl` block for internally " -"accessible functions is not annotated with any attribute, which means that " -"all the functions inside this block are private by default." -msgstr "" -"这些函数通常也分为两个不同的实现块。第一个`impl`块用于外部访问的函数,明确标注" -"了 `#[abi(embed_v0)]`属性。这表明该代码块中的所有函数都可以作为交易或视图函数" -"调用。第二个用于内部可访问函数的 `impl` 块没有注释任何属性,这意味着该块中的所" -"有函数默认都是私有的。" - -#: src/getting-started/basics/visibility-mutability.md:12 -msgid "## State Mutability" -msgstr "## 状态可变性" - -#: src/getting-started/basics/visibility-mutability.md:14 -msgid "" -"Regardless of whether a function is internal or external, it can either " -"modify the contract's state or not. When we declare functions that interact " -"with storage variables inside a smart contract,\n" -"we need to explicitly state that we are accessing the `ContractState` by " -"adding it as the first parameter of the function. This can be done in two " -"different ways:" -msgstr "" -"无论函数是内部函数还是外部函数,它都可以修改或不修改合约的状态。当我们在智能合" -"约中声明与存储变量交互的函数时,\n" -"我们需要将 `ContractState`添加为函数的第一个参数,明确说明我们正在访问 合约的" -"状态。这有两种不同的方法:" - -#: src/getting-started/basics/visibility-mutability.md:17 -msgid "" -"- If we want our function to be able to mutate the state of the contract, we " -"pass it by reference like this: `ref self: ContractState`.\n" -"- If we want our function to be read-only and not mutate the state of the " -"contract, we pass it by snapshot like this: `self: @ContractState`." -msgstr "" -"- 如果我们希望我们的函数能够更改合约的状态,我们可以像这样通过引用来传递它:" -"`ref self:ContractState`。\n" -"- 如果我们希望我们的函数是只读的,并且不更改合约的状态,我们可以通过快照传递" -"它,如下所示:`self:@ContractState`." - -#: src/getting-started/basics/visibility-mutability.md:20 -msgid "" -"Read-only functions, also called view functions, can be directly called " -"without making a transaction. You can interact with them directly through a " -"RPC node to read the contract's state, and they're free to call!\n" -"External functions, that modify the contract's state, on the other side can " -"only be called by making a transaction." -msgstr "" -"只读函数(也称为视图函数)可以直接调用,无需进行事务处理。你可以直接通过 RPC " -"节点与它们交互,读取合约的状态,而且可以自由调用!\n" -"而修改合约状态的外部函数则只能通过交易来调用。" - -#: src/getting-started/basics/visibility-mutability.md:23 -msgid "" -"Internal functions can't be called externally, but the same principle applies " -"regarding state mutability." -msgstr "内部函数不能被外部调用,同样的原则也适用于状态可变性。" - -#: src/getting-started/basics/visibility-mutability.md:25 -msgid "Let's take a look at a simple example contract to see these in action:" -msgstr "让我们通过一个简单的合约示例来了解这些功能:" - -#: src/getting-started/basics/visibility-mutability.md:27 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExampleContract {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExampleContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -"\n" -" // The `#[abi(embed_v0)]` attribute indicates that all the functions in this " -"implementation can be called externally.\n" -" // Omitting this attribute would make all the functions in this " -"implementation internal.\n" -" #[abi(embed_v0)]\n" -" impl ExampleContract of super::IExampleContract {\n" -" // The `set` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // It can modify the contract's state as it is passed as a " -"reference.\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // The `get` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn get(self: @ContractState) -> u32 {\n" -" // We can call an internal function from any functions within the " -"contract\n" -" PrivateFunctionsTrait::_read_value(self)\n" -" }\n" -" }\n" -"\n" -" // The lack of the `external` attribute indicates that all the functions " -"in this implementation can only be called internally.\n" -" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " -"internal trait allowing us to call internal functions.\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" // The `_read_value` function is outside the implementation that is " -"marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -" // and can only be called from within the contract.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn _read_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExampleContract {\n" -" fn set(ref self: TContractState, value: u32);\n" -" fn get(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExampleContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -"\n" -" // The `#[abi(embed_v0)]` attribute indicates that all the functions in this " -"implementation can be called externally.\n" -" // Omitting this attribute would make all the functions in this " -"implementation internal.\n" -" #[abi(embed_v0)]\n" -" impl ExampleContract of super::IExampleContract {\n" -" // The `set` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // It can modify the contract's state as it is passed as a " -"reference.\n" -" fn set(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -"\n" -" // The `get` function can be called externally because it is written " -"inside an implementation marked as `#[abi(embed_v0)]`.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn get(self: @ContractState) -> u32 {\n" -" // We can call an internal function from any functions within the " -"contract\n" -" PrivateFunctionsTrait::_read_value(self)\n" -" }\n" -" }\n" -"\n" -" // The lack of the `external` attribute indicates that all the functions " -"in this implementation can only be called internally.\n" -" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " -"internal trait allowing us to call internal functions.\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" // The `_read_value` function is outside the implementation that is " -"marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" -" // and can only be called from within the contract.\n" -" // However, it can't modify the contract's state, as it is passed as a " -"snapshot: it is only a \"view\" function.\n" -" fn _read_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/visibility-mutability.md:73 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/visibility/src/visibility.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F)上" -"的合约,或在[Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/visibility/src/visibility.cairo)中尝试它。" - -#: src/getting-started/basics/counter.md:1 -msgid "# Simple Counter" -msgstr "# 简单计数器" - -#: src/getting-started/basics/counter.md:3 -msgid "This is a simple counter contract." -msgstr "这是一个简单的计数合约。" - -#: src/getting-started/basics/counter.md:5 -msgid "Here's how it works:" -msgstr "这个合约是这样工作的:" - -#: src/getting-started/basics/counter.md:7 -msgid "" -"- The contract has a state variable called 'counter' that is initialized to " -"0.\n" -"\n" -"- When a user calls 'increment', the contract increments the counter by 1.\n" -"\n" -"- When a user calls 'decrement', the contract decrements the counter by 1." -msgstr "" -"- 合约有一个名为 'counter'的状态变量,初始化为 0。\n" -"\n" -"- 当用户调用 'increment'时,合约会将计数器递增 1。\n" -"\n" -"- 当用户调用 'decrement'时,合约会将计数器递减 1。" - -#: src/getting-started/basics/counter.md:13 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISimpleCounter {\n" -" fn get_current_count(self: @TContractState) -> u128;\n" -" fn increment(ref self: TContractState);\n" -" fn decrement(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleCounter {\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter variable\n" -" counter: u128,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128) {\n" -" // Store initial value\n" -" self.counter.write(init_value);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleCounter of super::ISimpleCounter {\n" -" fn get_current_count(self: @ContractState) -> u128 {\n" -" return self.counter.read();\n" -" }\n" -"\n" -" fn increment(ref self: ContractState) {\n" -" // Store counter value + 1\n" -" let counter = self.counter.read() + 1;\n" -" self.counter.write(counter);\n" -" }\n" -" fn decrement(ref self: ContractState) {\n" -" // Store counter value - 1\n" -" let counter = self.counter.read() - 1;\n" -" self.counter.write(counter);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISimpleCounter {\n" -" fn get_current_count(self: @TContractState) -> u128;\n" -" fn increment(ref self: TContractState);\n" -" fn decrement(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleCounter {\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter variable\n" -" counter: u128,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128) {\n" -" // Store initial value\n" -" self.counter.write(init_value);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleCounter of super::ISimpleCounter {\n" -" fn get_current_count(self: @ContractState) -> u128 {\n" -" return self.counter.read();\n" -" }\n" -"\n" -" fn increment(ref self: ContractState) {\n" -" // Store counter value + 1\n" -" let counter = self.counter.read() + 1;\n" -" self.counter.write(counter);\n" -" }\n" -" fn decrement(ref self: ContractState) {\n" -" // Store counter value - 1\n" -" let counter = self.counter.read() - 1;\n" -" self.counter.write(counter);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/counter.md:54 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/counter/src/contracts.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " -"上的合约,或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/counter/src/contracts.cairo) 中尝试它。" - -#: src/getting-started/basics/mappings.md:1 -msgid "# Mappings" -msgstr "# 映射" - -#: src/getting-started/basics/mappings.md:3 -msgid "" -"Maps are a key-value data structure used to store data within a smart " -"contract. In Cairo they are implemented using the `LegacyMap` type. It's " -"important to note that the `LegacyMap` type can only be used inside the " -"`Storage` struct of a contract and that it can't be used elsewhere." -msgstr "" -"映射是一种键值数据结构,用于在智能合约中存储数据。在Cairo,它们使用 " -"`LegacyMap` 类型实现。值得注意的是,`LegacyMap`类型只能在合约的 `Storage`结构" -"中使用,不能用在其他地方。" - -#: src/getting-started/basics/mappings.md:5 -msgid "" -"Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, " -"to map between a key of type `ContractAddress` and value of type `felt252`. " -"The key-value types are specified within angular brackets <>. We write to the " -"map by calling the `write()` method, passing in both the key and value. " -"Similarly, we can read the value associated with a given key by calling the " -"`read()` method and passing in the relevant key." -msgstr "" -"在此,我们演示如何在Cairo合约中使用 `LegacyMap` 类型,在 `ContractAddress` 类" -"型的键和 `felt252` 类型的值之间进行映射。键值类型在角括号 <> 中指定。我们通过" -"调用 `write()` 方法,传入键和值,写入映射。同样,我们可以通过调用 `read()` 方" -"法并输入相关键值来读取与给定键值相关的值。" - -#: src/getting-started/basics/mappings.md:7 -msgid "Some additional notes:" -msgstr "一些补充说明:" - -#: src/getting-started/basics/mappings.md:9 -msgid "" -"- More complex key-value mappings are possible, for example we could use " -"`LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an " -"allowance on an ERC20 token contract.\n" -"\n" -"- In mappings, the address of the value at key `k_1,...,k_n` is `h(..." -"h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the Pedersen " -"hash and the final value is taken `mod2251−256`. You can learn more about the " -"contract storage layout in the [Starknet Documentation](https://docs.starknet." -"io/documentation/architecture_and_concepts/Contracts/contract-storage/" -"#storage_variables)" -msgstr "" -"- 也有更复杂的键值对映射,例如,我们可以使用 `LegacyMap::<(ContractAddress, " -"ContractAddress), felt252>` 在 ERC20 代币合约上创建一个代币授权许可。\n" -"\n" -"- 在映射中,键`k_1,...,k_n`处的值的地址是`h(...h(h(sn_keccak(variable_name)," -"k_1),k_2),...,k_n)`,其中 `ℎ` 是 Pedersen 哈希值,最终值取`mod2251-256`。有关" -"合约存储布局的更多信息,请参阅 [Starknet Documentation](https://docs.starknet." -"io/documentation/architecture_and_concepts/Contracts/contract-storage/" -"#storage_variables)。" - -#: src/getting-started/basics/mappings.md:13 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMapContract {\n" -" fn set(ref self: TContractState, key: ContractAddress, value: felt252);\n" -" fn get(self: @TContractState, key: ContractAddress) -> felt252;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MapContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" // The `LegacyMap` type is only available inside the `Storage` " -"struct.\n" -" map: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl MapContractImpl of super::IMapContract {\n" -" fn set(ref self: ContractState, key: ContractAddress, value: felt252) " -"{\n" -" self.map.write(key, value);\n" -" }\n" -"\n" -" fn get(self: @ContractState, key: ContractAddress) -> felt252 {\n" -" self.map.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMapContract {\n" -" fn set(ref self: TContractState, key: ContractAddress, value: felt252);\n" -" fn get(self: @TContractState, key: ContractAddress) -> felt252;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MapContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" // The `LegacyMap` type is only available inside the `Storage` " -"struct.\n" -" map: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl MapContractImpl of super::IMapContract {\n" -" fn set(ref self: ContractState, key: ContractAddress, value: felt252) " -"{\n" -" self.map.write(key, value);\n" -" }\n" -"\n" -" fn get(self: @ContractState, key: ContractAddress) -> felt252 {\n" -" self.map.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/mappings.md:44 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/mappings/src/mappings.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " -"上的合约或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/mappings/src/mappings.cairo) 中尝试它。" - -#: src/getting-started/basics/errors.md:1 -msgid "# Errors" -msgstr "# 错误" - -#: src/getting-started/basics/errors.md:3 -msgid "" -"Errors can be used to handle validation and other conditions that may occur " -"during the execution of a smart contract.\n" -"If an error is thrown during the execution of a smart contract call, the " -"execution is stopped and any changes made during the transaction are reverted." -msgstr "" -"错误可用于处理智能合约执行过程中可能发生的验证和其他条件。\n" -"如果在执行智能合约调用期间抛出错误,则将停止执行,并恢复在交易期间所做的任何更" -"改。" - -#: src/getting-started/basics/errors.md:6 -msgid "To throw an error, use the `assert` or `panic` functions:" -msgstr "要抛出错误,请使用 `assert` 或 `panic`函数:" - -#: src/getting-started/basics/errors.md:8 -msgid "" -"- `assert` is used to validate conditions.\n" -" If the check fails, an error is thrown along with a specified value, often " -"a message.\n" -" It's similar to the `require` statement in Solidity.\n" -"\n" -"- `panic` immediately halt the execution with the given error value.\n" -" It should be used when the condition to check is complex and for internal " -"errors. It's similar to the `revert` statement in Solidity.\n" -" (Use `panic_with_felt252` to be able to directly pass a felt252 as the " -"error value)" -msgstr "" -"- 'assert' 用于验证条件。\n" -" 如果检查失败,则会引发错误以及指定的值,通常是一条消息。\n" -" 它类似于 Solidity 中的`require`语句。\n" -"\n" -"- 'panic' 立即停止执行,并给出错误值。\n" -" 当要检查的条件复杂且存在内部错误时,应使用它。它类似于 Solidity 中的" -"`revert` 语句。\n" -" (使用`panic_with_felt252` 可以直接传递一个felt252作为错误值)" - -#: src/getting-started/basics/errors.md:16 -msgid "Here's a simple example that demonstrates the use of these functions:" -msgstr "下面是一个简单的示例,演示了这些函数的用法:" - -#: src/getting-started/basics/errors.md:18 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"#[starknet::contract]\n" -"mod ErrorsExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ErrorsExample of super::IErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" // Assert used to validate a condition\n" -" // and abort execution if the condition is not met\n" -" assert(i > 0, 'i must be greater than 0');\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" // Panic used to abort execution directly\n" -" panic_with_felt252('i must not be 0');\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"#[starknet::contract]\n" -"mod ErrorsExample {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ErrorsExample of super::IErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" // Assert used to validate a condition\n" -" // and abort execution if the condition is not met\n" -" assert(i > 0, 'i must be greater than 0');\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" // Panic used to abort execution directly\n" -" panic_with_felt252('i must not be 0');\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:46 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/simple_errors.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " -"上访问合约或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/simple_errors.cairo) 中尝试它。" - -#: src/getting-started/basics/errors.md:48 -msgid "## Custom errors" -msgstr "## 自定义错误" - -#: src/getting-started/basics/errors.md:50 -msgid "" -"You can make error handling easier by defining your error codes in a specific " -"module." -msgstr "您可以通过在特定模块中定义错误代码来简化错误处理。" - -#: src/getting-started/basics/errors.md:52 -msgid "" -"```cairo\n" -"mod Errors {\n" -" const NOT_POSITIVE: felt252 = 'must be greater than 0';\n" -" const NOT_NULL: felt252 = 'must not be null';\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICustomErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CustomErrorsExample {\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CustomErrorsExample of super::ICustomErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" assert(i > 0, Errors::NOT_POSITIVE);\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" panic_with_felt252(Errors::NOT_NULL);\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"mod Errors {\n" -" const NOT_POSITIVE: felt252 = 'must be greater than 0';\n" -" const NOT_NULL: felt252 = 'must not be null';\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICustomErrorsExample {\n" -" fn test_assert(self: @TContractState, i: u256);\n" -" fn test_panic(self: @TContractState, i: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CustomErrorsExample {\n" -" use super::Errors;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl CustomErrorsExample of super::ICustomErrorsExample {\n" -" fn test_assert(self: @ContractState, i: u256) {\n" -" assert(i > 0, Errors::NOT_POSITIVE);\n" -" }\n" -"\n" -" fn test_panic(self: @ContractState, i: u256) {\n" -" if (i == 0) {\n" -" panic_with_felt252(Errors::NOT_NULL);\n" -" }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:85 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/custom_errors.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " -"上访问 contract 或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/custom_errors.cairo)中尝试它。" - -#: src/getting-started/basics/errors.md:87 -msgid "## Vault example" -msgstr "## Vault 示例" - -#: src/getting-started/basics/errors.md:89 -msgid "" -"Here's another example that demonstrates the use of errors in a more complex " -"contract:" -msgstr "下面是另一个示例,演示了在更复杂的合约中使用错误:" - -#: src/getting-started/basics/errors.md:91 -msgid "" -"```cairo\n" -"mod VaultErrors {\n" -" const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance';\n" -"// you can define more errors here\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IVaultErrorsExample {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, amount: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod VaultErrorsExample {\n" -" use super::VaultErrors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" balance: u256,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl VaultErrorsExample of super::IVaultErrorsExample {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -" balance = balance + amount;\n" -" self.balance.write(balance);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -"\n" -" assert(balance >= amount, VaultErrors::INSUFFICIENT_BALANCE);\n" -"\n" -" // Or using panic:\n" -" if (balance >= amount) {\n" -" panic_with_felt252(VaultErrors::INSUFFICIENT_BALANCE);\n" -" }\n" -"\n" -" let balance = balance - amount;\n" -"\n" -" self.balance.write(balance);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"mod VaultErrors {\n" -" const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance';\n" -"// you can define more errors here\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IVaultErrorsExample {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, amount: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod VaultErrorsExample {\n" -" use super::VaultErrors;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" balance: u256,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl VaultErrorsExample of super::IVaultErrorsExample {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -" balance = balance + amount;\n" -" self.balance.write(balance);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, amount: u256) {\n" -" let mut balance = self.balance.read();\n" -"\n" -" assert(balance >= amount, VaultErrors::INSUFFICIENT_BALANCE);\n" -"\n" -" // Or using panic:\n" -" if (balance >= amount) {\n" -" panic_with_felt252(VaultErrors::INSUFFICIENT_BALANCE);\n" -" }\n" -"\n" -" let balance = balance - amount;\n" -"\n" -" self.balance.write(balance);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/errors.md:137 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/vault_errors.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " -"上访问 contract 或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/errors/src/vault_errors.cairo) 中尝试它。" - -#: src/getting-started/basics/events.md:1 -msgid "# Events" -msgstr "# 事件" - -#: src/getting-started/basics/events.md:3 -msgid "" -"Events are a way to emit data from a contract. All events must be defined in " -"the `Event` enum, which must be annotated with the `#[event]` attribute.\n" -"An event is defined as struct that derives the `#[starknet::Event]` trait. " -"The fields of that struct correspond to the data that will be emitted. An " -"event can be indexed for easy and fast access when querying the data at a " -"later time. Events data can be indexed by adding a `#[key]` attribute to a " -"field member." -msgstr "" -"事件是从合约发出数据的一种方式。所有事件都必须在`Event`枚举中定义,该枚举必须" -"使用`#[event]`属性进行注释。\n" -"事件被定义为派生`#[starknet::Event]`trait的结构。该结构的字段对应于将要发出的数" -"据。可以对事件编制索引,以便在以后查询数据时轻松快速地访问。可以通过向字段成员" -"添加`#[key]` 属性来索引事件数据。" - -#: src/getting-started/basics/events.md:6 -msgid "" -"Here's a simple example of a contract using events that emit an event each " -"time a counter is incremented by the \"increment\" function:" -msgstr "" -"下面是合约使用事件的简单示例,这些事件在每次计数器通过“increment”函数递增时发" -"出一个事件:" - -#: src/getting-started/basics/events.md:8 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IEventCounter {\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod EventCounter {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter value\n" -" counter: u128,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" // The event enum must be annotated with the `#[event]` attribute.\n" -" // It must also derive the `Drop` and `starknet::Event` traits.\n" -" enum Event {\n" -" CounterIncreased: CounterIncreased,\n" -" UserIncreaseCounter: UserIncreaseCounter\n" -" }\n" -"\n" -" // By deriving the `starknet::Event` trait, we indicate to the compiler " -"that\n" -" // this struct will be used when emitting events.\n" -" #[derive(Drop, starknet::Event)]\n" -" struct CounterIncreased {\n" -" amount: u128\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct UserIncreaseCounter {\n" -" // The `#[key]` attribute indicates that this event will be indexed.\n" -" #[key]\n" -" user: ContractAddress,\n" -" new_value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl EventCounter of super::IEventCounter {\n" -" fn increment(ref self: ContractState) {\n" -" let mut counter = self.counter.read();\n" -" counter += 1;\n" -" self.counter.write(counter);\n" -" // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IEventCounter {\n" -" fn increment(ref self: TContractState);\n" -"}\n" -"#[starknet::contract]\n" -"mod EventCounter {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -" #[storage]\n" -" struct Storage {\n" -" // Counter value\n" -" counter: u128,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" // The event enum must be annotated with the `#[event]` attribute.\n" -" // It must also derive the `Drop` and `starknet::Event` traits.\n" -" enum Event {\n" -" CounterIncreased: CounterIncreased,\n" -" UserIncreaseCounter: UserIncreaseCounter\n" -" }\n" -"\n" -" // By deriving the `starknet::Event` trait, we indicate to the compiler " -"that\n" -" // this struct will be used when emitting events.\n" -" #[derive(Drop, starknet::Event)]\n" -" struct CounterIncreased {\n" -" amount: u128\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct UserIncreaseCounter {\n" -" // The `#[key]` attribute indicates that this event will be indexed.\n" -" #[key]\n" -" user: ContractAddress,\n" -" new_value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl EventCounter of super::IEventCounter {\n" -" fn increment(ref self: ContractState) {\n" -" let mut counter = self.counter.read();\n" -" counter += 1;\n" -" self.counter.write(counter);\n" -" // Emit event\n" -" self.emit(Event::CounterIncreased(CounterIncreased { amount: " -"1 }));\n" -" self\n" -" .emit(\n" -" Event::UserIncreaseCounter(\n" -" UserIncreaseCounter {\n" -" user: get_caller_address(), new_value: self." -"counter.read()\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/events.md:66 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/events/src/counter.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " -"上访问 合约 或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/events/src/counter.cairo) 中尝试它。" - -#: src/getting-started/basics/storing-custom-types.md:1 -msgid "# Storing Custom Types" -msgstr "# 存储自定义类型" - -#: src/getting-started/basics/storing-custom-types.md:3 -msgid "" -"While native types can be stored in a contract's storage without any " -"additional work, custom types require a bit more work. This is because at " -"compile time, the compiler does not know how to store custom types in " -"storage. To solve this, we need to implement the `Store` trait for our custom " -"type. Hopefully, we can just derive this trait for our custom type - unless " -"it contains arrays or dictionaries." -msgstr "" -"虽然自定义类型可以存储在合约的存储中,而无需任何额外的工作,但自定义类型需要更多" -"的工作。这是因为在编译时,编译器不知道如何在存储中存储自定义类型。为了解决这个" -"问题,我们需要为我们的自定义类型实现 `Store` trait。希望我们可以为我们的自定义类" -"型派生这个trait - 除非它包含数组或字典。" - -#: src/getting-started/basics/storing-custom-types.md:5 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoringCustomType {\n" -" fn set_person(ref self: TContractState, person: Person);\n" -"}\n" -"\n" -"// Deriving the starknet::Store trait\n" -"// allows us to store the `Person` struct in the contract's storage.\n" -"#[derive(Drop, Serde, Copy, starknet::Store)]\n" -"struct Person {\n" -" age: u8,\n" -" name: felt252\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoringCustomType {\n" -" use super::Person;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" person: Person\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoringCustomType of super::IStoringCustomType {\n" -" fn set_person(ref self: ContractState, person: Person) {\n" -" self.person.write(person);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoringCustomType {\n" -" fn set_person(ref self: TContractState, person: Person);\n" -"}\n" -"\n" -"// Deriving the starknet::Store trait\n" -"// allows us to store the `Person` struct in the contract's storage.\n" -"#[derive(Drop, Serde, Copy, starknet::Store)]\n" -"struct Person {\n" -" age: u8,\n" -" name: felt252\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoringCustomType {\n" -" use super::Person;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" person: Person\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoringCustomType of super::IStoringCustomType {\n" -" fn set_person(ref self: ContractState, person: Person) {\n" -" self.person.write(person);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/storing-custom-types.md:37 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/storing_custom_types/src/contract.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"storing_custom_types/src/contract.cairo) 中尝试这个合约。" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:1 -msgid "# Custom types in entrypoints" -msgstr "# 入口点中的自定义类型" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:3 -msgid "" -"Using custom types in entrypoints requires our type to implement the `Serde` " -"trait. This is because when calling an entrypoint, the input is sent as an " -"array of `felt252` to the entrypoint, and we need to be able to deserialize " -"it into our custom type. Similarly, when returning a custom type from an " -"entrypoint, we need to be able to serialize it into an array of `felt252`.\n" -"Thankfully, we can just derive the `Serde` trait for our custom type." -msgstr "" -"在入口点中使用自定义类型需要我们的类型来实现`Serde`trait。这是因为在调用入口点" -"时,输入以`felt252` 数组的形式发送到入口点,我们需要能够将其反序列化为我们的自" -"定义类型。同样,当从入口点返回自定义类型时,我们需要能够将其序列化为`felt252` " -"数组。\n" -"值得庆幸的是,我们可以为我们的自定义类型派生`Serde` trait。" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:6 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISerdeCustomType {\n" -" fn person_input(ref self: TContractState, person: SerdeCustomType::" -"Person);\n" -" fn person_output(self: @TContractState) -> SerdeCustomType::Person;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SerdeCustomType {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" // Deriving the `Serde` trait allows us to use\n" -" // the Person type as an entrypoint parameter and return value\n" -" #[derive(Drop, Serde)]\n" -" struct Person {\n" -" age: u8,\n" -" name: felt252\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SerdeCustomType of super::ISerdeCustomType {\n" -" fn person_input(ref self: ContractState, person: Person) {}\n" -"\n" -" fn person_output(self: @ContractState) -> Person {\n" -" Person { age: 10, name: 'Joe' }\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISerdeCustomType {\n" -" fn person_input(ref self: TContractState, person: SerdeCustomType::" -"Person);\n" -" fn person_output(self: @TContractState) -> SerdeCustomType::Person;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SerdeCustomType {\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" // Deriving the `Serde` trait allows us to use\n" -" // the Person type as an entrypoint parameter and return value\n" -" #[derive(Drop, Serde)]\n" -" struct Person {\n" -" age: u8,\n" -" name: felt252\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SerdeCustomType of super::ISerdeCustomType {\n" -" fn person_input(ref self: ContractState, person: Person) {}\n" -"\n" -" fn person_output(self: @ContractState) -> Person {\n" -" Person { age: 10, name: 'Joe' }\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/basics/custom-types-in-entrypoints.md:37 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/custom_type_serde/src/contract.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"custom_type_serde/src/contract.cairo) 中尝试这个合约。" - -#: src/getting-started/basics/documentation.md:1 -msgid "# Documentation" -msgstr "# 文档" - -#: src/getting-started/basics/documentation.md:3 -msgid "" -"It's important to take the time to document your code. It will helps " -"developers and users to understand the contract and its functionalities." -msgstr "" -"花时间为你的代码写文档非常重要。它将帮助开发人员和用户了解合约及其功能。" - -#: src/getting-started/basics/documentation.md:5 -msgid "In Cairo, you can add comments with `//`." -msgstr "在Cairo,您可以使用“//”添加注释。" - -#: src/getting-started/basics/documentation.md:7 -msgid "### Best Practices:" -msgstr "### 最佳实践:" - -#: src/getting-started/basics/documentation.md:9 -msgid "" -"Since Cairo 1, the community has adopted a [Rust-like documentation style]" -"(https://doc.rust-lang.org/rust-by-example/meta/doc.html)." -msgstr "" -"自 Cairo 1 以来,社区采用了 [类似 Rust 的文档风格](https://doc.rust-lang.org/" -"rust-by-example/meta/doc.html)。" - -#: src/getting-started/basics/documentation.md:11 -msgid "### Contract Interface:" -msgstr "### 合约接口:" - -#: src/getting-started/basics/documentation.md:13 -msgid "" -"In smart contracts, you will often have a trait that defines the contract's " -"interface (with `#[starknet::interface]`).\n" -"This is the perfect place to include detailed documentation explaining the " -"purpose and functionality of the contract entry points. You can follow this " -"template:" -msgstr "" -"在智能合约中,你通常会有一个定义合约接口的trait(即带有`#[starknet::" -"interface]`)。\n" -"这是包含详细文档的理想场所,这些文档解释了合约入口点的用途和功能。您可以遵循以" -"下模板:" - -#: src/getting-started/basics/documentation.md:16 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IContract {\n" -" /// High-level description of the function\n" -" ///\n" -" /// # Arguments\n" -" ///\n" -" /// * `arg_1` - Description of the argument\n" -" /// * `arg_n` - ...\n" -" ///\n" -" /// # Returns\n" -" ///\n" -" /// High-level description of the return value\n" -" fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IContract {\n" -" /// High-level description of the function\n" -" ///\n" -" /// # Arguments\n" -" ///\n" -" /// * `arg_1` - Description of the argument\n" -" /// * `arg_n` - ...\n" -" ///\n" -" /// # Returns\n" -" ///\n" -" /// High-level description of the return value\n" -" fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return;\n" -"}\n" -"```" - -#: src/getting-started/basics/documentation.md:33 -msgid "" -"Keep in mind that this should not describe the implementation details of the " -"function, but rather the high-level purpose and functionality of the contract " -"from the perspective of a user." -msgstr "" -"请记住,这不应该描述函数的实现细节,而应该从用户的角度描述合约的高级目的和功" -"能。" - -#: src/getting-started/basics/documentation.md:35 -msgid "### Implementation Details:" -msgstr "### 实装细节:" - -#: src/getting-started/basics/documentation.md:37 -msgid "" -"When writing the logic of the contract, you can add comments to describe the " -"technical implementation details of the functions." -msgstr "在编写合约逻辑时,可以添加注释来描述函数的技术实现细节。" - -#: src/getting-started/basics/documentation.md:39 -msgid "" -"> Avoid over-commenting: Comments should provide additional value and clarity." -msgstr "> 避免过度注释:注释应提供额外的价值和清晰度。" - -#: src/getting-started/basics/documentation.md:41 -msgid "
Last change: 2023-12-05
" -msgstr "
Last change: 2023-12-05
" - -#: src/getting-started/interacting/interacting.md:1 -msgid "# Deploy and interact with contracts" -msgstr "# 部署合约并与合约交互" - -#: src/getting-started/interacting/interacting.md:3 -msgid "In this chapter, we will see how to deploy and interact with contracts." -msgstr "在本章中,我们将了解如何部署合约并与之交互。" - -#: src/getting-started/interacting/interacting.md:4 -msgid "
Last change: 2023-10-19
" -msgstr "
Last change: 2023-10-19
" - -#: src/getting-started/interacting/interfaces-traits.md:1 -msgid "# Contract interfaces and Traits generation" -msgstr "# 合约接口和Trait生成" - -#: src/getting-started/interacting/interfaces-traits.md:3 -msgid "" -"Contract interfaces define the structure and behavior of a contract, serving " -"as the contract's public ABI. They list all the function signatures that a " -"contract exposes. For a detailed explanation of interfaces, you can refer to " -"the [Cairo Book](https://book.cairo-lang.org/ch99-01-02-a-simple-contract." -"html)." -msgstr "" -"合约接口定义合约的结构和行为,充当合约的公共 ABI。它们列出了合约公开的所有函数" -"签名。接口的详细说明可以参考 [Cairo之书](https://book.cairo-lang.org/" -"ch99-01-02-a-simple-contract.html)。" - -#: src/getting-started/interacting/interfaces-traits.md:5 -msgid "" -"In cairo, to specify the interface you need to define a trait annotated with " -"`#[starknet::interface]` and then implement that trait in the contract." -msgstr "" -"在cairo中,要指定接口,您需要定义一个带有`#[starknet::interface]`注释的trait," -"然后在合约中实现该trait。" - -#: src/getting-started/interacting/interfaces-traits.md:7 -msgid "" -"When a function needs to access the contract state, it must have a `self` " -"parameter of type `ContractState`. This implies that the corresponding " -"function signature in the interface trait must also take a `TContractState` " -"type as a parameter. It's important to note that every function in the " -"contract interface must have this `self` parameter of type `TContractState`." -msgstr "" -"当函数需要访问合约状态时,它必须具有类型为`ContractState`的`self`参数。这意味" -"着接口trait中的相应函数签名也必须采用`TContractState`类型作为参数。需要注意的" -"是,合约接口中的每个函数都必须具有此类型为`TContractState`的`self`参数。" - -#: src/getting-started/interacting/interfaces-traits.md:9 -msgid "" -"You can use the `#[generate_trait]` attribute to implicitly generate the " -"trait for a specific implementation block. This attribute automatically " -"generates a trait with the same functions as the ones in the implemented " -"block, replacing the `self` parameter with a generic `TContractState` " -"parameter. However, you will need to annotate the block with the " -"`#[abi(per_item)]` attribute, and each function with the appropriate " -"attribute depending on whether it's an external function, a constructor or a " -"l1 handler." -msgstr "" -"您可以使用`#[generate_trait]`属性隐式生成特定实现块的trait。此属性会自动生成一" -"个trait,其功能与已实现块中的函数相同,将`self`参数替换为通用的`TContractState`" -"参数。但是,您需要使用`#[abi(per_item)]` 属性注释块,并且每个函数都具有适当的" -"属性,具体取决于它是外部函数、构造函数还是 l1 处理程序。" - -#: src/getting-started/interacting/interfaces-traits.md:11 -msgid "In summary, there's two ways to handle interfaces:" -msgstr "总之,有两种方法可以处理接口:" - -#: src/getting-started/interacting/interfaces-traits.md:13 -msgid "" -"- Explicitly, by defining a trait annoted with `#[starknet::interface]`\n" -"- Implicitly, by using `#[generate_trait]` combined with the " -"#[abi(per_item)]` attributes, and annotating each function inside the " -"implementation block with the appropriate attribute." -msgstr "" -"- 显示地,通过定义一个用`#[starknet::interface]`标记的trait\n" -"- 隐式地,通过将`#[generate_trait]`与`#[abi(per_item)]`属性结合使用,并使用适" -"当的属性注释实现块中的每个函数。" - -#: src/getting-started/interacting/interfaces-traits.md:16 -msgid "## Explicit interface" -msgstr "## 显式接口" - -#: src/getting-started/interacting/interfaces-traits.md:18 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExplicitInterfaceContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ExplicitInterfaceContract of super::" -"IExplicitInterfaceContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IExplicitInterfaceContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ExplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ExplicitInterfaceContract of super::" -"IExplicitInterfaceContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:45 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/explicit.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"interfaces_traits/src/explicit.cairo)中尝试这个合约。" - -#: src/getting-started/interacting/interfaces-traits.md:47 -msgid "## Implicit interface" -msgstr "## 隐式接口" - -#: src/getting-started/interacting/interfaces-traits.md:49 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ImplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(per_item)]\n" -" #[generate_trait]\n" -" impl ImplicitInterfaceContract of IImplicitInterfaceContract {\n" -" #[external(v0)]\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" #[external(v0)]\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod ImplicitInterfaceContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[abi(per_item)]\n" -" #[generate_trait]\n" -" impl ImplicitInterfaceContract of IImplicitInterfaceContract {\n" -" #[external(v0)]\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" #[external(v0)]\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:73 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"interfaces_traits/src/implicit.cairo) 中尝试这个合约。" - -#: src/getting-started/interacting/interfaces-traits.md:75 -msgid "" -"> Note: You can import an implicitly generated contract interface with `use " -"contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not " -"be generated automatically." -msgstr "" -"> 注意:您可以使用`use contract::{GeneratedContractInterface}`导入隐式生成的合" -"约接口。但是,`Dispatcher`不会自动生成。" - -#: src/getting-started/interacting/interfaces-traits.md:77 -msgid "## Internal functions" -msgstr "## 内部函数" - -#: src/getting-started/interacting/interfaces-traits.md:79 -msgid "" -"You can also use `#[generate_trait]` for your internal functions.\n" -"Since this trait is generated in the context of the contract, you can define " -"pure functions as well (functions without the `self` parameter)." -msgstr "" -"您还可以将`#[generate_trait]`用于内部函数。\n" -"由于此trait是在合约的上下文中生成的,因此您也可以定义纯函数(没有“self”参数的函" -"数)。" - -#: src/getting-started/interacting/interfaces-traits.md:82 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IImplicitInternalContract {\n" -" fn add(ref self: TContractState, nb: u32);\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_const(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ImplicitInternalContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalFunctions of InternalFunctionsTrait {\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" fn get_const() -> u32 {\n" -" 42\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.set_value(0);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ImplicitInternalContract of super::" -"IImplicitInternalContract {\n" -" fn add(ref self: ContractState, nb: u32) {\n" -" self.set_value(self.value.read() + nb);\n" -" }\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" fn get_const(self: @ContractState) -> u32 {\n" -" self.get_const()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IImplicitInternalContract {\n" -" fn add(ref self: TContractState, nb: u32);\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_const(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ImplicitInternalContract {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalFunctions of InternalFunctionsTrait {\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" self.value.write(value);\n" -" }\n" -" fn get_const() -> u32 {\n" -" 42\n" -" }\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.set_value(0);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ImplicitInternalContract of super::" -"IImplicitInternalContract {\n" -" fn add(ref self: ContractState, nb: u32) {\n" -" self.set_value(self.value.read() + nb);\n" -" }\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -" fn get_const(self: @ContractState) -> u32 {\n" -" self.get_const()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/interfaces-traits.md:127 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/interfaces_traits/src/implicit_internal." -"cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"interfaces_traits/src/implicit_internal.cairo) 中尝试这个合约。" - -#: src/getting-started/interacting/calling_other_contracts.md:1 -msgid "# Calling other contracts" -msgstr "# 调用其他合约" - -#: src/getting-started/interacting/calling_other_contracts.md:3 -msgid "There are two different ways to call other contracts in Cairo." -msgstr "在Cairo,有两种不同的方式可以调用其他合约。" - -#: src/getting-started/interacting/calling_other_contracts.md:5 -msgid "" -"The easiest way to call other contracts is by using the dispatcher of the " -"contract you want to call.\n" -"You can read more about Dispatchers in the [Cairo Book](https://book.cairo-" -"lang.org/ch99-02-02-contract-dispatcher-library-dispatcher-and-system-calls." -"html#contract-dispatcher)" -msgstr "" -"调用其他合约的最简单方法是使用要调用的合约的调度程序。\n" -"您可以在 [Cairo Book](https://book.cairo-lang.org/ch99-02-02-contract-" -"dispatcher-library-dispatcher-and-system-calls.html#contract-dispatcher) 中阅" -"读有关 Dispatchers 的更多信息" - -#: src/getting-started/interacting/calling_other_contracts.md:8 -msgid "" -"The other way is to use the `starknet::call_contract_syscall` syscall " -"yourself. However, this method is not recommended." -msgstr "" -"另一种方法是自己使用`starknet::call_contract_syscall`系统调用。但是,不建议使" -"用此方法。" - -#: src/getting-started/interacting/calling_other_contracts.md:10 -msgid "" -"In order to call other contracts using dispatchers, you will need to define " -"the called contract's interface as a trait annotated with the `#[starknet::" -"interface]` attribute, and then import the `IContractDispatcher` and " -"`IContractDispatcherTrait` items in your contract." -msgstr "" -"为了使用调度程序调用其他合约,您需要将被调用合约的接口定义为使用 `#[starknet::" -"interface]` 属性注释的trait,然后将 `IContractDispatcher` 和 " -"`IContractDispatcherTrait` 项导入到合约中。" - -#: src/getting-started/interacting/calling_other_contracts.md:12 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Callee {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICalleeImpl of super::ICallee {\n" -" fn set_value(ref self: ContractState, value: u128) -> u128 {\n" -" self.value.write(value);\n" -" value\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Callee {\n" -" #[storage]\n" -" struct Storage {\n" -" value: u128,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICalleeImpl of super::ICallee {\n" -" fn set_value(ref self: ContractState, value: u128) -> u128 {\n" -" self.value.write(value);\n" -" value\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/calling_other_contracts.md:34 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x015c3Bb6D0DE26b64FEAF9A8f4655CfADb5c128bF4510398972704ee12775DB1) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/callee.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x015c3Bb6D0DE26b64FEAF9A8f4655CfADb5c128bF4510398972704ee12775DB1)上" -"访问 合约 或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/callee.cairo)中" -"尝试它。" - -#: src/getting-started/interacting/calling_other_contracts.md:36 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"// We need to have the interface of the callee contract defined\n" -"// so that we can import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICaller {\n" -" fn set_value_from_address(ref self: TContractState, addr: " -"ContractAddress, value: u128);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Caller {\n" -" // We import the Dispatcher of the called contract\n" -" use super::{ICalleeDispatcher, ICalleeDispatcherTrait};\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICallerImpl of super::ICaller {\n" -" fn set_value_from_address(ref self: ContractState, addr: " -"ContractAddress, value: u128) {\n" -" ICalleeDispatcher { contract_address: addr }.set_value(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"// We need to have the interface of the callee contract defined\n" -"// so that we can import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait ICallee {\n" -" fn set_value(ref self: TContractState, value: u128) -> u128;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ICaller {\n" -" fn set_value_from_address(ref self: TContractState, addr: " -"ContractAddress, value: u128);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod Caller {\n" -" // We import the Dispatcher of the called contract\n" -" use super::{ICalleeDispatcher, ICalleeDispatcherTrait};\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ICallerImpl of super::ICaller {\n" -" fn set_value_from_address(ref self: ContractState, addr: " -"ContractAddress, value: u128) {\n" -" ICalleeDispatcher { contract_address: addr }.set_value(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/calling_other_contracts.md:68 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x05fa8aF796343d2f22c53C17149386b67B7AC4aB52D9e308Aa507C185aA44778) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/caller.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x05fa8aF796343d2f22c53C17149386b67B7AC4aB52D9e308Aa507C185aA44778) " -"上访问合约或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/calling_other_contracts/src/caller.cairo) " -"中尝试它。" - -#: src/getting-started/interacting/factory.md:1 -msgid "# Factory Pattern" -msgstr "# 工厂模式" - -#: src/getting-started/interacting/factory.md:3 -msgid "" -"The factory pattern is a well known pattern in object oriented programming. " -"It provides an abstraction on how to instantiate a class. " -msgstr "" -"工厂模式是面向对象编程中众所周知的模式。它提供了有关如何实例化类的抽象。" - -#: src/getting-started/interacting/factory.md:5 -msgid "" -"In the case of smart contracts, we can use this pattern by defining a factory " -"contract that have the sole responsibility of creating and managing other " -"contracts." -msgstr "" -"在智能合约里,我们可以通过定义一个工厂合约来使用这种模式,该合约全权负责创建和" -"管理其他合约。" - -#: src/getting-started/interacting/factory.md:7 -msgid "## Class hash and contract instance" -msgstr "## 类哈希(Class hash)和合约实例" - -#: src/getting-started/interacting/factory.md:9 -msgid "" -"In Starknet, there's a separation between contract's classes and instances. A " -"contract class serves as a blueprint, defined by the underling Cairo " -"bytecode, contract's entrypoints, ABI and Sierra program hash. The contract " -"class is identified by a class hash. When you want to add a new class to the " -"network, you first need to declare it." -msgstr "" -"在Starknet中,合约的类和实例是分开的。合约类充当蓝图,由底层 Cairo 字节码、合" -"约的入口点、ABI 和 Sierra 程序哈希定义。合约类由类哈希标识。当您想向网络添加一" -"个新类时,首先需要声明它。" - -#: src/getting-started/interacting/factory.md:11 -msgid "" -"When deploying a contract, you need to specify the class hash of the contract " -"you want to deploy. Each instance of a contract has their own storage " -"regardless of the class hash." -msgstr "" -"部署合约时,需要指定要部署的合约的类哈希值。合约的每个实例都有自己的存储,这与" -"类哈希无关。" - -#: src/getting-started/interacting/factory.md:13 -msgid "" -"Using the factory pattern, we can deploy multiple instances of the same " -"contract class and handle upgrades easily." -msgstr "使用工厂模式,我们可以部署同一合约类的多个实例,并轻松处理升级。" - -#: src/getting-started/interacting/factory.md:15 -msgid "## Minimal example" -msgstr "## 最小范例" - -#: src/getting-started/interacting/factory.md:17 -msgid "" -"Here's a minimal example of a factory contract that deploy the " -"`SimpleCounter` contract:" -msgstr "下面是部署`SimpleCounter` 合约的工厂合约的最小范例:" - -#: src/getting-started/interacting/factory.md:19 -msgid "" -"```cairo\n" -"use starknet::{ContractAddress, ClassHash};\n" -"\n" -"#[starknet::interface]\n" -"trait ICounterFactory {\n" -" /// Create a new counter contract from stored arguments\n" -" fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"\n" -" /// Create a new counter contract from the given arguments\n" -" fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"\n" -" /// Update the argument\n" -" fn update_init_value(ref self: TContractState, init_value: u128);\n" -"\n" -" /// Update the class hash of the Counter contract to deploy when creating " -"a new counter\n" -" fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CounterFactory {\n" -" use starknet::{ContractAddress, ClassHash};\n" -" use starknet::syscalls::deploy_syscall;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" /// Store the constructor arguments of the contract to deploy\n" -" init_value: u128,\n" -" /// Store the class hash of the contract to deploy\n" -" counter_class_hash: ClassHash,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -" self.init_value.write(init_value);\n" -" self.counter_class_hash.write(class_hash);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"\n" -" fn create_counter(ref self: ContractState) -> ContractAddress {\n" -" self.create_counter_at(self.init_value.read())\n" -" }\n" -"\n" -" fn update_init_value(ref self: ContractState, init_value: u128) {\n" -" self.init_value.write(init_value);\n" -" }\n" -"\n" -" fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -" self.counter_class_hash.write(counter_class_hash);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::{ContractAddress, ClassHash};\n" -"\n" -"#[starknet::interface]\n" -"trait ICounterFactory {\n" -" /// Create a new counter contract from stored arguments\n" -" fn create_counter(ref self: TContractState) -> ContractAddress;\n" -"\n" -" /// Create a new counter contract from the given arguments\n" -" fn create_counter_at(ref self: TContractState, init_value: u128) -> " -"ContractAddress;\n" -"\n" -" /// Update the argument\n" -" fn update_init_value(ref self: TContractState, init_value: u128);\n" -"\n" -" /// Update the class hash of the Counter contract to deploy when creating " -"a new counter\n" -" fn update_counter_class_hash(ref self: TContractState, " -"counter_class_hash: ClassHash);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod CounterFactory {\n" -" use starknet::{ContractAddress, ClassHash};\n" -" use starknet::syscalls::deploy_syscall;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" /// Store the constructor arguments of the contract to deploy\n" -" init_value: u128,\n" -" /// Store the class hash of the contract to deploy\n" -" counter_class_hash: ClassHash,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, init_value: u128, class_hash: " -"ClassHash) {\n" -" self.init_value.write(init_value);\n" -" self.counter_class_hash.write(class_hash);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl Factory of super::ICounterFactory {\n" -" fn create_counter_at(ref self: ContractState, init_value: u128) -> " -"ContractAddress {\n" -" // Contructor arguments\n" -" let mut constructor_calldata: Array:: = array!" -"[init_value.into()];\n" -"\n" -" // Contract deployment\n" -" let (deployed_address, _) = deploy_syscall(\n" -" self.counter_class_hash.read(), 0, constructor_calldata." -"span(), false\n" -" )\n" -" .expect('failed to deploy counter');\n" -"\n" -" deployed_address\n" -" }\n" -"\n" -" fn create_counter(ref self: ContractState) -> ContractAddress {\n" -" self.create_counter_at(self.init_value.read())\n" -" }\n" -"\n" -" fn update_init_value(ref self: ContractState, init_value: u128) {\n" -" self.init_value.write(init_value);\n" -" }\n" -"\n" -" fn update_counter_class_hash(ref self: ContractState, " -"counter_class_hash: ClassHash) {\n" -" self.counter_class_hash.write(counter_class_hash);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/interacting/factory.md:86 -msgid "" -"\n" -"\n" -"
Last change: 2023-12-07
" -msgstr "" -"\n" -"\n" -"
Last change: 2023-12-07
" - -#: src/getting-started/testing/contract-testing.md:1 -msgid "# Contract Testing" -msgstr "# 合约测试" - -#: src/getting-started/testing/contract-testing.md:3 -msgid "" -"Testing plays a crucial role in software development, especially for smart " -"contracts. In this section, we'll guide you through the basics of testing a " -"smart contract on Starknet with `scarb`." -msgstr "" -"测试在软件开发中起着至关重要的作用,尤其是对于智能合约而言。在本节中,我们将通" -"过Starknet上的`scarb` ,引导你了解智能合约测试的基础知识。" - -#: src/getting-started/testing/contract-testing.md:5 -msgid "Let's start with a simple smart contract as an example:" -msgstr "让我们以一个简单的智能合约作为例子开始:" - -#: src/getting-started/testing/contract-testing.md:6 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_owner(self: @TContractState) -> ContractAddress;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleContract {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32,\n" -" owner: ContractAddress\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, initial_value: u32) {\n" -" self.value.write(initial_value);\n" -" self.owner.write(get_caller_address());\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleContract of super::ISimpleContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn get_owner(self: @ContractState) -> ContractAddress {\n" -" self.owner.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" assert(self.owner.read() == get_caller_address(), 'Not owner');\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleContract {\n" -" fn get_value(self: @TContractState) -> u32;\n" -" fn get_owner(self: @TContractState) -> ContractAddress;\n" -" fn set_value(ref self: TContractState, value: u32);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleContract {\n" -" use starknet::{get_caller_address, ContractAddress};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" value: u32,\n" -" owner: ContractAddress\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, initial_value: u32) {\n" -" self.value.write(initial_value);\n" -" self.owner.write(get_caller_address());\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleContract of super::ISimpleContract {\n" -" fn get_value(self: @ContractState) -> u32 {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn get_owner(self: @ContractState) -> ContractAddress {\n" -" self.owner.read()\n" -" }\n" -"\n" -" fn set_value(ref self: ContractState, value: u32) {\n" -" assert(self.owner.read() == get_caller_address(), ‘Not owner’);\n" -" self.value.write(value);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/testing/contract-testing.md:50 -msgid "Now, take a look at the tests for this contract:" -msgstr "现在,让我们看一下这个合约的测试:" - -#: src/getting-started/testing/contract-testing.md:51 -msgid "" -"```cairo\n" -"#[cfg(test)]\n" -"mod tests {\n" -" // Import the interface and dispatcher to be able to interact with the " -"contract.\n" -" use testing_how_to::contract::{\n" -" ISimpleContract, SimpleContract, ISimpleContractDispatcher, " -"ISimpleContractDispatcherTrait\n" -" };\n" -"\n" -" // Import the deploy syscall to be able to deploy the contract.\n" -" use starknet::class_hash::Felt252TryIntoClassHash;\n" -" use starknet::{\n" -" deploy_syscall, ContractAddress, get_caller_address, " -"get_contract_address,\n" -" contract_address_const\n" -" };\n" -"\n" -" // Use starknet test utils to fake the transaction context.\n" -" use starknet::testing::{set_caller_address, set_contract_address};\n" -"\n" -" // Deploy the contract and return its dispatcher.\n" -" fn deploy(initial_value: u32) -> ISimpleContractDispatcher {\n" -" // Set up constructor arguments.\n" -" let mut calldata = ArrayTrait::new();\n" -" initial_value.serialize(ref calldata);\n" -"\n" -" // Declare and deploy\n" -" let (contract_address, _) = deploy_syscall(\n" -" SimpleContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -" )\n" -" .unwrap();\n" -"\n" -" // Return the dispatcher.\n" -" // The dispatcher allows to interact with the contract based on its " -"interface.\n" -" ISimpleContractDispatcher { contract_address }\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_deploy() {\n" -" let initial_value: u32 = 10;\n" -" let contract = deploy(initial_value);\n" -"\n" -" assert(contract.get_value() == initial_value, 'wrong initial " -"value');\n" -" assert(contract.get_owner() == get_contract_address(), 'wrong " -"owner');\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_as_owner() {\n" -" // Fake the caller address to address 1\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -" assert(contract.get_owner() == owner, 'wrong owner');\n" -"\n" -" // Fake the contract address to address 1\n" -" set_contract_address(owner);\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -"\n" -" assert(contract.get_value() == new_value, 'wrong value');\n" -" }\n" -"\n" -" #[test]\n" -" #[should_panic]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_not_owner() {\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -"\n" -" let not_owner = contract_address_const::<2>();\n" -" set_contract_address(not_owner);\n" -"\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[cfg(test)]\n" -"mod tests {\n" -" // Import the interface and dispatcher to be able to interact with the " -"contract.\n" -" use testing_how_to::contract::{\n" -" ISimpleContract, SimpleContract, ISimpleContractDispatcher, " -"ISimpleContractDispatcherTrait\n" -" };\n" -"\n" -" // Import the deploy syscall to be able to deploy the contract.\n" -" use starknet::class_hash::Felt252TryIntoClassHash;\n" -" use starknet::{\n" -" deploy_syscall, ContractAddress, get_caller_address, " -"get_contract_address,\n" -" contract_address_const\n" -" };\n" -"\n" -" // Use starknet test utils to fake the transaction context.\n" -" use starknet::testing::{set_caller_address, set_contract_address};\n" -"\n" -" // Deploy the contract and return its dispatcher.\n" -" fn deploy(initial_value: u32) -> ISimpleContractDispatcher {\n" -" // Set up constructor arguments.\n" -" let mut calldata = ArrayTrait::new();\n" -" initial_value.serialize(ref calldata);\n" -"\n" -" // Declare and deploy\n" -" let (contract_address, _) = deploy_syscall(\n" -" SimpleContract::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata." -"span(), false\n" -" )\n" -" .unwrap();\n" -"\n" -" // Return the dispatcher.\n" -" // The dispatcher allows to interact with the contract based on its " -"interface.\n" -" ISimpleContractDispatcher { contract_address }\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_deploy() {\n" -" let initial_value: u32 = 10;\n" -" let contract = deploy(initial_value);\n" -"\n" -" assert(contract.get_value() == initial_value, 'wrong initial " -"value');\n" -" assert(contract.get_owner() == get_contract_address(), 'wrong " -"owner');\n" -" }\n" -"\n" -" #[test]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_as_owner() {\n" -" // Fake the caller address to address 1\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -" assert(contract.get_owner() == owner, 'wrong owner');\n" -"\n" -" // Fake the contract address to address 1\n" -" set_contract_address(owner);\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -"\n" -" assert(contract.get_value() == new_value, 'wrong value');\n" -" }\n" -"\n" -" #[test]\n" -" #[should_panic]\n" -" #[available_gas(2000000000)]\n" -" fn test_set_not_owner() {\n" -" let owner = contract_address_const::<1>();\n" -" set_contract_address(owner);\n" -"\n" -" let contract = deploy(10);\n" -"\n" -" let not_owner = contract_address_const::<2>();\n" -" set_contract_address(not_owner);\n" -"\n" -" let new_value: u32 = 20;\n" -" contract.set_value(new_value);\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/testing/contract-testing.md:132 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/getting-started/testing_how_to/src/lib.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/getting-started/" -"testing_how_to/src/lib.cairo)中与这个合约进行互动。" - -#: src/getting-started/testing/contract-testing.md:134 -msgid "" -"To define our test, we use scarb, which allows us to create a separate module " -"guarded with `#[cfg(test)]`. This ensures that the test module is only " -"compiled when running tests using `scarb test`." -msgstr "" -"为了定义我们的测试,我们使用 scarb,它允许我们创建一个被 `#[cfg(test)]` 保护的" -"独立模块。这样可以确保测试模块只在使用 `scarb test` 运行测试时被编译。" - -#: src/getting-started/testing/contract-testing.md:136 -msgid "" -"Each test is defined as a function with the `#[test]` attribute. You can also " -"check if a test panics using the `#[should_panic]` attribute." -msgstr "" -"每个测试都被定义为带有 `#[test]` 属性的函数。您还可以使用 `#[should_panic]` 属" -"性检查测试是否会引发 panic。" - -#: src/getting-started/testing/contract-testing.md:138 -msgid "" -"As we are in the context of a smart contract, it's essential to set up the " -"gas limit. You do this by using the `#[available_gas(X)]` attribute to " -"specify the gas limit for a test. This is also a great way to ensure that " -"your contract's features stay under a certain gas limit!" -msgstr "" -"由于我们处于智能合约的上下文中,设置 gas 限制非常重要。你可以通过使用 " -"`#[available_gas(X)]` 属性来指定测试的 gas 限制。这也是确保合约功能保持在某个" -"特定 gas 限制下的好方法!" - -#: src/getting-started/testing/contract-testing.md:140 -msgid "> Note: The term \"gas\" here refers to Sierra gas, not L1 gas" -msgstr "> 注意:这里的 “gas” 一词指的是 Sierra gas,而不是 L1 的 gas" - -#: src/getting-started/testing/contract-testing.md:142 -msgid "Now, let's move on to the testing process:" -msgstr "现在,让我们进入测试过程:" - -#: src/getting-started/testing/contract-testing.md:143 -msgid "" -"- Use the `deploy` function logic to declare and deploy your contract.\n" -"- Use `assert` to verify that the contract behaves as expected in the given " -"context." -msgstr "" -"- 使用 `deploy` 函数的逻辑来声明和部署您的合约。\n" -"- 使用 `assert` 来验证合约在给定的上下文中的行为是否符合预期。" - -#: src/getting-started/testing/contract-testing.md:146 -msgid "" -"To make testing more convenient, the `testing` module of the corelib provides " -"some helpful functions:" -msgstr "为了使测试更加方便,corelib 的 `testing` 模块提供了一些有用的函数:" - -#: src/getting-started/testing/contract-testing.md:147 -msgid "" -"- `set_caller_address(address: ContractAddress)`\n" -"- `set_contract_address(address: ContractAddress)`\n" -"- `set_block_number(block_number: u64)`\n" -"- `set_block_timestamp(block_timestamp: u64)`\n" -"- `set_account_contract_address(address: ContractAddress)`\n" -"- `set_max_fee(fee: u128)`" -msgstr "" -"- `set_caller_address(address: ContractAddress)`\n" -"- `set_contract_address(address: ContractAddress)`\n" -"- `set_block_number(block_number: u64)`\n" -"- `set_block_timestamp(block_timestamp: u64)`\n" -"- `set_account_contract_address(address: ContractAddress)`\n" -"- `set_max_fee(fee: u128)`" - -#: src/getting-started/testing/contract-testing.md:154 -msgid "" -"You may also need the `info` module from the corelib, which allows you to " -"access information about the current transaction context:" -msgstr "" -"你可能还需要 corelib 中的 `info` 模块,它允许你访问有关当前交易上下文的信息:" - -#: src/getting-started/testing/contract-testing.md:155 -msgid "" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" -msgstr "" -"- `get_caller_address() -> ContractAddress`\n" -"- `get_contract_address() -> ContractAddress`\n" -"- `get_block_info() -> Box`\n" -"- `get_tx_info() -> Box`\n" -"- `get_block_timestamp() -> u64`\n" -"- `get_block_number() -> u64`" - -#: src/getting-started/testing/contract-testing.md:163 -msgid "" -"You can found the full list of functions in the [Starknet Corelib repo]" -"(https://github.com/starkware-libs/cairo/tree/main/corelib/src/starknet).\n" -"You can also find a detailled explaination of testing in cairo in the [Cairo " -"book - Chapter 8](https://book.cairo-lang.org/ch08-01-how-to-write-tests." -"html)." -msgstr "" -"你可以在 [Starknet Corelib 仓库](https://github.com/starkware-libs/cairo/tree/" -"main/corelib/src/starknet) 中找到完整的函数列表。\n" -"你还可以在 [Cairo book 第8章](https://book.cairo-lang.org/ch08-01-how-to-" -"write-tests.html) 中找到有关在 cairo 中进行测试的详细说明。" - -#: src/getting-started/testing/contract-testing.md:166 -msgid "## Starknet Foundry" -msgstr "## Starknet Foundry" - -#: src/getting-started/testing/contract-testing.md:168 -msgid "" -msgstr "" - -#: src/getting-started/testing/contract-testing.md:170 -msgid "" -"Starknet Foundry is a powerful toolkit for developing smart contracts on " -"Starknet. It offers support for testing Starknet smart contracts on top of " -"`scarb` with the `Forge` tool." -msgstr "" -"Starknet Foundry是在Starknet上开发智能合约的强大工具包。它提供了对使用`Forge` " -"工具在 `scarb` 上测试Starknet智能合约的支持。" - -#: src/getting-started/testing/contract-testing.md:172 -msgid "" -"Testing with `snforge` is similar to the process we just described but " -"simplified. Moreover, additional features are on the way, including " -"cheatcodes or parallel tests execution. We highly recommend exploring " -"Starknet Foundry and incorporating it into your projects." -msgstr "" -"使用 `snforge` 进行测试与我们刚刚描述的过程类似,但更简化。此外,还有其他功能" -"正在开发中,包括作弊码或并行测试执行。我们强烈推荐探索Starknet Foundry并将其纳" -"入您你的项目中。" - -#: src/getting-started/testing/contract-testing.md:174 -msgid "" -"For more detailed information about testing contracts with Starknet Foundry, " -"check out the [Starknet Foundry Book - Testing Contracts](https://foundry-rs." -"github.io/starknet-foundry/testing/contracts.html)." -msgstr "" -"有关使用Starknet Foundry测试合约的更详细信息,请参阅[Starknet Foundry Book - " -"合约测试](https://foundry-rs.github.io/starknet-foundry/testing/contracts." -"html)。" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:1 -msgid "# Cairo Cheatsheet" -msgstr "# Cairo 备忘单" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:3 -msgid "" -"This chapter aims to provide a quick reference for the most common Cairo " -"constructs." -msgstr "本章旨在为最常见的Cairo结构提供快速参考。" - -#: src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md:5 -msgid "
Last change: 2023-10-31
" -msgstr "
Last change: 2023-10-31
" - -#: src/getting-started/cairo_cheatsheet/felt.md:1 -msgid "# Felt252" -msgstr "# Felt252" - -#: src/getting-started/cairo_cheatsheet/felt.md:3 -msgid "" -"Felt252 is a fundamental data type in Cairo from which all other data types " -"are derived.\n" -"Felt252 can also be used to store short-string representations with a maximum " -"length of 31 characters." -msgstr "" -"Felt252是Cairo中的基本数据类型,所有其他数据类型都派生自它。\n" -"Felt252也可以用于存储最多31个字符长度的短字符串表示。" - -#: src/getting-started/cairo_cheatsheet/felt.md:6 src/getting-started/cairo_cheatsheet/arrays.md:20 -#: src/advanced-concepts/hash-solidity-compatible.md:5 -msgid "For example:" -msgstr "例如:" - -#: src/getting-started/cairo_cheatsheet/felt.md:8 -msgid "" -"```cairo\n" -" let felt: felt252 = 100;\n" -" let felt_as_str = 'Hello Starknet!';\n" -"\n" -" let felt = felt + felt_as_str;\n" -"```" -msgstr "" -"```cairo\n" -" let felt: felt252 = 100;\n" -" let felt_as_str = ‘Hello Starknet!’;\n" -"\n" -" let felt = felt + felt_as_str;\n" -"```" - -#: src/getting-started/cairo_cheatsheet/mapping.md:1 -msgid "# Mapping" -msgstr "# Mapping" - -#: src/getting-started/cairo_cheatsheet/mapping.md:3 -msgid "" -"The ```LegacyMap``` type can be used to represent a collection of key-value." -msgstr "`LegacyMap` 类型可以用于表示键值对的集合。" - -#: src/getting-started/cairo_cheatsheet/mapping.md:5 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMappingExample {\n" -" fn register_user(ref self: TContractState, student_add: ContractAddress, " -"studentName: felt252);\n" -" fn record_student_score(\n" -" ref self: TContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" );\n" -" fn view_student_name(self: @TContractState, student_add: ContractAddress) " -"-> felt252;\n" -" fn view_student_score(\n" -" self: @TContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MappingContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" students_name: LegacyMap::,\n" -" students_result_record: LegacyMap::<(ContractAddress, felt252), " -"u16>,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl External of super::IMappingExample {\n" -" fn register_user(\n" -" ref self: ContractState, student_add: ContractAddress, " -"studentName: felt252\n" -" ) {\n" -" self.students_name.write(student_add, studentName);\n" -" }\n" -"\n" -" fn record_student_score(\n" -" ref self: ContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" ) {\n" -" self.students_result_record.write((student_add, subject), " -"score);\n" -" }\n" -"\n" -" fn view_student_name(self: @ContractState, student_add: " -"ContractAddress) -> felt252 {\n" -" self.students_name.read(student_add)\n" -" }\n" -"\n" -" fn view_student_score(\n" -" self: @ContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16 {\n" -" // for a 2D mapping its important to take note of the amount of " -"brackets being used.\n" -" self.students_result_record.read((student_add, subject))\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IMappingExample {\n" -" fn register_user(ref self: TContractState, student_add: ContractAddress, " -"studentName: felt252);\n" -" fn record_student_score(\n" -" ref self: TContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" );\n" -" fn view_student_name(self: @TContractState, student_add: ContractAddress) " -"-> felt252;\n" -" fn view_student_score(\n" -" self: @TContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod MappingContract {\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" students_name: LegacyMap::,\n" -" students_result_record: LegacyMap::<(ContractAddress, felt252), " -"u16>,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl External of super::IMappingExample {\n" -" fn register_user(\n" -" ref self: ContractState, student_add: ContractAddress, " -"studentName: felt252\n" -" ) {\n" -" self.students_name.write(student_add, studentName);\n" -" }\n" -"\n" -" fn record_student_score(\n" -" ref self: ContractState, student_add: ContractAddress, subject: " -"felt252, score: u16\n" -" ) {\n" -" self.students_result_record.write((student_add, subject), " -"score);\n" -" }\n" -"\n" -" fn view_student_name(self: @ContractState, student_add: " -"ContractAddress) -> felt252 {\n" -" self.students_name.read(student_add)\n" -" }\n" -"\n" -" fn view_student_score(\n" -" self: @ContractState, student_add: ContractAddress, subject: " -"felt252\n" -" ) -> u16 {\n" -" // 对于二维映射,重要的是注意使用的括号数量。\n" -" self.students_result_record.read((student_add, subject))\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/arrays.md:1 -msgid "# Arrays" -msgstr "# 数组" - -#: src/getting-started/cairo_cheatsheet/arrays.md:3 -msgid "" -"Arrays are collections of elements of the same type.\n" -"The possible operations on arrays are defined with the `array::ArrayTrait` of " -"the corelib:" -msgstr "" -"数组是相同类型元素的集合。\n" -"可以使用 corelib 的 `array::ArrayTrait` 来定义可能的数组操作:" - -#: src/getting-started/cairo_cheatsheet/arrays.md:6 -msgid "" -"```cairo\n" -"trait ArrayTrait {\n" -" fn new() -> Array;\n" -" fn append(ref self: Array, value: T);\n" -" fn pop_front(ref self: Array) -> Option nopanic;\n" -" fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic;\n" -" fn get(self: @Array, index: usize) -> Option>;\n" -" fn at(self: @Array, index: usize) -> @T;\n" -" fn len(self: @Array) -> usize;\n" -" fn is_empty(self: @Array) -> bool;\n" -" fn span(self: @Array) -> Span;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait ArrayTrait {\n" -" fn new() -> Array;\n" -" fn append(ref self: Array, value: T);\n" -" fn pop_front(ref self: Array) -> Option nopanic;\n" -" fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic;\n" -" fn get(self: @Array, index: usize) -> Option>;\n" -" fn at(self: @Array, index: usize) -> @T;\n" -" fn len(self: @Array) -> usize;\n" -" fn is_empty(self: @Array) -> bool;\n" -" fn span(self: @Array) -> Span;\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/arrays.md:22 -msgid "" -"```cairo\n" -"fn array() -> bool {\n" -" let mut arr = ArrayTrait::::new();\n" -" arr.append(10);\n" -" arr.append(20);\n" -" arr.append(30);\n" -"\n" -" assert(arr.len() == 3, 'array length should be 3');\n" -"\n" -" let first_value = arr.pop_front().unwrap();\n" -" assert(first_value == 10, 'first value should match');\n" -"\n" -" let second_value = *arr.at(0);\n" -" assert(second_value == 20, 'second value should match');\n" -"\n" -" // Returns true if an array is empty, then false if it isn't.\n" -" arr.is_empty()\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"fn array() -> bool {\n" -" let mut arr = ArrayTrait::::new();\n" -" arr.append(10);\n" -" arr.append(20);\n" -" arr.append(30);\n" -"\n" -" assert(arr.len() == 3, 'array length should be 3');\n" -"\n" -" let first_value = arr.pop_front().unwrap();\n" -" assert(first_value == 10, 'first value should match');\n" -"\n" -" let second_value = *arr.at(0);\n" -" assert(second_value == 20, 'second value should match');\n" -"\n" -" // Returns true if an array is empty, then false if it isn't.\n" -" arr.is_empty()\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/loop.md:1 -msgid "# Loop" -msgstr "# 循环" - -#: src/getting-started/cairo_cheatsheet/loop.md:3 -msgid "" -"A loop specifies a block of code that will run repetitively until a halting " -"condition is encountered.\n" -"For example:" -msgstr "" -"循环指定一个代码块,该代码块将重复运行,直到遇到停止条件。\n" -"例如:" - -#: src/getting-started/cairo_cheatsheet/loop.md:6 -msgid "" -"```cairo\n" -" let mut arr = ArrayTrait::new();\n" -"\n" -" // Same as ~ while (i < 10) arr.append(i++);\n" -" let mut i: u32 = 0;\n" -" let limit = 10;\n" -" loop {\n" -" if i == limit {\n" -" break;\n" -" };\n" -"\n" -" arr.append(i);\n" -"\n" -" i += 1;\n" -" };\n" -"```" -msgstr "" -"```cairo\n" -" let mut arr = ArrayTrait::new();\n" -"\n" -" // 与 ~ while (i < 10) arr.append(i++); 相同\n" -" let mut i: u32 = 0;\n" -" let limit = 10;\n" -" loop {\n" -" if i == limit {\n" -" break;\n" -" };\n" -"\n" -" arr.append(i);\n" -"\n" -" i += 1;\n" -" };\n" -"```" - -#: src/getting-started/cairo_cheatsheet/match.md:1 -msgid "# Match" -msgstr "# 分支" - -#: src/getting-started/cairo_cheatsheet/match.md:3 -msgid "" -"The `match` expression in Cairo allows us to control the flow of our code " -"by comparing a `felt252` data type or an enum against various patterns and then " -"running specific code based on the pattern that matches.\n" -"For example:" -msgstr "" -"在 Cairo 中,`match` 表达式允许我们通过将 `felt252` 数据类型或枚举与各种模式进行比" -"较,然后根据匹配的模式运行特定的代码来控制代码的流程。例如:" - -#: src/getting-started/cairo_cheatsheet/match.md:6 -msgid "" -"```cairo\n" -"#[derive(Drop, Serde)]\n" -"enum Colour {\n" -" Red,\n" -" Blue,\n" -" Green,\n" -" Orange,\n" -" Black\n" -"}\n" -"\n" -"#[derive(Drop, Serde)]\n" -"enum Coin {\n" -" Penny,\n" -" Nickel,\n" -" Dime,\n" -" Quarter,\n" -"}\n" -"\n" -"fn value_in_cents(coin: Coin) -> felt252 {\n" -" match coin {\n" -" Coin::Penny => 1,\n" -" Coin::Nickel => 5,\n" -" Coin::Dime => 10,\n" -" Coin::Quarter => 25,\n" -" }\n" -"}\n" -"\n" -"fn specified_colour(colour: Colour) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match colour {\n" -" Colour::Red => { response = 'You passed in Red'; },\n" -" Colour::Blue => { response = 'You passed in Blue'; },\n" -" Colour::Green => { response = 'You passed in Green'; },\n" -" Colour::Orange => { response = 'You passed in Orange'; },\n" -" Colour::Black => { response = 'You passed in Black'; },\n" -" };\n" -"\n" -" response\n" -"}\n" -"\n" -"fn quiz(num: felt252) -> felt252 {\n" -" let mut response: felt252 = '';\n" -"\n" -" match num {\n" -" 0 => { response = 'You failed' },\n" -" _ => { response = 'You Passed' },\n" -" };\n" -"\n" -" response\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[derive(Drop, Serde)]\n" -"enum Colour {\n" -" Red,\n" -" Blue,\n" -" Green,\n" -" Orange,\n" -" Black\n" -"}\n" -"\n" -"#[derive(Drop, Serde)]\n" -"enum Coin {\n" -" Penny,\n" -" Nickel,\n" -" Dime,\n" -" Quarter,\n" -"}\n" -"\n" -"fn value_in_cents(coin: Coin) -> felt252 {\n" -" match coin {\n" -" Coin::Penny => 1,\n" -" Coin::Nickel => 5,\n" -" Coin::Dime => 10,\n" -" Coin::Quarter => 25,\n" -" }\n" -"}\n" -"\n" -"fn specified_colour(colour: Colour) -> felt252 {\n" -" let mut response: felt252 = ‘’;\n" -"\n" -" match colour {\n" -" Colour::Red => { response = ‘You passed in Red’; },\n" -" Colour::Blue => { response = ‘You passed in Blue’; },\n" -" Colour::Green => { response = ‘You passed in Green’; },\n" -" Colour::Orange => { response = ‘You passed in Orange’; },\n" -" Colour::Black => { response = ‘You passed in Black’; },\n" -" };\n" -"\n" -" response\n" -"}\n" -"\n" -"fn quiz(num: felt252) -> felt252 {\n" -" let mut response: felt252 = ‘’;\n" -"\n" -" match num {\n" -" 0 => { response = ‘You failed’ },\n" -" _ => { response = ‘You Passed’ },\n" -" };\n" -"\n" -" response\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/tuples.md:1 -msgid "# Tuples" -msgstr "# 元组" - -#: src/getting-started/cairo_cheatsheet/tuples.md:3 -msgid "" -"Tuples is a data type to group a fixed number of items of potentially " -"different types into a single compound structure. Unlike arrays, tuples have " -"a set length and can contain elements of varying types. Once a tuple is " -"created, its size cannot change.\n" -"For example:" -msgstr "" -"元组是一种数据类型,用于将固定数量的不同类型的项组合成一个单一的复合结构。与数" -"组不同,元组具有固定的长度,并且可以包含不同类型的元素。一旦创建了元组,其大小" -"就无法更改。\n" -"例如:" - -#: src/getting-started/cairo_cheatsheet/tuples.md:6 -msgid "" -"```cairo\n" -" let address = \"0x000\";\n" -" let age = 20;\n" -" let active = true;\n" -"\n" -" // Create tuple\n" -" let user_tuple = (address, age, active);\n" -"\n" -" // Access tuple\n" -" let (address, age, active) = stored_tuple;\n" -"```" -msgstr "" -"```cairo\n" -" let address = “0x000”;\n" -" let age = 20;\n" -" let active = true;\n" -"\n" -" // Create tuple\n" -" let user_tuple = (address, age, active);\n" -"\n" -" // Access tuple\n" -" let (address, age, active) = stored_tuple;\n" -"```" - -#: src/getting-started/cairo_cheatsheet/struct.md:1 -msgid "# Struct" -msgstr "# 结构体" - -#: src/getting-started/cairo_cheatsheet/struct.md:3 -msgid "" -"A struct is a data type similar to tuple. Like tuples they can be used to " -"hold data of different types.\n" -"For example:" -msgstr "" -"结构体是一种类似于元组的数据类型。与元组类似,它们可以用于保存不同类型的数" -"据。\n" -"例如:" - -#: src/getting-started/cairo_cheatsheet/struct.md:6 -msgid "" -"```cairo\n" -"// With Store, you can store Data's structs in the storage part of " -"contracts.\n" -"#[derive(Drop, starknet::Store)]\n" -"struct Data {\n" -" address: starknet::ContractAddress,\n" -" age: u8\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"// 使用 Store,您可以将 Data 结构体存储在合约的存储部分。\n" -"#[derive(Drop, starknet::Store)]\n" -"struct Data {\n" -" address: starknet::ContractAddress,\n" -" age: u8\n" -"}\n" -"```" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:1 -msgid "# Type casting" -msgstr "# 类型转换" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:3 -msgid "" -"Cairo supports the conversion from one scalar types to another by using the " -"into and try_into methods.\n" -"`traits::Into` is used for conversion from a smaller data type to a larger " -"data type, while `traits::TryInto` is used when converting from a larger to a " -"smaller type that might not fit. \n" -"For example:" -msgstr "" -"Cairo支持使用into和try_into方法将一个标量类型转换为另一个类型。\n" -"`traits::Into` 用于从较小的数据类型转换为较大的数据类型,而 `traits::TryInto` " -"用于从较大的数据类型转换为较小的数据类型,可能会发生溢出的情况。\n" -"例如:" - -#: src/getting-started/cairo_cheatsheet/type_casting.md:7 -msgid "" -"```cairo\n" -" let a_number: u32 = 15;\n" -" let my_felt252 = 15;\n" -"\n" -" // Since a u32 might not fit in a u8 and a u16, we need to use try_into,\n" -" // then unwrap the Option type thats returned.\n" -" let new_u8: u8 = a_number.try_into().unwrap();\n" -" let new_u16: u16 = a_number.try_into().unwrap();\n" -"\n" -" // since new_u32 is the of the same type (u32) as rand_number, we can " -"directly assign them,\n" -" // or use the .into() method.\n" -" let new_u32: u32 = a_number;\n" -"\n" -" // When typecasting from a smaller size to an equal or larger size we use " -"the .into() method.\n" -" // Note: u64 and u128 are larger than u32, so a u32 type will always fit " -"into them.\n" -" let new_u64: u64 = a_number.into();\n" -" let new_u128: u128 = a_number.into();\n" -"\n" -" // Since a felt252 is smaller than a u256, we can use the into() method\n" -" let new_u256: u256 = my_felt252.into();\n" -" let new_felt252: felt252 = new_u16.into();\n" -"\n" -" // Note: usize is smaller than felt252, so we use try_into\n" -" let new_usize: usize = my_felt252.try_into().unwrap();\n" -"```" -msgstr "" -"```cairo\n" -" let a_number: u32 = 15;\n" -" let my_felt252 = 15;\n" -"\n" -" // 由于 u32 可能不匹配 u8 和 u16,我们需要使用 try_into\n" -" // 然后解包返回的 Option 类型。\n" -" let new_u8: u8 = a_number.try_into().unwrap();\n" -" let new_u16: u16 = a_number.try_into().unwrap();\n" -"\n" -" // 由于 new_u32 的类型(u32)与 a_number 相同,我们可以直接赋值\n" -" // 或使用 .into() 方法\n" -" let new_u32: u32 = a_number;\n" -"\n" -" // 当从较小的大小类型强制转换为相等或较大的大小类型时,我们使用 .into() 方" -"法\n" -" // 注意:u64 和 u128 大于 u32,所以 u32 类型将始终适合其中\n" -" let new_u64: u64 = a_number.into();\n" -" let new_u128: u128 = a_number.into();\n" -"\n" -" // 由于 felt252 比 u256 小,我们可以使用 into() 方法\n" -" let new_u256: u256 = my_felt252.into();\n" -" let new_felt252: felt252 = new_u16.into();\n" -"\n" -" //注意,usize 比 felt252 小,因此我们使用 try_into\n" -" let new_usize: usize = my_felt252.try_into().unwrap();\n" -"```" - -#: src/components/how_to.md:1 -msgid "# Components How-To" -msgstr "" - -#: src/components/how_to.md:3 -msgid "" -"Components are like modular addons that can be snapped into contracts to add " -"reusable logic, storage, and events.\n" -"They are used to separate the core logic from common functionalities, " -"simplifying the contract's code and making it easier to read and maintain.\n" -"It also reduces the risk of bugs and vulnerabilities by using well-tested " -"components." -msgstr "" - -#: src/components/how_to.md:7 -msgid "Key characteristics:" -msgstr "" - -#: src/components/how_to.md:8 -msgid "" -"- Modularity: Easily pluggable into multiple contracts.\n" -"- Reusable Logic: Encapsulates specific functionalities.\n" -"- Not Standalone: Cannot be declared or deployed independently." -msgstr "" - -#: src/components/how_to.md:12 -msgid "## How to create a component" -msgstr "" - -#: src/components/how_to.md:14 -msgid "" -"The following example shows a simple `Switch` component that can be used to " -"turn a boolean on or off.\n" -"It contains a storage variable `value`, a function `switch` and an event " -"`Switch`." -msgstr "" - -#: src/components/how_to.md:17 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchComponent {\n" -" fn value(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod switch_component {\n" -" #[storage]\n" -" struct Storage {\n" -" value: bool,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct SwitchEvent {}\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchEvent: SwitchEvent,\n" -" }\n" -"\n" -" #[embeddable_as(Switch)]\n" -" impl SwitchImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ISwitchComponent> {\n" -" fn value(self: @ComponentState) -> bool {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn switch(ref self: ComponentState) {\n" -" self.value.write(!self.value.read());\n" -" self.emit(Event::SwitchEvent(SwitchEvent {}));\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalSwitchImpl<\n" -" TContractState, +HasComponent\n" -" > of InternalSwitchTrait {\n" -" fn _off(ref self: ComponentState) {\n" -" self.value.write(false);\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISwitchComponent {\n" -" fn value(self: @TContractState) -> bool;\n" -" fn switch(ref self: TContractState);\n" -"}\n" -"\n" -"#[starknet::component]\n" -"mod switch_component {\n" -" #[storage]\n" -" struct Storage {\n" -" value: bool,\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct SwitchEvent {}\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchEvent: SwitchEvent,\n" -" }\n" -"\n" -" #[embeddable_as(Switch)]\n" -" impl SwitchImpl<\n" -" TContractState, +HasComponent\n" -" > of super::ISwitchComponent> {\n" -" fn value(self: @ComponentState) -> bool {\n" -" self.value.read()\n" -" }\n" -"\n" -" fn switch(ref self: ComponentState) {\n" -" self.value.write(!self.value.read());\n" -" self.emit(Event::SwitchEvent(SwitchEvent {}));\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalSwitchImpl<\n" -" TContractState, +HasComponent\n" -" > of InternalSwitchTrait {\n" -" fn _off(ref self: ComponentState) {\n" -" self.value.write(false);\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/components/how_to.md:65 -msgid "" -"A component in itself is really similar to a contract, it *can* also have:" -msgstr "" - -#: src/components/how_to.md:66 -msgid "" -"- An interface defining entrypoints (`ISwitchComponent`)\n" -"- A Storage struct\n" -"- Events\n" -"- Internal functions" -msgstr "" - -#: src/components/how_to.md:71 -msgid "" -"It don't have a constructor, but you can create a `_init` internal function " -"and call it from the contract's constructor. In the previous example, the " -"`_off` function is used this way." -msgstr "" - -#: src/components/how_to.md:73 -msgid "## How to use a component" -msgstr "" - -#: src/components/how_to.md:75 -msgid "" -"Now that we have a component, we can use it in a contract.\n" -"The following contract incorporates the `Switch` component:" -msgstr "" - -#: src/components/how_to.md:78 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod SwitchContract {\n" -" use components::switch::switch_component;\n" -" // This is needed to be able to use internal functions of the switch " -"component.\n" -" use components::switch::switch_component::InternalSwitchImpl;\n" -"\n" -" component!(path: switch_component, storage: switch, event: SwitchEvent);\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SwitchImpl = switch_component::Switch;\n" -" impl SwitchInternalImpl = switch_component::" -"InternalSwitchImpl;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" #[substorage(v0)]\n" -" switch: switch_component::Storage,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState) {\n" -" self.switch._off();\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" SwitchEvent: switch_component::Event\n" -" }\n" -"}\n" -"```" -msgstr "" - -#: src/components/how_to.md:110 -msgid "## Deep dive into components" -msgstr "" - -#: src/components/how_to.md:112 -msgid "" -"You can find more in-depth information about components in the [Cairo book - " -"Components](https://book.cairo-lang.org/ch99-01-05-00-components.html)." -msgstr "" - -#: src/applications/upgradeable_contract.md:1 -msgid "# Upgradeable Contract" -msgstr "# 可升级合约" - -#: src/applications/upgradeable_contract.md:3 -msgid "" -"In Starknet, contracts are divided into two parts: contract classes and " -"contract\n" -"instances. This division follows a similar concept used in object-oriented\n" -"programming languages, where we distinguish between the definition and " -"implementation\n" -"of objects." -msgstr "" -"在Starknet中,合约分为两个部分:合约类和合约实例。\n" -"这种划分遵循了面向对象编程语言中的类和实例的概念。\n" -"这样,我们区分了对象的定义和实现。" - -#: src/applications/upgradeable_contract.md:8 -msgid "" -"A contract class is the definition of a contract: it specifies how the " -"contract\n" -"behaves. It contains essential information like the Cairo byte code, hint\n" -"information, entry point names, and everything that defines its semantics\n" -"unambiguously." -msgstr "" -"合约类是合约的定义:它指定了合约的行为方式。\n" -"合约类包含了关键信息,如Cairo字节码、提示信息、入口点名称等,\n" -"以及一切明确定义合约类语义的内容。" - -#: src/applications/upgradeable_contract.md:13 -msgid "" -"To identify different contract classes, Starknet assigns a unique identifier " -"to each\n" -"class: the class hash. A contract instance is a deployed contract that " -"corresponds to\n" -"a specific contract class. Think of it as an instance of an object in " -"languages like\n" -"Java." -msgstr "" -"为了识别不同的合约类,Starknet为每个类分配一个唯一的标识符:类哈希。\n" -"合约实例是对应于特定合约类的已部署合约。\n" -"可以将其视为在诸如Java等语言中对象的一个实例。" - -#: src/applications/upgradeable_contract.md:18 -msgid "" -"Each class is identified by its class hash, which is analogous to a class " -"name in an object-oriented programming language. A contract instance is a " -"deployed contract corresponding to a class." -msgstr "" -"每个类由其类哈希值标识,类似于面向对象编程语言中的类名。合约实例是对应于某个类" -"的已部署合约。" - -#: src/applications/upgradeable_contract.md:20 -msgid "" -"You can upgrade a deployed contract to a newer version by calling the " -"`replace_class_syscall` function. By using this function, you can update the " -"class hash associated with a deployed contract, effectively upgrading its " -"implementation. However, this will not modify the contract's storage, so all " -"the data stored in the contract will remain the same." -msgstr "" -"当调用`replace_class_syscall`函数,你可以将已部署的合约升级到更新的版本。通过" -"使用这个函数,你可以更新与已部署合约相关联的类哈希,从而有效地升级合约的实现。" -"然而,这不会修改合约中的存储,因此合约中存储的所有数据将保持不变。" - -#: src/applications/upgradeable_contract.md:22 -msgid "" -"To illustrate this concept, let's consider an example with two contracts: " -"`UpgradeableContract_V0`, and `UpgradeableContract_V1`.\n" -"Start by deploying `UpgradeableContract_V0` as the initial version. Next, " -"send a transaction that invokes the `upgrade` function, with the class hash " -"of `UpgradeableContract_V1` as parameter to upgrade the class hash of the " -"deployed contract to the `UpgradeableContract_V1` one. Then, call the " -"`version` method on the contract to see that the contract was upgraded to the " -"V1 version." -msgstr "" -"为了说明这个概念,让我们以两个合约为例:`UpgradeableContract_V0`和" -"`UpgradeableContract_V1`。\n" -"首先,部署`UpgradeableContract_V0`作为初始版本。接下来,发送一个调用`upgrade`" -"函数的交易,将部署合约的类哈希升级为`UpgradeableContract_V1`的类哈希。然后,调" -"用合约上的`version`方法,查看合约是否已升级到V1版本。" - -#: src/applications/upgradeable_contract.md:25 -msgid "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V0 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract {\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 0\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V0 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract {\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 0\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/upgradeable_contract.md:68 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x005300003ade5d10447d941a42d48b7141074cd8bade2b16520684896a5090ea) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v0.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x005300003ade5d10447d941a42d48b7141074cd8bade2b16520684896a5090ea) " -"上访问合约或在[Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v0.cairo)中尝试它 。" - -#: src/applications/upgradeable_contract.md:71 -msgid "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V1 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract {\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 1\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::class_hash::ClassHash;\n" -"\n" -"#[starknet::interface]\n" -"trait IUpgradeableContract {\n" -" fn upgrade(ref self: TContractState, impl_hash: ClassHash);\n" -" fn version(self: @TContractState) -> u8;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod UpgradeableContract_V1 {\n" -" use starknet::class_hash::ClassHash;\n" -" use starknet::SyscallResultTrait;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Upgraded: Upgraded\n" -" }\n" -"\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Upgraded {\n" -" implementation: ClassHash\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl UpgradeableContract of super::IUpgradeableContract {\n" -" fn upgrade(ref self: ContractState, impl_hash: ClassHash) {\n" -" assert(impl_hash.is_non_zero(), 'Class hash cannot be zero');\n" -" starknet::replace_class_syscall(impl_hash).unwrap_syscall();\n" -" self.emit(Event::Upgraded(Upgraded { implementation: " -"impl_hash }))\n" -" }\n" -"\n" -" fn version(self: @ContractState) -> u8 {\n" -" 1\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/upgradeable_contract.md:114 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x017c86152badd1d665b9836571bd6b0a484f028748aa13d9b2d5d9c9192fafc6) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v1.cairo)." -msgstr "" -"在 [Voyager](https://goerli.voyager.online/" -"contract/0x017c86152badd1d665b9836571bd6b0a484f028748aa13d9b2d5d9c9192fafc6) " -"上访问合约或在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/upgradeable_contract/src/" -"upgradeable_contract_v1.cairo) 中尝试它。" - -#: src/applications/simple_vault.md:1 -msgid "# Simple Defi Vault" -msgstr "# 简单的去中心化金融保险库" - -#: src/applications/simple_vault.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example Vault](https://" -"solidity-by-example.org/defi/vault/).\n" -"Here's how it works:" -msgstr "" -"这是 [Solidity by example Vault](https://solidity-by-example.org/defi/vault/) " -"的Cairo版本\n" -"以下是它的工作原理:" - -#: src/applications/simple_vault.md:6 -msgid "" -"- When a user deposits a token, the contract calculates the amount of shares " -"to mint.\n" -"\n" -"- When a user withdraws, the contract burns their shares, calculates the " -"yield, and withdraw both the yield and the initial amount of token deposited." -msgstr "" -"- 当用户存入代笔时,合约会计算要铸造的份额数量。\n" -"\n" -"- 当用户取款时,合约会销毁他们的份额,计算收益,并提取存款的收益和初始代币金" -"额。" - -#: src/applications/simple_vault.md:10 -msgid "" -"```cairo\n" -"use starknet::{ContractAddress};\n" -"\n" -"// In order to make contract calls within our Vault,\n" -"// we need to have the interface of the remote ERC20 contract defined to " -"import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn name(self: @TContractState) -> felt252;\n" -" fn symbol(self: @TContractState) -> felt252;\n" -" fn decimals(self: @TContractState) -> u8;\n" -" fn total_supply(self: @TContractState) -> u256;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> u256;\n" -" fn allowance(self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress) -> u256;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, amount: " -"u256) -> bool;\n" -" fn transfer_from(\n" -" ref self: TContractState, sender: ContractAddress, recipient: " -"ContractAddress, amount: u256\n" -" ) -> bool;\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"u256) -> bool;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleVault {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, shares: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleVault {\n" -" use super::{IERC20Dispatcher, IERC20DispatcherTrait};\n" -" use starknet::{ContractAddress, get_caller_address, " -"get_contract_address};\n" -" #[storage]\n" -" struct Storage {\n" -" token: IERC20Dispatcher,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, token: ContractAddress) {\n" -" self.token.write(IERC20Dispatcher { contract_address: token });\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, shares: u256) " -"{\n" -" self.total_supply.write(self.total_supply.read() + shares);\n" -" self.balance_of.write(to, self.balance_of.read(to) + shares);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, shares: " -"u256) {\n" -" self.total_supply.write(self.total_supply.read() - shares);\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"shares);\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleVault of super::ISimpleVault {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" // a = amount\n" -" // B = balance of token before deposit\n" -" // T = total supply\n" -" // s = shares to mint\n" -" //\n" -" // (T + s) / T = (a + B) / B \n" -" //\n" -" // s = aT / B\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let mut shares = 0;\n" -" if self.total_supply.read() == 0 {\n" -" shares = amount;\n" -" } else {\n" -" let balance = self.token.read().balance_of(this);\n" -" shares = (amount * self.total_supply.read()) / balance;\n" -" }\n" -"\n" -" PrivateFunctions::_mint(ref self, caller, shares);\n" -" self.token.read().transfer_from(caller, this, amount);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, shares: u256) {\n" -" // a = amount\n" -" // B = balance of token before withdraw\n" -" // T = total supply\n" -" // s = shares to burn\n" -" //\n" -" // (T - s) / T = (B - a) / B \n" -" //\n" -" // a = sB / T\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let balance = self.token.read().balance_of(this);\n" -" let amount = (shares * balance) / self.total_supply.read();\n" -" PrivateFunctions::_burn(ref self, caller, shares);\n" -" self.token.read().transfer(caller, amount);\n" -" }\n" -" }\n" -"}\n" -"\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::{ContractAddress};\n" -"\n" -"// In order to make contract calls within our Vault,\n" -"// we need to have the interface of the remote ERC20 contract defined to " -"import the Dispatcher.\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn name(self: @TContractState) -> felt252;\n" -" fn symbol(self: @TContractState) -> felt252;\n" -" fn decimals(self: @TContractState) -> u8;\n" -" fn total_supply(self: @TContractState) -> u256;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> u256;\n" -" fn allowance(self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress) -> u256;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, amount: " -"u256) -> bool;\n" -" fn transfer_from(\n" -" ref self: TContractState, sender: ContractAddress, recipient: " -"ContractAddress, amount: u256\n" -" ) -> bool;\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"u256) -> bool;\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait ISimpleVault {\n" -" fn deposit(ref self: TContractState, amount: u256);\n" -" fn withdraw(ref self: TContractState, shares: u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod SimpleVault {\n" -" use super::{IERC20Dispatcher, IERC20DispatcherTrait};\n" -" use starknet::{ContractAddress, get_caller_address, " -"get_contract_address};\n" -" #[storage]\n" -" struct Storage {\n" -" token: IERC20Dispatcher,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(ref self: ContractState, token: ContractAddress) {\n" -" self.token.write(IERC20Dispatcher { contract_address: token });\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, shares: u256) " -"{\n" -" self.total_supply.write(self.total_supply.read() + shares);\n" -" self.balance_of.write(to, self.balance_of.read(to) + shares);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, shares: " -"u256) {\n" -" self.total_supply.write(self.total_supply.read() - shares);\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"shares);\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SimpleVault of super::ISimpleVault {\n" -" fn deposit(ref self: ContractState, amount: u256) {\n" -" // a = amount\n" -" // B = balance of token before deposit\n" -" // T = total supply\n" -" // s = shares to mint\n" -" //\n" -" // (T + s) / T = (a + B) / B \n" -" //\n" -" // s = aT / B\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let mut shares = 0;\n" -" if self.total_supply.read() == 0 {\n" -" shares = amount;\n" -" } else {\n" -" let balance = self.token.read().balance_of(this);\n" -" shares = (amount * self.total_supply.read()) / balance;\n" -" }\n" -"\n" -" PrivateFunctions::_mint(ref self, caller, shares);\n" -" self.token.read().transfer_from(caller, this, amount);\n" -" }\n" -"\n" -" fn withdraw(ref self: ContractState, shares: u256) {\n" -" // a = amount\n" -" // B = balance of token before withdraw\n" -" // T = total supply\n" -" // s = shares to burn\n" -" //\n" -" // (T - s) / T = (B - a) / B \n" -" //\n" -" // a = sB / T\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -"\n" -" let balance = self.token.read().balance_of(this);\n" -" let amount = (shares * balance) / self.total_supply.read();\n" -" PrivateFunctions::_burn(ref self, caller, shares);\n" -" self.token.read().transfer(caller, amount);\n" -" }\n" -" }\n" -"}\n" -"\n" -"```" - -#: src/applications/simple_vault.md:113 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/simple_vault/src/simple_vault.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/applications/" -"simple_vault/src/simple_vault.cairo) 中测试这个合约。" - -#: src/applications/erc20.md:1 -msgid "# ERC20 Token" -msgstr "# ERC20 代币" - -#: src/applications/erc20.md:3 -msgid "" -"Contracts that follow the [ERC20 Standard](https://eips.ethereum.org/EIPS/" -"eip-20) are called ERC20 tokens. They are used to represent fungible assets." -msgstr "" -"遵循 [ERC20 Standard](https://eips.ethereum.org/EIPS/eip-20) 的合约被称为 " -"ERC20 代币。它们用于代表可互换的资产。" - -#: src/applications/erc20.md:5 -msgid "To create an ERC20 conctract, it must implement the following interface:" -msgstr "要创建 ERC20 合约,必须实现以下接口:" - -#: src/applications/erc20.md:7 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn get_name(self: @TContractState) -> felt252;\n" -" fn get_symbol(self: @TContractState) -> felt252;\n" -" fn get_decimals(self: @TContractState) -> u8;\n" -" fn get_total_supply(self: @TContractState) -> felt252;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> " -"felt252;\n" -" fn allowance(\n" -" self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, amount: " -"felt252);\n" -" fn transfer_from(\n" -" ref self: TContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" );\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"felt252);\n" -" fn increase_allowance(ref self: TContractState, spender: ContractAddress, " -"added_value: felt252);\n" -" fn decrease_allowance(\n" -" ref self: TContractState, spender: ContractAddress, subtracted_value: " -"felt252\n" -" );\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IERC20 {\n" -" fn get_name(self: @TContractState) -> felt252;\n" -" fn get_symbol(self: @TContractState) -> felt252;\n" -" fn get_decimals(self: @TContractState) -> u8;\n" -" fn get_total_supply(self: @TContractState) -> felt252;\n" -" fn balance_of(self: @TContractState, account: ContractAddress) -> " -"felt252;\n" -" fn allowance(\n" -" self: @TContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252;\n" -" fn transfer(ref self: TContractState, recipient: ContractAddress, amount: " -"felt252);\n" -" fn transfer_from(\n" -" ref self: TContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" );\n" -" fn approve(ref self: TContractState, spender: ContractAddress, amount: " -"felt252);\n" -" fn increase_allowance(ref self: TContractState, spender: ContractAddress, " -"added_value: felt252);\n" -" fn decrease_allowance(\n" -" ref self: TContractState, spender: ContractAddress, subtracted_value: " -"felt252\n" -" );\n" -"}\n" -"```" - -#: src/applications/erc20.md:33 -msgid "" -"In Starknet, function names should be written in *snake_case*. This is not " -"the case in Solidity, where function names are written in *camelCase*.\n" -"The Starknet ERC20 interface is therefore slightly different from the " -"Solidity ERC20 interface." -msgstr "" -"在Starknet中,函数名应该使用*snake_case*(蛇形命名法)。而在Solidity中,函数名" -"使用*camelCase*(驼峰命名法)。因此,Starknet的ERC20接口与Solidity的ERC20接口" -"略有不同。" - -#: src/applications/erc20.md:36 -msgid "Here's an implementation of the ERC20 interface in Cairo:" -msgstr "以下是一个在Cairo中实现的ERC20接口的示例:" - -#: src/applications/erc20.md:38 -msgid "" -"```cairo\n" -"#[starknet::contract]\n" -"mod erc20 {\n" -" use zeroable::Zeroable;\n" -" use starknet::get_caller_address;\n" -" use starknet::contract_address_const;\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" name: felt252,\n" -" symbol: felt252,\n" -" decimals: u8,\n" -" total_supply: felt252,\n" -" balances: LegacyMap::,\n" -" allowances: LegacyMap::<(ContractAddress, ContractAddress), " -"felt252>,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Transfer: Transfer,\n" -" Approval: Approval,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Transfer {\n" -" from: ContractAddress,\n" -" to: ContractAddress,\n" -" value: felt252,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Approval {\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" value: felt252,\n" -" }\n" -"\n" -" mod Errors {\n" -" const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0';\n" -" const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0';\n" -" const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0';\n" -" const TRANSFER_TO_ZERO: felt252 = 'ERC20: transfer to 0';\n" -" const BURN_FROM_ZERO: felt252 = 'ERC20: burn from 0';\n" -" const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0';\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState,\n" -" recipient: ContractAddress,\n" -" name: felt252,\n" -" decimals: u8,\n" -" initial_supply: felt252,\n" -" symbol: felt252\n" -" ) {\n" -" self.name.write(name);\n" -" self.symbol.write(symbol);\n" -" self.decimals.write(decimals);\n" -" self.mint(recipient, initial_supply);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl IERC20Impl of super::IERC20 {\n" -" fn get_name(self: @ContractState) -> felt252 {\n" -" self.name.read()\n" -" }\n" -"\n" -" fn get_symbol(self: @ContractState) -> felt252 {\n" -" self.symbol.read()\n" -" }\n" -"\n" -" fn get_decimals(self: @ContractState) -> u8 {\n" -" self.decimals.read()\n" -" }\n" -"\n" -" fn get_total_supply(self: @ContractState) -> felt252 {\n" -" self.total_supply.read()\n" -" }\n" -"\n" -" fn balance_of(self: @ContractState, account: ContractAddress) -> " -"felt252 {\n" -" self.balances.read(account)\n" -" }\n" -"\n" -" fn allowance(\n" -" self: @ContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252 {\n" -" self.allowances.read((owner, spender))\n" -" }\n" -"\n" -" fn transfer(ref self: ContractState, recipient: ContractAddress, " -"amount: felt252) {\n" -" let sender = get_caller_address();\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn transfer_from(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self.spend_allowance(sender, caller, amount);\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn approve(ref self: ContractState, spender: ContractAddress, amount: " -"felt252) {\n" -" let caller = get_caller_address();\n" -" self.approve_helper(caller, spender, amount);\n" -" }\n" -"\n" -" fn increase_allowance(\n" -" ref self: ContractState, spender: ContractAddress, added_value: " -"felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"+ added_value\n" -" );\n" -" }\n" -"\n" -" fn decrease_allowance(\n" -" ref self: ContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"- subtracted_value\n" -" );\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalImpl of InternalTrait {\n" -" fn _transfer(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(sender.is_non_zero(), Errors::TRANSFER_FROM_ZERO);\n" -" assert(recipient.is_non_zero(), Errors::TRANSFER_TO_ZERO);\n" -" self.balances.write(sender, self.balances.read(sender) - " -"amount);\n" -" self.balances.write(recipient, self.balances.read(recipient) + " -"amount);\n" -" self.emit(Transfer { from: sender, to: recipient, value: " -"amount });\n" -" }\n" -"\n" -" fn spend_allowance(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let allowance = self.allowances.read((owner, spender));\n" -" self.allowances.write((owner, spender), allowance - amount);\n" -" }\n" -"\n" -" fn approve_helper(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(spender.is_non_zero(), Errors::APPROVE_TO_ZERO);\n" -" self.allowances.write((owner, spender), amount);\n" -" self.emit(Approval { owner, spender, value: amount });\n" -" }\n" -"\n" -" fn mint(ref self: ContractState, recipient: ContractAddress, amount: " -"felt252) {\n" -" assert(recipient.is_non_zero(), Errors::MINT_TO_ZERO);\n" -" let supply = self.total_supply.read() + amount; // What can go " -"wrong here?\n" -" self.total_supply.write(supply);\n" -" let balance = self.balances.read(recipient) + amount;\n" -" self.balances.write(recipient, amount);\n" -" self\n" -" .emit(\n" -" Event::Transfer(\n" -" Transfer {\n" -" from: contract_address_const::<0>(), to: " -"recipient, value: amount\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::contract]\n" -"mod erc20 {\n" -" use zeroable::Zeroable;\n" -" use starknet::get_caller_address;\n" -" use starknet::contract_address_const;\n" -" use starknet::ContractAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" name: felt252,\n" -" symbol: felt252,\n" -" decimals: u8,\n" -" total_supply: felt252,\n" -" balances: LegacyMap::,\n" -" allowances: LegacyMap::<(ContractAddress, ContractAddress), " -"felt252>,\n" -" }\n" -"\n" -" #[event]\n" -" #[derive(Drop, starknet::Event)]\n" -" enum Event {\n" -" Transfer: Transfer,\n" -" Approval: Approval,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Transfer {\n" -" from: ContractAddress,\n" -" to: ContractAddress,\n" -" value: felt252,\n" -" }\n" -" #[derive(Drop, starknet::Event)]\n" -" struct Approval {\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" value: felt252,\n" -" }\n" -"\n" -" mod Errors {\n" -" const APPROVE_FROM_ZERO: felt252 = 'ERC20: approve from 0';\n" -" const APPROVE_TO_ZERO: felt252 = 'ERC20: approve to 0';\n" -" const TRANSFER_FROM_ZERO: felt252 = 'ERC20: transfer from 0';\n" -" const TRANSFER_TO_ZERO: felt252 = 'ERC20: transfer to 0';\n" -" const BURN_FROM_ZERO: felt252 = 'ERC20: burn from 0';\n" -" const MINT_TO_ZERO: felt252 = 'ERC20: mint to 0';\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState,\n" -" recipient: ContractAddress,\n" -" name: felt252,\n" -" decimals: u8,\n" -" initial_supply: felt252,\n" -" symbol: felt252\n" -" ) {\n" -" self.name.write(name);\n" -" self.symbol.write(symbol);\n" -" self.decimals.write(decimals);\n" -" self.mint(recipient, initial_supply);\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl IERC20Impl of super::IERC20 {\n" -" fn get_name(self: @ContractState) -> felt252 {\n" -" self.name.read()\n" -" }\n" -"\n" -" fn get_symbol(self: @ContractState) -> felt252 {\n" -" self.symbol.read()\n" -" }\n" -"\n" -" fn get_decimals(self: @ContractState) -> u8 {\n" -" self.decimals.read()\n" -" }\n" -"\n" -" fn get_total_supply(self: @ContractState) -> felt252 {\n" -" self.total_supply.read()\n" -" }\n" -"\n" -" fn balance_of(self: @ContractState, account: ContractAddress) -> " -"felt252 {\n" -" self.balances.read(account)\n" -" }\n" -"\n" -" fn allowance(\n" -" self: @ContractState, owner: ContractAddress, spender: " -"ContractAddress\n" -" ) -> felt252 {\n" -" self.allowances.read((owner, spender))\n" -" }\n" -"\n" -" fn transfer(ref self: ContractState, recipient: ContractAddress, " -"amount: felt252) {\n" -" let sender = get_caller_address();\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn transfer_from(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self.spend_allowance(sender, caller, amount);\n" -" self._transfer(sender, recipient, amount);\n" -" }\n" -"\n" -" fn approve(ref self: ContractState, spender: ContractAddress, amount: " -"felt252) {\n" -" let caller = get_caller_address();\n" -" self.approve_helper(caller, spender, amount);\n" -" }\n" -"\n" -" fn increase_allowance(\n" -" ref self: ContractState, spender: ContractAddress, added_value: " -"felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"+ added_value\n" -" );\n" -" }\n" -"\n" -" fn decrease_allowance(\n" -" ref self: ContractState, spender: ContractAddress, " -"subtracted_value: felt252\n" -" ) {\n" -" let caller = get_caller_address();\n" -" self\n" -" .approve_helper(\n" -" caller, spender, self.allowances.read((caller, spender)) " -"- subtracted_value\n" -" );\n" -" }\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl InternalImpl of InternalTrait {\n" -" fn _transfer(\n" -" ref self: ContractState,\n" -" sender: ContractAddress,\n" -" recipient: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(sender.is_non_zero(), Errors::TRANSFER_FROM_ZERO);\n" -" assert(recipient.is_non_zero(), Errors::TRANSFER_TO_ZERO);\n" -" self.balances.write(sender, self.balances.read(sender) - " -"amount);\n" -" self.balances.write(recipient, self.balances.read(recipient) + " -"amount);\n" -" self.emit(Transfer { from: sender, to: recipient, value: " -"amount });\n" -" }\n" -"\n" -" fn spend_allowance(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" let allowance = self.allowances.read((owner, spender));\n" -" self.allowances.write((owner, spender), allowance - amount);\n" -" }\n" -"\n" -" fn approve_helper(\n" -" ref self: ContractState,\n" -" owner: ContractAddress,\n" -" spender: ContractAddress,\n" -" amount: felt252\n" -" ) {\n" -" assert(spender.is_non_zero(), Errors::APPROVE_TO_ZERO);\n" -" self.allowances.write((owner, spender), amount);\n" -" self.emit(Approval { owner, spender, value: amount });\n" -" }\n" -"\n" -" fn mint(ref self: ContractState, recipient: ContractAddress, amount: " -"felt252) {\n" -" assert(recipient.is_non_zero(), Errors::MINT_TO_ZERO);\n" -" let supply = self.total_supply.read() + amount; // What can go " -"wrong here?\n" -" self.total_supply.write(supply);\n" -" let balance = self.balances.read(recipient) + amount;\n" -" self.balances.write(recipient, amount);\n" -" self\n" -" .emit(\n" -" Event::Transfer(\n" -" Transfer {\n" -" from: contract_address_const::<0>(), to: " -"recipient, value: amount\n" -" }\n" -" )\n" -" );\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/erc20.md:224 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/erc20/src/token.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/applications/erc20/src/" -"token.cairo) 中测试这个合约。" - -#: src/applications/erc20.md:226 -msgid "" -"There's several other implementations, such as the [Open Zeppelin](https://" -"docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the [Cairo By Example]" -"(https://cairo-by-example.com/examples/erc20/) ones." -msgstr "" -"还有一些其他的实现,比如 [Open Zeppelin](https://docs.openzeppelin.com/" -"contracts-cairo/0.7.0/erc20) 或者 [Cairo By Example](https://cairo-by-example." -"com/examples/erc20/) 中的实现。" - -#: src/applications/constant-product-amm.md:1 -msgid "# Constant Product AMM" -msgstr "# 恒定乘积自动做市商" - -#: src/applications/constant-product-amm.md:3 -msgid "" -"This is the Cairo adaptation of the [Solidity by example Constant Product AMM]" -"(https://solidity-by-example.org/defi/constant-product-amm/)." -msgstr "" -"这个是 用Cairo 改编的 [Solidity by example Constant Product AMM](https://" -"solidity-by-example.org/defi/constant-product-amm/)." - -#: src/applications/constant-product-amm.md:5 -msgid "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IConstantProductAmm {\n" -" fn swap(ref self: TContractState, token_in: ContractAddress, amount_in: " -"u256) -> u256;\n" -" fn add_liquidity(ref self: TContractState, amount0: u256, amount1: u256) -" -"> u256;\n" -" fn remove_liquidity(ref self: TContractState, shares: u256) -> (u256, " -"u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ConstantProductAmm {\n" -" use core::traits::Into;\n" -" use openzeppelin::token::erc20::interface::{IERC20Dispatcher, " -"IERC20DispatcherTrait};\n" -" use starknet::{\n" -" ContractAddress, get_caller_address, get_contract_address, " -"contract_address_const\n" -" };\n" -" use integer::u256_sqrt;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" token0: IERC20Dispatcher,\n" -" token1: IERC20Dispatcher,\n" -" reserve0: u256,\n" -" reserve1: u256,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap::,\n" -" // Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -" // E.g. 3 = 0.3%\n" -" fee: u16,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState, token0: ContractAddress, token1: " -"ContractAddress, fee: u16\n" -" ) {\n" -" // assert(fee <= 1000, 'fee > 1000');\n" -" self.token0.write(IERC20Dispatcher { contract_address: token0 });\n" -" self.token1.write(IERC20Dispatcher { contract_address: token1 });\n" -" self.fee.write(fee);\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, amount: u256) " -"{\n" -" self.balance_of.write(to, self.balance_of.read(to) + amount);\n" -" self.total_supply.write(self.total_supply.read() + amount);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, amount: " -"u256) {\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"amount);\n" -" self.total_supply.write(self.total_supply.read() - amount);\n" -" }\n" -"\n" -" fn _update(ref self: ContractState, reserve0: u256, reserve1: u256) " -"{\n" -" self.reserve0.write(reserve0);\n" -" self.reserve1.write(reserve1);\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn select_token(self: @ContractState, token: ContractAddress) -> bool " -"{\n" -" assert(\n" -" token == self.token0.read().contract_address\n" -" || token == self.token1.read().contract_address,\n" -" 'invalid token'\n" -" );\n" -" token == self.token0.read().contract_address\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn min(x: u256, y: u256) -> u256 {\n" -" if (x <= y) {\n" -" x\n" -" } else {\n" -" y\n" -" }\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ConstantProductAmm of super::IConstantProductAmm {\n" -" fn swap(ref self: ContractState, token_in: ContractAddress, " -"amount_in: u256) -> u256 {\n" -" assert(amount_in > 0, 'amount in = 0');\n" -" let is_token0: bool = self.select_token(token_in);\n" -"\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" let (\n" -" token_in, token_out, reserve_in, reserve_out\n" -" ): (IERC20Dispatcher, IERC20Dispatcher, u256, u256) =\n" -" if (is_token0) {\n" -" (token0, token1, reserve0, reserve1)\n" -" } else {\n" -" (token1, token0, reserve1, reserve0)\n" -" };\n" -"\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" token_in.transfer_from(caller, this, amount_in);\n" -"\n" -" // How much dy for dx?\n" -" // xy = k\n" -" // (x + dx)(y - dy) = k\n" -" // y - dy = k / (x + dx)\n" -" // y - k / (x + dx) = dy\n" -" // y - xy / (x + dx) = dy\n" -" // (yx + ydx - xy) / (x + dx) = dy\n" -" // ydx / (x + dx) = dy\n" -"\n" -" let amount_in_with_fee = (amount_in * (1000 - self.fee.read()." -"into()) / 1000);\n" -" let amount_out = (reserve_out * amount_in_with_fee) / (reserve_in " -"+ amount_in_with_fee);\n" -"\n" -" token_out.transfer(caller, amount_out);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" amount_out\n" -" }\n" -"\n" -" fn add_liquidity(ref self: ContractState, amount0: u256, amount1: " -"u256) -> u256 {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" token0.transfer_from(caller, this, amount0);\n" -" token1.transfer_from(caller, this, amount1);\n" -"\n" -" // How much dx, dy to add?\n" -" //\n" -" // xy = k\n" -" // (x + dx)(y + dy) = k'\n" -" //\n" -" // No price change, before and after adding liquidity\n" -" // x / y = (x + dx) / (y + dy)\n" -" //\n" -" // x(y + dy) = y(x + dx)\n" -" // x * dy = y * dx\n" -" //\n" -" // x / y = dx / dy\n" -" // dy = y / x * dx\n" -"\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" if (reserve0 > 0 || reserve1 > 0) {\n" -" assert(reserve0 * amount1 == reserve1 * amount0, 'x / y != " -"dx / dy');\n" -" }\n" -"\n" -" // How much shares to mint?\n" -" //\n" -" // f(x, y) = value of liquidity\n" -" // We will define f(x, y) = sqrt(xy)\n" -" //\n" -" // L0 = f(x, y)\n" -" // L1 = f(x + dx, y + dy)\n" -" // T = total shares\n" -" // s = shares to mint\n" -" //\n" -" // Total shares should increase proportional to increase in " -"liquidity\n" -" // L1 / L0 = (T + s) / T\n" -" //\n" -" // L1 * T = L0 * (T + s)\n" -" //\n" -" // (L1 - L0) * T / L0 = s\n" -"\n" -" // Claim\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -" //\n" -" // Proof\n" -" // --- Equation 1 ---\n" -" // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // dx / dy = x / y so replace dy = dx * y / x\n" -" //\n" -" // --- Equation 2 ---\n" -" // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // Multiply by sqrt(x) / sqrt(x)\n" -" // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - sqrt(x^2y)) / " -"sqrt(x^2y)\n" -" // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(y)sqrt(x^2))\n" -" // sqrt(y) on top and bottom cancels out\n" -" //\n" -" // --- Equation 3 ---\n" -" // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(x^2)\n" -" // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -" // = ((x + dx) - x) / x\n" -" // = dx / x\n" -" // Since dx / dy = x / y,\n" -" // dx / x = dy / y\n" -" //\n" -" // Finally\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let shares = if (total_supply == 0) {\n" -" u256_sqrt(amount0 * amount1).into()\n" -" } else {\n" -" PrivateFunctions::min(\n" -" amount0 * total_supply / reserve0, amount1 * " -"total_supply / reserve1\n" -" )\n" -" };\n" -" assert(shares > 0, 'shares = 0');\n" -" self._mint(caller, shares);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" shares\n" -" }\n" -"\n" -" fn remove_liquidity(ref self: ContractState, shares: u256) -> (u256, " -"u256) {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" // Claim\n" -" // dx, dy = amount of liquidity to remove\n" -" // dx = s / T * x\n" -" // dy = s / T * y\n" -" //\n" -" // Proof\n" -" // Let's find dx, dy such that\n" -" // v / L = s / T\n" -" //\n" -" // where\n" -" // v = f(dx, dy) = sqrt(dxdy)\n" -" // L = total liquidity = sqrt(xy)\n" -" // s = shares\n" -" // T = total supply\n" -" //\n" -" // --- Equation 1 ---\n" -" // v = s / T * L\n" -" // sqrt(dxdy) = s / T * sqrt(xy)\n" -" //\n" -" // Amount of liquidity to remove must not change price so\n" -" // dx / dy = x / y\n" -" //\n" -" // replace dy = dx * y / x\n" -" // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -" //\n" -" // Divide both sides of Equation 1 with sqrt(y / x)\n" -" // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -" // = s / T * sqrt(x^2) = s / T * x\n" -" //\n" -" // Likewise\n" -" // dy = s / T * y\n" -"\n" -" // bal0 >= reserve0\n" -" // bal1 >= reserve1\n" -" let (bal0, bal1): (u256, u256) = (token0.balance_of(this), token1." -"balance_of(this));\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let (amount0, amount1): (u256, u256) = (\n" -" (shares * bal0) / total_supply, (shares * bal1) / " -"total_supply\n" -" );\n" -" assert(amount0 > 0 && amount1 > 0, 'amount0 or amount1 = 0');\n" -"\n" -" self._burn(caller, shares);\n" -" self._update(bal0 - amount0, bal1 - amount1);\n" -"\n" -" token0.transfer(caller, amount0);\n" -" token1.transfer(caller, amount1);\n" -" (amount0, amount1)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"use starknet::ContractAddress;\n" -"\n" -"#[starknet::interface]\n" -"trait IConstantProductAmm {\n" -" fn swap(ref self: TContractState, token_in: ContractAddress, amount_in: " -"u256) -> u256;\n" -" fn add_liquidity(ref self: TContractState, amount0: u256, amount1: u256) -" -"> u256;\n" -" fn remove_liquidity(ref self: TContractState, shares: u256) -> (u256, " -"u256);\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ConstantProductAmm {\n" -" use core::traits::Into;\n" -" use openzeppelin::token::erc20::interface::{IERC20Dispatcher, " -"IERC20DispatcherTrait};\n" -" use starknet::{\n" -" ContractAddress, get_caller_address, get_contract_address, " -"contract_address_const\n" -" };\n" -" use integer::u256_sqrt;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" token0: IERC20Dispatcher,\n" -" token1: IERC20Dispatcher,\n" -" reserve0: u256,\n" -" reserve1: u256,\n" -" total_supply: u256,\n" -" balance_of: LegacyMap::,\n" -" // Fee 0 - 1000 (0% - 100%, 1 decimal places)\n" -" // E.g. 3 = 0.3%\n" -" fee: u16,\n" -" }\n" -"\n" -" #[constructor]\n" -" fn constructor(\n" -" ref self: ContractState, token0: ContractAddress, token1: " -"ContractAddress, fee: u16\n" -" ) {\n" -" // assert(fee <= 1000, 'fee > 1000');\n" -" self.token0.write(IERC20Dispatcher { contract_address: token0 });\n" -" self.token1.write(IERC20Dispatcher { contract_address: token1 });\n" -" self.fee.write(fee);\n" -" }\n" -"\n" -" #[generate_trait]\n" -" impl PrivateFunctions of PrivateFunctionsTrait {\n" -" fn _mint(ref self: ContractState, to: ContractAddress, amount: u256) " -"{\n" -" self.balance_of.write(to, self.balance_of.read(to) + amount);\n" -" self.total_supply.write(self.total_supply.read() + amount);\n" -" }\n" -"\n" -" fn _burn(ref self: ContractState, from: ContractAddress, amount: " -"u256) {\n" -" self.balance_of.write(from, self.balance_of.read(from) - " -"amount);\n" -" self.total_supply.write(self.total_supply.read() - amount);\n" -" }\n" -"\n" -" fn _update(ref self: ContractState, reserve0: u256, reserve1: u256) " -"{\n" -" self.reserve0.write(reserve0);\n" -" self.reserve1.write(reserve1);\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn select_token(self: @ContractState, token: ContractAddress) -> bool " -"{\n" -" assert(\n" -" token == self.token0.read().contract_address\n" -" || token == self.token1.read().contract_address,\n" -" 'invalid token'\n" -" );\n" -" token == self.token0.read().contract_address\n" -" }\n" -"\n" -" #[inline(always)]\n" -" fn min(x: u256, y: u256) -> u256 {\n" -" if (x <= y) {\n" -" x\n" -" } else {\n" -" y\n" -" }\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ConstantProductAmm of super::IConstantProductAmm {\n" -" fn swap(ref self: ContractState, token_in: ContractAddress, " -"amount_in: u256) -> u256 {\n" -" assert(amount_in > 0, 'amount in = 0');\n" -" let is_token0: bool = self.select_token(token_in);\n" -"\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" let (\n" -" token_in, token_out, reserve_in, reserve_out\n" -" ): (IERC20Dispatcher, IERC20Dispatcher, u256, u256) =\n" -" if (is_token0) {\n" -" (token0, token1, reserve0, reserve1)\n" -" } else {\n" -" (token1, token0, reserve1, reserve0)\n" -" };\n" -"\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" token_in.transfer_from(caller, this, amount_in);\n" -"\n" -" // How much dy for dx?\n" -" // xy = k\n" -" // (x + dx)(y - dy) = k\n" -" // y - dy = k / (x + dx)\n" -" // y - k / (x + dx) = dy\n" -" // y - xy / (x + dx) = dy\n" -" // (yx + ydx - xy) / (x + dx) = dy\n" -" // ydx / (x + dx) = dy\n" -"\n" -" let amount_in_with_fee = (amount_in * (1000 - self.fee.read()." -"into()) / 1000);\n" -" let amount_out = (reserve_out * amount_in_with_fee) / (reserve_in " -"+ amount_in_with_fee);\n" -"\n" -" token_out.transfer(caller, amount_out);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" amount_out\n" -" }\n" -"\n" -" fn add_liquidity(ref self: ContractState, amount0: u256, amount1: " -"u256) -> u256 {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" token0.transfer_from(caller, this, amount0);\n" -" token1.transfer_from(caller, this, amount1);\n" -"\n" -" // How much dx, dy to add?\n" -" //\n" -" // xy = k\n" -" // (x + dx)(y + dy) = k'\n" -" //\n" -" // No price change, before and after adding liquidity\n" -" // x / y = (x + dx) / (y + dy)\n" -" //\n" -" // x(y + dy) = y(x + dx)\n" -" // x * dy = y * dx\n" -" //\n" -" // x / y = dx / dy\n" -" // dy = y / x * dx\n" -"\n" -" let (reserve0, reserve1): (u256, u256) = (self.reserve0.read(), " -"self.reserve1.read());\n" -" if (reserve0 > 0 || reserve1 > 0) {\n" -" assert(reserve0 * amount1 == reserve1 * amount0, 'x / y != " -"dx / dy');\n" -" }\n" -"\n" -" // How much shares to mint?\n" -" //\n" -" // f(x, y) = value of liquidity\n" -" // We will define f(x, y) = sqrt(xy)\n" -" //\n" -" // L0 = f(x, y)\n" -" // L1 = f(x + dx, y + dy)\n" -" // T = total shares\n" -" // s = shares to mint\n" -" //\n" -" // Total shares should increase proportional to increase in " -"liquidity\n" -" // L1 / L0 = (T + s) / T\n" -" //\n" -" // L1 * T = L0 * (T + s)\n" -" //\n" -" // (L1 - L0) * T / L0 = s\n" -"\n" -" // Claim\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -" //\n" -" // Proof\n" -" // --- Equation 1 ---\n" -" // (L1 - L0) / L0 = (sqrt((x + dx)(y + dy)) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // dx / dy = x / y so replace dy = dx * y / x\n" -" //\n" -" // --- Equation 2 ---\n" -" // Equation 1 = (sqrt(xy + 2ydx + dx^2 * y / x) - sqrt(xy)) / " -"sqrt(xy)\n" -" //\n" -" // Multiply by sqrt(x) / sqrt(x)\n" -" // Equation 2 = (sqrt(x^2y + 2xydx + dx^2 * y) - sqrt(x^2y)) / " -"sqrt(x^2y)\n" -" // = (sqrt(y)(sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(y)sqrt(x^2))\n" -" // sqrt(y) on top and bottom cancels out\n" -" //\n" -" // --- Equation 3 ---\n" -" // Equation 2 = (sqrt(x^2 + 2xdx + dx^2) - sqrt(x^2)) / " -"(sqrt(x^2)\n" -" // = (sqrt((x + dx)^2) - sqrt(x^2)) / sqrt(x^2)\n" -" // = ((x + dx) - x) / x\n" -" // = dx / x\n" -" // Since dx / dy = x / y,\n" -" // dx / x = dy / y\n" -" //\n" -" // Finally\n" -" // (L1 - L0) / L0 = dx / x = dy / y\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let shares = if (total_supply == 0) {\n" -" u256_sqrt(amount0 * amount1).into()\n" -" } else {\n" -" PrivateFunctions::min(\n" -" amount0 * total_supply / reserve0, amount1 * " -"total_supply / reserve1\n" -" )\n" -" };\n" -" assert(shares > 0, 'shares = 0');\n" -" self._mint(caller, shares);\n" -"\n" -" self._update(self.token0.read().balance_of(this), self.token1." -"read().balance_of(this));\n" -" shares\n" -" }\n" -"\n" -" fn remove_liquidity(ref self: ContractState, shares: u256) -> (u256, " -"u256) {\n" -" let caller = get_caller_address();\n" -" let this = get_contract_address();\n" -" let (token0, token1): (IERC20Dispatcher, IERC20Dispatcher) = (\n" -" self.token0.read(), self.token1.read()\n" -" );\n" -"\n" -" // Claim\n" -" // dx, dy = amount of liquidity to remove\n" -" // dx = s / T * x\n" -" // dy = s / T * y\n" -" //\n" -" // Proof\n" -" // Let's find dx, dy such that\n" -" // v / L = s / T\n" -" //\n" -" // where\n" -" // v = f(dx, dy) = sqrt(dxdy)\n" -" // L = total liquidity = sqrt(xy)\n" -" // s = shares\n" -" // T = total supply\n" -" //\n" -" // --- Equation 1 ---\n" -" // v = s / T * L\n" -" // sqrt(dxdy) = s / T * sqrt(xy)\n" -" //\n" -" // Amount of liquidity to remove must not change price so\n" -" // dx / dy = x / y\n" -" //\n" -" // replace dy = dx * y / x\n" -" // sqrt(dxdy) = sqrt(dx * dx * y / x) = dx * sqrt(y / x)\n" -" //\n" -" // Divide both sides of Equation 1 with sqrt(y / x)\n" -" // dx = s / T * sqrt(xy) / sqrt(y / x)\n" -" // = s / T * sqrt(x^2) = s / T * x\n" -" //\n" -" // Likewise\n" -" // dy = s / T * y\n" -"\n" -" // bal0 >= reserve0\n" -" // bal1 >= reserve1\n" -" let (bal0, bal1): (u256, u256) = (token0.balance_of(this), token1." -"balance_of(this));\n" -"\n" -" let total_supply = self.total_supply.read();\n" -" let (amount0, amount1): (u256, u256) = (\n" -" (shares * bal0) / total_supply, (shares * bal1) / " -"total_supply\n" -" );\n" -" assert(amount0 > 0 && amount1 > 0, 'amount0 or amount1 = 0');\n" -"\n" -" self._burn(caller, shares);\n" -" self._update(bal0 - amount0, bal1 - amount1);\n" -"\n" -" token0.transfer(caller, amount0);\n" -" token1.transfer(caller, amount1);\n" -" (amount0, amount1)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/applications/constant-product-amm.md:274 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/applications/constant_product_amm/src/constant_product_amm." -"cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/applications/" -"constant_product_amm/src/constant_product_amm.cairo) 中测试这个合约。" - -#: src/advanced-concepts/write_to_any_slot.md:1 -msgid "# Writing to any storage slot" -msgstr "# 写入任何存储槽" - -#: src/advanced-concepts/write_to_any_slot.md:3 -msgid "" -"On Starknet, a contract's storage is a map with 2^251 slots, where each slot " -"is a felt which is initialized to 0.\n" -"The address of storage variables is computed at compile time using the " -"formula: `storage variable address := pedersen(keccak(variable name), keys)`. " -"Interactions with storage variables are commonly performed using the `self." -"var.read()` and `self.var.write()` functions." -msgstr "" -"在Starknet上,一个合约的存储是一个拥有 2^251 个槽的map,每个槽是一个初始化为 " -"0 的 felt。存储变量的地址在编译时通过公式计算得出:`存储变量地址 := " -"pedersen(keccak(变量名), keys)`。与存储变量的交互通常使用 `self.var.read()` " -"和 `self.var.write()` 。" - -#: src/advanced-concepts/write_to_any_slot.md:6 -msgid "" -"Nevertheless, we can use the `storage_write_syscall` and " -"`storage_read_syscall` syscalls, to write to and read from any storage slot.\n" -"This is useful when writing to storage variables that are not known at " -"compile time, or to ensure that even if the contract is upgraded and the " -"computation method of storage variable addresses changes, they remain " -"accessible." -msgstr "" -"然而,我们可以使用 `storage_write_syscall` 和 `storage_read_syscall` 系统调" -"用,来对任何存储槽进行写入和读取。\n" -"这在写入那些在编译时还未确定的存储变量时非常有用,这也可以确保即使合约升级且存" -"储变量地址的计算方法改变,这些变量仍然可访问。" - -#: src/advanced-concepts/write_to_any_slot.md:9 -msgid "" -"In the following example, we use the Poseidon hash function to compute the " -"address of a storage variable. Poseidon is a ZK-friendly hash function that " -"is cheaper and faster than Pedersen, making it an excellent choice for " -"onchain computations. Once the address is computed, we use the storage " -"syscalls to interact with it." -msgstr "" -"在以下示例中,我们使用 Poseidon 哈希函数来计算存储变量的地址。Poseidon 是一个 " -"ZK 友好的哈希函数,比 Pedersen 更便宜、更快,是链上计算的绝佳选择。一旦地址被" -"计算出来,我们就使用存储相关的系统调用与之交互。" - -#: src/advanced-concepts/write_to_any_slot.md:11 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IWriteToAnySlots {\n" -" fn write_slot(ref self: TContractState, value: u32);\n" -" fn read_slot(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod WriteToAnySlot {\n" -" use starknet::syscalls::{storage_read_syscall, storage_write_syscall};\n" -" use starknet::SyscallResultTrait;\n" -" use poseidon::poseidon_hash_span;\n" -" use starknet::storage_access::Felt252TryIntoStorageAddress;\n" -" use starknet::StorageAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" const SLOT_NAME: felt252 = 'test_slot';\n" -"\n" -" #[abi(embed_v0)]\n" -" impl WriteToAnySlot of super::IWriteToAnySlots {\n" -" fn write_slot(ref self: ContractState, value: u32) {\n" -" storage_write_syscall(0, get_address_from_name(SLOT_NAME), value." -"into());\n" -" }\n" -"\n" -" fn read_slot(self: @ContractState) -> u32 {\n" -" storage_read_syscall(0, get_address_from_name(SLOT_NAME))\n" -" .unwrap_syscall()\n" -" .try_into()\n" -" .unwrap()\n" -" }\n" -" }\n" -" fn get_address_from_name(variable_name: felt252) -> StorageAddress {\n" -" let mut data: Array = ArrayTrait::new();\n" -" data.append(variable_name);\n" -" let hashed_name: felt252 = poseidon_hash_span(data.span());\n" -" let MASK_250: u256 = " -"0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n" -" // By taking the 250 least significant bits of the hash output, we " -"get a valid 250bits storage address.\n" -" let result: felt252 = (hashed_name.into() & MASK_250).try_into()." -"unwrap();\n" -" let result: StorageAddress = result.try_into().unwrap();\n" -" result\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IWriteToAnySlots {\n" -" fn write_slot(ref self: TContractState, value: u32);\n" -" fn read_slot(self: @TContractState) -> u32;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod WriteToAnySlot {\n" -" use starknet::syscalls::{storage_read_syscall, storage_write_syscall};\n" -" use starknet::SyscallResultTrait;\n" -" use poseidon::poseidon_hash_span;\n" -" use starknet::storage_access::Felt252TryIntoStorageAddress;\n" -" use starknet::StorageAddress;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" const SLOT_NAME: felt252 = 'test_slot';\n" -"\n" -" #[abi(embed_v0)]\n" -" impl WriteToAnySlot of super::IWriteToAnySlots {\n" -" fn write_slot(ref self: ContractState, value: u32) {\n" -" storage_write_syscall(0, get_address_from_name(SLOT_NAME), value." -"into());\n" -" }\n" -"\n" -" fn read_slot(self: @ContractState) -> u32 {\n" -" storage_read_syscall(0, get_address_from_name(SLOT_NAME))\n" -" .unwrap_syscall()\n" -" .try_into()\n" -" .unwrap()\n" -" }\n" -" }\n" -" fn get_address_from_name(variable_name: felt252) -> StorageAddress {\n" -" let mut data: Array = ArrayTrait::new();\n" -" data.append(variable_name);\n" -" let hashed_name: felt252 = poseidon_hash_span(data.span());\n" -" let MASK_250: u256 = " -"0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n" -" // By taking the 250 least significant bits of the hash output, we " -"get a valid 250bits storage address.\n" -" let result: felt252 = (hashed_name.into() & MASK_250).try_into()." -"unwrap();\n" -" let result: StorageAddress = result.try_into().unwrap();\n" -" result\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/write_to_any_slot.md:56 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x033943CB781A4E63C9dcE0A1A09eAa3b617AA43CC61637C08c043a67f3fe0087) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/write_to_any_slot/src/contract.cairo)." -msgstr "" -"访问 [Voyager](https://goerli.voyager.online/" -"contract/0x033943CB781A4E63C9dcE0A1A09eAa3b617AA43CC61637C08c043a67f3fe0087) " -"上的合约,或者在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/write_to_any_slot/src/contract.cairo) 中" -"测试它." - -#: src/advanced-concepts/storing_arrays.md:1 -msgid "# Storing Arrays" -msgstr "# 存储数组" - -#: src/advanced-concepts/storing_arrays.md:3 -msgid "" -"On Starknet, complex values (e.g., tuples or structs), are stored in a " -"continuous segment starting from the address of the storage variable. There " -"is a 256 field elements limitation to the maximal size of a complex storage " -"value, meaning that to store arrays of more than 255 elements in storage, we " -"would need to split it into segments of size `n <= 255` and store these " -"segments in multiple storage addresses. There is currently no native support " -"for storing arrays in Cairo, so you will need to write your own " -"implementation of the `Store` trait for the type of array you wish to store." -msgstr "" -"在Starknet上,复杂值(例如元组或结构体)存储在以该存储变量地址开头的连续段中。" -"复杂存储值的大小有 256 个元素的限制,这意味着要在存储中存储超过 255 个元素的数" -"组,我们需要将其分割为大小 `n <= 255` 的段,并将这些段存储在多个存储地址中。目" -"前 Cairo 没有原生支持存储数组,所以你需要为你希望存储的数组类型实现自己的 " -"`Store` 特性。" - -#: src/advanced-concepts/storing_arrays.md:5 -msgid "" -"> Note: While storing arrays in storage is possible, it is not always " -"recommended, as the read and write operations can get very costly. For " -"example, reading an array of size `n` requires `n` storage reads, and writing " -"to an array of size `n` requires `n` storage writes. If you only need to " -"access a single element of the array at a time, it is recommended to use a " -"`LegacyMap` and store the length in another variable instead." -msgstr "" -"> 注:虽然在存储中保存数组是可行的,但并不总是推荐这么做,因为读写操作的成本可" -"能非常高。例如,读取一个大小为 n 的数组需要进行 `n` 次存储读取,而向一个大小" -"为 `n` 的数组写入需要进行 `n` 次存储写入。如果你只需要一次访问数组中的一个元" -"素,建议使用 `LegacyMap` 并在另一个变量中存储数组长度。" - -#: src/advanced-concepts/storing_arrays.md:7 -msgid "" -"The following example demonstrates how to write a simple implementation of " -"the `StorageAccess` trait for the `Array` type, allowing us to store " -"arrays of up to 255 `felt252` elements." -msgstr "" -"以下示例展示了如何为 `Array` 类型实现一个简单的 `StorageAccess` 特" -"性,使我们能够存储多达 255 个 `felt252` 元素的数组。" - -#: src/advanced-concepts/storing_arrays.md:9 -msgid "" -"```cairo\n" -"impl StoreFelt252Array of Store> {\n" -" fn read(address_domain: u32, base: StorageBaseAddress) -> " -"SyscallResult> {\n" -" StoreFelt252Array::read_at_offset(address_domain, base, 0)\n" -" }\n" -"\n" -" fn write(\n" -" address_domain: u32, base: StorageBaseAddress, value: Array\n" -" ) -> SyscallResult<()> {\n" -" StoreFelt252Array::write_at_offset(address_domain, base, 0, value)\n" -" }\n" -"\n" -" fn read_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8\n" -" ) -> SyscallResult> {\n" -" let mut arr: Array = ArrayTrait::new();\n" -"\n" -" // Read the stored array's length. If the length is superior to 255, " -"the read will fail.\n" -" let len: u8 = Store::::read_at_offset(address_domain, base, " -"offset)\n" -" .expect('Storage Span too large');\n" -" offset += 1;\n" -"\n" -" // Sequentially read all stored elements and append them to the " -"array.\n" -" let exit = len + offset;\n" -" loop {\n" -" if offset >= exit {\n" -" break;\n" -" }\n" -"\n" -" let value = Store::::read_at_offset(address_domain, " -"base, offset).unwrap();\n" -" arr.append(value);\n" -" offset += Store::::size();\n" -" };\n" -"\n" -" // Return the array.\n" -" Result::Ok(arr)\n" -" }\n" -"\n" -" fn write_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8, mut " -"value: Array\n" -" ) -> SyscallResult<()> {\n" -" // // Store the length of the array in the first storage slot.\n" -" let len: u8 = value.len().try_into().expect('Storage - Span too " -"large');\n" -" Store::::write_at_offset(address_domain, base, offset, len);\n" -" offset += 1;\n" -"\n" -" // Store the array elements sequentially\n" -" loop {\n" -" match value.pop_front() {\n" -" Option::Some(element) => {\n" -" Store::::write_at_offset(address_domain, base, " -"offset, element);\n" -" offset += Store::::size();\n" -" },\n" -" Option::None(_) => { break Result::Ok(()); }\n" -" };\n" -" }\n" -" }\n" -"\n" -" fn size() -> u8 {\n" -" 255 * Store::::size()\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"impl StoreFelt252Array of Store> {\n" -" fn read(address_domain: u32, base: StorageBaseAddress) -> " -"SyscallResult> {\n" -" StoreFelt252Array::read_at_offset(address_domain, base, 0)\n" -" }\n" -"\n" -" fn write(\n" -" address_domain: u32, base: StorageBaseAddress, value: Array\n" -" ) -> SyscallResult<()> {\n" -" StoreFelt252Array::write_at_offset(address_domain, base, 0, value)\n" -" }\n" -"\n" -" fn read_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8\n" -" ) -> SyscallResult> {\n" -" let mut arr: Array = ArrayTrait::new();\n" -"\n" -" // Read the stored array's length. If the length is superior to 255, " -"the read will fail.\n" -" let len: u8 = Store::::read_at_offset(address_domain, base, " -"offset)\n" -" .expect('Storage Span too large');\n" -" offset += 1;\n" -"\n" -" // Sequentially read all stored elements and append them to the " -"array.\n" -" let exit = len + offset;\n" -" loop {\n" -" if offset >= exit {\n" -" break;\n" -" }\n" -"\n" -" let value = Store::::read_at_offset(address_domain, " -"base, offset).unwrap();\n" -" arr.append(value);\n" -" offset += Store::::size();\n" -" };\n" -"\n" -" // Return the array.\n" -" Result::Ok(arr)\n" -" }\n" -"\n" -" fn write_at_offset(\n" -" address_domain: u32, base: StorageBaseAddress, mut offset: u8, mut " -"value: Array\n" -" ) -> SyscallResult<()> {\n" -" // // Store the length of the array in the first storage slot.\n" -" let len: u8 = value.len().try_into().expect('Storage - Span too " -"large');\n" -" Store::::write_at_offset(address_domain, base, offset, len);\n" -" offset += 1;\n" -"\n" -" // Store the array elements sequentially\n" -" loop {\n" -" match value.pop_front() {\n" -" Option::Some(element) => {\n" -" Store::::write_at_offset(address_domain, base, " -"offset, element);\n" -" offset += Store::::size();\n" -" },\n" -" Option::None(_) => { break Result::Ok(()); }\n" -" };\n" -" }\n" -" }\n" -"\n" -" fn size() -> u8 {\n" -" 255 * Store::::size()\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/storing_arrays.md:73 -msgid "" -"You can then import this implementation in your contract and use it to store " -"arrays in storage:" -msgstr "您可以在合约中导入上面的实现方式,并使用它来在存储中存储数组:" - -#: src/advanced-concepts/storing_arrays.md:75 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoreArrayContract {\n" -" fn store_array(ref self: TContractState, arr: Array);\n" -" fn read_array(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoreArrayContract {\n" -" use super::StoreFelt252Array;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" arr: Array\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoreArrayImpl of super::IStoreArrayContract {\n" -" fn store_array(ref self: ContractState, arr: Array) {\n" -" self.arr.write(arr);\n" -" }\n" -"\n" -" fn read_array(self: @ContractState) -> Array {\n" -" self.arr.read()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IStoreArrayContract {\n" -" fn store_array(ref self: TContractState, arr: Array);\n" -" fn read_array(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod StoreArrayContract {\n" -" use super::StoreFelt252Array;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" arr: Array\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl StoreArrayImpl of super::IStoreArrayContract {\n" -" fn store_array(ref self: ContractState, arr: Array) {\n" -" self.arr.write(arr);\n" -" }\n" -"\n" -" fn read_array(self: @ContractState) -> Array {\n" -" self.arr.read()\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/storing_arrays.md:103 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x008F8069a3Fcd7691Db46Dc3b6F9D2C0436f9200E861330957Fd780A3595da86) " -"or play with it in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/storing_arrays/src/contract.cairo)." -msgstr "" -"访问[Voyager](https://goerli.voyager.online/" -"contract/0x008F8069a3Fcd7691Db46Dc3b6F9D2C0436f9200E861330957Fd780A3595da86) " -"上的合约,或者在 [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/storing_arrays/src/contract.cairo)上测试." - -#: src/advanced-concepts/struct-mapping-key.md:1 -msgid "# Structs as mapping keys" -msgstr "# 结构体作为映射键" - -#: src/advanced-concepts/struct-mapping-key.md:3 -msgid "" -"In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the " -"struct definition. This will automatically generate a hash function for the " -"struct that can be used to represent the struct as a key in a `LegacyMap`." -msgstr "" -"为了使用结构体作为映射键,您可以在结构体定义上使用 `#[derive(Hash)]`。这将为结" -"构体自动生成一个哈希函数,可以在 `LegacyMap` 中将该结构体作为键来使用。" - -#: src/advanced-concepts/struct-mapping-key.md:5 -msgid "" -"Consider the following example in which we would like to use an object of\n" -"type `Pet` as a key in a `LegacyMap`. The `Pet` struct has three fields: " -"`name`, `age` and `owner`. We consider that the combination of these three " -"fields uniquely identifies a pet." -msgstr "" -"考虑以下示例,我们希望使用类型为 `Pet` 的对象作为 `LegacyMap` 中的键。`Pet` 结" -"构体有三个字段:`name` 、`age` 和 `owner`。假设这三个字段的组合能唯一地标识一" -"只宠物。" - -#: src/advanced-concepts/struct-mapping-key.md:8 -msgid "" -"```cairo\n" -"#[derive(Copy, Drop, Serde, Hash)]\n" -"struct Pet {\n" -" name: felt252,\n" -" age: u8,\n" -" owner: felt252,\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IPetRegistry {\n" -" fn register_pet(ref self: TContractState, key: Pet, timestamp: u64);\n" -" fn get_registration_date(self: @TContractState, key: Pet) -> u64;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod PetRegistry {\n" -" use hash::{HashStateTrait, Hash};\n" -" use super::Pet;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" registration_time: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl PetRegistry of super::IPetRegistry {\n" -" fn register_pet(ref self: ContractState, key: Pet, timestamp: u64) {\n" -" self.registration_time.write(key, timestamp);\n" -" }\n" -"\n" -" fn get_registration_date(self: @ContractState, key: Pet) -> u64 {\n" -" self.registration_time.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[derive(Copy, Drop, Serde, Hash)]\n" -"struct Pet {\n" -" name: felt252,\n" -" age: u8,\n" -" owner: felt252,\n" -"}\n" -"\n" -"#[starknet::interface]\n" -"trait IPetRegistry {\n" -" fn register_pet(ref self: TContractState, key: Pet, timestamp: u64);\n" -" fn get_registration_date(self: @TContractState, key: Pet) -> u64;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod PetRegistry {\n" -" use hash::{HashStateTrait, Hash};\n" -" use super::Pet;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" registration_time: LegacyMap::,\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl PetRegistry of super::IPetRegistry {\n" -" fn register_pet(ref self: ContractState, key: Pet, timestamp: u64) {\n" -" self.registration_time.write(key, timestamp);\n" -" }\n" -"\n" -" fn get_registration_date(self: @ContractState, key: Pet) -> u64 {\n" -" self.registration_time.read(key)\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/struct-mapping-key.md:45 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/struct_as_mapping_key/src/contract." -"cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts/" -"struct_as_mapping_key/src/contract.cairo) 上测试这个合约." - -#: src/advanced-concepts/hash-solidity-compatible.md:1 -msgid "# Hash Solidity Compatible" -msgstr "# 兼容Hash Solidity" - -#: src/advanced-concepts/hash-solidity-compatible.md:3 -msgid "" -"This contract demonstrates Keccak hashing in Cairo to match Solidity's " -"keccak256. While both use Keccak, their endianness differs: Cairo is little-" -"endian, Solidity big-endian. The contract achieves compatibility by hashing " -"in big-endian using `keccak_u256s_be_inputs`, and reversing the bytes of the " -"result with `u128_byte_reverse`." -msgstr "" -"这个合约展示了在 Cairo 中进行 Keccak 哈希处理以匹配 Solidity 的 keccak256。尽" -"管两者都使用 Keccak,但它们的字节序不同:Cairo 是小端序,Solidity 是大端序。该" -"合约通过使用 `keccak_u256s_be_inputs` 以大端序进行哈希处理,并使用 " -"`u128_byte_reverse` 反转结果的字节来实现兼容。" - -#: src/advanced-concepts/hash-solidity-compatible.md:7 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISolidityHashExample {\n" -" fn hash_data(ref self: TContractState, input_data: Span) -> u256;\n" -"}\n" -"\n" -"\n" -"#[starknet::contract]\n" -"mod SolidityHashExample {\n" -" use keccak::{keccak_u256s_be_inputs};\n" -" use array::Span;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SolidityHashExample of super::ISolidityHashExample {\n" -" fn hash_data(ref self: ContractState, input_data: Span) -> u256 " -"{\n" -" let hashed = keccak_u256s_be_inputs(input_data);\n" -"\n" -" // Split the hashed value into two 128-bit segments\n" -" let low: u128 = hashed.low;\n" -" let high: u128 = hashed.high;\n" -"\n" -" // Reverse each 128-bit segment\n" -" let reversed_low = integer::u128_byte_reverse(low);\n" -" let reversed_high = integer::u128_byte_reverse(high);\n" -"\n" -" // Reverse merge the reversed segments back into a u256 value\n" -" let compatible_hash = u256 { low: reversed_high, high: " -"reversed_low };\n" -"\n" -" compatible_hash\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ISolidityHashExample {\n" -" fn hash_data(ref self: TContractState, input_data: Span) -> u256;\n" -"}\n" -"\n" -"\n" -"#[starknet::contract]\n" -"mod SolidityHashExample {\n" -" use keccak::{keccak_u256s_be_inputs};\n" -" use array::Span;\n" -"\n" -" #[storage]\n" -" struct Storage {}\n" -"\n" -" #[abi(embed_v0)]\n" -" impl SolidityHashExample of super::ISolidityHashExample {\n" -" fn hash_data(ref self: ContractState, input_data: Span) -> u256 " -"{\n" -" let hashed = keccak_u256s_be_inputs(input_data);\n" -"\n" -" // Split the hashed value into two 128-bit segments\n" -" let low: u128 = hashed.low;\n" -" let high: u128 = hashed.high;\n" -"\n" -" // Reverse each 128-bit segment\n" -" let reversed_low = integer::u128_byte_reverse(low);\n" -" let reversed_high = integer::u128_byte_reverse(high);\n" -"\n" -" // Reverse merge the reversed segments back into a u256 value\n" -" let compatible_hash = u256 { low: reversed_high, high: " -"reversed_low };\n" -"\n" -" compatible_hash\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/hash-solidity-compatible.md:44 -msgid "" -"Play with the contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" -"blob/main/listings/advanced-concepts/hash_solidity_compatible/src/contract." -"cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://github." -"com/NethermindEth/StarknetByExample/blob/main/listings/advanced-concepts/" -"hash_solidity_compatible/src/contract.cairo) 上测试这个合约." - -#: src/advanced-concepts/optimisations/optimisations.md:1 -msgid "# Optimisations " -msgstr "# 优化" - -#: src/advanced-concepts/optimisations/optimisations.md:3 -msgid "A collection of optimisation patterns to save gas and steps." -msgstr "这里列出了一系列优化模式,用以节省Gas和计算步骤。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:1 -msgid "# Storage optimisation " -msgstr "# 存储优化" - -#: src/advanced-concepts/optimisations/store_using_packing.md:3 -msgid "" -"A smart contract has a limited amount of **storage slots**. Each slot can " -"store a single `felt252` value.\n" -"Writing to a storage slot has a cost, so we want to use as few storage slots " -"as possible." -msgstr "" -"智能合约只有有限的**存储槽位**。每个槽位可以存储一个 `felt252` 值。\n" -"写入一个存储槽位会产生成本,因此我们希望尽可能少地使用存储槽位。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:6 -msgid "" -"In Cairo, every type is derived from the `felt252` type, which uses 252 bits " -"to store a value.\n" -"This design is quite simple, but it does have a drawback: it is not storage " -"efficient. For example, if we want to store a `u8` value, we need to use an " -"entire slot, even though we only need 8 bits." -msgstr "" -"在 Cairo 中,每种类型都源自 `felt252` 类型,它使用 252 位来存储一个值。\n" -"这种设计相当简单,但它有一个缺点:它在存储效率方面并不高。例如,如果要存储一" -"个 `u8` 值,我们需要使用整个槽位,尽管我们只需要 8 位。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:9 -msgid "## Packing" -msgstr "## 打包" - -#: src/advanced-concepts/optimisations/store_using_packing.md:11 -msgid "" -"When storing multiple values, we can use a technique called **packing**. " -"Packing is a technique that allows us to store multiple values in a single " -"felt value. This is done by using the bits of the felt value to store " -"multiple values." -msgstr "" -"当存储多个值时,我们可以使用一种称为 **打包(packing)** 的技术。打包是一种允许" -"我们在单个 felt 值中存储多个值的技术。这是通过使用 felt 值的位来存储多个值来实" -"现的。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:13 -msgid "" -"For example, if we want to store two `u8` values, we can use the first 8 bits " -"of the felt value to store the first `u8` value, and the last 8 bits to store " -"the second `u8` value. This way, we can store two `u8` values in a single " -"felt value." -msgstr "" -"例如,如果我们想存储两个 `u8` 值,我们可以使用 felt 值的前 8 位来存储第一个 " -"`u8` 值,而使用后 8 位来存储第二个 `u8` 值。这样,我们就可以在单个 felt 值中存" -"储两个 `u8` 值。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:15 -msgid "" -"Cairo provides a built-in store using packing that you can use with the " -"`StorePacking` trait." -msgstr "" -"Cairo 提供了一个内置的打包存储功能,您可以通过 `StorePacking` 特性来使用它。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:17 -msgid "" -"```cairo\n" -"trait StorePacking {\n" -" fn pack(value: T) -> PackedT;\n" -" fn unpack(value: PackedT) -> T;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait StorePacking {\n" -" fn pack(value: T) -> PackedT;\n" -" fn unpack(value: PackedT) -> T;\n" -"}\n" -"```" - -#: src/advanced-concepts/optimisations/store_using_packing.md:24 -msgid "" -"This allows to store the type `T` by first packing it into the type `PackedT` " -"with the `pack` function, and then storing the `PackedT` value with it's " -"`Store` implementation. When reading the value, we first retrieve the " -"`PackedT` value, and then unpack it into the type `T` using the `unpack` " -"function." -msgstr "" -"这允许通过首先使用 `pack` 函数将类型 `T` 打包成 `PackedT` 类型,然后使用其 " -"`Store` 实现来存储 `PackedT` 值。在读取值时,我们首先获取 `PackedT` 值,然后使" -"用 `unpack` 函数将其解包为类型 `T`。" - -#: src/advanced-concepts/optimisations/store_using_packing.md:26 -msgid "" -"Here's an example of storing a `Time` struct with two `u8` values using the " -"`StorePacking` trait:" -msgstr "" -"以下是一个使用 `StorePacking` 特性存储包含两个 `u8` 值的 `Time` 结构体的示例:" - -#: src/advanced-concepts/optimisations/store_using_packing.md:28 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ITime {\n" -" fn set(ref self: TContractState, value: TimeContract::Time);\n" -" fn get(self: @TContractState) -> TimeContract::Time;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod TimeContract {\n" -" use starknet::storage_access::StorePacking;\n" -" use integer::{\n" -" U8IntoFelt252, Felt252TryIntoU16, U16DivRem, u16_as_non_zero, " -"U16IntoFelt252,\n" -" Felt252TryIntoU8\n" -" };\n" -" use traits::{Into, TryInto, DivRem};\n" -" use option::OptionTrait;\n" -" use serde::Serde;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" time: Time\n" -" }\n" -"\n" -" #[derive(Copy, Serde, Drop)]\n" -" struct Time {\n" -" hour: u8,\n" -" minute: u8\n" -" }\n" -"\n" -" impl TimePackable of StorePacking {\n" -" fn pack(value: Time) -> felt252 {\n" -" let msb: felt252 = 256 * value.hour.into();\n" -" let lsb: felt252 = value.minute.into();\n" -" return msb + lsb;\n" -" }\n" -" fn unpack(value: felt252) -> Time {\n" -" let value: u16 = value.try_into().unwrap();\n" -" let (q, r) = U16DivRem::div_rem(value, u16_as_non_zero(256));\n" -" let hour: u8 = Into::::into(q).try_into()." -"unwrap();\n" -" let minute: u8 = Into::::into(r).try_into()." -"unwrap();\n" -" return Time { hour, minute };\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl TimeContract of super::ITime {\n" -" fn set(ref self: ContractState, value: Time) {\n" -" // This will call the pack method of the TimePackable trait\n" -" // and store the resulting felt252\n" -" self.time.write(value);\n" -" }\n" -" fn get(self: @ContractState) -> Time {\n" -" // This will read the felt252 value from storage\n" -" // and return the result of the unpack method of the TimePackable " -"trait\n" -" return self.time.read();\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait ITime {\n" -" fn set(ref self: TContractState, value: TimeContract::Time);\n" -" fn get(self: @TContractState) -> TimeContract::Time;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod TimeContract {\n" -" use starknet::storage_access::StorePacking;\n" -" use integer::{\n" -" U8IntoFelt252, Felt252TryIntoU16, U16DivRem, u16_as_non_zero, " -"U16IntoFelt252,\n" -" Felt252TryIntoU8\n" -" };\n" -" use traits::{Into, TryInto, DivRem};\n" -" use option::OptionTrait;\n" -" use serde::Serde;\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" time: Time\n" -" }\n" -"\n" -" #[derive(Copy, Serde, Drop)]\n" -" struct Time {\n" -" hour: u8,\n" -" minute: u8\n" -" }\n" -"\n" -" impl TimePackable of StorePacking {\n" -" fn pack(value: Time) -> felt252 {\n" -" let msb: felt252 = 256 * value.hour.into();\n" -" let lsb: felt252 = value.minute.into();\n" -" return msb + lsb;\n" -" }\n" -" fn unpack(value: felt252) -> Time {\n" -" let value: u16 = value.try_into().unwrap();\n" -" let (q, r) = U16DivRem::div_rem(value, u16_as_non_zero(256));\n" -" let hour: u8 = Into::::into(q).try_into()." -"unwrap();\n" -" let minute: u8 = Into::::into(r).try_into()." -"unwrap();\n" -" return Time { hour, minute };\n" -" }\n" -" }\n" -"\n" -" #[abi(embed_v0)]\n" -" impl TimeContract of super::ITime {\n" -" fn set(ref self: ContractState, value: Time) {\n" -" // This will call the pack method of the TimePackable trait\n" -" // and store the resulting felt252\n" -" self.time.write(value);\n" -" }\n" -" fn get(self: @ContractState) -> Time {\n" -" // This will read the felt252 value from storage\n" -" // and return the result of the unpack method of the TimePackable " -"trait\n" -" return self.time.read();\n" -" }\n" -" }\n" -"}\n" -"```" - -#: src/advanced-concepts/optimisations/store_using_packing.md:88 -msgid "" -"Play with this contract in [Remix](https://remix.ethereum.org/?" -"#activate=Starknet-cairo1-compiler&url=https://github.com/NethermindEth/" -"StarknetByExample/blob/main/listings/advanced-concepts/store_using_packing/" -"src/contract.cairo)." -msgstr "" -"在 [Remix](https://remix.ethereum.org/?#activate=Starknet-cairo1-" -"compiler&url=https://github.com/NethermindEth/StarknetByExample/blob/main/" -"listings/advanced-concepts/store_using_packing/src/contract.cairo) 上测试这个" -"合约." - -#: src/advanced-concepts/list.md:1 -msgid "# List" -msgstr "# 列表" - -#: src/advanced-concepts/list.md:3 -msgid "" -"By default, there is no list type supported in Cairo, but you can use " -"Alexandria. You can refer to the [Alexandria documentation](https://github." -"com/keep-starknet-strange/alexandria/tree/main/src/storage) for more details." -msgstr "" -"默认情况下,Cairo 不支持列表类型,但您可以使用 Alexandria。您可以参考 " -"[Alexandria 文档](https://github.com/keep-starknet-strange/alexandria/tree/" -"main/src/storage) 获取更多详细信息。" - -#: src/advanced-concepts/list.md:5 -msgid "## What is `List`?" -msgstr "## `List`是什么?" - -#: src/advanced-concepts/list.md:7 -msgid "An ordered sequence of values that can be used in Starknet storage:" -msgstr "可以在 Starknet 存储中使用的有序值序列:" - -#: src/advanced-concepts/list.md:9 -msgid "" -"```cairo\n" -"#[storage]\n" -"stuct Storage {\n" -" amounts: List\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[storage]\n" -"stuct Storage {\n" -" amounts: List\n" -"}\n" -"```" - -#: src/advanced-concepts/list.md:16 -msgid "### Interface" -msgstr "### 接口" - -#: src/advanced-concepts/list.md:18 -msgid "" -"```cairo\n" -"trait ListTrait {\n" -" fn len(self: @List) -> u32;\n" -" fn is_empty(self: @List) -> bool;\n" -" fn append(ref self: List, value: T) -> u32;\n" -" fn get(self: @List, index: u32) -> Option;\n" -" fn set(ref self: List, index: u32, value: T);\n" -" fn pop_front(ref self: List) -> Option;\n" -" fn array(self: @List) -> Array;\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"trait ListTrait {\n" -" fn len(self: @List) -> u32;\n" -" fn is_empty(self: @List) -> bool;\n" -" fn append(ref self: List, value: T) -> u32;\n" -" fn get(self: @List, index: u32) -> Option;\n" -" fn set(ref self: List, index: u32, value: T);\n" -" fn pop_front(ref self: List) -> Option;\n" -" fn array(self: @List) -> Array;\n" -"}\n" -"```" - -#: src/advanced-concepts/list.md:30 -msgid "" -"`List` also implements `IndexView` so you can use the familiar bracket " -"notation to access its members:" -msgstr "" -"`List` 还实现了 `IndexView`,因此您可以使用熟悉的方括号表示法来访问其成员:" - -#: src/advanced-concepts/list.md:32 -msgid "" -"```cairo\n" -"let second = self.amounts.read()[1];\n" -"```" -msgstr "" -"```cairo\n" -"let second = self.amounts.read()[1];\n" -"```" - -#: src/advanced-concepts/list.md:36 -msgid "" -"Note that unlike `get`, using this bracket notation panics when accessing an " -"out of bounds index." -msgstr "" -"请注意,与 `get` 不同的是,使用这种方括号表示法在访问越界索引时会引发 panic" -"(崩溃)。" - -#: src/advanced-concepts/list.md:38 -msgid "### Support for custom types" -msgstr "### 支持自定义类型" - -#: src/advanced-concepts/list.md:40 -msgid "" -"`List` supports most of the corelib types out of the box. If you want to " -"store a your own custom type in a `List`, it has to implement the `Store` " -"trait. You can have the compiler derive it for you using the " -"`#[derive(starknet::Store)]` attribute." -msgstr "" -"`List` 默认支持大多数 corelib 类型。如果您想在 `List` 中存储自己的自定义类型," -"该类型必须实现 `Store` 特性。您可以使用 `#[derive(starknet::Store)]` 属性让编" -"译器自动生成。" - -#: src/advanced-concepts/list.md:42 -msgid "### Caveats" -msgstr "### 注意事项" - -#: src/advanced-concepts/list.md:44 -msgid "There are two idiosyncacies you should be aware of when using `List`" -msgstr "在使用 `List` 时,有两个特点应该注意:" - -#: src/advanced-concepts/list.md:46 -msgid "" -"1. The `append` operation costs 2 storage writes - one for the value itself " -"and another one for updating the List's length\n" -"2. Due to a compiler limitation, it is not possible to use mutating " -"operations with a single inline statement. For example, `self.amounts.read()." -"append(42);` will not work. You have to do it in 2 steps:" -msgstr "" -"1. `append` 操作消耗 2 次存储写入操作 - 一次是为了值本身,另一次是为了更新列表" -"的长度。\n" -"2. 由于编译器的限制,不能使用单个内联语句进行变更操作。例如,`self.amounts." -"read().append(42);` 是不行的。你必须分两步进行:" - -#: src/advanced-concepts/list.md:49 -msgid "" -"```cairo\n" -"let mut amounts = self.amounts.read();\n" -"amounts.append(42);\n" -"```" -msgstr "" -"```cairo\n" -"let mut amounts = self.amounts.read();\n" -"amounts.append(42);\n" -"```" - -#: src/advanced-concepts/list.md:54 -msgid "### Dependencies" -msgstr "### 依赖关系" - -#: src/advanced-concepts/list.md:56 -msgid "Update your project dependencies by in the `Scarb.toml` file:" -msgstr "在 `Scarb.toml` 里更新您项目的依赖:" - -#: src/advanced-concepts/list.md:57 -msgid "" -"```cairo\n" -"[dependencies]\n" -"(...)\n" -"alexandria_storage = { git = \"https://github.com/keep-starknet-strange/" -"alexandria.git\" }\n" -"```" -msgstr "" -"```cairo\n" -"[dependencies]\n" -"(...)\n" -"alexandria_storage = { git = \"https://github.com/keep-starknet-strange/" -"alexandria.git\" }\n" -"```" - -#: src/advanced-concepts/list.md:63 -msgid "" -"For example, let's use `List` to create a contract that tracks a list of " -"amounts and tasks:" -msgstr "例如,我们用 `List` 来创建一个跟踪`amount`和`tasks`的合约:" - -#: src/advanced-concepts/list.md:65 -msgid "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IListExample {\n" -" fn add_in_amount(ref self: TContractState, number: u128);\n" -" fn add_in_task(ref self: TContractState, description: felt252, status: " -"felt252);\n" -" fn is_empty_list(self: @TContractState) -> bool;\n" -" fn list_length(self: @TContractState) -> u32;\n" -" fn get_from_index(self: @TContractState, index: u32) -> u128;\n" -" fn set_from_index(ref self: TContractState, index: u32, number: u128);\n" -" fn pop_front_list(ref self: TContractState);\n" -" fn array_conversion(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ListExample {\n" -" use alexandria_storage::list::{List, ListTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" amounts: List,\n" -" tasks: List\n" -" }\n" -"\n" -" #[derive(Copy, Drop, Serde, starknet::Store)]\n" -" struct Task {\n" -" description: felt252,\n" -" status: felt252\n" -" }\n" -"\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ListExample of super::IListExample {\n" -" fn add_in_amount(ref self: ContractState, number: u128) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.append(number);\n" -" }\n" -"\n" -" fn add_in_task(ref self: ContractState, description: felt252, status: " -"felt252) {\n" -" let new_task = Task { description: description, status: " -"status };\n" -" let mut current_tasks_list = self.tasks.read();\n" -" current_tasks_list.append(new_task);\n" -" }\n" -"\n" -" fn is_empty_list(self: @ContractState) -> bool {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.is_empty()\n" -" }\n" -"\n" -" fn list_length(self: @ContractState) -> u32 {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.len()\n" -" }\n" -"\n" -" fn get_from_index(self: @ContractState, index: u32) -> u128 {\n" -" self.amounts.read()[index]\n" -" }\n" -"\n" -" fn set_from_index(ref self: ContractState, index: u32, number: u128) " -"{\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.set(index, number);\n" -" }\n" -"\n" -" fn pop_front_list(ref self: ContractState) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.pop_front();\n" -" }\n" -"\n" -" fn array_conversion(self: @ContractState) -> Array {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.array()\n" -" }\n" -" }\n" -"}\n" -"```" -msgstr "" -"```cairo\n" -"#[starknet::interface]\n" -"trait IListExample {\n" -" fn add_in_amount(ref self: TContractState, number: u128);\n" -" fn add_in_task(ref self: TContractState, description: felt252, status: " -"felt252);\n" -" fn is_empty_list(self: @TContractState) -> bool;\n" -" fn list_length(self: @TContractState) -> u32;\n" -" fn get_from_index(self: @TContractState, index: u32) -> u128;\n" -" fn set_from_index(ref self: TContractState, index: u32, number: u128);\n" -" fn pop_front_list(ref self: TContractState);\n" -" fn array_conversion(self: @TContractState) -> Array;\n" -"}\n" -"\n" -"#[starknet::contract]\n" -"mod ListExample {\n" -" use alexandria_storage::list::{List, ListTrait};\n" -"\n" -" #[storage]\n" -" struct Storage {\n" -" amount: List,\n" -" tasks: List\n" -" }\n" -"\n" -" #[derive(Copy, Drop, Serde, starknet::Store)]\n" -" struct Task {\n" -" description: felt252,\n" -" status: felt252\n" -" }\n" -"\n" -"\n" -" #[abi(embed_v0)]\n" -" impl ListExample of super::IListExample {\n" -" fn add_in_amount(ref self: ContractState, number: u128) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.append(number);\n" -" }\n" -"\n" -" fn add_in_task(ref self: ContractState, description: felt252, status: " -"felt252) {\n" -" let new_task = Task { description: description, status: " -"status };\n" -" let mut current_tasks_list = self.tasks.read();\n" -" current_tasks_list.append(new_task);\n" -" }\n" -"\n" -" fn is_empty_list(self: @ContractState) -> bool {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.is_empty()\n" -" }\n" -"\n" -" fn list_length(self: @ContractState) -> u32 {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.len()\n" -" }\n" -"\n" -" fn get_from_index(self: @ContractState, index: u32) -> u128 {\n" -" self.amounts.read()[index]\n" -" }\n" -"\n" -" fn set_from_index(ref self: ContractState, index: u32, number: u128) " -"{\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.set(index, number);\n" -" }\n" -"\n" -" fn pop_front_list(ref self: ContractState) {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.pop_front();\n" -" }\n" -"\n" -" fn array_conversion(self: @ContractState) -> Array {\n" -" let mut current_amount_list = self.amounts.read();\n" -" current_amount_list.array()\n" -" }\n" -" }\n" -"}\n" -"```" - -#~ msgid "Here's a list of other resources that you might find useful:" -#~ msgstr "以下是您可能会用到的其他资源清单:" - -#~ msgid "" -#~ "- [Starklings](https://github.com/shramee/starklings-cairo1): An " -#~ "interactive tutorial to get you up and running with Cairo v1 and " -#~ "Starknet \n" -#~ "- [Cairopractice](https://cairopractice.com/): A blog with a series of " -#~ "articles about Cairo and Starknet\n" -#~ "- [Cairo by example](https://cairo-by-example.com/): An introduction to " -#~ "Cairo, with simple examples" -#~ msgstr "" -#~ "- [Starklings](https://github.com/shramee/starklings-cairo1):让您使用 " -#~ "Cairo v1 和Starknet互动的教程\n" -#~ "- [Cairopractice](https://cairopractice.com/):关于Cairo和Starknet的一系列" -#~ "文章的博客\n" -#~ "- [Cairo by example](https://cairo-by-example.com/):Cairo 简介,附带简单示" -#~ "例" - -#~ msgid "
Last change: 2023-11-20
" -#~ msgstr "
Last change: 2023-11-20
" - -#~ msgid "
Last change: 2023-11-04
" -#~ msgstr "
Last change: 2023-11-04
" - -#~ msgid "
Last change: 2023-11-26
" -#~ msgstr "
Last change: 2023-11-26
" - -#~ msgid "
Last change: 2023-11-30
" -#~ msgstr "
Last change: 2023-11-30
" - -#~ msgid "
Last change: 2023-10-24
" -#~ msgstr "
Last change: 2023-10-24
" - -#~ msgid "
Last change: 2023-11-21
" -#~ msgstr "
Last change: 2023-11-21
" - -#~ msgid "
Last change: 2023-11-27
" -#~ msgstr "
Last change: 2023-11-27
" diff --git a/src/advanced-concepts/optimisations/store_using_packing.md b/src/advanced-concepts/optimisations/store_using_packing.md index 28709f0c..48f256aa 100644 --- a/src/advanced-concepts/optimisations/store_using_packing.md +++ b/src/advanced-concepts/optimisations/store_using_packing.md @@ -25,6 +25,11 @@ This allows us to store the type `T` by first packing it into the type `PackedT` Here's an example of storing a `Time` struct with two `u8` values using the `StorePacking` trait: +<<<<<<<< HEAD:src/advanced-concepts/optimisations/store_using_packing.md ```cairo {{#include ../../../listings/advanced-concepts/store_using_packing/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/store_using_packing/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/optimisations/store_using_packing.md ``` diff --git a/src/advanced-concepts/struct-mapping-key.md b/src/advanced-concepts/struct-mapping-key.md index 7b138963..b0eec8b1 100644 --- a/src/advanced-concepts/struct-mapping-key.md +++ b/src/advanced-concepts/struct-mapping-key.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Structs as mapping keys In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the struct definition. This will automatically generate a hash function for the struct that can be used to represent the struct as a key in a `Map`. @@ -5,6 +12,11 @@ In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the st Consider the following example in which we would like to use an object of type `Pet` as a key in a `Map`. The `Pet` struct has three fields: `name`, `age` and `owner`. We consider that the combination of these three fields uniquely identifies a pet. +<<<<<<<< HEAD:src/advanced-concepts/struct-mapping-key.md ```cairo {{#include ../../listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/struct-mapping-key.md ``` diff --git a/src/advanced-concepts/write_to_any_slot.md b/src/advanced-concepts/write_to_any_slot.md index c0c89a12..50dd24ba 100644 --- a/src/advanced-concepts/write_to_any_slot.md +++ b/src/advanced-concepts/write_to_any_slot.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Writing to any storage slot On Starknet, a contract's storage is a map with \\( 2^{251} \\) slots, where each slot is a `felt252` which is initialized to 0. @@ -8,6 +15,11 @@ This is useful when writing to storage variables that are not known at compile t In the following example, we use the Poseidon hash function to compute the address of a storage variable. Poseidon is a ZK-friendly hash function that is cheaper and faster than Pedersen, making it an excellent choice for onchain computations. Once the address is computed, we use the storage syscalls to interact with it. +<<<<<<<< HEAD:src/advanced-concepts/write_to_any_slot.md ```cairo {{#include ../../listings/advanced-concepts/write_to_any_slot/src/contract.cairo}} +======== +```rust +// [!include ~/listings/advanced-concepts/write_to_any_slot/src/contract.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/write_to_any_slot.md ``` diff --git a/src/applications/erc20.md b/src/applications/erc20.md index 6b2ac43a..dbc21402 100644 --- a/src/applications/erc20.md +++ b/src/applications/erc20.md @@ -1,11 +1,23 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # ERC20 Token Contracts that follow the [ERC20 Standard](https://eips.ethereum.org/EIPS/eip-20) are called ERC20 tokens. They are used to represent fungible assets. To create an ERC20 contract, it must implement the following interface: +<<<<<<<< HEAD:src/applications/erc20.md ```cairo {{#include ../../listings/applications/erc20/src/token.cairo:interface}} +======== +```rust +// [!include ~/listings/applications/erc20/src/token.cairo:interface] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md ``` In Starknet, function names should be written in _snake_case_. This is not the case in Solidity, where function names are written in _camelCase_. @@ -13,8 +25,13 @@ The Starknet ERC20 interface is therefore slightly different from the Solidity E Here's an implementation of the ERC20 interface in Cairo: +<<<<<<<< HEAD:src/applications/erc20.md ```cairo {{#include ../../listings/applications/erc20/src/token.cairo:erc20}} +======== +```rust +// [!include ~/listings/applications/erc20/src/token.cairo:erc20] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md ``` There's several other implementations, such as the [Open Zeppelin](https://docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the [Cairo By Example](https://cairo-by-example.com/examples/erc20/) ones. diff --git a/src/applications/simple_vault.md b/src/applications/simple_vault.md index 1a6015ec..7f9138fc 100644 --- a/src/applications/simple_vault.md +++ b/src/applications/simple_vault.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Simple Defi Vault This is the Cairo adaptation of the [Solidity by Example - Vault](https://solidity-by-example.org/defi/vault/). @@ -7,6 +14,11 @@ Here's how it works: - When a user withdraws, the contract burns their shares, calculates the yield, and withdraws both the yield and the initial amount of tokens deposited. +<<<<<<<< HEAD:src/applications/simple_vault.md ```cairo {{#include ../../listings/applications/simple_vault/src/simple_vault.cairo}} +======== +```rust +// [!include ~/listings/applications/simple_vault/src/simple_vault.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/simple_vault.md ``` diff --git a/src/applications/upgradeable_contract.md b/src/applications/upgradeable_contract.md index 95432037..48388029 100644 --- a/src/applications/upgradeable_contract.md +++ b/src/applications/upgradeable_contract.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Upgradeable Contract In Starknet, contracts are divided into two parts: contract classes and contract @@ -22,10 +29,19 @@ You can upgrade a deployed contract to a newer version by calling the `replace_c To illustrate this concept, let's consider an example with two contracts: `UpgradeableContract_V0`, and `UpgradeableContract_V1`. Start by deploying `UpgradeableContract_V0` as the initial version. Next, send a transaction that invokes the `upgrade` function, with the class hash of `UpgradeableContract_V1` as parameter to upgrade the class hash of the deployed contract to the `UpgradeableContract_V1` one. Then, call the `version` method on the contract to see that the contract was upgraded to the V1 version. +<<<<<<<< HEAD:src/applications/upgradeable_contract.md ```cairo {{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract}} ``` ```cairo {{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo}} +======== +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract] +``` + +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/upgradeable_contract.md ``` diff --git a/src/components/ownable.md b/src/components/ownable.md deleted file mode 100644 index ead71ade..00000000 --- a/src/components/ownable.md +++ /dev/null @@ -1,15 +0,0 @@ -# Ownable - -The following `Ownable` component is a simple component that allows the contract to set an owner and provides an `_assert_is_owner` function that can be used to ensure that the caller is the owner. - -It can also be used to renounce ownership of a contract, meaning that no one will be able to satisfy the `_assert_is_owner` function. - -```cairo -{{#include ../../listings/applications/components/src/ownable.cairo:component}} -``` - -A mock contract that uses the `Ownable` component: - -```cairo -{{#rustdoc_include ../../listings/applications/components/src/ownable.cairo:contract}} -``` diff --git a/src/getting-started/basics/bytearrays-strings.md b/src/getting-started/basics/bytearrays-strings.md index b70fab07..fc59f9c0 100644 --- a/src/getting-started/basics/bytearrays-strings.md +++ b/src/getting-started/basics/bytearrays-strings.md @@ -19,10 +19,23 @@ ByteArrays are declared with double quotes, like this: `"Hello, World!"`. They can be stored in the contract's storage and passed as arguments to entrypoints. +<<<<<<<< HEAD:src/getting-started/basics/bytearrays-strings.md ```cairo {{#rustdoc_include ../../../listings/getting-started/bytearray/src/bytearray.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/bytearrays-strings.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:tests] ``` +::: + ### Operations ByteArrays also provide a set of operations that facilitate the manipulation of strings. diff --git a/src/getting-started/basics/constructor.md b/src/getting-started/basics/constructor.md index 2c92a1dc..f751c0c6 100644 --- a/src/getting-started/basics/constructor.md +++ b/src/getting-started/basics/constructor.md @@ -1,9 +1,29 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Constructor Constructors are a special type of function that runs only once when deploying a contract, and can be used to initialize the state of the contract. Your contract must not have more than one constructor, and that constructor function must be annotated with the `#[constructor]` attribute. Also, a good practice consists in naming that function `constructor`. Here's a simple example that demonstrates how to initialize the state of a contract on deployment by defining logic inside a constructor. +<<<<<<<< HEAD:src/getting-started/basics/constructor.md ```cairo {{#rustdoc_include ../../../listings/getting-started/constructor/src/constructor.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/constructor/src/constructor.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/constructor.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/constructor/src/constructor.cairo:tests] +``` + +::: diff --git a/src/getting-started/basics/counter.md b/src/getting-started/basics/counter.md index 266d70b0..7ba0493e 100644 --- a/src/getting-started/basics/counter.md +++ b/src/getting-started/basics/counter.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Simple Counter We now understand how to create a contract with state variables and functions. Let's create a simple counter contract that increments and decrements a counter. @@ -10,6 +17,19 @@ Here's how it works: - When a user calls the `decrement`, the contract decrements `counter` by `1`. +<<<<<<<< HEAD:src/getting-started/basics/counter.md ```cairo {{#rustdoc_include ../../../listings/getting-started/counter/src/counter.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/counter/src/counter.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/counter.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/counter/src/counter.cairo:tests] +``` + +::: diff --git a/src/getting-started/basics/custom-types-in-entrypoints.md b/src/getting-started/basics/custom-types-in-entrypoints.md index 7603dfe7..97e8ce79 100644 --- a/src/getting-started/basics/custom-types-in-entrypoints.md +++ b/src/getting-started/basics/custom-types-in-entrypoints.md @@ -1,10 +1,34 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Custom types in entrypoints Using custom types in entrypoints requires our type to implement the `Serde` trait. This is because when calling an entrypoint, the input is sent as an array of `felt252` to the entrypoint, and we need to be able to deserialize it into our custom type. Similarly, when returning a custom type from an entrypoint, we need to be able to serialize it into an array of `felt252`. Thankfully, we can just derive the `Serde` trait for our custom type. +<<<<<<<< HEAD:src/getting-started/basics/custom-types-in-entrypoints.md ```cairo {{#rustdoc_include ../../../listings/getting-started/custom_type_serde/src/contract.cairo:contract}} ``` > Note: The purpose of this example is to demonstrate the ability to use custom types as inputs and outputs in contract calls. For simplicity, we are not using getters and setters to manage the contract's state. +======== +The purpose is to only show the capability of using custom types as inputs and outputs in contract calls. +We are not employing getters and setters for managing the contract's state in this example for simplicity. + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:tests] +``` + +::: +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/custom-types-in-entrypoints.md diff --git a/src/getting-started/basics/documentation.md b/src/getting-started/basics/documentation.md index 3d425691..81b14b37 100644 --- a/src/getting-started/basics/documentation.md +++ b/src/getting-started/basics/documentation.md @@ -1,3 +1,11 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Documentation It's important to take the time to document your code. It will help developers and users to understand the contract and its functionalities. diff --git a/src/getting-started/basics/errors.md b/src/getting-started/basics/errors.md index ce6ea155..7d6df40b 100644 --- a/src/getting-started/basics/errors.md +++ b/src/getting-started/basics/errors.md @@ -17,22 +17,61 @@ The `assert_eq!`, `assert_ne!`, `assert_lt!`, `assert_le!`, `assert_gt!` and `as Here's a simple example that demonstrates the use of these functions: +<<<<<<<< HEAD:src/getting-started/basics/errors.md ```cairo {{#rustdoc_include ../../../listings/getting-started/errors/src/simple_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:tests] ``` +::: + ## Custom errors You can make error handling easier by defining your error codes in a specific module. +<<<<<<<< HEAD:src/getting-started/basics/errors.md ```cairo {{#rustdoc_include ../../../listings/getting-started/errors/src/custom_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:tests] ``` +::: + ## Vault example Here's another example that demonstrates the use of errors in a more complex contract: +<<<<<<<< HEAD:src/getting-started/basics/errors.md ```cairo {{#rustdoc_include ../../../listings/getting-started/errors/src/vault_errors.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:tests] +``` + +::: diff --git a/src/getting-started/basics/introduction.md b/src/getting-started/basics/introduction.md index 2f4f91c1..0c3367aa 100644 --- a/src/getting-started/basics/introduction.md +++ b/src/getting-started/basics/introduction.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Basics of Smart Contracts in Cairo The following chapters will introduce you to Starknet smart contracts and how to write them in Cairo. diff --git a/src/getting-started/basics/storage.md b/src/getting-started/basics/storage.md index 3aee55b5..7d621c2b 100644 --- a/src/getting-started/basics/storage.md +++ b/src/getting-started/basics/storage.md @@ -1,21 +1,57 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Storage Here's the most minimal contract you can write in Cairo: +<<<<<<<< HEAD:src/getting-started/basics/storage.md ```cairo {{#rustdoc_include ../../../listings/getting-started/storage/src/minimal_contract.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:tests] ``` +::: + Storage is a `struct` annotated with `#[storage]`. Every contract must have one and only one storage. It's a key-value store, where each key will be mapped to a storage address of the contract's storage space. You can define [storage variables](./variables.md#storage-variables) in your contract, and then use them to store and retrieve data. +<<<<<<<< HEAD:src/getting-started/basics/storage.md ```cairo {{#rustdoc_include ../../../listings/getting-started/storage/src/contract.cairo:contract}} ``` > Actually these two contracts have the same underlying Sierra program. +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/storage/src/contract.cairo:contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/storage/src/contract.cairo:tests] +``` + +::: + +> Actually these two contracts have the same underlying sierra program. +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md > From the compiler's perspective, the storage variables don't exist until they are used. You can also read about [storing custom types](./storing-custom-types.md). diff --git a/src/getting-started/basics/syscalls.md b/src/getting-started/basics/syscalls.md index 3957becd..bac7a1c2 100644 --- a/src/getting-started/basics/syscalls.md +++ b/src/getting-started/basics/syscalls.md @@ -134,8 +134,13 @@ The success result is a tuple containing the deployed contract address and the r Example of the usage of the `deploy` syscall from the [Factory pattern](../interacting/factory.md): +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md ```cairo {{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:deploy}} +======== +```rust +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:deploy] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md ``` #### emit_event @@ -150,8 +155,13 @@ Emit an event with the given `keys` and `data`. Example of the usage of the `emit_event` syscall from the [Events](../basics/events.md) chapter: +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md ```cairo {{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:emit}} +======== +```rust +// [!include ~/listings/getting-started/events/src/counter.cairo:emit] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md ``` @@ -203,8 +213,13 @@ Replace the class of the calling contract with the class `class_hash`. This is used for contract upgrades. Here's an example from the [Upgradeable Contract](../../applications/upgradeable_contract.md): +<<<<<<<< HEAD:src/getting-started/basics/syscalls.md ```cairo {{#rustdoc_include ../../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade}} +======== +```rust +// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md ``` The new class code will only be used for future calls to the contract. diff --git a/src/getting-started/basics/variables.md b/src/getting-started/basics/variables.md index 411f4a53..9ad59a6e 100644 --- a/src/getting-started/basics/variables.md +++ b/src/getting-started/basics/variables.md @@ -20,10 +20,23 @@ Local variables are stored in memory and are not stored on the blockchain. This Here's a simple example of a contract with only local variables: +<<<<<<<< HEAD:src/getting-started/basics/variables.md ```cairo {{#rustdoc_include ../../../listings/getting-started/variables/src/local_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/local_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/local_variables.cairo:tests] ``` +::: + ## Storage Variables Storage variables are persistent data stored on the blockchain. They can be accessed from one execution to another, allowing the contract to remember and update information over time. See [Storage](./storage.md) for more information. @@ -34,10 +47,23 @@ On the other hand, you can read state variables for free, without any transactio Here's a simple example of a contract with one storage variable: +<<<<<<<< HEAD:src/getting-started/basics/variables.md ```cairo {{#rustdoc_include ../../../listings/getting-started/variables/src/storage_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:tests] ``` +::: + ## Global Variables Global variables are predefined variables that provide information about the blockchain and the current execution environment. They can be accessed at any time and from anywhere! @@ -46,6 +72,19 @@ In Starknet, you can access global variables by using specific functions from th For example, the `get_caller_address` function returns the address of the caller of the current transaction, and the `get_contract_address` function returns the address of the current contract. +<<<<<<<< HEAD:src/getting-started/basics/variables.md ```cairo {{#rustdoc_include ../../../listings/getting-started/variables/src/global_variables.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/variables/src/global_variables.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/variables/src/global_variables.cairo:tests] +``` + +::: diff --git a/src/getting-started/basics/visibility-mutability.md b/src/getting-started/basics/visibility-mutability.md index 7da3c801..24cfab47 100644 --- a/src/getting-started/basics/visibility-mutability.md +++ b/src/getting-started/basics/visibility-mutability.md @@ -24,6 +24,19 @@ Internal functions can't be called externally, but the same principle applies re Let's take a look at a simple example contract to see these in action: +<<<<<<<< HEAD:src/getting-started/basics/visibility-mutability.md ```cairo {{#rustdoc_include ../../../listings/getting-started/visibility/src/visibility.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/visibility/src/visibility.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/visibility-mutability.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/visibility/src/visibility.cairo:tests] ``` + +::: diff --git a/src/getting-started/cairo_cheatsheet/arrays.md b/src/getting-started/cairo_cheatsheet/arrays.md index 036af262..8e7a30ba 100644 --- a/src/getting-started/cairo_cheatsheet/arrays.md +++ b/src/getting-started/cairo_cheatsheet/arrays.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Arrays Arrays are collections of elements of the same type. @@ -19,6 +26,11 @@ trait ArrayTrait { For example: +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/arrays.md ```cairo {{#include ../../../listings/getting-started/cairo_cheatsheet/src/array_example.cairo}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/array_example.cairo] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/arrays.md ``` diff --git a/src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md b/src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md index 173f12b4..57761760 100644 --- a/src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md +++ b/src/getting-started/cairo_cheatsheet/cairo_cheatsheet.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Cairo Cheatsheet This chapter aims to provide a quick reference for the most common Cairo constructs. diff --git a/src/getting-started/cairo_cheatsheet/if_let.md b/src/getting-started/cairo_cheatsheet/if_let.md index 9110b125..f7edd7e7 100644 --- a/src/getting-started/cairo_cheatsheet/if_let.md +++ b/src/getting-started/cairo_cheatsheet/if_let.md @@ -1,12 +1,24 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # `if let` A `if let` statement is a combination of an `if` statement and a `let` statement. It allows you to execute the block only if the pattern matches. It's a cleaner way to handle a `match` statement with only one pattern that you want to handle. +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/if_let.md ```cairo {{#include ../../../listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/if_let.md ``` ### See also [while let](while_let.md) - diff --git a/src/getting-started/cairo_cheatsheet/loop.md b/src/getting-started/cairo_cheatsheet/loop.md index 7411e8b7..7efb6193 100644 --- a/src/getting-started/cairo_cheatsheet/loop.md +++ b/src/getting-started/cairo_cheatsheet/loop.md @@ -1,11 +1,23 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # `loop` A `loop` specifies a block of code that will run repetitively until a halting condition is encountered. For example: +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/loop.md ```cairo {{#include ../../../listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/loop.md ``` ### See also diff --git a/src/getting-started/cairo_cheatsheet/tuples.md b/src/getting-started/cairo_cheatsheet/tuples.md index b81bcabc..6d2935b9 100644 --- a/src/getting-started/cairo_cheatsheet/tuples.md +++ b/src/getting-started/cairo_cheatsheet/tuples.md @@ -1,9 +1,22 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Tuples Tuples is a data type to group a fixed number of items of potentially different types into a single compound structure. Unlike arrays, tuples have a set length and can contain elements of varying types. Once a tuple is created, its size cannot change. For example: +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/tuples.md ```cairo {{#include ../../../listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/tuples.md ``` diff --git a/src/getting-started/cairo_cheatsheet/while_let.md b/src/getting-started/cairo_cheatsheet/while_let.md index fbad1232..c5ec9813 100644 --- a/src/getting-started/cairo_cheatsheet/while_let.md +++ b/src/getting-started/cairo_cheatsheet/while_let.md @@ -1,9 +1,22 @@ +--- +showOutline: false +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # `while let` A `while let` loop is a combination of a `while` loop and a `let` statement. It allows you to execute the loop body only if the pattern matches. +<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/while_let.md ```cairo {{#include ../../../listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet}} +======== +```rust +// [!include ~/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/while_let.md ``` ### See also diff --git a/src/getting-started/interacting/calling_other_contracts.md b/src/getting-started/interacting/calling_other_contracts.md index 72551a44..2768dffe 100644 --- a/src/getting-started/interacting/calling_other_contracts.md +++ b/src/getting-started/interacting/calling_other_contracts.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Calling other contracts There are two different ways to call other contracts in Cairo. @@ -11,6 +18,7 @@ In order to call other contracts using dispatchers, you will need to define the Here's the `Callee` contract interface and implementation: +<<<<<<<< HEAD:src/getting-started/interacting/calling_other_contracts.md ```cairo {{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract}} ``` @@ -19,4 +27,30 @@ The following `Caller` contract uses the `Callee` dispatcher to call the `Callee ```cairo {{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract] +``` + +```rust [tests] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] +``` + +::: + +The following `Caller` contract use the `Callee` interface to call the `Callee` contract: + +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/calling_other_contracts.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] +``` + +::: diff --git a/src/getting-started/interacting/factory.md b/src/getting-started/interacting/factory.md index 64dd47e0..90dd5681 100644 --- a/src/getting-started/interacting/factory.md +++ b/src/getting-started/interacting/factory.md @@ -16,10 +16,23 @@ Using the factory pattern, we can deploy multiple instances of the same contract Here's a minimal example of a factory contract that deploys the `SimpleCounter` contract: +<<<<<<<< HEAD:src/getting-started/interacting/factory.md ```cairo {{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/factory.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:tests] ``` +::: + This factory can be used to deploy multiple instances of the `SimpleCounter` contract by calling the `create_counter` and `create_counter_at` functions. The `SimpleCounter` class hash is stored inside the factory, and can be upgraded with the `update_counter_class_hash` function which allows to reuse the same factory contract when the `SimpleCounter` contract is upgraded. diff --git a/src/getting-started/interacting/interacting.md b/src/getting-started/interacting/interacting.md index 56f111a4..67dc71eb 100644 --- a/src/getting-started/interacting/interacting.md +++ b/src/getting-started/interacting/interacting.md @@ -1,3 +1,10 @@ +--- +content: + horizontalPadding: 50px + width: 100% + verticalPadding: 30px +--- + # Deploy and interact with contracts -In this chapter, we will see how to deploy and interact with contracts. \ No newline at end of file +In this chapter, we will see how to deploy and interact with contracts. diff --git a/src/getting-started/interacting/interfaces-traits.md b/src/getting-started/interacting/interfaces-traits.md index dc69c225..b94760da 100644 --- a/src/getting-started/interacting/interfaces-traits.md +++ b/src/getting-started/interacting/interfaces-traits.md @@ -15,16 +15,42 @@ In summary, there's two ways to handle interfaces: ## Explicit interface +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md ```cairo {{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/explicit.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:tests] ``` +::: + ## Implicit interface +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md ```cairo {{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md +``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:tests] ``` +::: + > Note: You can import an implicitly generated contract interface with `use contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not be generated automatically. ## Internal functions @@ -32,6 +58,19 @@ In summary, there's two ways to handle interfaces: You can also use `#[generate_trait]` for your internal functions. Since this trait is generated in the context of the contract, you can define pure functions as well (functions without the `self` parameter). +<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md ```cairo {{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract}} +======== +:::code-group + +```rust [contract] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md ``` + +```rust [tests] +// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:tests] +``` + +::: diff --git a/src/getting-started/testing/contract-testing.md b/src/getting-started/testing/contract-testing.md index 51d73937..66c80731 100644 --- a/src/getting-started/testing/contract-testing.md +++ b/src/getting-started/testing/contract-testing.md @@ -4,14 +4,24 @@ Testing plays a crucial role in software development, especially for smart contr Let's start with a simple smart contract as an example: +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md ```cairo {{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:contract}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:contract] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md ``` Now, take a look at the tests for this contract: +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md ```cairo {{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md ``` To define our test, we use scarb, which allows us to create a separate module guarded with `#[cfg(test)]`. This ensures that the test module is only compiled when running tests using `scarb test`. @@ -39,18 +49,28 @@ This can be useful for testing internal functions, or specific state mutations t Here is an example of how to do the same previous test using the contract state: +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md ```cairo {{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state}} +======== +```rust +// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md ``` ## Testing events In order to test events, you need to use the `starknet::pop_log` function. If the contract did not emit any events, the function will return `Option::None`. -See the test for the [Events](../events.md) section: +See the test for the [Events](../basics/events.md) section: +<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md ```cairo {{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:test_events}} +======== +```rust +// [!include ~/listings/getting-started/events/src/counter.cairo:test_events] +>>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md ``` ## Starknet Corelib Testing Module diff --git a/theme/book.js b/theme/book.js deleted file mode 100644 index 8b8004ff..00000000 --- a/theme/book.js +++ /dev/null @@ -1,792 +0,0 @@ -"use strict"; - -// Fix back button cache problem -window.onunload = function () {}; - -// Global variable, shared between modules -function playground_text(playground, hidden = true) { - let code_block = playground.querySelector("code"); - - if (window.ace && code_block.classList.contains("editable")) { - let editor = window.ace.edit(code_block); - return editor.getValue(); - } else if (hidden) { - return code_block.textContent; - } else { - return code_block.innerText; - } -} - -(function codeSnippets() { - function fetch_with_timeout(url, options, timeout = 6000) { - return Promise.race([ - fetch(url, options), - new Promise((_, reject) => - setTimeout(() => reject(new Error("timeout")), timeout) - ), - ]); - } - - var playgrounds = Array.from(document.querySelectorAll(".playground")); - if (playgrounds.length > 0) { - fetch_with_timeout("https://play.rust-lang.org/meta/crates", { - headers: { - "Content-Type": "application/json", - }, - method: "POST", - mode: "cors", - }) - .then((response) => response.json()) - .then((response) => { - // get list of crates available in the rust playground - let playground_crates = response.crates.map((item) => item["id"]); - playgrounds.forEach((block) => - handle_crate_list_update(block, playground_crates) - ); - }); - } - - function handle_crate_list_update(playground_block, playground_crates) { - // update the play buttons after receiving the response - update_play_button(playground_block, playground_crates); - - // and install on change listener to dynamically update ACE editors - if (window.ace) { - let code_block = playground_block.querySelector("code"); - if (code_block.classList.contains("editable")) { - let editor = window.ace.edit(code_block); - editor.addEventListener("change", function (e) { - update_play_button(playground_block, playground_crates); - }); - // add Ctrl-Enter command to execute rust code - editor.commands.addCommand({ - name: "run", - bindKey: { - win: "Ctrl-Enter", - mac: "Ctrl-Enter", - }, - exec: (_editor) => run_rust_code(playground_block), - }); - } - } - } - - // updates the visibility of play button based on `no_run` class and - // used crates vs ones available on https://play.rust-lang.org - function update_play_button(pre_block, playground_crates) { - var play_button = pre_block.querySelector(".play-button"); - - // skip if code is `no_run` - if (pre_block.querySelector("code").classList.contains("no_run")) { - play_button.classList.add("hidden"); - return; - } - - // get list of `extern crate`'s from snippet - var txt = playground_text(pre_block); - var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; - var snippet_crates = []; - var item; - while ((item = re.exec(txt))) { - snippet_crates.push(item[1]); - } - - // check if all used crates are available on play.rust-lang.org - var all_available = snippet_crates.every(function (elem) { - return playground_crates.indexOf(elem) > -1; - }); - - if (all_available) { - play_button.classList.remove("hidden"); - } else { - play_button.classList.add("hidden"); - } - } - - function run_rust_code(code_block) { - var result_block = code_block.querySelector(".result"); - if (!result_block) { - result_block = document.createElement("code"); - result_block.className = "result hljs language-bash"; - - code_block.append(result_block); - } - - let text = playground_text(code_block); - let classes = code_block.querySelector("code").classList; - let edition = "2015"; - if (classes.contains("edition2018")) { - edition = "2018"; - } else if (classes.contains("edition2021")) { - edition = "2021"; - } - var params = { - version: "stable", - optimize: "0", - code: text, - edition: edition, - }; - - if (text.indexOf("#![feature") !== -1) { - params.version = "nightly"; - } - - result_block.innerText = "Running..."; - - fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { - headers: { - "Content-Type": "application/json", - }, - method: "POST", - mode: "cors", - body: JSON.stringify(params), - }) - .then((response) => response.json()) - .then((response) => { - if (response.result.trim() === "") { - result_block.innerText = "No output"; - result_block.classList.add("result-no-output"); - } else { - result_block.innerText = response.result; - result_block.classList.remove("result-no-output"); - } - }) - .catch( - (error) => - (result_block.innerText = - "Playground Communication: " + error.message) - ); - } - - // Syntax highlighting Configuration - hljs.configure({ - tabReplace: " ", // 4 spaces - languages: [], // Languages used for auto-detection - }); - - let code_nodes = Array.from(document.querySelectorAll("code")) - // Don't highlight `inline code` blocks in headers. - .filter(function (node) { - return !node.parentElement.classList.contains("header"); - }); - - if (window.ace) { - // language-cairo class needs to be removed for editable - // blocks or highlightjs will capture events - code_nodes - .filter(function (node) { - return node.classList.contains("editable"); - }) - .forEach(function (block) { - block.classList.remove("language-cairo"); - }); - - code_nodes - .filter(function (node) { - return !node.classList.contains("editable"); - }) - .forEach(function (block) { - hljs.highlightBlock(block); - }); - } else { - code_nodes.forEach(function (block) { - hljs.highlightBlock(block); - }); - } - - // Adding the hljs class gives code blocks the color css - // even if highlighting doesn't apply - code_nodes.forEach(function (block) { - block.classList.add("hljs"); - }); - - Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) { - var lines = Array.from(block.querySelectorAll(".boring")); - // If no lines were hidden, return - if (!lines.length) { - return; - } - block.classList.add("hide-boring"); - - var buttons = document.createElement("div"); - buttons.className = "buttons"; - buttons.innerHTML = - ''; - - // add expand button - var pre_block = block.parentNode; - pre_block.insertBefore(buttons, pre_block.firstChild); - - pre_block.querySelector(".buttons").addEventListener("click", function (e) { - if (e.target.classList.contains("fa-eye")) { - e.target.classList.remove("fa-eye"); - e.target.classList.add("fa-eye-slash"); - e.target.title = "Hide lines"; - e.target.setAttribute("aria-label", e.target.title); - - block.classList.remove("hide-boring"); - } else if (e.target.classList.contains("fa-eye-slash")) { - e.target.classList.remove("fa-eye-slash"); - e.target.classList.add("fa-eye"); - e.target.title = "Show hidden lines"; - e.target.setAttribute("aria-label", e.target.title); - - block.classList.add("hide-boring"); - } - }); - }); - - if (window.playground_copyable) { - Array.from(document.querySelectorAll("pre code")).forEach(function (block) { - var pre_block = block.parentNode; - if (!pre_block.classList.contains("playground")) { - var buttons = pre_block.querySelector(".buttons"); - if (!buttons) { - buttons = document.createElement("div"); - buttons.className = "buttons"; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - var clipButton = document.createElement("button"); - clipButton.className = "fa fa-copy clip-button"; - clipButton.title = "Copy to clipboard"; - clipButton.setAttribute("aria-label", clipButton.title); - clipButton.innerHTML = ''; - - buttons.insertBefore(clipButton, buttons.firstChild); - } - }); - } - - // Process playground code blocks - Array.from(document.querySelectorAll(".playground")).forEach(function ( - pre_block - ) { - // Add play button - var buttons = pre_block.querySelector(".buttons"); - if (!buttons) { - buttons = document.createElement("div"); - buttons.className = "buttons"; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - var runCodeButton = document.createElement("button"); - runCodeButton.className = "fa fa-play play-button"; - runCodeButton.hidden = true; - runCodeButton.title = "Run this code"; - runCodeButton.setAttribute("aria-label", runCodeButton.title); - - buttons.insertBefore(runCodeButton, buttons.firstChild); - runCodeButton.addEventListener("click", function (e) { - run_rust_code(pre_block); - }); - - if (window.playground_copyable) { - var copyCodeClipboardButton = document.createElement("button"); - copyCodeClipboardButton.className = "fa fa-copy clip-button"; - copyCodeClipboardButton.innerHTML = ''; - copyCodeClipboardButton.title = "Copy to clipboard"; - copyCodeClipboardButton.setAttribute( - "aria-label", - copyCodeClipboardButton.title - ); - - buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); - } - - let code_block = pre_block.querySelector("code"); - if (window.ace && code_block.classList.contains("editable")) { - var undoChangesButton = document.createElement("button"); - undoChangesButton.className = "fa fa-history reset-button"; - undoChangesButton.title = "Undo changes"; - undoChangesButton.setAttribute("aria-label", undoChangesButton.title); - - buttons.insertBefore(undoChangesButton, buttons.firstChild); - - undoChangesButton.addEventListener("click", function () { - let editor = window.ace.edit(code_block); - editor.setValue(editor.originalCode); - editor.clearSelection(); - }); - } - }); -})(); - -(function themes() { - var html = document.querySelector("html"); - var themeToggleButton = document.getElementById("theme-toggle"); - var themePopup = document.getElementById("theme-list"); - var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); - var stylesheets = { - ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), - tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), - highlight: document.querySelector("[href$='highlight.css']"), - }; - - function showThemes() { - themePopup.style.display = "block"; - themeToggleButton.setAttribute("aria-expanded", true); - themePopup.querySelector("button#" + get_theme()).focus(); - } - - function updateThemeSelected() { - themePopup.querySelectorAll(".theme-selected").forEach(function (el) { - el.classList.remove("theme-selected"); - }); - themePopup - .querySelector("button#" + get_theme()) - .classList.add("theme-selected"); - } - - function hideThemes() { - themePopup.style.display = "none"; - themeToggleButton.setAttribute("aria-expanded", false); - themeToggleButton.focus(); - } - - function get_theme() { - var theme; - try { - theme = localStorage.getItem("mdbook-theme"); - } catch (e) {} - if (theme === null || theme === undefined) { - return default_theme; - } else { - return theme; - } - } - - function set_theme(theme, store = true) { - let ace_theme; - - if (theme == "coal" || theme == "navy") { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = false; - stylesheets.highlight.disabled = true; - - ace_theme = "ace/theme/tomorrow_night"; - } else if (theme == "ayu") { - stylesheets.ayuHighlight.disabled = false; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = true; - ace_theme = "ace/theme/tomorrow_night"; - } else { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = false; - ace_theme = "ace/theme/dawn"; - } - - setTimeout(function () { - themeColorMetaTag.content = getComputedStyle( - document.documentElement - ).backgroundColor; - }, 1); - - if (window.ace && window.editors) { - window.editors.forEach(function (editor) { - editor.setTheme(ace_theme); - }); - } - - var previousTheme = get_theme(); - - if (store) { - try { - localStorage.setItem("mdbook-theme", theme); - } catch (e) {} - } - - html.classList.remove(previousTheme); - html.classList.add(theme); - updateThemeSelected(); - } - - // Set theme - var theme = get_theme(); - - set_theme(theme, false); - - themeToggleButton.addEventListener("click", function () { - if (themePopup.style.display === "block") { - hideThemes(); - } else { - showThemes(); - } - }); - - themePopup.addEventListener("click", function (e) { - var theme; - if (e.target.className === "theme") { - theme = e.target.id; - } else if (e.target.parentElement.className === "theme") { - theme = e.target.parentElement.id; - } else { - return; - } - set_theme(theme); - }); - - themePopup.addEventListener("focusout", function (e) { - // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) - if ( - !!e.relatedTarget && - !themeToggleButton.contains(e.relatedTarget) && - !themePopup.contains(e.relatedTarget) - ) { - hideThemes(); - } - }); - - // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 - document.addEventListener("click", function (e) { - if ( - themePopup.style.display === "block" && - !themeToggleButton.contains(e.target) && - !themePopup.contains(e.target) - ) { - hideThemes(); - } - }); - - document.addEventListener("keydown", function (e) { - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { - return; - } - if (!themePopup.contains(e.target)) { - return; - } - - switch (e.key) { - case "Escape": - e.preventDefault(); - hideThemes(); - break; - case "ArrowUp": - e.preventDefault(); - var li = document.activeElement.parentElement; - if (li && li.previousElementSibling) { - li.previousElementSibling.querySelector("button").focus(); - } - break; - case "ArrowDown": - e.preventDefault(); - var li = document.activeElement.parentElement; - if (li && li.nextElementSibling) { - li.nextElementSibling.querySelector("button").focus(); - } - break; - case "Home": - e.preventDefault(); - themePopup.querySelector("li:first-child button").focus(); - break; - case "End": - e.preventDefault(); - themePopup.querySelector("li:last-child button").focus(); - break; - } - }); -})(); - -(function sidebar() { - var body = document.querySelector("body"); - var sidebar = document.getElementById("sidebar"); - var sidebarLinks = document.querySelectorAll("#sidebar a"); - var sidebarToggleButton = document.getElementById("sidebar-toggle"); - var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); - var firstContact = null; - - function showSidebar() { - body.classList.remove("sidebar-hidden"); - body.classList.add("sidebar-visible"); - Array.from(sidebarLinks).forEach(function (link) { - link.setAttribute("tabIndex", 0); - }); - sidebarToggleButton.setAttribute("aria-expanded", true); - sidebar.setAttribute("aria-hidden", false); - try { - localStorage.setItem("mdbook-sidebar", "visible"); - } catch (e) {} - } - - var sidebarAnchorToggles = document.querySelectorAll("#sidebar a.toggle"); - - function toggleSection(ev) { - ev.currentTarget.parentElement.classList.toggle("expanded"); - const toggleId = ev.currentTarget.parentElement.getAttribute("toggle-id"); - const isExpanded = - ev.currentTarget.parentElement.classList.contains("expanded"); - try { - localStorage.setItem( - `mdbook-sidebar-toggle-${toggleId}`, - isExpanded ? 1 : 0 - ); - } catch (e) {} - } - - Array.from(sidebarAnchorToggles).forEach(function (el, id) { - el.parentElement.setAttribute("toggle-id", id); - const isActive = - el.parentElement.nextSibling.querySelector(".active") !== null || - el.previousSibling.classList.contains("active"); - if (!isActive) { - try { - const isExpanded = - localStorage.getItem(`mdbook-sidebar-toggle-${id}`) === "1"; - if (!isExpanded) { - el.parentElement.classList.remove("expanded"); - } - localStorage.setItem(`mdbook-sidebar-toggle-${id}`, isExpanded ? 1 : 0); - } catch (e) { - el.parentElement.classList.remove("expanded"); - } - } - el.addEventListener("click", toggleSection); - }); - - function hideSidebar() { - body.classList.remove("sidebar-visible"); - body.classList.add("sidebar-hidden"); - Array.from(sidebarLinks).forEach(function (link) { - link.setAttribute("tabIndex", -1); - }); - sidebarToggleButton.setAttribute("aria-expanded", false); - sidebar.setAttribute("aria-hidden", true); - try { - localStorage.setItem("mdbook-sidebar", "hidden"); - } catch (e) {} - } - - // Toggle sidebar - sidebarToggleButton.addEventListener("click", function sidebarToggle() { - if (body.classList.contains("sidebar-hidden")) { - var current_width = parseInt( - document.documentElement.style.getPropertyValue("--sidebar-width"), - 10 - ); - if (current_width < 150) { - document.documentElement.style.setProperty("--sidebar-width", "150px"); - } - showSidebar(); - } else if (body.classList.contains("sidebar-visible")) { - hideSidebar(); - } else { - if (getComputedStyle(sidebar)["transform"] === "none") { - hideSidebar(); - } else { - showSidebar(); - } - } - }); - - sidebarResizeHandle.addEventListener("mousedown", initResize, false); - - function initResize(e) { - window.addEventListener("mousemove", resize, false); - window.addEventListener("mouseup", stopResize, false); - body.classList.add("sidebar-resizing"); - } - function resize(e) { - var pos = e.clientX - sidebar.offsetLeft; - if (pos < 20) { - hideSidebar(); - } else { - if (body.classList.contains("sidebar-hidden")) { - showSidebar(); - } - pos = Math.min(pos, window.innerWidth - 100); - document.documentElement.style.setProperty("--sidebar-width", pos + "px"); - } - } - //on mouseup remove windows functions mousemove & mouseup - function stopResize(e) { - body.classList.remove("sidebar-resizing"); - window.removeEventListener("mousemove", resize, false); - window.removeEventListener("mouseup", stopResize, false); - } - - document.addEventListener( - "touchstart", - function (e) { - firstContact = { - x: e.touches[0].clientX, - time: Date.now(), - }; - }, - { passive: true } - ); - - document.addEventListener( - "touchmove", - function (e) { - if (!firstContact) return; - - var curX = e.touches[0].clientX; - var xDiff = curX - firstContact.x, - tDiff = Date.now() - firstContact.time; - - if (tDiff < 250 && Math.abs(xDiff) >= 150) { - if ( - xDiff >= 0 && - firstContact.x < Math.min(document.body.clientWidth * 0.25, 300) - ) - showSidebar(); - else if (xDiff < 0 && curX < 300) hideSidebar(); - - firstContact = null; - } - }, - { passive: true } - ); -})(); - -(function chapterNavigation() { - document.addEventListener("keydown", function (e) { - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { - return; - } - if (window.search && window.search.hasFocus()) { - return; - } - var html = document.querySelector("html"); - - function next() { - var nextButton = document.querySelector(".nav-chapters.next"); - if (nextButton) { - window.location.href = nextButton.href; - } - } - function prev() { - var previousButton = document.querySelector(".nav-chapters.previous"); - if (previousButton) { - window.location.href = previousButton.href; - } - } - switch (e.key) { - case "ArrowRight": - e.preventDefault(); - if (html.dir == "rtl") { - prev(); - } else { - next(); - } - break; - case "ArrowLeft": - e.preventDefault(); - if (html.dir == "rtl") { - next(); - } else { - prev(); - } - break; - } - }); -})(); - -(function clipboard() { - var clipButtons = document.querySelectorAll(".clip-button"); - - function hideTooltip(elem) { - elem.firstChild.innerText = ""; - elem.className = "fa fa-copy clip-button"; - } - - function showTooltip(elem, msg) { - elem.firstChild.innerText = msg; - elem.className = "fa fa-copy tooltipped"; - } - - var clipboardSnippets = new ClipboardJS(".clip-button", { - text: function (trigger) { - hideTooltip(trigger); - let playground = trigger.closest("pre"); - return playground_text(playground, false); - }, - }); - - Array.from(clipButtons).forEach(function (clipButton) { - clipButton.addEventListener("mouseout", function (e) { - hideTooltip(e.currentTarget); - }); - }); - - clipboardSnippets.on("success", function (e) { - e.clearSelection(); - showTooltip(e.trigger, "Copied!"); - }); - - clipboardSnippets.on("error", function (e) { - showTooltip(e.trigger, "Clipboard error!"); - }); -})(); - -(function scrollToTop() { - var menuTitle = document.querySelector(".menu-title"); - - menuTitle.addEventListener("click", function () { - document.scrollingElement.scrollTo({ top: 0, behavior: "smooth" }); - }); -})(); - -(function controllMenu() { - var menu = document.getElementById("menu-bar"); - - (function controllPosition() { - var scrollTop = document.scrollingElement.scrollTop; - var prevScrollTop = scrollTop; - var minMenuY = -menu.clientHeight - 50; - // When the script loads, the page can be at any scroll (e.g. if you reforesh it). - menu.style.top = scrollTop + "px"; - // Same as parseInt(menu.style.top.slice(0, -2), but faster - var topCache = menu.style.top.slice(0, -2); - menu.classList.remove("sticky"); - var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster - document.addEventListener( - "scroll", - function () { - scrollTop = Math.max(document.scrollingElement.scrollTop, 0); - // `null` means that it doesn't need to be updated - var nextSticky = null; - var nextTop = null; - var scrollDown = scrollTop > prevScrollTop; - var menuPosAbsoluteY = topCache - scrollTop; - if (scrollDown) { - nextSticky = false; - if (menuPosAbsoluteY > 0) { - nextTop = prevScrollTop; - } - } else { - if (menuPosAbsoluteY > 0) { - nextSticky = true; - } else if (menuPosAbsoluteY < minMenuY) { - nextTop = prevScrollTop + minMenuY; - } - } - if (nextSticky === true && stickyCache === false) { - menu.classList.add("sticky"); - stickyCache = true; - } else if (nextSticky === false && stickyCache === true) { - menu.classList.remove("sticky"); - stickyCache = false; - } - if (nextTop !== null) { - menu.style.top = nextTop + "px"; - topCache = nextTop; - } - prevScrollTop = scrollTop; - }, - { passive: true } - ); - })(); - (function controllBorder() { - function updateBorder() { - if (menu.offsetTop === 0) { - menu.classList.remove("bordered"); - } else { - menu.classList.add("bordered"); - } - } - updateBorder(); - document.addEventListener("scroll", updateBorder, { passive: true }); - })(); -})(); diff --git a/theme/css/catppuccin.css b/theme/css/catppuccin.css deleted file mode 100644 index 1ac81462..00000000 --- a/theme/css/catppuccin.css +++ /dev/null @@ -1,787 +0,0 @@ -.mocha.hljs { - color: #cdd6f4; - background: #1e1e2e; -} -.mocha .hljs-keyword { - color: #cba6f7; -} -.mocha .hljs-built_in { - color: #f38ba8; -} -.mocha .hljs-type { - color: #f9e2af; -} -.mocha .hljs-literal { - color: #fab387; -} -.mocha .hljs-number { - color: #fab387; -} -.mocha .hljs-operator { - color: #94e2d5; -} -.mocha .hljs-punctuation { - color: #bac2de; -} -.mocha .hljs-property { - color: #94e2d5; -} -.mocha .hljs-regexp { - color: #f5c2e7; -} -.mocha .hljs-string { - color: #a6e3a1; -} -.mocha .hljs-char.escape_ { - color: #a6e3a1; -} -.mocha .hljs-subst { - color: #a6adc8; -} -.mocha .hljs-symbol { - color: #f2cdcd; -} -.mocha .hljs-variable { - color: #cba6f7; -} -.mocha .hljs-variable.language_ { - color: #cba6f7; -} -.mocha .hljs-variable.constant_ { - color: #fab387; -} -.mocha .hljs-title { - color: #89b4fa; -} -.mocha .hljs-title.class_ { - color: #f9e2af; -} -.mocha .hljs-title.function_ { - color: #89b4fa; -} -.mocha .hljs-params { - color: #cdd6f4; -} -.mocha .hljs-comment { - color: #585b70; -} -.mocha .hljs-doctag { - color: #f38ba8; -} -.mocha .hljs-meta { - color: #fab387; -} -.mocha .hljs-section { - color: #89b4fa; -} -.mocha .hljs-tag { - color: #a6adc8; -} -.mocha .hljs-name { - color: #cba6f7; -} -.mocha .hljs-attr { - color: #89b4fa; -} -.mocha .hljs-attribute { - color: #a6e3a1; -} -.mocha .hljs-bullet { - color: #94e2d5; -} -.mocha .hljs-code { - color: #a6e3a1; -} -.mocha .hljs-emphasis { - color: #f38ba8; - font-style: italic; -} -.mocha .hljs-strong { - color: #f38ba8; - font-weight: bold; -} -.mocha .hljs-formula { - color: #94e2d5; -} -.mocha .hljs-link { - color: #74c7ec; - font-style: italic; -} -.mocha .hljs-quote { - color: #a6e3a1; - font-style: italic; -} -.mocha .hljs-selector-tag { - color: #f9e2af; -} -.mocha .hljs-selector-id { - color: #89b4fa; -} -.mocha .hljs-selector-class { - color: #94e2d5; -} -.mocha .hljs-selector-attr { - color: #cba6f7; -} -.mocha .hljs-selector-pseudo { - color: #94e2d5; -} -.mocha .hljs-template-tag { - color: #f2cdcd; -} -.mocha .hljs-template-variable { - color: #f2cdcd; -} -.mocha .hljs-addition { - color: #a6e3a1; - background: rgba(166, 227, 161, 0.15); -} -.mocha .hljs-deletion { - color: #f38ba8; - background: rgba(243, 139, 168, 0.15); -} -.mocha code { - color: #cdd6f4; - background: #181825; -} -.mocha blockquote blockquote { - border-top: 0.1em solid #585b70; - border-bottom: 0.1em solid #585b70; -} -.mocha hr { - color: #585b70; -} -.mocha del { - color: #9399b2; -} -.mocha .ace_gutter { - color: #7f849c; - background: #181825; -} -.mocha .ace_gutter-active-line.ace_gutter-cell { - color: #f5c2e7; - background: #181825; -} - -.macchiato.hljs { - color: #cad3f5; - background: #24273a; -} -.macchiato .hljs-keyword { - color: #c6a0f6; -} -.macchiato .hljs-built_in { - color: #ed8796; -} -.macchiato .hljs-type { - color: #eed49f; -} -.macchiato .hljs-literal { - color: #f5a97f; -} -.macchiato .hljs-number { - color: #f5a97f; -} -.macchiato .hljs-operator { - color: #8bd5ca; -} -.macchiato .hljs-punctuation { - color: #b8c0e0; -} -.macchiato .hljs-property { - color: #8bd5ca; -} -.macchiato .hljs-regexp { - color: #f5bde6; -} -.macchiato .hljs-string { - color: #a6da95; -} -.macchiato .hljs-char.escape_ { - color: #a6da95; -} -.macchiato .hljs-subst { - color: #a5adcb; -} -.macchiato .hljs-symbol { - color: #f0c6c6; -} -.macchiato .hljs-variable { - color: #c6a0f6; -} -.macchiato .hljs-variable.language_ { - color: #c6a0f6; -} -.macchiato .hljs-variable.constant_ { - color: #f5a97f; -} -.macchiato .hljs-title { - color: #8aadf4; -} -.macchiato .hljs-title.class_ { - color: #eed49f; -} -.macchiato .hljs-title.function_ { - color: #8aadf4; -} -.macchiato .hljs-params { - color: #cad3f5; -} -.macchiato .hljs-comment { - color: #5b6078; -} -.macchiato .hljs-doctag { - color: #ed8796; -} -.macchiato .hljs-meta { - color: #f5a97f; -} -.macchiato .hljs-section { - color: #8aadf4; -} -.macchiato .hljs-tag { - color: #a5adcb; -} -.macchiato .hljs-name { - color: #c6a0f6; -} -.macchiato .hljs-attr { - color: #8aadf4; -} -.macchiato .hljs-attribute { - color: #a6da95; -} -.macchiato .hljs-bullet { - color: #8bd5ca; -} -.macchiato .hljs-code { - color: #a6da95; -} -.macchiato .hljs-emphasis { - color: #ed8796; - font-style: italic; -} -.macchiato .hljs-strong { - color: #ed8796; - font-weight: bold; -} -.macchiato .hljs-formula { - color: #8bd5ca; -} -.macchiato .hljs-link { - color: #7dc4e4; - font-style: italic; -} -.macchiato .hljs-quote { - color: #a6da95; - font-style: italic; -} -.macchiato .hljs-selector-tag { - color: #eed49f; -} -.macchiato .hljs-selector-id { - color: #8aadf4; -} -.macchiato .hljs-selector-class { - color: #8bd5ca; -} -.macchiato .hljs-selector-attr { - color: #c6a0f6; -} -.macchiato .hljs-selector-pseudo { - color: #8bd5ca; -} -.macchiato .hljs-template-tag { - color: #f0c6c6; -} -.macchiato .hljs-template-variable { - color: #f0c6c6; -} -.macchiato .hljs-addition { - color: #a6da95; - background: rgba(166, 218, 149, 0.15); -} -.macchiato .hljs-deletion { - color: #ed8796; - background: rgba(237, 135, 150, 0.15); -} -.macchiato code { - color: #cad3f5; - background: #1e2030; -} -.macchiato blockquote blockquote { - border-top: 0.1em solid #5b6078; - border-bottom: 0.1em solid #5b6078; -} -.macchiato hr { - color: #5b6078; -} -.macchiato del { - color: #939ab7; -} -.macchiato .ace_gutter { - color: #8087a2; - background: #1e2030; -} -.macchiato .ace_gutter-active-line.ace_gutter-cell { - color: #f5bde6; - background: #1e2030; -} - -.frappe.hljs { - color: #c6d0f5; - background: #303446; -} -.frappe .hljs-keyword { - color: #ca9ee6; -} -.frappe .hljs-built_in { - color: #e78284; -} -.frappe .hljs-type { - color: #e5c890; -} -.frappe .hljs-literal { - color: #ef9f76; -} -.frappe .hljs-number { - color: #ef9f76; -} -.frappe .hljs-operator { - color: #81c8be; -} -.frappe .hljs-punctuation { - color: #b5bfe2; -} -.frappe .hljs-property { - color: #81c8be; -} -.frappe .hljs-regexp { - color: #f4b8e4; -} -.frappe .hljs-string { - color: #a6d189; -} -.frappe .hljs-char.escape_ { - color: #a6d189; -} -.frappe .hljs-subst { - color: #a5adce; -} -.frappe .hljs-symbol { - color: #eebebe; -} -.frappe .hljs-variable { - color: #ca9ee6; -} -.frappe .hljs-variable.language_ { - color: #ca9ee6; -} -.frappe .hljs-variable.constant_ { - color: #ef9f76; -} -.frappe .hljs-title { - color: #8caaee; -} -.frappe .hljs-title.class_ { - color: #e5c890; -} -.frappe .hljs-title.function_ { - color: #8caaee; -} -.frappe .hljs-params { - color: #c6d0f5; -} -.frappe .hljs-comment { - color: #626880; -} -.frappe .hljs-doctag { - color: #e78284; -} -.frappe .hljs-meta { - color: #ef9f76; -} -.frappe .hljs-section { - color: #8caaee; -} -.frappe .hljs-tag { - color: #a5adce; -} -.frappe .hljs-name { - color: #ca9ee6; -} -.frappe .hljs-attr { - color: #8caaee; -} -.frappe .hljs-attribute { - color: #a6d189; -} -.frappe .hljs-bullet { - color: #81c8be; -} -.frappe .hljs-code { - color: #a6d189; -} -.frappe .hljs-emphasis { - color: #e78284; - font-style: italic; -} -.frappe .hljs-strong { - color: #e78284; - font-weight: bold; -} -.frappe .hljs-formula { - color: #81c8be; -} -.frappe .hljs-link { - color: #85c1dc; - font-style: italic; -} -.frappe .hljs-quote { - color: #a6d189; - font-style: italic; -} -.frappe .hljs-selector-tag { - color: #e5c890; -} -.frappe .hljs-selector-id { - color: #8caaee; -} -.frappe .hljs-selector-class { - color: #81c8be; -} -.frappe .hljs-selector-attr { - color: #ca9ee6; -} -.frappe .hljs-selector-pseudo { - color: #81c8be; -} -.frappe .hljs-template-tag { - color: #eebebe; -} -.frappe .hljs-template-variable { - color: #eebebe; -} -.frappe .hljs-addition { - color: #a6d189; - background: rgba(166, 209, 137, 0.15); -} -.frappe .hljs-deletion { - color: #e78284; - background: rgba(231, 130, 132, 0.15); -} -.frappe code { - color: #c6d0f5; - background: #292c3c; -} -.frappe blockquote blockquote { - border-top: 0.1em solid #626880; - border-bottom: 0.1em solid #626880; -} -.frappe hr { - color: #626880; -} -.frappe del { - color: #949cbb; -} -.frappe .ace_gutter { - color: #838ba7; - background: #292c3c; -} -.frappe .ace_gutter-active-line.ace_gutter-cell { - color: #f4b8e4; - background: #292c3c; -} - -.latte.hljs { - color: #4c4f69; - background: #eff1f5; -} -.latte .hljs-keyword { - color: #8839ef; -} -.latte .hljs-built_in { - color: #d20f39; -} -.latte .hljs-type { - color: #df8e1d; -} -.latte .hljs-literal { - color: #fe640b; -} -.latte .hljs-number { - color: #fe640b; -} -.latte .hljs-operator { - color: #179299; -} -.latte .hljs-punctuation { - color: #5c5f77; -} -.latte .hljs-property { - color: #179299; -} -.latte .hljs-regexp { - color: #ea76cb; -} -.latte .hljs-string { - color: #40a02b; -} -.latte .hljs-char.escape_ { - color: #40a02b; -} -.latte .hljs-subst { - color: #6c6f85; -} -.latte .hljs-symbol { - color: #dd7878; -} -.latte .hljs-variable { - color: #8839ef; -} -.latte .hljs-variable.language_ { - color: #8839ef; -} -.latte .hljs-variable.constant_ { - color: #fe640b; -} -.latte .hljs-title { - color: #1e66f5; -} -.latte .hljs-title.class_ { - color: #df8e1d; -} -.latte .hljs-title.function_ { - color: #1e66f5; -} -.latte .hljs-params { - color: #4c4f69; -} -.latte .hljs-comment { - color: #acb0be; -} -.latte .hljs-doctag { - color: #d20f39; -} -.latte .hljs-meta { - color: #fe640b; -} -.latte .hljs-section { - color: #1e66f5; -} -.latte .hljs-tag { - color: #6c6f85; -} -.latte .hljs-name { - color: #8839ef; -} -.latte .hljs-attr { - color: #1e66f5; -} -.latte .hljs-attribute { - color: #40a02b; -} -.latte .hljs-bullet { - color: #179299; -} -.latte .hljs-code { - color: #40a02b; -} -.latte .hljs-emphasis { - color: #d20f39; - font-style: italic; -} -.latte .hljs-strong { - color: #d20f39; - font-weight: bold; -} -.latte .hljs-formula { - color: #179299; -} -.latte .hljs-link { - color: #209fb5; - font-style: italic; -} -.latte .hljs-quote { - color: #40a02b; - font-style: italic; -} -.latte .hljs-selector-tag { - color: #df8e1d; -} -.latte .hljs-selector-id { - color: #1e66f5; -} -.latte .hljs-selector-class { - color: #179299; -} -.latte .hljs-selector-attr { - color: #8839ef; -} -.latte .hljs-selector-pseudo { - color: #179299; -} -.latte .hljs-template-tag { - color: #dd7878; -} -.latte .hljs-template-variable { - color: #dd7878; -} -.latte .hljs-addition { - color: #40a02b; - background: rgba(64, 160, 43, 0.15); -} -.latte .hljs-deletion { - color: #d20f39; - background: rgba(210, 15, 57, 0.15); -} -.latte code { - color: #4c4f69; - background: #e6e9ef; -} -.latte blockquote blockquote { - border-top: 0.1em solid #acb0be; - border-bottom: 0.1em solid #acb0be; -} -.latte hr { - color: #acb0be; -} -.latte del { - color: #7c7f93; -} -.latte .ace_gutter { - color: #8c8fa1; - background: #e6e9ef; -} -.latte .ace_gutter-active-line.ace_gutter-cell { - color: #ea76cb; - background: #e6e9ef; -} - -.mocha { - --bg: #1e1e2e; - --fg: #cdd6f4; - --sidebar-bg: #181825; - --sidebar-fg: #cdd6f4; - --sidebar-non-existant: #6c7086; - --sidebar-active: #89b4fa; - --sidebar-spacer: #6c7086; - --scrollbar: #6c7086; - --icons: #6c7086; - --icons-hover: #7f849c; - --links: #89b4fa; - --inline-code-color: #fab387; - --theme-popup-bg: #181825; - --theme-popup-border: #6c7086; - --theme-hover: #6c7086; - --quote-bg: #181825; - --quote-border: #11111b; - --table-border-color: #11111b; - --table-header-bg: #181825; - --table-alternate-bg: #181825; - --searchbar-border-color: #11111b; - --searchbar-bg: #181825; - --searchbar-fg: #cdd6f4; - --searchbar-shadow-color: #11111b; - --searchresults-header-fg: #cdd6f4; - --searchresults-border-color: #11111b; - --searchresults-li-bg: #1e1e2e; - --search-mark-bg: #fab387; - --warning-border: #fab387; -} - -.macchiato { - --bg: #24273a; - --fg: #cad3f5; - --sidebar-bg: #1e2030; - --sidebar-fg: #cad3f5; - --sidebar-non-existant: #6e738d; - --sidebar-active: #8aadf4; - --sidebar-spacer: #6e738d; - --scrollbar: #6e738d; - --icons: #6e738d; - --icons-hover: #8087a2; - --links: #8aadf4; - --inline-code-color: #f5a97f; - --theme-popup-bg: #1e2030; - --theme-popup-border: #6e738d; - --theme-hover: #6e738d; - --quote-bg: #1e2030; - --quote-border: #181926; - --table-border-color: #181926; - --table-header-bg: #1e2030; - --table-alternate-bg: #1e2030; - --searchbar-border-color: #181926; - --searchbar-bg: #1e2030; - --searchbar-fg: #cad3f5; - --searchbar-shadow-color: #181926; - --searchresults-header-fg: #cad3f5; - --searchresults-border-color: #181926; - --searchresults-li-bg: #24273a; - --search-mark-bg: #f5a97f; - --warning-border: #f5a97f; -} - -.frappe { - --bg: #303446; - --fg: #c6d0f5; - --sidebar-bg: #292c3c; - --sidebar-fg: #c6d0f5; - --sidebar-non-existant: #737994; - --sidebar-active: #8caaee; - --sidebar-spacer: #737994; - --scrollbar: #737994; - --icons: #737994; - --icons-hover: #838ba7; - --links: #8caaee; - --inline-code-color: #ef9f76; - --theme-popup-bg: #292c3c; - --theme-popup-border: #737994; - --theme-hover: #737994; - --quote-bg: #292c3c; - --quote-border: #232634; - --table-border-color: #232634; - --table-header-bg: #292c3c; - --table-alternate-bg: #292c3c; - --searchbar-border-color: #232634; - --searchbar-bg: #292c3c; - --searchbar-fg: #c6d0f5; - --searchbar-shadow-color: #232634; - --searchresults-header-fg: #c6d0f5; - --searchresults-border-color: #232634; - --searchresults-li-bg: #303446; - --search-mark-bg: #ef9f76; - --warning-border: #ef9f76; -} - -.latte { - --bg: #eff1f5; - --fg: #4c4f69; - --sidebar-bg: #e6e9ef; - --sidebar-fg: #4c4f69; - --sidebar-non-existant: #9ca0b0; - --sidebar-active: #1e66f5; - --sidebar-spacer: #9ca0b0; - --scrollbar: #9ca0b0; - --icons: #9ca0b0; - --icons-hover: #8c8fa1; - --links: #1e66f5; - --inline-code-color: #fe640b; - --theme-popup-bg: #e6e9ef; - --theme-popup-border: #9ca0b0; - --theme-hover: #9ca0b0; - --quote-bg: #e6e9ef; - --quote-border: #dce0e8; - --table-border-color: #dce0e8; - --table-header-bg: #e6e9ef; - --table-alternate-bg: #e6e9ef; - --searchbar-border-color: #dce0e8; - --searchbar-bg: #e6e9ef; - --searchbar-fg: #4c4f69; - --searchbar-shadow-color: #dce0e8; - --searchresults-header-fg: #4c4f69; - --searchresults-border-color: #dce0e8; - --searchresults-li-bg: #eff1f5; - --search-mark-bg: #fe640b; - --warning-border: #fe640b; -} diff --git a/theme/css/chrome.css b/theme/css/chrome.css deleted file mode 100644 index 29992f7b..00000000 --- a/theme/css/chrome.css +++ /dev/null @@ -1,545 +0,0 @@ -/* CSS for UI elements (a.k.a. chrome) */ - -@import 'variables.css'; - -html { - scrollbar-color: var(--scrollbar) var(--bg); -} -#searchresults a, -.content a:link, -a:visited, -a > .hljs { - color: var(--links); -} - -/* - body-container is necessary because mobile browsers don't seem to like - overflow-x on the body tag when there is a tag. -*/ -#body-container { - /* - This is used when the sidebar pushes the body content off the side of - the screen on small screens. Without it, dragging on mobile Safari - will want to reposition the viewport in a weird way. - */ - overflow-x: clip; -} - -/* Menu Bar */ - -#menu-bar, -#menu-bar-hover-placeholder { - z-index: 101; - margin: auto calc(0px - var(--page-padding)); -} -#menu-bar { - position: relative; - display: flex; - flex-wrap: wrap; - background-color: var(--bg); - border-bottom-color: var(--bg); - border-bottom-width: 1px; - border-bottom-style: solid; -} -#menu-bar.sticky, -.js #menu-bar-hover-placeholder:hover + #menu-bar, -.js #menu-bar:hover, -.js.sidebar-visible #menu-bar { - position: -webkit-sticky; - position: sticky; - top: 0 !important; -} -#menu-bar-hover-placeholder { - position: sticky; - position: -webkit-sticky; - top: 0; - height: var(--menu-bar-height); -} -#menu-bar.bordered { - border-bottom-color: var(--table-border-color); -} -#menu-bar i, #menu-bar .icon-button { - position: relative; - padding: 0 8px; - z-index: 10; - line-height: var(--menu-bar-height); - cursor: pointer; - transition: color 0.5s; -} -@media only screen and (max-width: 420px) { - #menu-bar i, #menu-bar .icon-button { - padding: 0 5px; - } -} - -.icon-button { - border: none; - background: none; - padding: 0; - color: inherit; -} -.icon-button i { - margin: 0; -} - -.right-buttons { - margin: 0 15px; -} -.right-buttons a { - text-decoration: none; -} - -.left-buttons { - display: flex; - margin: 0 5px; -} -.no-js .left-buttons { - display: none; -} - -.menu-title { - display: inline-block; - font-weight: 200; - font-size: 2.4rem; - line-height: var(--menu-bar-height); - text-align: center; - margin: 0; - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.js .menu-title { - cursor: pointer; -} - -.menu-bar, -.menu-bar:visited, -.nav-chapters, -.nav-chapters:visited, -.mobile-nav-chapters, -.mobile-nav-chapters:visited, -.menu-bar .icon-button, -.menu-bar a i { - color: var(--icons); -} - -.menu-bar i:hover, -.menu-bar .icon-button:hover, -.nav-chapters:hover, -.mobile-nav-chapters i:hover { - color: var(--icons-hover); -} - -/* Nav Icons */ - -.nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; - - position: fixed; - top: 0; - bottom: 0; - margin: 0; - max-width: 150px; - min-width: 90px; - - display: flex; - justify-content: center; - align-content: center; - flex-direction: column; - - transition: color 0.5s, background-color 0.5s; -} - -.nav-chapters:hover { - text-decoration: none; - background-color: var(--theme-hover); - transition: background-color 0.15s, color 0.15s; -} - -.nav-wrapper { - margin-top: 50px; - display: none; -} - -.mobile-nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; - width: 90px; - border-radius: 5px; - background-color: var(--sidebar-bg); -} - -.previous { - float: left; -} - -.next { - float: right; - right: var(--page-padding); -} - -@media only screen and (max-width: 1080px) { - .nav-wide-wrapper { display: none; } - .nav-wrapper { display: block; } -} - -@media only screen and (max-width: 1380px) { - .sidebar-visible .nav-wide-wrapper { display: none; } - .sidebar-visible .nav-wrapper { display: block; } -} - -/* Inline code */ - -:not(pre) > .hljs { - display: inline; - padding: 0.1em 0.3em; - border-radius: 3px; -} - -:not(pre):not(a) > .hljs { - color: var(--inline-code-color); - overflow-x: initial; -} - -a:hover > .hljs { - text-decoration: underline; -} - -pre { - position: relative; -} -pre > .buttons { - position: absolute; - z-index: 100; - right: 0px; - top: 2px; - margin: 0px; - padding: 2px 0px; - - color: var(--sidebar-fg); - cursor: pointer; - visibility: hidden; - opacity: 0; - transition: visibility 0.1s linear, opacity 0.1s linear; -} -pre:hover > .buttons { - visibility: visible; - opacity: 1 -} -pre > .buttons :hover { - color: var(--sidebar-active); - border-color: var(--icons-hover); - background-color: var(--theme-hover); -} -pre > .buttons i { - margin-left: 8px; -} -pre > .buttons button { - cursor: inherit; - margin: 0px 5px; - padding: 3px 5px; - font-size: 14px; - - border-style: solid; - border-width: 1px; - border-radius: 4px; - border-color: var(--icons); - background-color: var(--theme-popup-bg); - transition: 100ms; - transition-property: color,border-color,background-color; - color: var(--icons); -} -@media (pointer: coarse) { - pre > .buttons button { - /* On mobile, make it easier to tap buttons. */ - padding: 0.3rem 1rem; - } -} -pre > code { - padding: 1rem; -} - -/* FIXME: ACE editors overlap their buttons because ACE does absolute - positioning within the code block which breaks padding. The only solution I - can think of is to move the padding to the outer pre tag (or insert a div - wrapper), but that would require fixing a whole bunch of CSS rules. -*/ -.hljs.ace_editor { - padding: 0rem 0rem; -} - -pre > .result { - margin-top: 10px; -} - -/* Search */ - -#searchresults a { - text-decoration: none; -} - -mark { - border-radius: 2px; - padding: 0 3px 1px 3px; - margin: 0 -3px -1px -3px; - background-color: var(--search-mark-bg); - transition: background-color 300ms linear; - cursor: pointer; -} - -mark.fade-out { - background-color: rgba(0,0,0,0) !important; - cursor: auto; -} - -.searchbar-outer { - margin-left: auto; - margin-right: auto; - max-width: var(--content-max-width); -} - -#searchbar { - width: 100%; - margin: 5px auto 0px auto; - padding: 10px 16px; - transition: box-shadow 300ms ease-in-out; - border: 1px solid var(--searchbar-border-color); - border-radius: 3px; - background-color: var(--searchbar-bg); - color: var(--searchbar-fg); -} -#searchbar:focus, -#searchbar.active { - box-shadow: 0 0 3px var(--searchbar-shadow-color); -} - -.searchresults-header { - font-weight: bold; - font-size: 1em; - padding: 18px 0 0 5px; - color: var(--searchresults-header-fg); -} - -.searchresults-outer { - margin-left: auto; - margin-right: auto; - max-width: var(--content-max-width); - border-bottom: 1px dashed var(--searchresults-border-color); -} - -ul#searchresults { - list-style: none; - padding-left: 20px; -} -ul#searchresults li { - margin: 10px 0px; - padding: 2px; - border-radius: 2px; -} -ul#searchresults li.focus { - background-color: var(--searchresults-li-bg); -} -ul#searchresults span.teaser { - display: block; - clear: both; - margin: 5px 0 0 20px; - font-size: 0.8em; -} -ul#searchresults span.teaser em { - font-weight: bold; - font-style: normal; -} - -/* Sidebar */ - -.sidebar { - position: fixed; - left: 0; - top: 0; - bottom: 0; - width: var(--sidebar-width); - font-size: 0.875em; - box-sizing: border-box; - -webkit-overflow-scrolling: touch; - overscroll-behavior-y: contain; - background-color: var(--sidebar-bg); - color: var(--sidebar-fg); -} -.sidebar-resizing { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} -.js:not(.sidebar-resizing) .sidebar { - transition: transform 0.3s; /* Animation: slide away */ -} -.sidebar code { - line-height: 2em; -} -.sidebar .sidebar-scrollbox { - overflow-y: auto; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - padding: 10px 10px; -} -.sidebar .sidebar-resize-handle { - position: absolute; - cursor: col-resize; - width: 0; - right: 0; - top: 0; - bottom: 0; -} -.js .sidebar .sidebar-resize-handle { - cursor: col-resize; - width: 5px; -} -.sidebar-hidden .sidebar { - transform: translateX(calc(0px - var(--sidebar-width))); -} -.sidebar::-webkit-scrollbar { - background: var(--sidebar-bg); -} -.sidebar::-webkit-scrollbar-thumb { - background: var(--scrollbar); -} - -.sidebar-visible .page-wrapper { - transform: translateX(var(--sidebar-width)); -} -@media only screen and (min-width: 620px) { - .sidebar-visible .page-wrapper { - transform: none; - margin-left: var(--sidebar-width); - } -} - -.chapter { - list-style: none outside none; - padding-left: 0; - line-height: 2.2em; -} - -.chapter ol { - width: 100%; -} - -.chapter li { - display: flex; - color: var(--sidebar-non-existant); -} -.chapter li a { - display: block; - padding: 0; - text-decoration: none; - color: var(--sidebar-fg); -} - -.chapter li a:hover { - color: var(--sidebar-active); -} - -.chapter li a.active { - color: var(--sidebar-active); -} - -.chapter li > a.toggle { - cursor: pointer; - display: block; - margin-left: auto; - padding: 0 10px; - user-select: none; - opacity: 0.68; -} - -.chapter li > a.toggle div { - transition: transform 0.5s; -} - -/* collapse the section */ -.chapter li:not(.expanded) + li > ol { - display: none; -} - -.chapter li.chapter-item { - line-height: 1.5em; - margin-top: 0.6em; -} - -.chapter li.expanded > a.toggle div { - transform: rotate(90deg); -} - -.spacer { - width: 100%; - height: 3px; - margin: 5px 0px; -} -.chapter .spacer { - background-color: var(--sidebar-spacer); -} - -@media (-moz-touch-enabled: 1), (pointer: coarse) { - .chapter li a { padding: 5px 0; } - .spacer { margin: 10px 0; } -} - -.section { - list-style: none outside none; - padding-left: 20px; - line-height: 1.9em; -} - -/* Theme Menu Popup */ - -.theme-popup { - position: absolute; - left: 10px; - top: var(--menu-bar-height); - z-index: 1000; - border-radius: 4px; - font-size: 0.7em; - color: var(--fg); - background: var(--theme-popup-bg); - border: 1px solid var(--theme-popup-border); - margin: 0; - padding: 0; - list-style: none; - display: none; - /* Don't let the children's background extend past the rounded corners. */ - overflow: hidden; -} -.theme-popup .default { - color: var(--icons); -} -.theme-popup .theme { - width: 100%; - border: 0; - margin: 0; - padding: 2px 20px; - line-height: 25px; - white-space: nowrap; - text-align: left; - cursor: pointer; - color: inherit; - background: inherit; - font-size: inherit; -} -.theme-popup .theme:hover { - background-color: var(--theme-hover); -} - -.theme-selected::before { - display: inline-block; - content: "✓"; - margin-left: -14px; - width: 14px; -} diff --git a/theme/css/general.css b/theme/css/general.css deleted file mode 100644 index d21e26ee..00000000 --- a/theme/css/general.css +++ /dev/null @@ -1,259 +0,0 @@ -/* Base styles and content styles */ - -@import "variables.css"; - -:root { - /* Browser default font-size is 16px, this way 1 rem = 10px */ - font-size: 62.5%; -} - -html { - font-family: "Open Sans", sans-serif; - color: var(--fg); - background-color: var(--bg); - text-size-adjust: none; - -webkit-text-size-adjust: none; -} - -body { - margin: 0; - font-size: 1.6rem; - overflow-x: hidden; -} - -code { - font-family: var(--mono-font) !important; - font-size: var(--code-font-size); -} - -/* make long words/inline code not x overflow */ -main { - overflow-wrap: break-word; -} - -/* make wide tables scroll if they overflow */ -.table-wrapper { - overflow-x: auto; -} - -/* Don't change font size in headers. */ -h1 code, -h2 code, -h3 code, -h4 code, -h5 code, -h6 code { - font-size: unset; -} - -.left { - float: left; -} -.right { - float: right; -} -.boring { - opacity: 0.6; -} -.hide-boring .boring { - display: none; -} -.hidden { - display: none !important; -} - -h2, -h3 { - margin-top: 2.5em; -} -h4, -h5 { - margin-top: 2em; -} - -.header + .header h3, -.header + .header h4, -.header + .header h5 { - margin-top: 1em; -} - -h1:target::before, -h2:target::before, -h3:target::before, -h4:target::before, -h5:target::before, -h6:target::before { - display: inline-block; - content: "»"; - margin-left: -30px; - width: 30px; -} - -/* This is broken on Safari as of version 14, but is fixed - in Safari Technology Preview 117 which I think will be Safari 14.2. - https://bugs.webkit.org/show_bug.cgi?id=218076 -*/ -:target { - scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); -} - -.page { - outline: 0; - padding: 0 var(--page-padding); - margin-top: calc( - 0px - var(--menu-bar-height) - ); /* Compensate for the #menu-bar-hover-placeholder */ -} -.page-wrapper { - box-sizing: border-box; -} -.js:not(.sidebar-resizing) .page-wrapper { - transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ -} - -.content { - overflow-y: auto; - padding: 0 5px 50px 5px; -} -.content main { - margin-left: auto; - margin-right: auto; - max-width: var(--content-max-width); -} -.content p { - line-height: 1.45em; -} -.content ol { - line-height: 1.45em; -} -.content ul { - line-height: 1.45em; -} -.content a { - text-decoration: none; -} -.content a:hover { - text-decoration: underline; -} -.content img, -.content video { - max-width: 100%; -} -.content .header:link, -.content .header:visited { - color: var(--fg); -} -.content .header:link, -.content .header:visited:hover { - text-decoration: none; -} - -table { - margin: 0 auto; - border-collapse: collapse; -} -table td { - padding: 3px 20px; - border: 1px var(--table-border-color) solid; -} -table thead { - background: var(--table-header-bg); -} -table thead td { - font-weight: 700; - border: none; -} -table thead th { - padding: 3px 20px; -} -table thead tr { - border: 1px var(--table-header-bg) solid; -} -/* Alternate background colors for rows */ -table tbody tr:nth-child(2n) { - background: var(--table-alternate-bg); -} - -blockquote { - margin: 20px 0; - padding: 0 20px; - color: var(--fg); - background-color: var(--quote-bg); - border-top: 0.1em solid var(--quote-border); - border-bottom: 0.1em solid var(--quote-border); -} - -kbd { - background-color: var(--table-border-color); - border-radius: 4px; - border: solid 1px var(--theme-popup-border); - box-shadow: inset 0 -1px 0 var(--theme-hover); - display: inline-block; - font-size: var(--code-font-size); - font-family: var(--mono-font); - line-height: 10px; - padding: 4px 5px; - vertical-align: middle; -} - -:not(.footnote-definition) + .footnote-definition, -.footnote-definition + :not(.footnote-definition) { - margin-top: 2em; -} -.footnote-definition { - font-size: 0.9em; - margin: 0.5em 0; -} -.footnote-definition p { - display: inline; -} - -.tooltiptext { - position: absolute; - visibility: hidden; - color: #fff; - background-color: #333; - transform: translateX( - -50% - ); /* Center by moving tooltip 50% of its width left */ - left: -8px; /* Half of the width of the icon */ - top: -35px; - font-size: 0.8em; - text-align: center; - border-radius: 6px; - padding: 5px 8px; - margin: 5px; - z-index: 1000; -} -.tooltipped .tooltiptext { - visibility: visible; -} - -.chapter li.part-title { - color: var(--sidebar-fg); - margin: 5px 0px; - font-weight: bold; -} - -.result-no-output { - font-style: italic; -} - -span.caption { - font-size: 0.8em; - font-weight: 600; -} - -span.caption code { - font-size: 0.875em; - font-weight: 400; -} - -#language-list { - left: auto; - right: 10px; -} - -#language-list a { - color: inherit; -} diff --git a/theme/css/last-changed.css b/theme/css/last-changed.css deleted file mode 100644 index 1875a7dc..00000000 --- a/theme/css/last-changed.css +++ /dev/null @@ -1,6 +0,0 @@ -footer { - font-size: 0.8em; - text-align: right; - padding: 10px 0; -} - diff --git a/theme/css/print.css b/theme/css/print.css deleted file mode 100644 index 5e690f75..00000000 --- a/theme/css/print.css +++ /dev/null @@ -1,54 +0,0 @@ - -#sidebar, -#menu-bar, -.nav-chapters, -.mobile-nav-chapters { - display: none; -} - -#page-wrapper.page-wrapper { - transform: none; - margin-left: 0px; - overflow-y: initial; -} - -#content { - max-width: none; - margin: 0; - padding: 0; -} - -.page { - overflow-y: initial; -} - -code { - background-color: #666666; - border-radius: 5px; - - /* Force background to be printed in Chrome */ - -webkit-print-color-adjust: exact; -} - -pre > .buttons { - z-index: 2; -} - -a, a:visited, a:active, a:hover { - color: #4183c4; - text-decoration: none; -} - -h1, h2, h3, h4, h5, h6 { - page-break-inside: avoid; - page-break-after: avoid; -} - -pre, code { - page-break-inside: avoid; - white-space: pre-wrap; -} - -.fa { - display: none !important; -} diff --git a/theme/css/variables.css b/theme/css/variables.css deleted file mode 100644 index 70698792..00000000 --- a/theme/css/variables.css +++ /dev/null @@ -1,295 +0,0 @@ - -/* Globals */ - -:root { - --sidebar-width: 300px; - --page-padding: 15px; - --content-max-width: 750px; - --menu-bar-height: 50px; - --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; - --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ -} - -/* Themes */ - -.ayu { - --bg: hsl(210, 25%, 8%); - --fg: #c5c5c5; - - --sidebar-bg: #14191f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #5c6773; - --sidebar-active: #ffb454; - --sidebar-spacer: #2d334f; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #b7b9cc; - - --links: #0096cf; - - --inline-code-color: #ffb454; - - --theme-popup-bg: #14191f; - --theme-popup-border: #5c6773; - --theme-hover: #191f26; - - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); - - --table-border-color: hsl(210, 25%, 13%); - --table-header-bg: hsl(210, 25%, 28%); - --table-alternate-bg: hsl(210, 25%, 11%); - - --searchbar-border-color: #848484; - --searchbar-bg: #424242; - --searchbar-fg: #fff; - --searchbar-shadow-color: #d4c89f; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #252932; - --search-mark-bg: #e3b171; -} - -.coal { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; -} - -.light { - --bg: hsl(0, 0%, 100%); - --fg: hsl(0, 0%, 0%); - - --sidebar-bg: #fafafa; - --sidebar-fg: hsl(0, 0%, 0%); - --sidebar-non-existant: #aaaaaa; - --sidebar-active: #1f1fff; - --sidebar-spacer: #f4f4f4; - - --scrollbar: #8F8F8F; - - --icons: #747474; - --icons-hover: #000000; - - --links: #20609f; - - --inline-code-color: #301900; - - --theme-popup-bg: #fafafa; - --theme-popup-border: #cccccc; - --theme-hover: #e6e6e6; - - --quote-bg: hsl(197, 37%, 96%); - --quote-border: hsl(197, 37%, 91%); - - --table-border-color: hsl(0, 0%, 95%); - --table-header-bg: hsl(0, 0%, 80%); - --table-alternate-bg: hsl(0, 0%, 97%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #e4f2fe; - --search-mark-bg: #a2cff5; -} - -.navy { - --bg: hsl(226, 23%, 11%); - --fg: #bcbdd0; - - --sidebar-bg: #282d3f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505274; - --sidebar-active: #2b79a2; - --sidebar-spacer: #2d334f; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #b7b9cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #161923; - --theme-popup-border: #737480; - --theme-hover: #282e40; - - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); - - --table-border-color: hsl(226, 23%, 16%); - --table-header-bg: hsl(226, 23%, 31%); - --table-alternate-bg: hsl(226, 23%, 14%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #aeaec6; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #5f5f71; - --searchresults-border-color: #5c5c68; - --searchresults-li-bg: #242430; - --search-mark-bg: #a2cff5; -} - -.rust { - --bg: hsl(60, 9%, 87%); - --fg: #262625; - - --sidebar-bg: #3b2e2a; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505254; - --sidebar-active: #e69f67; - --sidebar-spacer: #45373a; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #262625; - - --links: #2b79a2; - - --inline-code-color: #6e6b5e; - - --theme-popup-bg: #e1e1db; - --theme-popup-border: #b38f6b; - --theme-hover: #99908a; - - --quote-bg: hsl(60, 5%, 75%); - --quote-border: hsl(60, 5%, 70%); - - --table-border-color: hsl(60, 9%, 82%); - --table-header-bg: #b3a497; - --table-alternate-bg: hsl(60, 9%, 84%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #dec2a2; - --search-mark-bg: #e69f67; -} - -.cairo { - --bg: hsl(60, 9%, 87%); - --fg: #262625; - - --sidebar-bg: #3b2e2a; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505254; - --sidebar-active: #e69f67; - --sidebar-spacer: #45373a; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #262625; - - --links: #2b79a2; - - --inline-code-color: #6e6b5e; - - --theme-popup-bg: #e1e1db; - --theme-popup-border: #b38f6b; - --theme-hover: #99908a; - - --quote-bg: hsl(60, 5%, 75%); - --quote-border: hsl(60, 5%, 70%); - - --table-border-color: hsl(60, 9%, 82%); - --table-header-bg: #b3a497; - --table-alternate-bg: hsl(60, 9%, 84%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #dec2a2; - --search-mark-bg: #e69f67; -} - -@media (prefers-color-scheme: dark) { - .light.no-js { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; - } -} diff --git a/theme/favicon.png b/theme/favicon.png deleted file mode 100644 index a5b1aa16c4dcb6c872cb5af799bfc9b5552c7b9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5679 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 A;{X5v diff --git a/theme/favicon.svg b/theme/favicon.svg deleted file mode 100644 index 90e0ea58..00000000 --- a/theme/favicon.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/theme/fonts/OPEN-SANS-LICENCE.txt b/theme/fonts/OPEN-SANS-LICENCE.txt deleted file mode 100644 index 7a4a3ea2..00000000 --- a/theme/fonts/OPEN-SANS-LICENCE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt b/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt deleted file mode 100644 index 366206f5..00000000 --- a/theme/fonts/SOURCE-CODE-PRO-LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/theme/fonts/fonts.css b/theme/fonts/fonts.css deleted file mode 100644 index 858efa59..00000000 --- a/theme/fonts/fonts.css +++ /dev/null @@ -1,100 +0,0 @@ -/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ -/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ - -/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 300; - src: local('Open Sans Light'), local('OpenSans-Light'), - url('open-sans-v17-all-charsets-300.woff2') format('woff2'); -} - -/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 300; - src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), - url('open-sans-v17-all-charsets-300italic.woff2') format('woff2'); -} - -/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans Regular'), local('OpenSans-Regular'), - url('open-sans-v17-all-charsets-regular.woff2') format('woff2'); -} - -/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 400; - src: local('Open Sans Italic'), local('OpenSans-Italic'), - url('open-sans-v17-all-charsets-italic.woff2') format('woff2'); -} - -/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 600; - src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), - url('open-sans-v17-all-charsets-600.woff2') format('woff2'); -} - -/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 600; - src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), - url('open-sans-v17-all-charsets-600italic.woff2') format('woff2'); -} - -/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), - url('open-sans-v17-all-charsets-700.woff2') format('woff2'); -} - -/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 700; - src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), - url('open-sans-v17-all-charsets-700italic.woff2') format('woff2'); -} - -/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 800; - src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), - url('open-sans-v17-all-charsets-800.woff2') format('woff2'); -} - -/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 800; - src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), - url('open-sans-v17-all-charsets-800italic.woff2') format('woff2'); -} - -/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 500; - src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2'); -} diff --git a/theme/fonts/open-sans-v17-all-charsets-300.woff2 b/theme/fonts/open-sans-v17-all-charsets-300.woff2 deleted file mode 100644 index 9f51be370fa913ce6de2922b580c262c4822b337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44352 zcmV(;K-<4}Pew8T0RR910Ifg(5dZ)H0f7hr0Ib{q0RR9100000000000000000000 z0000QE*lUWfmQ}!0EY+&fhq})G!YOAg!yQMtSAeP3IG8%0we>R0t6rhgFFYi4Ge-h zTM$x_K;*{m=TyO<(oF`$dr#+gT@uRz<@OP72f1way{Ld4djxa`IG0*=K;{4c|Nq>i zF~-^s+Z{rPn$}0zLzV=G*ddk#MfRZCOSo7Svxg)@O1QTM(GtC{-8am>TkfXJ&}5JO zXokZnNWAaG&x#r1r&DFc3k@sfl$|@RDaX?kWW{EN@TZnHp}gCDd}u9PW@H>gZ142z+QEhtr+J1&#|>KAj6Y2`)3tZkBe+ebjmTS6=W*;+$iHPBB3Un)Qo?6q*dE(P3T9y565vHowfyevYxI9K2P(y z$<_L{@8?J5hBF;TxvX%vUMY{MW;AQOFw;MRE?UNs>(i)Pw#F30SO&%}gA&nV#5ynh z%lr4w|41^EwI78NR7X_&MdMPeXq|gj4oJ6}tzd{4Fvwwq1Zjy_sfS1l0YYgJLOuSa zG~qZt#{MG5VL1;uY?c0qywYwhjn*_`$CiZFZCFDFz-?kG;zz}gkK?(Z;(4Ip0|Y@p zL`0q-DhfWlFW)O~_Uv1l(z*7n%=kiif-51?{(S1>dTz;-%RXz{zW_NG4POWVdSfQ{H?gb&VPWmSuI@as@lXQ zCML+EVq_sv+K31qR)E!rHdbOZcI*#x`rpX1-FQZd2?w2J5+HD^d^xN_9WLUu;R1_>$Sl2l1j{i_PqRoxBKXmEfAv5RRCG~gHz zoRPqp)jl)`>4DtY_ee=+oD0vBlrtv1+}R|)Aj>WYFNl--dsEGJL13vB!x?g=A&fDlOONKn#&pyZ<<^Gt#Y5O9+B{||V8CFK!GIY^G7 ziird-fZ=XPfYkAzOvx!^1&5rvR8_9Zlqy%TZCti4x_G(NsHD}UoUD}Q&&1ywU=hnR zK_eK;d!w1V-89?ZEBgl|7bFMOFTBI&;bU#pwZ9KM5d*ckoOlTrnn@#e=0bxf_LKF$ zd-0Mi4MXYT*CGx?Tq%ZXXdY`yIWWVJf|?K(5DNrL%GP_mZs@nw-vBb}Rw0W;wB!)N z5TjzUSNZXIA7943^nXK*r#Dw9|Mtf&ksu-=h_`Yp9V;Dkh;8<4psUZVb-$?#qp%T! ziAdB1b$5t5hjOzR8iD$*)2$e71R6>Zt8%DEY$Sg2KWN&b4Cqr8h>8`6#((@8#L}XktLaTS zryU~vMx03nNxOB%uQY)H>VL7pz)zP2nhY%8WH@)-0RsdY-07d0c5ee-ah{%=QSM%u z*8so2)#K3GU!m!|?O$6+?&yD~(Fj>ZOxK05BApxGi zJr7YET6WG{j1#TYt(MkW%SPIA4dOUU&zsN+<{}nS6r*LQrr)v8tl?2R`* z6w<>(odO>Dg>%+<`=H~%Re+D2bI267Gb@WPo}vT*tKEȮck{9tEK*~BMoW% zH1u#!Fgnv{uTh~Qj7=wBs zEV{oNz3jaM^fjm3f5p0ts}vL5&Hz2z`{vHMV{Y#7-q@n{XJgw;zp&JQG^?7_9F3|5 zb%A^H(zJleM37Kj^<5Rd-kNVveVMOa|7TD*sLAge+zbX~|NLN5zpCGgeo($uzEQqZ z_9`DLyOmwaX5}sVK+kAj84r{uR*J9v{)%bEgkn%}9d-mLYyw|;5&3g@gZ$38VhSK! z91j9#SN8o}-9Aj&E9v&zM3VhC5uz|tJyNKbG|LC_~4)y^U{G4SDak_&pA0eTVu z6_eTTLGRuF#<9LN^II`5^`!oVKDX`#bi9rj!Vt-hn}{NUeE(;(&z>F+PaZ#d_+WqkW_RyuJ*<|CwyCSK;CU7}Cc#Ffw>oIl zs^53W3J?t_hMIZBhO2(rN~Tq3m$?n+9&|-mEn~UAf5^ub3EssDPjy37EM!6ZHZp@m zNCrI-Ph2^!1CkVodtev1twq1^)3hf`9uNh_*BuuvO#q~x zo3i&bCN&_SF$YDaBdznXwfezT+!n4u3btLsIYX@@ay@atqR6=)=k;Ella!UZXMGwf zN*n4pGr(t?9>{71QY`4|b%Dy~#ad zHcpe-Y@VZsd^gwabqyO2`rp(oNU^k7MLZ$IR@s7NL5)6KPfYTpi98%UgInDEW|x<)35StzjSF@3~6#5ED`klNtH9po~lK1bVv zV%1l-ys(6zR|}y15?Q4|9H8RZE;_Vj%4z$JTi-31_tUXO$;J4jec%(Iu=?}K7-NlL zpup*nGf*+dIQ9VRV8n`Uj4G4|bxxmXRv}7e-KnJjfmz44o+MeKj<(T0~ zBcE5bcE4GO8pxhU<%_j_OCo>XCs3%QnpuHMEuFv-;q%-y#a>+exG0 zh*26N@<3s`E)SH%r?F=ef__@I>lpByPhE^w*p$#YGK0aOcZP;ZJpnVSwo`j#CnwFw zd?)P0?E)G(r*aG|9GE7|v8+Jdk`;*>m8Hr_{5FaxcOU7+34$DRJ??r6)njjjA-#?# z-UKAn0&UPi4|5{rCfe6QY8(Vglu9viflq~oP!FB7`xNmfZ>66}2d`c+t(uE>m&DKl zVFo_AI*6|6wveNanfs8ehR8Dkls`fQtkBgpk;N3+NIE+6+WFM81qg<7Z#~S?THA&g zkXj9bvPS?TMFtRVHICx*MYb`(U{63GYD8itVkDD3>6duG_XUJ^h)=EtKp@8CtwrN8 z2{ybAz=5EC1WYyq)31l1ND%z2QqiANz_f;Hl8!o{b<<$*<&}4L(b7x4Oc`D<+QiOC z@>BDwckq2I)!Rr;|1Ny0Qz9W+>0)*;(B(kh-@qgUxc25`Yk?d562!!qh)?K+0TcIW-Og6iUno+oZG88gzfgX}aM)Lh*O<2)vr=ybX$BL2YXHcy% zj*hvL5F-K8qqR5~jQOxg9>^llzb~%aKxSE_;FDXCX`>L(_TnyZ+#kb{7&Ds-`+|z)O!jY0I_UWTmXp3;!wDC^iTXzyT7<4Nw3GKghd(e|=9)u2-BmkM1< zY3IEHMhs3sqJSRMgbWsnATY-KcBDs4YuisFSCrjexZ`n1fn} z9JArWjM>b`$o;5gle+H`5SXn-Q=4K^f<}35p6cyE8Fa+%UR?5p6Qt1?9Jrltzjo#- z)^<462JcPHCR7}Ic_0jM>zR#Zy1EoUT)?O+@0hUW?i3B(6&Z&!DzN*CH zJt?}VScA$mXRo|`tXT=2sev0;##!-$G1l@0g1&-rv`BtVXYG32o$GTYqFEK!cy63Y zs*h)o$tj4TM#VFLZeo{bQ#Bf|q4~g$-zUaY$C)xru-p`IX^fdmp!hD)gy^hT_pl6k zwrs-6U95auKw)=msV-n%}c%{|;V&KnIs)vm-gWAA`#1{7Nc&9M}2 zm4q&@ckt9BIxD3K4A zp#)&N0ddXFd!(sF8T7;)0aY$(5cHmA@Fp?sCJsD#EBxGBRL{?NwVMuP)K;i_s~t-H<(q=wQ?$FrmCm)_9bxXW_mko;)+|#pMUnVmKu<5mys)9)Y}3UwdK;b33ne zr>4Kg$$Ob~pG2(JD1JU2=#1ce~j^*%71Oot)8H0cHt%=-|TS(P4+_qUdt} zj^-@cS|MOwqAb z^W*p0XHI68OeM%iZ^A!M(~P24R;P&TA-ws9e(#N2t9NE(>}#f!eCxGwnXfnYU-oB- z*mK>#tL>>}^mCnDd*}#ncqqtohQ{4&AA#O0cHX?X^``C3x9n`c_4NTTli1qfd|pm% zY^sR^Hm>qLW08JHZK0x>P`zRb4bJ|LH7Ug zxcd%1qFxoiZFnV=q!_NUYvVZ&ehZn{JFpkZ!*nn{Ethn}zm9IgkbN!GaTj_@Xb+Y= zI3Vc_`1PovIgqsuk{!Dgy1-vuH3nAn(B;JwP_3L8uQ{#zhh^Anr^t19V|tMDXv%#~ zY{Rwwr{PVASo(jZUP|y|&4;@!$eC5Wvx|hlt_B<$HmXDNh7neM0Ic z&!PPAN(77yI-)x#olk|kBu3Xn1lq~fD-rA>pm$Ob+~xpNfwQ*vyYD2A2oTP zA&yY4x+s$>q`W}>$ldrOO}!$XdFRi>&=wk8z#G(e?_kB~*)5F|7S8LGLH+UucQb zqwMN%zJ0Tp=`=jC4DOrf;L}a_I&xC?_*tjLpK?#*>?5xvLQ2^=>YYgCjNP36S0UXy z$`SYhh6`DdVk_?MEHe@z;H)0T8uNVLii~?3L*Etw%`XIm-;QGk1K6$C&qX{%anO{3 zK`Y28K|LdXMUyZt*YyCbpzEx$H3sFHikaVURwe9N-;|Y}8wcGSs@|LRMOg=FJT7M| z@(xTCGu_fSJf&XKe_)<}_(ioeq}`!i1fyi)&6?mA*W5?SL!^$$&^Uv*I4 z5t{YlLLuOFtOSuEIjFH1Fi&RG!Fr>6%Knh6X(WC;wi$u8qv2l+q5!_`(+C*H(d@+n zu%nKC9~m;#wRw7LKXm;SyyBB3=4p!8j!!p2kFp9>|C~gxb-#-kU0IG;$vQZOD7q2$ z|L8N6iw;UU{SWkvFi=Oo&FC6k^~fF3m8*EoMehpobOCNp7!zG$hx~#>$1@8Nc5Csu zO0Vlpdx%PKAzVXZ)y77pO?oP$`CCgS2jyb-J6-f{TLD#au>*sM^LSib8#cCy-2Bdh6CYk8iWbv-}Y#o_9{ zZR^O;^K8QV9)q_pH=T{mZKTwsP|iHoZgovzs-zU}mKUhKxI8Ju(T8(c*Rzc?xb0&Q zW+*!g<}{A@cPyxzCYan|Ow`?X(F@zd!}=xoEnNN_$T!U4M`PbGwQ#|XF<{zV?sh?22_+&fym3(0LFiy5 zIaNO{FkUDjo5;j()L_zp{Lt{n>{v}+t#HAW%!Rm>mqdZ_msb|1Lw%S`m06hY&{?=b z@s)sbztJ-W^wZn|Sn!LsEkd|?{U=)Mo$1kMl&H!0^&H)}5PFqp$0rPo7D}}}!)2-F z3Rg`C;2vlN5EvbNwfW;51tE6oaQHr~#Gl87NM8+-k^YR7=A)YrhVsVO;zP+NZ7B!g zG2AwpUcY2B1e^tVZmF!(9{6oLSJ%4i~ZoUo`4|-=WMPrJ>_QZg?803S}k3!`nh9`eG zmVVMNRSvnsCMX%sw{E6MI^<&5k7q%pgCXr%#hbf(Jd?2d;86ljz-IGtJRf`uE|V7} zUx$Y$e`+tKI3c6d##|lX?T`{fatVcLeduw#dleQ&WduyWKgHjDA;w8QGIW|r>|7tP z5@9A_AHKBAdyj?OKyd|U`m-$ld}Y+C^~vS0e@CST1QyysF_r`bEJ%>k78(|XhFoaK zP?Cp|#)Yn@tjXrbC`p*CLRR${GGrJmFLCo}(AxJh_0zlFAo`p}0FU~z$Jt){4sne1 zX8>p8JYx!sNd}l78q0SSG67V#itGbFW^Z|qIG_B-1`cYY;2Rxvl6f#Tr}R0NRF%c=I$e~8JY62rCrHnUG;n9`q;^Ep{8Zv9?u)3 zGOe%_UP|xG-C)uGIS%q>5fqH$`o_%m9PdP4@)mT_!`(o1Q`a*2_{`5}!a<2Ca;jq+ zRXP}UQVoai**$-yRBIUr9TxlV*I~En>&HvD5=pFxuP8Ms_Jgs_eUWwciga^Xta!5R zw6|XUuH=F@;`Cxvu2!f8;wuB(ehU&v??EGYSX#0e;ODcqWP%~ zQJK**y!2oE{`CqFg<48G;!ieNeK^XbIDW{5m}TSnsV-`TT>bsJl8oAF?()RO8ogfzkiQkM*NbTaT(Y*vD1aQi z(ss~xLxxO#la=9AdmuJW5)?A!?v9A44(JpM${Yq2fL#|K(Fo0zo~ODPE+v>9o)sHqj@NBXAI zHm@|E_)&C$ct=qNx*LIUQ19JjNlx=F9v2t}d>18tuakRc&X&Pz?tCvU{Q5R&E@S#&b&`iVDXFpO-yc|aZ-NsX`AUhbR57R9r_On)?rhT*q z#ZogsVof;Dvn`w_IcCodY7_fzKun41$C6X)Ga?!a4{mEKc5kWXCY>6d7sD;5B1ZKo zJ}?=2A;rpJa~MqVcaPd4f~4CUkYkqlG{Z7rQiImY_QJ^W`OYg3=jx~I2S@KRjs`XR zTEV<#i$`@xonR-r1pe>U^b;Wu+?x8+z|RRhw0^pmkXxMIqID=?xyllzF0ZQh^h zoQ}_a7pt_?bUGJ~wTc!wZAC5r5Z*0B8Xzsjy20QDG-# zq-T>lg62oPG@+deTVE5u(?DmXCAF!TU?Blb&a<~faR=ab<(QlJXkxY2VCVr`= z9RC?rEXT*MK04v~c}BBMG(7%QhLL_=Z}1a${v|0HqDq&SimqCYq``l+mbL!D;}z5l zrmGQwPgf~x%#zk8p2^Tgeby_}JN<{0M&^ziCE1l$?5trx+tqlwl(E1(vI~pu-J%-R zw2v|sdH{8iQl3WMUhOT&v8JMBQ+=XM*VnmLb9Fo*G1w_erKK-R?afNUHSRd6KzEac ziFBcmp6CXSRy!JpW6eT0n?qQ^1gXP^iesMRB%jM{oNQ>YrFzWzbxRCnUQA_QlqX+g z!7nLg8cr|vzsmAkd&_G~h_uKUY%{UzbUdAsMJE`wP30J$zw$YjxyPY^AMvH<@FD%? zvz1yYUG%*k^5qYWRW>zuAQH*5=K-J+aX=BZ>lj_6flj41=4FjD%KOrJ<%L=Kbp^Ei zO%*~z=?*WFQmy*ts0~5`Yx?qf_e5~7Jw)jYUnIp_q`o!b<$e#!vg)0R;9YYmh9LU; z4Ip)`cfTg>iaA|&xU3@P@1$I3)4Fa0=YCto&l&p6A*DliIhbUS^ZVJKAmP18vZ>=U zlhog$M|AV83Dx_{pp`pP4Kr6~!nD=U$WKqQr>#D`m~$TV=gt|Q? z*m-|1*6eUtUOXy_5%ZB=e)Um_Vl1ubS5ZvSU-(rFVCm;yk;UGI*EMY=vlbXQ*#6wQkQEt+;I8C0xZFT z9cLr`W*P@hG9(Gki{y(h1-zkU^ub#p(c2%TbB(15>_Q51Dn;5)$rE1R?LeU*cd|nH zGx5laat}nt((#dEhGqLcs{9$s$O-@K-RDpFGqvSDOm3>|1gUfYZcw?qPT>63}_u8{TUjOEz_P@JAZQ+lF<0snl(^Ad65Vcq5GJjG)SW`W>i8mMc?a;2AhpYGTzF zLb$y^V3hBU>W}ouEaBbfS*J!)aNC^#R{Kg&p30?lV2}Giq7TCGS%G)>$%! zQEc)D4mPL+ebN$L)67I%JSmCLK3VWBUF(u|9!zeN?vM~>@P+C*@!z%M9>cqX&jF{b zckB+UJJL7TK*o7Q-8haSlUsdS?zO4dgG8_WG`}x-i$l|WgWXchj}ATMbo)N=7j$Gi z*{vLQ^j2pA*fn(v)tOFTSJaji^8iV;!E)re!jOnCj3EG_pYmNlH~J0@N@(h|*!Q5^kn-?y~y$4BxkI{miUm$uLX& zApt2q#&@8@%ws@0<#lnwcGdXx3?R_DhLfD6j6(f#5DY_z_$swSnu7FSZJm`JizL7t z3woQ^N{vXpP4y&O4 z=uke&>!G%9Sor*^I5)A0(YtIDac<@A&ze8qkW(kE<24*ihJyVoDsBB~%LQv*=?aRh zr9NsOaxSUJO13<94WP$Yhm9@4DQO09uAR=MSYpQ1^6pR=ZvLn_IpC!I}-v3 zJ?P?P{XrzpktVm5hIlE4NE_+fg7=2(%cZpYlcj(ZKjPc*A0ZQw>X}^=miGV4mi@jW zow+TT?ra&KXe_!D^+lZr!>BnhbG6)3b8X{OsKSgGGUm=a3kYFCGF@8D*v71oRa1r; z%NnW925U~ezQBhtz!a%va{|P8yGm)A^uzb6dA32U>sC`OPbq;?bZ}2@qSf1f@1C$} zRdy@o7mmHLAFw&^m}_59i;;QR_ieQEBz`B`HtM1I$H|zTddi>_{C)uWt%^qkloQcG z=L-eHsHHHZ8tVIesD>x?7e|L=l$}{O0eZe$&+4$H)taS?|EivdPB%w2JdjPN96fs6 zq;m_gP?lsxwAu%vW$tGcPfW*>XkrI{;13AlNaa|27+o2`oJl%(I3u6i)-5}Ar7F|p zl+JTn)Akxkg@Wb^VLX3%6=M9!>~-O>bWF0Y?e+)&$rLrSHRCrhbixHwsU<0AclPb+ z%NYY|qY@Zw_~oV>l@4p=1OZDJ;iU>3INkPyKU z0aCZQss}I<0Y~(=c>eGKKZMOoSwrtnWR&FblRU7rQ731;^SjAxIF0Ag|U`QzkW>J7PE^YnD{?DgN34h zmuXi5i%xwHYunu;O#gD}K|w~&#_Uk-)K_N&Bbs7p%EN=>+oor-0)4sAJ+Hx6ZQ^@k zYHfR0q8fTVqO!Ns)LY|>Q|JwOn=so#>KRd431!zi@-nEBh?Fgn8yhKV6lO`r!H8b} zMn+V&{~bIp+Bh-RlGoi5!7QPFobW_{@zcPvu!ky>RiWSu*t40jSLAR6VTsAWcndl% zJ>OwNz)Gy11$NlVfUeE%N~@=m$@QD!9A0B$i0byN}cC*;`u&#Z(G4C5}B*o&+ z4XNjMghVMWz7P#6)yNizcpg%1&PJ_rSthzJxmo}L@y*y(<$(^DthsR4nbOq|0n(MWuuc|Uk$M<_?DU86)S4NQ2AE($B-Wy>qWvu(s4 zmBGBAtgt8izZ5RpERoP zdTXE5=qo*Ob#+o%vsqss@PR8295c8sN*~!Sw8djff{z=2jUk7WO*f0&7TtEcex9G3 z9w`lDjz+e2py(-2M(EV=Pq$BMWVW^^qi|;2!69Sr#*Sn(Rzo(}r;&S>Bc3oQLMxYC>%3^hJ7887)K8=(NQM3!61akqD>8 zUtAWvx^i{RypqJN$w;Pmf}B=#wIMA%<{OO4acZ(oXzEla1^5zF;nnVEuw5<41IP53 zZp>_Y^D41Qd(4iBNS{j>+?I$)4MgLrBCEVE$91*nDIy~h`eF}8&|H(1xCktDbNm)` zqJ=Oo(Og^Z{mK!?V&SkAOx`aw`ydFRbD}7zAUKn(qI73xcxIirI^NyP-@K{H_CwGG zo`F5GE0>{Z3s-BPmlvQ{FP3YhE!}K_-Z-bhy*QKc)Mt8z_4Ls6vze)+C%#AKGM*or zenoNA^s^BojJ3O^*Z;k&v8&a*Qhs%zu85Lt(#-4iD#KinzFBtpe@R zut1u@_ek5Ff2M(PxB1Yx#8X4(lQ*IeL?uB)Zh8&i zKK`m-G{g0-+KeZ4!|`wh(%4TMYQM*)kJUcn-v8tTY+?qsvIlvCWUfmES?eEBZ?Jh& zL|AA@Sa@jI!-onUEDH_1N*(l=@!hxsQxzYQQg!0875F=6ueUg6Z;B1g-F%v7o)y}< z_o>*hLAD55l7wFl4;se$>osI7XfI7-w$K8?f7U~n){tI6fcy)f>jrbJwpQ~*Y)G7o z=Tdwm&QnI@2tBj#qX(0sb;c3zvvJ5tpXmIOoUEjTQaQ1Tm9Aoi;Y9Jl@j*C#NLrhy zp@$ymaayE4z$+{+svt^^>-kqN;Sj_ntorknrB{h;#Mc{e$WxF2k z$>9#~bGUxti2UTk{N}CvV;dV8+(locjYkq9&{)Ikw~vjY$e(+d;ff&7#9o4!^t9!9 z(n875V0e(>%ieMzDW6@_P*B86V;8IiE-5Cqa$vS?wt#!u&YNZ#VFdz12C0B`VvP5RKACGOGZ>zZ^sYE(UA59Gr{ z;av-T%@n7_cK1fy-ym8z77>P?eg|&Bjq#fgF#uw4cyS8s13)(lhINdtSeWNlNBX<= zMy%v7o@__JN75oOI<+f3mD}!1$ppXUb-88oG7Gvwa7J>R$)_j30<9@Qp;k0r%2UYb zWB<2xA=MW*M&QA?P1Tt9t#S(|;C(%QXbiQCvjVhR7^pbcRQBqyB7d{$wfEutJ941u zcw=61Y`ejv4~{r*Eld|4mmZg-OTq)N`^UN-?D>Go9(6E=g>kA(R`F2V(q}#NdR%%v z3$cN+n8Ybsgfk%_6x;*k);@leTV3@BwBeLFdw|hv!MV&};72%an0{tC-azy&gy#cF zVtXql8yZ`X(KO1qz_!*J>0qE#g`5PFs6!8q3;d(&X*4O`4A!rPY~6OyWTswHBSX<3SwV=`r8Jm?-)h#e31 z^ghuSvbaPxTO46VtVFvnj#@}LALn4=?PcbGGxKF0>WLtjhba4dAUSURwp3y2#@Im4 z9DeCIqb@wUoq)LWZ#%~;lwiV&*UgnxF;G-=kL^#p)!}hqI@!2DR_Y8!tUm=Q89Q1e znilMHVra&XeQ>AJlMYG@d|()_GBF{itobE}SUJ9^ByM--_N=P%&>}4p1}eq4c5fLvWH~|HUbl$mo-3MB_;tTLM2Dkp~so#k=d_eZKR) z&<00gqhX96ylGz4t9Fr?Y@w}RjaJBT24uTVHvIyxc}`d()nv;?ShUx`HRP;^nWy#7 zsn$KlfeS~JiL0jb2KzUzT^_}369*690gApFPr{eyuNDNuk0fr7zI}K+AoTeyLl`Kz zXln)2(p^h@@=VaNaBh=iljXAa7HHUH6?| zKYFgvp15zl{4O;$WO)L5a!(Kp6ZgkdKJ+Ef#D}0~7XM$NNc`-c?lqICy-(TK_sgINw#+U~0@k%{$D;qFvDQ0Kw*u$V=QYnb5 zZ*{q$2=`(r!%wQ;P!R-VzBiU7Srfn>1z~6u{PupTdijL7?D%lVf3vP-p`OgVpmDb( zd6k&KkmVoE-pLzim)n{D;uoRl6a8|(xp!mh(PnIUoJt?OpOTu1YUfT~txm}-Zmb%$0X`! zoMtVOeow$yHMS$l;Hr8`J#@2URd6s9ABL`sVDgp2QglF(hs^9I^2kz=p6`*=sfM() z!bXlEP%|QA{#~lM{znt`yU0GHuD4`CvQg;4lT)sVGk8Kl*=Kj&$|yGZ?%w zQ$~a0itCBnVF!>E83L7JkgpsS`NkKz$;@sbk6ok_X*}Wsy%KnSM_&D&652xo=rEf# zP6dx>r?qWE{$Fu|i@!;5A7N0vQY8gSEAw^X`pU;0wjWq4dS?Uibhzbrhxd$ff1Lk@ z4QU&Wy9wb2Ym6r=W0$VZvw{9;JA7DwnBe@W>DAH7`A>gp9j&8oa&|No>p{3 zyl)IYAU>qoH?kwjf&+TPjZC1b> z&a(bLaQTgs!}9zzJCie6_h9xi`0K~1cNi@!Yig&DX;ld+#*ERJH#D3`XFUknYU`O| z_UQf=xlzbl*wL0yCrfxnJ!J$!%ZbJX=#ffYNYwR(TG-i5t}D@4#g0o;mXF6kHk3OkiI z@T=kZn?`gp2I0;oQ$j-$QBj$J?R%1`t(JDTL)Lt4qJrUev9UMf&@rX}qC+nJQfqvV z#bfvoKVnsP2{ghG{80E1phdGcun|I69?dr%1=Qh%n}8^*B`}_zv!sqE+kNaDaBHwW zu2~W}6aX50GmZ}F$ziJ8rFnNEA z3mEdE&c+xr+G%`9Tnb2WBL4(m>lIa!lb#!sn_MXa^81npC!@`bK|BNP0FMM?W_-@5 zT$A04J1>VmJwwI4F+XT<0aBDJjL76(L=h4)@Or7f;R}?;^V?r;&0RcwwKOJ`UWn_@ z0LR=$pZoXQt;L3&S3{p~FSo(}0UMY73;-E@dZ9Er{rP12G9Xa1ymP0L6N|-UMm;LU z;B21$ab4#~ z)cMU{HEv4LvaAoFjaeFm=K@kZ`2XA$%aCjLyhmgeuc_CoN#`#hFObex(=IAMHtRlr zfqWr;-uyeFpKtFS2_(hXE!aHW@V=Cp$@990=3jZ45*0o~8R~(r-l?Spxg8w{u{aiy zO%A3m4DDZ>L9h)YsNJC6GYOh0~mX3eMXd zqx@E5>Pk;dkI*1g2tr7BEAB=AWd6PUYe5T3&&P7RmLF-nIQh$;r#MP|^-Ip%AYgm!79t$yRh7*NjZRok=h0?rnhm)H+Wc6UwPo^YL@ zs80B}Q#a`J;ym#sZ_@XokuA;87s%5xH%ECymDjCkllq;Jq)v^b@!gc^oH!Xsl0uNg z-dI6eux|2?9}7alLP4~Dzc1WKb*yNrC?D<)zp`r~0yxe+`@^qt<6@qPzr5AFJUiN1AH$2X zz2B`+eVA>yr&bbMA1uu%%(u{~Gb$`mj@?M8uK%`pyuj~=;)-RW>;A;7^p>$-oy_H$pgE%|aU+5PL(mQ+?3l?7@+mHV1uU_Xx8`hmoLXr- zE8Oz{JwU?0 zrxzz9x%w(*uw zD7$zUGWs7~wvM5VAAxtyN$b48K1MAA71i5CTQhd# zip_Bys4sB1j;viZ?s~At`++4h(hZ@X!4HU3#enaTf|Q(*+m-n`cckh zPbcYE7+7iPr~86B%pwHZWkk9p3Bj=P!^AL1cABN41xx@VervE9 zEdu4be~y3=vX^f)5;^hliD@h*Ej=!dmS&G!+5XKtfO}>Kge|_dVAK9n0^bqzn6}Ds z11S8i`sJJ&W}iA2;kUiU(-?`&oK$&*kkdudO94iUJHCG_^scKYq8E8cJm%-y%8nFQ2kp}T=#_Ol=@#_O@o}ShzhZ#|K7Ov-=f0ME$+_e!f(HUy!o2y z!L;~%v*D2!y&e2UI=^FGqE6rLu-X(`C^Ku*0#CRUq$npNmh}VdHM;v`)`)7 z_oKh_5}jJDVxL=By6Ml-_hU$!8T;u+osAvP57|9VL>FgfeQa&oGG$^k8;_05p)q3E zSZsLCe6*{iR*;@iUsfTm<%`6%rtuT|*fF$%e3~BD9-7RsBbV0Hy4Dw!R*D%83?|~> z*1CEjkxz-;XZ@U_)ia#p(bWh5SETM~5QfY)75SsPVz8jFb~Cn!d-){Ot0}qM;7+tG zQ5GAIPcK;7^t*i(d^FP+0|x28+M)xJ!#{NNfI6>|j|;um7?b0P=m1J$96-&)pu^b$ zx{Ihnz!O)MRtRhP7dO=LSr1r>py#am2Y>Y_kCN*i!-1MtPAM%{K2Cd*R=LdT)V!h5 zA5AWSjs10`Vc*!kz<(bO4TLY}HHqvD6>IH`rq`+9?5-&nkJrXeRC^=5U9)Tpzn;}iX^XN>Zt-Vr3K_N{5Wqc?P2Xs}3Y%ZFbc+RkNd zH9Eyd+s$>m+dM|dA&vv(iB8&;!7{iu+<&tb!M)U~&>lmq{U1h1ffXb(>#_MFng7M` z>aX6fPmea?)wO zVU*cykIx;{2-s{x0_Zd!txh(1PuNtdG?$mk%@(9r ziDD$h^}gDK(W&m@mozpOfz<{9VZJ=G*LXN zZ8j3wKhmSBc?e791_W>`?NfIMzF(dfm4x=fAJN+HgAbzRuz5>mf+%maBW%6yYmu`eMZ=l9~T%RL{r@A-P@=Nc;y91bO+#Z|JKk4G@U z#{y&AXwzH39P9%h42l?wNy3NZ5kqZEu`#hRQE_n*xY#&+93eIc6ba{P;apUjy`Soi zrKNv0Rv8r|1JA-;GHi%{#wRB8()^8NMp@MVHxx|0_akk{SUyikiX|7W@GX2gIp0#) zKTktja*E{{W8RYz`vJ6~4clg&A;3Gl;S5;2$FYjvwZBWc;^6G^J*0pr6eO!f;3C&T zWYvrF_Z=D=#4BwO?D7uTWt+qYT&0!R8KXJ5k})BFe&o9~y?!_DO8BiIv zu{f0vR$3(wsvk|AT)Z&Psjd2BeQ^~Ve@nL{QFoeclo;rVit?eLE>l7Sb4oaR1JB?% zXo(*OI{h`fm9$er{UP}x4?cXM$1rl94jmdW!1A14yQksd`L?llUc0jM3`f6ZoO4g` z*CP23yXXBdJfmcMt9kIF0E&aTr^UikEqt;k`c$Fk3C}Yae;XR&5H#~ChSaJMn|TxG zEaQ6toydthdN1z0hP;XE+j(GmI(_OlFYn^lXD{?)HU4=X6fOy0WvtR2erYsyRsa9^ zU6_x8t=Pk9@k~4r%^?pQjj|wMJ87Mz)vND8IP;^5Yp)UDW6JsTIve@B_$lTJiAyrn z_IIb6toIPbZ`9T=TS7iypiQypr9N-JnO z(2D9^mqEFxhNvA&HjGD0H>SD?B4xeL9{2TFjKNpk0P?{46$!S;z%e1hTU*4K*NHL$XJHMN$#cLF52aRV2A9no?vnu|DM~ z%Bqlb?c~BF-)`1nPPsgHKnn?pFQg8)ZYq!AbkKUD)UUpgr-aG zd?_umkp%c&iT7PK@{}tp>?x1B&!&o7h)ojKiyQpenZC6(pv;D3x10iExd&JX_NWL3 zbHnOFYA**Tatal$JZUSqU=Bl z%IRg5>>bW`%?cPuO6y(uhUqZ3gT#~KA@P<_OlM?7P&)()A;gm)1amt~8>I(l_k}(T z1yiY1aKbwD6NPR6nKTUD$b?hD)HUdLVo(gs>BIdS^H9@RBEc;B6!fvnoA+He&q57J zncC1`qE)_uG#B6;wpx4Ti>tB}GgG zr(d|IPjH?~7#$f$-ErcVYs@o|Ywbgrd!wg6?zv`pw1!%L8X7JT?WsxewQ|xm(x5QnKXA&W83=pBzr2(Oco`N z%AGtoH7oGi*cnjp*)xlym1hn&Drp=xc)__-BlPL)SQo5`4uF#l1qIm9P+5r@2qGB4 z)wSqybjQ$?d_>EZy3YVpcr~!lAfWJ?zmtbQL$=zJN2iO^RK{Q2af!Om(7*6nfHaHY zUC(O!;3VS7!DYXVVZjV&^iY)az7t*6D5u_zK4r1w7_&I>U5|f_j7*TI{m9!_EI*{S zFlnAPyZ5wfy!YXEp)Y6M<4}js{h=;ess7WR@rmzssQ8xd98WNu{c9bHK1PpoaVxOf2kr`}L@5mr_Dpp!CfdhQHV-HH`9>INO9zs$J>e2;d8X zLP5!5mFAoJJnANV%w>drm=y5Bc$?;(Q`CoBsRw?~(fjj*P>YkX*GMk{RL1c&;rI4F z+Cd^GMva>8zD2H!JriAiDNYoy-7K*a8&^J(-?*b2DW_thmufVl(C}<*oZBot+J?P* zv6;DAO}>73b;k|cI)$zr4iAw@;lPORkv_IzPG+h?AxqcKWLsFt)R(T|!xQc56*|n` z4-P#x8HknC;Gdicm5C?FC%aX4(>;Ftt99NX{S>cDC!>>rGJNNSG?M`XKAj(})7!Lw zqBH^${dY{UBsqlH_t*zXKK(qgt6q;Pw*Z{1NvXKF`2e5t#? zAZiaCc3+RoN&VDqyTCgZyX&qjCA>_{slSe%D1YUvMYwSf;(Ed+*otVHtWGEn9m?)vhwGNM#!P9`1@Ar zvh-i7PI=--j(ui5F>xtx-&c{|?DsJ8KFhzRCHrYcYeIgEpG2Pg5%cZOe3m;GkbNZH zKBMDcjXCnj72PYfklGIiR%j!59>mv?M7jb%sAv|)@b~kh{KBkd$|6F=3h=jK9n0DQ zj-)#BikF1Savu#3S-ZVxRaK}_X}BLXT~x%12BcVeciDc>Y6b+iE@T=LCZx)xB>+tO za+0M*?m64>{yP^UjoDv&l&Flxz{<0KJT}obNB$^`u^@%t5^`;5KYsJW_0PZ$w_Y|S zKD(iHT`?M^6=wqyuHIzxThj%fa&9s|O0F@Pjn5{Exq|{hci3K$%jOIBkB%s<$f7&l z>L@lg=|s!CUz-B$soKswz1^9D0-xD0w~e+R$Q8@_KJi2H$HQvale0dc4mGXE7yrE3@+{_@6~r%Zcj6dvqb2tpHHgF z8gYhk9g^|`vD20@EUYD$(>Km%<;DT~;kDjt5;?E94S_6lhgC;`JtM9wyUpqs>peVO zxWM2GB`G(_J+atXSolgB*t!!%lPfXFvCBX>tx3Gbof5&HiFz8t&M-==(P&fznG)X{JAe_F z-JkgL(SJcEKx_@oN?=iuAd)OL399baHh=mr(dw;HW#UBpvD;g28=3`pNYg|DZ$H~M z_RU5PdRZyTI0;=g*La=YlCMFxAVDBZuN?W_oldW8ww8AkEdql#X8qpZ=`t5wz54(H zMCjXeaa>7es?V~)I>zOzPp>;cz|(>sb9K&DoM7==iAzl9rp009v|v=5Y8^+!@rHVN zc6Ew!!|gK35dQ6578}v>j-)#Fk-o&@1?B?~8un5+2p;tAtnx)a_DLk6# zLqLtT0_v++7$H9_r$Kf9(G2Uj2pjv3nhV`WS!nhrGlTx&py@HF(wosUkJsdma;0!d zW!H9tSd~(=kva(yaxL?OKZoXD=B3&M9sdDL=G`eU4Z4%;In(U&CF{;Jd2zM-QK&SY z-6VfHplo||{*-NgPB_L%V6Sbz2F4jeFS)!72zO{;_y$GqF9O~>h%MzG=5ZKl{Mj{E zrqOFFbK|5q588tuO?=adhQb0y=NG-x=Of$gKK7Wq=bJ7))ctaSF29(5|Hg14C2Xbe zML5Ji;5|Q|PmDMW+o1E{d9cgVr}mx8cxg$B`z|ngiAuD$VX3a{65P#)jye0`JCW>?!1erVz7KFFHWl) zExvYUs8|rXRb%@DrbjyRRM(hO2D4uNp6$!vq2kn6i0MVFU)bQfoh8!GnUkRCp_ z<9N!)&ws|3rNfi|aUI< zFce$T0@4X!N1Uj5x^#DoS#|F?NSJWyAU9#l?JY3v&(DzFm+Q%K{=CGep_hu&mnz`r zE;mF6yYJ~o8BB-eQG%#>wA-;&=N@t5aTGT3DsV4iVCwKT{i&knCa2<_0X}l|WO`Lx zX-0)uFL`+(0@`5K#Zq+i8HmzqWhLdKu?QL!Htf#cc_b)6OIVg}0aRFK78xrI1Oa&| zK56gJ1>DI!T)?(9lH6|AYLr{gOA4RmcMP$DuL1YMdUjIYj{y&&Z)7NZjHh>4!}2&b zixhV-_TH>!pK~N-sdh-p)v{FyZ9>Dkh>wBDCvbjkT9p zI9=vo>}p0~c4b4)2h7^KaaJf`W?ihPbl(ls?a9exVS;s^hvX>tFGCwl zPUZTh%x1kBE|2gd?4Eoa2fwhsS+OOokJ>z+u9`7O(E*y@yg;t0VqXL9gzh`=7k{^Z zZV@8FRb8hnsQ+G;6a4YRw8`r2J&W<90cOCdsK+_sfgLb^{y?s_KkpgIq?t05Q2sY< z(a~5)eUxf5BUsS~aZ`0A7+=k0(=W1n??M2#H)~h?b{p`H^P*fMvVsmWY*E?H@T9%menolPpMQmpnX{##dlW8t&I~q{ z(kRX>V>#NBsE)j7CdS8im)tcCULUJI*2W$eqMf$&rssAPHc9 z3oZ2Xv4{~~n#!Ai-yJ6Mq-3-st{8e=;BAlsdkpay=ZrAFjR89x2*BJ_P?K@NGvhJ? zXbif%))u6&?ngf9qA4|G(Bnp6>*a-h)nLXJGh<7AN z_c-tn*RM``y}b!3pPxZIzD^#286!$BK_;)qr1Z2V;`*N%NLkUCpRpMl&pqkvZ$n(? zSqmu?p~8Uhw%U8yTi8bKNg(!jC#Q4KLvou!*2aJ(T2EkB?KBVCvaP&KNy?yAKj>I3~p>8 zA*l3pvxsv2!4neletOIb47HcqI^zOOdnGG*USM*=1WFWB%-DD$dx_Nwn4zmwQ#*J2 z8?VS8o@(#p1B~l#-QUv<2C$ho*i|bsp5~cD(Rc=3an`V9`LGXtri~md#woA4Gs5T3 ztF!L&yzu>;LOg#9a1j2ESwCCil?7ea*)-gx0IhOo$QJ&BoOcMVE)3HV98e+;)yN?Q zs@1s^p!IA%gT_~(Tmz{~f_TFHHJpWrUT;v{kLWPr0|B|AzVkxe;`_jz_>_%;0v73xk1Bt)oXZv7Yd)a zL{3)%!^el)^q*mZY~PF8he97DALzIL^`7hdWVO=cUiWlt-PVa+%N6T3|E~p(%mR1b zWZMJ0a&s#=c;qurce|BoqReviCj(sA0G6-{*1%d=2UcJQjt8$N@}4Q;dfc)-7=DYeN! z_ZYzWP|Ba$1}PM`fZuxxQLPL^d^pBIxV_{RrcoQ~t(PI6u~_}AzQ4j89saS7tVATFt?U*ZecMKJ{NgM-{-o2u z|7?yV_mKTrD#a@-R=cYXR?-UNs0ZVw$0f|b{!s4`0AT59!@5Z|cZi1V*EV0i)e&eDaeU}F=Xm>;0x3DBF z7Bp?caI(Tpc2nFGH#JM`I>bdFTcA%8U|JPu34_x^w2h{_PTwhsjL*lx^52N25jDhx zO+Z9IbQ(|xJ5o^UsF%s;8AV}JHD-}TrRbGO)2nL&tx^=?K}p4v-mMh0aDd%H50IHy zwe~}i|JeLFQcv1;ZHVjqXA)9yLxE2M!CgSmH6ZRefSD4&(2Vm22ds2008zSX!4WyB z7-K!@3&qGkGE~|N5LWhT$T=_UnGYi~_QyOUhgv=IVYSP}i~Y6b8!oU{&;IWMBKExd z$#&ntc{b1 zZvp#7dNX9)>9$#?lZmp8GzTh`HqrT3mID*C0$l4#D7t@h$-`vEeh!TAT&w*z0$ZCO z#zZzS`C84}-a5Lz5+k{jn8kjVeSd~Hahll+rDH)@6Q?>}t@e8fY;ArR+cFy^_npai zl5%EJO(8Q&BF%d^e@i7q&52yJR|QvMJ_`cv8%>g9iZD(5Ra6JKiQ9Ypzep zYp9ZN%u#d+&Yhc+JJ#1 z+h!YwGFVUN$sAikjGf8fLr|=NnsuHHWTn(Dbg0%aM-=Vz=0!k63bP#EWiHN~o{#fO zHk|Ss^-SNui|v?m6bg&9Y&!iSm9X^s`Sk1dWLAtJ5A>7w;9c{enq8^p?KoQnO<|({ z8_7tV6k|>An^itn2H+&lLfIl97ZJk^1>3<6fFH0apBuaw&qhd|noJp)@^b>IoNAWS zTFB)xbH%y2HrRYF&%5SN^)7O8Jh}3&BwGFp1?x|`X5rXmMuTsfltG1G$5j}gqTh&9uF7R~gE zeP-%YO>UG2Cn(IG0I&3oeU{sfROWq_biEDDNxnO~vDG)xk4TgrM{^}8m~8m+*7pIy9miY8w`qMHUk0yoX3N9i`wn9(y( zP9qUgbuB+t))o|+trs+BWG*RHIZNPPIty)#Wh#X6yvco;#pJX4%sI3xd@Jd?Kr=BcC#gszIC2V={<2WPU=)Gb#t&vCz*NS zYJ%I*SpezHQr0Ga%=JEbxU#75+|ladGi#037X+~@@iKPihGcGx=a1|sX=9|S5OgmaNmVIn5AhRf#-Pg154bwev08 zs5@8hFN1{YwVvW;?K=l(J&2xC#70BBbE z7WuSS!~AC1;v3&J=kSVQ=7>0!p}q3UnPEEJIBTxnJvr{|v|`rHHIY1`q1Uzfv|-yb z`K8tTPHTOArf!pO{8VcK%zZc@oB838>aW1DL*Rfa7S<*jRj0YbPlu9*dE5AW=nMT0 zWnc;voyicc+jP8L>I1pE^V_fZ^JjZSAX5mnAf`Y`f2ShsZlK$RyIX}hzr8x(4E#@u zuEB`ldHYG&`+NB)<|)xedSl|Wb>_6jrd=#K)dMAPqFq_)j;XgeWb9P8S_@ig`NKr2 z3pnq-rcZuXy*WRe|5^3y-$>ssShZBX%n_A9$GF`dw$^?>40o-$-S#HfZaINQ`{1IB z#0SfH@n*yR1g_S{LU)6->Sd9ZYtULiQh`eAp)}IIH{PPs5o6VBhg{2_Oed1Q`Dx!*_{c+Je4 zaT7Epm`Yd$D@61d&Ba2f`VyU`bu4gjuFAnot_)GS4( z8Z@`i(MI(_y?8{?H)|6vD=MnWB(ftdD|YY?fFv9$Yd*33EFE%4MejvuHFb)&SPQ9H zj0+05Ka8A#{his8sO#rH71DC78cUF zUZmB|15o%{xkg~Rf6kVCb;zoZv#?E06BYmIz8jNf>fRQ zBKJM4CQnYJ>UF2=Ml5ofIseVPp<*~Ec_{JzN|J+p_QOCB>ZWwGsHFx93wdkGe9~+C4qh<^J?$i*VbGH*9O(&5F`v1h)MK8 zf{!%zrxq~)WJ5~X(l*bmfN;q_gSPR}GV-n{>K&)&35Ev%IOp+*ro4ZI#y30V3d#}@ zL7-Hp7q^1AOHx89jZ$Dk+*&IRVKP(nfrxt8cu{FEA0m*lgV$Xkha#;O55z!iee`7| z09HeZUgrsE^7t=6ctOTiZ^Xf|q~G;~0T`L+$rj%lQ-5LL}!aj301p+#zX z$7WXzo50}M%k+Sx)LmZ~2{1Ohh9sg2yQt_-lv1T!4dt{2#_hIL5Pa#t58!kJU2?f=zu_{8@fOs!ix-u638E17cgQ$29*l{kRuNW za67$z5>n34K?xl2PX&;3kty(VGG@q0Kj9X`CvE)Hnh^7_=r=-~BA%ZWu$kp6thtyX zQz;vy`*JNZ@E`18h3aH&DfHP!1qKz$2JHcGY;lA&)MMv0R^^ARk$lD6 zGW{NN;9oFr?Rk!YUN9C9-plohng#}GgQg>??iZp)QFAPM*=bD_7hFu8KC<216%a8D zOt)kEVx6#^j|r-#;YFZ%nb4udq}>q>g0^eOQDe19mZVE+1D-JbPnECD{3rB_)2H#e zCv@%SQ}&lXdcmjXb}hO6_bY(^tN){6CA0mNef|<_ebmLDzv9AO6{_OOwojI{w2&{W1f?qr)Pxp;cuodSs41|q*$3#7{)bYR5Z{(MiJGH1SauF}TT2JNrpVK0iWSgJ(cbYe zWr&TDz4Lq4DLYZ>3ht-kD{wdss%P7?LUPEC8wt&B*7cUwhiTCLdtQUYOK{y zURv#i7v}tshk(2(_?$MHppIEQ}%-BIsoYYqqvQY9<6w@ z%uOC~HPfbv(TsyO)%wlaEbe5e_523jw-4=Siu!I=w+7dnx2xfkXc@OGrb3k+#RUhV z-T;)InEoAeKc2BC!SAO9n!|$5OKE?`ApT$c7{3}dQN{-j=P|v;jjQq5h(CG#)cNL& zjpKszhaSkE`nUffCt@ReZf_Lupw?8}TYw^7>b7L78LC!)HPyAPv3pJAg3b6ByaNvH zu3}GEM!q0thO-)i#L`C0gSxux!oJ@e{37 zF07*^K@UI)NAr-e5Mho^WXuL&Y9YS?|BNy8KAgT7ua{r-e};j54nUeujFPlJvH5eQmt~BU#V2<^V%kx&$Yr8Ce^d)%k z&i|h@>&0@<7yZZFq(ytZc|OqVO@tk-DWmDzfcTubiaadZ%-GW6$!4k4IsnkXg4#NN z5cvP?lgyZ=Bv&0-s)2KiT$Nid;(up?%hv0^3cZgE3&N;2sgwMJEwAOSd{;lzZ{-*A zo%|r12osRlb8&Y`Q{%gAo6Ooy3i=r%<_MNORMN3u@8ugVvg)&$6pf3%A=ohEh zG;g$b+ItQ4Hl`vaF|FrHyp2L#t)uD*bdW9HcKA~SsWpLPIQ#oHXEpS(GgZxgw0g^< zqX*7mV!Xfz|HiEmU;)XrI8wSdY4oCoE9tj}h8{_NvW8KCR$4>loE3DoaP2i+J~$|V zASNfLM+R@)j@G_XU4;XqOAl?WT+%AplFd`ok^_*16t#6nEPq!bDwQ_Z{fxh%V(DP_ z;>E9ny?3P6?{;b*p3JZm$)@E@udis|FPCAxKL2~xE;*Ebf?%1XP}FaNE6?HPg%>+< zvi2>%rQ#w$%cXDdId)<(davq+4lDv#MkrIGsuxyarj$?zK5~vQnKH6?4?}Eh2}YK^ z-rYiLg*SSVrr%)I3)zcF?caF=x!*_oZ3R=bEd|yc9s0z$z6h2-^LPDy|JHtH-x*hx z%s9rSP9lB6CT@5}{KVhjFe&6-T#IMk&1BiW-qF1T1*<2mGmzdH@;e~k@N+)*04e1UV0mDP+t}T|~xCCcOS)Uve zYv{C(9GFOLRP2*%Bq^oBYuy@BiY7QfH`z%JBJ8!(#S*Il)t4)vuU3wsfeN=%A=N9O*alxBU9 zDi7_~={V~;yOzGV_HRhg>I*FnvPNoH2Lb|q$_=teMHE2pM0_z3D{m*Z?MdLbg2X$# zs0$`p2v0MdPnKFw5>Uv1c_)zOorQfW286gXB<1Ras$%B?bPlS$+jRos8s}ft4y|V* z_3(SK_7*+0T|JAA7ex$~0kFnCaLIf8Z$m&L?mODgU8$I4?Q4#*z>*9sxfKq=_n&|F z{54@+q|Q|@KU5k$^;_hGtJ@jV7Qo?L*|=2#+t*us!V_I4yHb zPkb*h!j+$xrQG~j5d>0dVeE*+^C=L82PA^@1SE<(qL2+Me+PxDMi)a%yFKk>_Q2)x ze|2#@gQ*=>t7hYg(>8CU-8~5S{_Q(&kw#wIi-N9RfoVpeh661cw@60{V$V<5w25kh zj7zMZd)bC2++v|D6bmsEQ<2)jQs_MEj(eR%RjsF#+cNjUEH>5?JB;o_>Jez)sW!xL563k+lIwf7ndIzBLS<0lDvno#^z9d^ zZf`$hMCBri2=_w9JSVzbv?<9xYLh>5#++(^xb^e^de^Ud>@7S?F?B1@ZdmU1EY*ZnC(23c}0j3NJFPF8P(oI-u^*tL>9}N=h%> z`#q|*O$#Gt-9rIaP`?=Tm=P7EL>XY($L(fhv?Dp!9Rn)W_r|D!=Nu1c3Lh(%E7p7Mrym%#E ziLLj%d)AY21DVB9ctW9AS*w=)hy$7XC~+&*O$ix4@@s0TE!MaIvGj{_H7|n=uPJQb zvvz!q^)byo7>Crn`Flb7?(%vCL#1dB%<9_q*H5Js_Q?N`w@>$@c$_(G7pOjS))7f3 ze$VzqrP23JDgO2Iu6$qOWhrMIrR)s?MB-4&k(i~O`}bfL!JAq@x^Z`ZIselaDUOfF zU)(;u=EwW#)35C1yRx|ao6%Rq(Et3!^R!QWI0w=AzoI3UAMTbSp)=$vj#Pb__?Mo~ z3ay{zxR(WIN~P9h)LY_DRlt=b!&)&s9ft{p2okB)nC%n6^|_e?ad?)!f`oyN(%cGM zZ?;5RYfSiJ73*M-Jl=%-~el4b}7G<+(s z#^|(Bir2ck)2G9tu0xQId6GYsUxxtj{NmT>?yR;nj3sE6{f-JfllxQI4*?lXacjl-<^=a8f6c82$|v9c40n#c(?}Q(8!;1V9>7{zq1b5y+YSCloOO zq!+La$~kuOblVkOe@#uP59~a$YQ-lv>yv!)NC5|zR~aoGas_wS_4OnA#}{d>0@oG) zFbPZK>EnMnhOPp@U6u^>fQxBFXRz#+ufVP5`z+ksz=}RTh$v=a-K5whVXd)k{lrc- z6O(?3B-lw2*)_(RC*`?MSsRV`X%m$+1LmTFQfP5hVwR3)R@wY+YR8pDIDr+e^5w!I#>0Z% zKApXlCj(>khQZyoloT?Soi%bDtcE7 zvF08U!ts32f)Ha$c7yyLu;0`3vtDahPY@7p2;h(|{n3h*m4IE!^pvK=p={iMg)DYf z4>` z;(`g%DV&gb*05>zktWCZ3K@A|oE{R5xVQD>AsfvI=IjlsLFW=mxSrS3!uH`)e6hY5 zVOiB}IQ?WvGw8$e^n!iM5csn!OvU3IGj9YrFx(@oNDDaABr_93HO$r)ZRit*kWMWSY z(@3T6_EAO4xX&ZAkBnP?#M7=n$%82Q#O!H=(cympwW5-V_ z`_S+`A1S;>F!uCOA)_$^TkW}Ecl7Z{pdsbb+t#zp*)uV=b=|2i%~;OMwo<;fg)<4s z2me4okXPW~QQh%^4!jH6r^s}nddYMgkiD>onTXn!;E`uy|;brU+o^ho|Z2a zmMP*R0$XSY(6-|3Hovz4E1{GswNIKF&@TW6t7f#$K5*e)S6hi$8`)dCiSEq;Be(zw z)smFxsT8jc91_E{NO(Y+X|+dFtL+>5k_?Z0EMG0&3oh(~=ALCxpw*>0UnL=}vIV71 z)dgYYR6r~h*&0$lDffWF4!V}U!T`e(?z0+X+DZw+wKnsBISo%lYD*b|G^AYs7EX~` zUaE!A1LKJ{+w0G(INl-+;7gFSt;>t^BDHOLz_yJXWe_JPi+fI}XpqBXr^FbI$%fIf zrRR1P?Ftk-4E*MII+0Rzhiq>PiI9wlfg_b1EG2evxT7a@?POdg0h*vEriO%o4+2V= zD%&dUz&ccvwx=a%MQLK+#oNH5IvmN79%X@UvMBjzW}qJg>nYzB2l$-=BQzPYh!_gm zi*tEJDGsrGRA(;s^r4&5mN2sI0y!h&3^HSjn3&0VHYNbhg%>AFr1qpaG#1+v#R1#4 zB+J#0D(hBL4bQN;Dt^d&1~ndvW5F$E};@mV?i`f7xW>5 zffGw1XLsHjh*vwLV1f1k9?7#71u}G9=9G3RNgDf}PGfHGv6<)%K?74zK}PGGZALXB zc4~Tv6~kynXr#y4s1QhpZyyuI>88^?aTNEOHc~7)sbX<+0^GDt7#3ELCO)(XyF}Gy zZg$NZwPM!@Es46?BByAIX0rj%6)(;=#_XM&r{;DoD`DS9X06eOy@T2ZOWI^`d}Nd0l;Ta3;W$c5E9Pn;YAg#(bA-S^YO=`~2tO}zOd%hE`m^eyrK+uZHO*^JlPV(nJ0%}z>MGlZud)nb za%Um_*_!ZV$3^$^=jPh$t2XOK?(9iQ58tegY^a;3_EomBcqtmFO5%CBPgE_*_#h$Z z3ZTj2v5EIuJ)G1 zUQMF18WJU*(NbWL)hAsFcri}HS+{b}EC#dkbtVT`pE7w0Mm%%puEs4gTot~)X+TWznm|l%*6 z{cB!%(?~2o+uD)RVaB(Np{m! z{j`ozrHu-XBGp%!5=6(G(5RzuG}Z00pQ-X7$Es7PfZsYz1)y9C@Y_YYp>8f3)`!S> z4by3u%qQhEa{u!?ei7w{9t3Br-5J?TjIzPV?|O60LyVudOQTJ~_wS9^A%borj0)^3 z!Y=R${+Ev3?_X0h0Bx7{Hefp}bU$qPd23TrWqL{$h;jU&)0FtXFzES{&92b%PyHZk zT^uJdNG|3(ztem5IQY7N-l^j0@av(5Xv7{S_lP=Jn#LQ5hFyzJL9ryci*c%k2xt+a zC`XrbM-(daOfDlOcAOSxm&k%cUo)vcXH|_Z8QWewBPHBu>}1S+!l^mpE5(hxTq5-N zJ=sN-2-v40t*SaV0*D}F)#Ib`y+#M5mjLX4-3Muq8tVi5kVUZCR_n)yglAzjnrRYaemcI*)A z%^KeP8^0;B0=fR$(#v+s$3vh2=v|tf7mMImA}t-rB;wD|xfVV!^eEV?86f?Pgp;|CEwpvjWE81T_%>cFr?6B#0AZs)@HK&0LtfRtv`ttq0o3>z8wDpL8JP2`Lux9L=Ex| zxk((~su_dxBonciE9-aEkyZr*2}fp%&ZNOJW`nglkCXt56`Ko$LTn&&@Es_CYmjJy zNV>Ye5v}d*UQzH{);&l10&3vRGP_!$f(oZeX4e!cHmr$N=b zl|hKZ`f!fgr2ZM}(`&W3<>;pV$ywjjnqgd7y;sSGWiJyw$|+E@z$i_T<|vRBIS=b( z{~k;wYujO+C(U0>@bk;_b`NpUn?JT{C3@3i<_kV%73%%AmHMNsK_&reP10KwemSJe z3P*)2VWz}s<8-9Q0>(bw-WW$T8LG!OQ-UqR8cw1SqO%NR9Zva^6l54{nz;kp=|f!7 z2VFr$8eVx~eY`MDduAKz2(#+PUlYzkb`Cib-|=5%x($jmd79( zC=38J)k;z;od#Q(sYi!OeBCJ&tmEcv;b@^>Yr-s2F3@`lJ6VKWj1Z2R3dV{|);BY# zfxLBBhvIR~@D$bC^=NIz_8V&;1vl3tp9?F^Q4IK)7||Df)Jng54!{|GkfQA~S79yW zD*{4vBuzzU6WnUi0wTN(Wc~Rh1uqPA`!E0K&<3w$oU^Fvv>x3sJzN2@qRj2g_l$Im z>9@88ZWNUeVi&LjeS-AYqga92%s%dS3lBY7QaQk~2-&DK>?k9O{>wX%6JE>n;IP51 z!hp-LRrBFLYmk4Xkc4C?(A(h>pCQ=yO5K6s6uUzQGqk(!ja*WF@mkV2;$mAXl!*NV z5OfXLBs#_|lx@5ccGE<}kz5H1Y83fsU^LT%B18$e1Mdw5)%{y!ifzHH0 zpvA>CXD^%OUHB3-c|N>*TZ-99~VLM}r`{$o5J zChIaha!SV)+q5%(#g*n<07sCS8V-8*(sTl5s&-L5l5HX$GriwMn}by+4?-pvfL?0? z)6BFe_PhMA3rUF>a&$|#C z^QFasAt7}B8TFeV6S70^0Rwtt%IDM}lDiFkYw1Q<8!e$@PZl13^DVoc*xx_ap4QXY z{E;5=S1NzSQXP@7KAD571~~1%W=J=+xX3j16=p$tmXfq8pA6wcx6o-;PTo0b$iD-u zyRZpq`B%X2yS*M?PD|&X`r_YQZbdSStF>xt?XLxYfDZ+qZ-v{1x9MtV$?4B55!bZ( zm3W=~edAYWsLrbzI7TAfS`e_U>~M{cFet6;dR;ocODg+-^y^;lm+Nl~W>UbCh14B< zq3!K)_pggc#sO;!Rw{E%w_V?we($>5v42wRSvn85msM2!I$mB>in#cllK!V6pjoj* ze5W+FUv*H+X;E?!0X;(*r!vOokZ#c}W16*{;ZwU<$Vg;ulC$fmb2e+ZP_RKuDkj)q zk4t5tT9GZNnTzCU>*KHPdq9}m4}273+R_+4Y+Vot{ESq#Zb`H@ZKx{@JaTvE$jnlt z?p1|H8=jhTL+>Zkmg?V*`{HdXhH5z-2We`NO6$ zq@1rhwQUwGeyBKC%~(;ak#9i4ei!Vyc2roQg%yWIm^$+K~*E#6tb7I6`mj_r|WPl@D+$#lQGFseDGY&OE)0@TJ&>rpT&SwK!3R{tqr+Y zc47~fFggo{NdCzd&b3mpvpVbnMJDrkO}jR~Vs;8k716n83Sj{V;m60=ulVcqabFCkeX^OExfuUdVQR(l#>pS;E2m8OIX9A; z3$Oo*Wo}iGkn}A3bN%epbU$Ivb2VFdCOuQdu8pKC077o20(n-V)ARHbPm!TNu7wXI z!YPf=M^x7>FDU9V>md5WxZ4NwnIfsrPEYP1P4g4&8&j~gO(T_SE;QJoX`!P!4DLNm zbFpxIElZ%tEB$s**b)!GO2(qxj|bmc(-i^_g`$(0t}0vyurf)OnBYk979tfP8`Lnq z$I`1!?48zQX?%|GU@~)K++mGr-eTPV`Rq*FDifxjZbxix>o6l;(KhEi$iaBCJp6*S z!{3Znf3;W&S^amfuU|9WhABjV00vq07K_}GP4grk{+OWD;UDaRseYuN2P*AsQXxRs zW)923R@Vl!_}?|aqLQkhCC}7c^F|%HVK4oaE!#ZUn-EeemHr2=rRh~4a2QIgI+Mdf zE`^3f1`;Ey2|MY(iL1htx<^`X0=BD;L%FIXQDkH3L&xisaro<6BHF`Z$1uT$u)td$$G5J2PF9_1Xa{xeS4u#naDUMHV@e?$){Z z)7O7r9k>85dkcdNti0PZ?yJqV&PJBV3`23t2F(R~mpQ~d{``P`?dWJ-Qo9n>)K@q} zCnhMFX2+Y09rWpm*`JLT+TT*_BJt`Qk|#4&_UqsRFshqZ4+|?N3okSR&?ne@?K zHBor2geqp)1>#8%Beubm#68jhYe<~pJ={T`Q-Uw{_{Ik7L8X-$)#CiHwZZ4LEJh{E zfCu&<-Da8+vdZDN}AqfHDr^)@@Xe??moz5bnBcPLmePFCm z)swtdC#jCJU_Z^S7;ncg>s5Ku_eBSdc{Tf zQYSTR&fmDDI?G2c#E>O9RIr97tYZL)@~Y6I>K;p2IkC1;fW#SvCCVL^9*yqL=PQF{ z@jC_A2Z&+a`-)oMubZ-;zxW^pZ`uai3@YvYw)MZ-L3ta4Dc6^p%(?;bOc2Hl6ZK%& zBuylGEOZvu?`uF7APA;qhBDhie*;Zh)wTok4X;-VK0L0-L8aZUtlzOG=? zURm4`&&#Sx%rZcjYiSMafeUGQHpcYsr5)SSmDSG#K0oA?{5@TWZU_yi-3otK$G~rS zg_d}rvuS^JY1{Dxv^Z$4emZ25mQxnVcBZarXldM={y|#-^+Knt&U}2(%Ovw%SQzS` zLQ-x66O|r`o4rsxo)CX2y@c7Bbf7Eu-l@M?#Mx6WmN3BGoJpum6OV|A&4?W#Vv6mD zuI@%oPsgj=tLR^+%XS`v6gB*5+qfv!7pjd5kZCXtsT#$JOXi#pD20M;9a#aOmJe67 zh!+m&Q$p5X@Dz%lpD!~nv+>L7;QacIv>obW=eW!sSuoBut%0)sQ>;P zusZ+ruc`LZb*@EjUAPK+LY@aAV?|apC-xKp^lx$jw{*331lj2`U+Y-0b4{*S+WU~7 z%abKh;w_&njbaqP#@qb??M+R704DZmLiAMA7Z*Ev#_Vy&(ZCLq*u+8q26+Wv6QKqR zy5)u|wS`{vyDbwtX@W!YK`)aelCLPey(~lz^AL+8FT-Ej&iY$S=Hje3;nRqoFT_Ci z_dJ4HBBB-7w5wU2PWJ`tEb9!Ce8=(gmU+W*Qf6ckS_XeVGPG zLnr13J-g+}JfceEQwWgsvMG}$qM`&$Q6+pTA{PY}iP^c^-a-qznd-si+5*oC99agKSTnm^ zC^=|VJt?_@EzyEzlBASnE=E~~ApPYAD}*9w}Rpa)=x+>eL+Jq zQTya*RX*UKcOAouCh6!}g4JXehhJw-f3?Umnui$VmPhimbnn?z>tlqOyyA^Q3a~^? zZ#6^o<*t|*v{+}prW~9NG82C3kFvGn;ktCA3`OA;#k@r zTemkl*sHC+HBq<51(LIBi6e&wi0VCP;+>(x+a!1=MT~kFD6hIG+wbeoNzh6Ll}w1}Jw~G&n#COV zOGB_rrY?7jLVO#Gg|ef6OVN-y9vhj#_ZK_@8e;m8#r|?}F&?(H^&68A<_d8*8yZ-m zTP;OR1--*)j58t-`j<|W7&1@bPBgnE7b0Zh8N)29=$902Pb9SCBFZVwOY4_JUpBw= zxm5Ua0OUvB@(Xr(Ew2keR52Gz^&%LhC)rTF5-Mt(X@)Gr#^h|tD04R^XcUW%@rz9g zosr_b4Wd>*xB8(OI50(wv0#i_&gxyIhE)Ewl>Ca!xwOWfu&;?AHFRsdK*r5kdP{#0DVfVlvbI{an2QbebS625->qFi)rx~@f5n_U z0#1Xd_EWgGP07VMBmD$H?4Y8)@g3V z{d@Z>?r_T!;=wQ^J*%)nk!?kpV2v0fWEgElL@^TxQz<{sB@?xZD?zD`RCoR(_ag91yA3CyW=2ia3xJ~aK-dbiz!EwM& zsDLxHW0b@ivH>-r&`W1>5yI?<5A|nv#Q|;M2C_HE-zd;tQCsee2XVd>^DD%QgzovH z!6)O^1;pGNq`ma8$yP2X3~n4?y}a{4__Wl=c4vAboH)pEB7N-$_DOmfW*!)l(^5ew z4wFS}&8AbzUPX*zvGr4FE1pw2EIKy&n6dUx7ATOWgx9OxbVnj&7!uy#Q3+_LyBT7; z8*AHcs!h7?(VhdBL!2|=XpJ8>N#xK9PgtVb=Yc4eYge{${`bdaSNNYDUn+vuuHE&d ziL`GvPC}YW9Ta>lV;C&UrtoMP-}g$)khWY|B$b`&d>Z;gju8#5vS1vm3!lxWc01N3 zsu>f($=1G&PtWA;gphcjTRD42$=Ye8)eTl+S(Zolj(-UZH*>tZ9@vU$@K9=}4fhjuaw$gA5YG|-RkLV4yh6(ARo>4)HNW;LSx}+6xYY&yVH5*qWN~9S` zYe_Oy#Lq`I&LieR=qGmP3wSVIdT#(udW1YVl2Eoq`evMJOu ze<`Q47i8|~{2`zl;f{fRdUmjz`(#*wo(hVGzk+bTNq0;NWMti#vO!T=k=#Qr|GPvfr{$fgwzPZTFf;=9!In>42wbp15!K94%P%}&f;RfG zPyG0QO4&OP|3W7Jte4v?89Ei;)019aP4)`!pfFM|#HLGB;FW8YmJOK34Q0qtGi!<$ z-`pY=D^1{ULjefTdbc%=ux%;M7T4z+ivO9jMmNM-0)uDKU^wgSe528LUtdFDnN@;C zUDDD`Q!QHuD?5hZ*`ibfdWAzQ)0IcX?M_h)iN8Q&KQnU(iMt=oiK>u{88!AfWg#F;~5ndrI0HvVY+*Mk?=+{fZ`1}D7H=RQ-424$0uvFoih!#2+! z;zpi!X^ynSMls+g2w88uF!HpIRC~wO`vf%AXX@QW<66&zV=tpGe6od6>fECZUW0TD zn$>cv>{Tm<6CqPF^PECSdqZSa@&2FV)}1>orY%t0-wTaa^c$PBX_bV>A0r+X)jWr# zHw}5)9G4}ORwo>avi-tra(I_bgr%TTqf<2Sjw@6fkUBTY!YYW@>)d11nY_dxJC1Cm zjM$JhbQ(_vlr?RnKZ_2^J_L|w9J#p)qBW;B#(E`p`z zYVI9EIomOrwS^F_t4U?;7a_-DrNg}#f7Hbn7 zP>}gSQ7@)$D zB^oN0NtR~6rKILsp#XC%)gT2YW+_$CCZ24q(f8Xm9ORba&9TZ>#xyNt)Z6LA91kl9 zhN^6#go5`RU}Q7R;iJ6EHjOqTi&kdX#kwPQoz;T6flz^@GP-o=SE)&lG7~-AG#Kj^B%;C7To|K19G_@ z$KmSAW|^E!XbvOrv_!dJ*hRQ@oau^bwZUzmtI`v^6PvXr(wPrHd9#uZ0{xQE-x3Jr ziZKJWUmHV)!9i3e-XaQ|yo$5?)d|6$i&2O0Z$DueK#bM-3Z_t`{ZxRoELMG;^Bh+E zFpwdd5aI17_Y(Bj(*@{B1;Wu&Xv3b`5f2KG-RzgG%gx@rl=!Z~=ETgzyc5N(Gz`&$ z6uTzFA{b_&)QmyX3ZyKTGP!G0Xc02>Su%VU%M4Sb1CT-6Kl6yXyz;<5M!2RDhspaz zhUqSRXwcCIEzmTvkxtvypvkHD4q$ZV0_a+!!u8!cKhDBy+wanHvHTw%b=9P4>a;Ap z+LrH%fMS4-eV?})p)UliZMJ}Y1L?(oz{ixV>AVS4t7gRE?^x!Hx+=4W>)fA!+oEaB zY51vgpaKnGGkv`mc_qiQ)*rzzywv&rudq{$u2(0YFmpnbA@XART$ zW&xKU3wMOxL8bjMC|lg1T!=86)8+Z-U7r5uhJt1Fs<1aR6&!WT7EIp*X)g_~Nxs!; z{uJS5aLlD3v}{unbyCmQ3_Xeecbud}7`zJk>BQkGd+dSWsL~@Rk4ohAKx2%>Vbsoe zn+D*OwP3n;i{b>juE!Hn5}G$?H9~=D`ZfR=XDu$!4m1_!;f9Mk{)k_-fI$jF z8yhZ?Yz7T}+%qC!%)g(n_k0&Is@x?AS9=X1g$GtJ2oTm6P+;Oek{ofP?|Hp^*s|Bz zoJk+Zyx}&a3r`+Jbzk_^C=^3IaMhkAJ~g6sK@Lxp!AfAd z;LIg_+{2mKPZX3lD15LUplASr2A$CppL6uLg4Bb8m(%KUtqtp3TC0h@Q1_Ehw9z$` z?OK@)S46Z+;GwG%Bn)=B5X1?@C3cKgkNZkS_n{&by21Zc1Su80fd?5AxE97M_CcZ_ zRN$jkQbe7k%xq-<^V;VC1wLC@xr6YegT#CFCriX964XLd0&`4Z^$z}hZ?T;6euL|e zQLk|bQnA0j-KU2o$TUmp!mQMY>4iv;b(=>X8j5(tuRWqTO;n*zhI#Hqt|2#{?UJn; zr8BY82ML-3s1~!NINf7HcFcu^O>b6gKN&GVQsy!MV9aoE#jW6Hv zXB-P5F@g*_uE#+t9h@$`?)iZUf5vd3y)m%5d03F+ecXM3+~$pTVfR z+?{#_|J6}2(dnr|XB{+ruty?f0J>|Gv(nOWu&0CaXa2?*PeN9@mA4pR$c9KR(CmfD zz6%co6oa61g^sOC^2x!!${c~+oRJTQl8efClNW7XRyG+9@AJslmJXX44R(01v? zqMP>9fMr$nP=U__sT0!Dqj3*Y&K-e=DHh9XAg1UoJ^z~5n$e?EkYKJhdBNKkx)5** z1z#|PX*K0BKp1cY#?(z-RDjjlbgHSMBv-59-nxCz0a2zMRpaB)q;D-D9v$J6J4eDp z?iMJ-lB{0%FA}BGz(T8ls}~|U96ikY8L(~8cIt)6rfB?B>%KFyg8hjtwQa^6lOGaz zKpAo%geTLAnyk)@-uTdhXnto^FQ~a1&I-VSC>PKOfrd*Xs$6C!3^T+Lj?*`;Lj&Ow z6sW)Gwhc%CRCu6cWu&acY3B!@cEg$|(KtUm2^hF!W+RVb(h7Dej*nya1xK+r0+3_Q zX8fh5-04w|lyuRxAuJv2As&bS2*^fjBW)aA?3z56x$DUzgjvRhCjg*`Px8a>%M@B% z7X#qRDO?Me(=uQ|=tHkPD4xcKrZ&Z0$1@Im&c5APG(YO0H7(Am@dzQ3+2z8@eF{*B zT3%E`HP$ix^eUVY{8?y-IEWlH7u3M;{Xs7f3;Hu@1l48dbikS3*(6xk#G%KuR=q&H zQL-j!q``*x*qjVir4LZR^^2{3xX==+%;Q)jLY}H|%fL?lKwgqxh)V)Q;22uFhMJGOtiOAlIdv0aN-QlpLoZZrZWt^eVpmhNr0QHSUji*yzu4-yNE!x7`Icneg*8@QjxT?s z3`ya_;1VV`8>CxAbL@?__H)}9#+k0-MvoD3wm)#6|D^tsf2w%2Q`2p?4HPBHSLJL> z(WkHKBrpJeb`W7(Aa4F*t6A=qk2}p^R`vGPIa8QhDLtGmbtcU~2-6%ieFxtJ`Y$j3 ztks4gAl#?-m#;9kqqe((tBq{Z+W^v{GYjq$EawvS`hed!E}~JCGFWnMesb&IUlcp} zZW~3tomY?TQ?s{s^I`<_pVCFkmW}i*#`~%5uIfEN1I6pgFZGq~IWy@&oQ_k8)66?r zdH(T{L!fJ2Bvs=JQp4$WpCe|MFT8$L!IymuJ!p}_*VPRUCOaYn0Y5kyIx9RKJ})#C zHYf5=qTT>v9Vsm_jNqk0^(;4nPM3>{>F@BlI99{Ccq1~27+g-H`D81Is6q4ya+Xk; zBGzxWIZd7`8(K4&3)vKYc8Wjfp7w+ZHf}unglP&ZlG{(5|ZWf zGB38;+hGy+@K>E`7oG7Rmne7nAiB3Fb#Y)U6oUL@Km3k#`l9=NvB@(UD3wD&OYkaSV7lIE3m=?TtF|Kik9f}3>rwEi$ z(|h-Cb#-fyA_-cgDdU(j>he8Sa&psC4D_&czwvduuIG;Of{T)xqN=iZvBIfPq}8#< zF=%6E3>#Ood)|$dh|)%}VZ@F9s8P1nH#fF|V#r{YU#CjIpW$(s>UQMtN1q}}sQzT5 zKWP)R9w}^n!NtMD%}USA(ACn>1{XGj!GMw^R<=ZV?i-ar^1l53_`j;6OIB91j?u6% z`E7BtdwTfqnH^v6ogG~r$o_virTdqCCsDP4A5GZ=i4ulRZq~9!ppdq4@I)d zOV2g?4pX0Si2*%5K0G}*IXe4D!cj4;FPI#|(6ac-(iXgr$6zPM|2;Qx!`6^D+04B` z&@su+dEEN*gw=WdT`i03|vfM})8FsrqHM4Q4m!_t{Y;@V5{8&88=)9?|FBukxFqn=x{@2F9kk{Yx7eh!eh z;!7@r%{HS?A#q}*N>(mVNyEnuo<4y}P)gM5`8q|RF8}aMg`7C@=8OG*$GJUa zLP#CAoL!w21^M{8LH=XpZ*jTw8P-xQ6`e`a@GrhU04#IhcMdi)lpg%*eqA&nsNrTJ zNm-#Jr7(f}OK++CUR|os5Dg?RV$b@u#9AqF@_>$#enYyE=4Jy|1|kD9G+nF5RO-t` z6~-PsP$|q%7;2yyIWLZ?>;?rbtqH!Fy5JhThhlI+QEs`R+NuoZFpW z!U)<@hyJmPeUUq}gkp=iP|?p}V-omN@ylMLS(mA=!}-Pt=o5`|zrdRrD8=6vg+M0W z8P(rtvS+r;Vx!G{$?d($%a4V4)%FYfE?@L_pW7cB<2CMix2tDmGlLKAI5VucF4-4m z521kq<}9zz=<~J!&$s zyx1Pbt)a8~AG`Fgfo0l3ss*%@Y2niEFJOPf}~W8=AmCyKObQnY!BTVu>7Qg_fk zT>|gSVOR832zIUG4Rm)A^Va*{TX0X`*~GWL@2Byv+NOa;FBf^?R^gsFO0SeU6+6nBkE?{ArIE`x*p=&-C#PdfRKAa-%g_476yd-jH8)rqe z{f~Wf$$C7{^6$-ZZ{Vb_U*asED;DjNA&Zq!q~BWksfo(O$1RwslzPc)909@v7*~H6 ze}qt%|3oRUIR_z$4t@_P%ViqDK^K7`2|;OOS0BOYa?D4ebU6=jCj1K>!Bh|(RY65l zlB_a8WM>EV#&;wf0&AuxNAm*ask=9+NRt;Z|`h(sI2%r-hh%p5! zL}k)UYWM?CeCP-AUuT4`kgx|Fe*}5MO0+1u?H)c=e~GYNPFdFu!n+s|F}n3`8&&Zb zjjuen0(CA0KJho#uiR=Q>Sei3r}vf~i}#}Joo;L^H#f^hxnE$0sM1=h;v4Zu|J$AN zo;ZM@7>VFwt5}(=aU%x6pihLTt!ud{B>iXS=7!5`ETR9>s#Hmg*-10#|HzdE|AV&2 z%iz;>!4nUJurL0CNO1EcmVRu z|Lu}GL@HFm-Kj_Z6J^y3)G7wM{(B%st4XbXerp%`e+0vg|7(>$@p(z6UEk^g*=+_I zT<=vIwpJ3i8R@|kf-gQS3V4Djj=TOoyBL&9vSw56plwAXH1NZ9v(@o~xj`H)ok;5@ zfG3n>-?ZPb&ewm0Kb0p`)|5W7Evqgn%_{^&aDv^F%XffFZDENjp_*ZckU<-;hLN7n zb>tDy2Zj~pNPGg>IVa9Rp4nKIeIeX-zOvRdYZ)}AtfX#X$mVSh)qQw1K?vBGo7u8T zI+_eN2ofyuIWl$@RIg9MbQY+GFzuE{N1ml9WbE?#n2|#y*#sy4$hog3!qd)&4WB22 zA@J}5Gjv>BU4~)eK?l(VZpt%-!X~NRI0k1dcspY5a0n4_zr|(;;W)f0K1yQaLq*YU zLAN!s hhfh%|@Ua&j`L*R)KmEEae+|!p_7!~^Xo7%%{6CxLlyCq5 diff --git a/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 b/theme/fonts/open-sans-v17-all-charsets-300italic.woff2 deleted file mode 100644 index 2f545448418cba6668a2e7d49e9616e8c69dfd15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40656 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 bQBM5)6s%p?oy_T)fR3IrepgG2|qH4K6n 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

D& zKmG7e67!kl#@t`?2092GluuaI?(wqHGc$CxbhOu&-QklBs;yusvX`9XbS$sFoH+FwvSs*$VNBEt-3}x$RNG$?<{E4Ybo(b3OQlfghskNz z9}K5Z3VQ3758HkG0jW@{RIXI$g7RShkH;@~Tu&=BS_r#d@9~%{hig#_2T@|P9H)w? z=gh}5S>q^Cq)p*cpk@GaSXq4sH<14^6;np5c+t|$J9x&lS&Se9UXJl& z`)tC!CGF^PM{9Gle70PoNpUr~Y%X6Z!}+OG>@qySno#@WZs|(!*Vl)pnmp&Xm-VKQ zd#My=>7WO!yH+kA!}m@QP$?RL){Bk$Qv*y2cO;BUYachhU4q|dA!Mv|yd}&v+!gE% z{DqB_ousX_y~Gbfu*tQR**BQz*PQqTVG6mV8#<{f+pRkMaZ3L)vy(`szQ9`Qf3L->DdXY}1dMc^^Csk2NTKs7&QcmZsc@0=Q*+*}0+ubaVYp z?_|MQ3hbnc(VG!jcF*kMaE)V8EC4oZFthXNL(^I^9lZlOJ$lJAO5=PrN|Oa{fGt+^ z86n<5N4dk4So5{kLjS&dhC18h8m3KH)**}vqTFD5^iMTKEbcl&5* zW^QC_D;06l5fzsu|eN0BcF>w|9d0O=b_CFVJ+E}_9y>Lu<@sRBZRB_KQXt_6*y+3*^M zE`8Gx-~2b)<#e>sMPht9=HdY`yV6x{- z64g$bGMR7NOT#uSC|2C5PQzyT^d!Zjg}qSQ?g6h$P4ccGk1(o5QhVy0CTs#8Vc)~9 zOq7?zT_f$!BRru4nCKiVUdJbNGaH|)2T8r+vx5vQZAuho$o6xH5)jXZGCov~fcRfT z&bKQLJ3z=#;>0N62R2Ai419Sb^WkaElLsFHLI;>$2KQ0{9@j2ZT<&_5+_Qnn+unjA znR%4OQ<~yW{LJ??8#ND;4y+f5FkhH;oGaMu*V%`Yil((-`_{i*wzrFu0@>r@;Q!@9 ztG-5C$|o66q0!cO8N3oR-ZuJgm%HhR9u|9gr72nkgf z`o9%BG~SIbmXx=T6}XWG!96o?82ddt~la{g9g5aRjJlk4d!jyanU_J7pF% z77h|AA4MVw=oD5BKVh$ZqKjco|ES*^`7lni8w`M~OOWG;!0pS{gxy|=mLhl`j&hO$ zyh#a7>{8aWnp$JtTk9*E)-=y}7@o8Aa4GKMcm(?Dkj`*yw&d^BbmmXdiwG6W=0S!H zhPH0Do+Bm19r|tQO1}!sqQwXgXJt)nTYP{voU&oA`&wBCy5wXMu+q{aM~Pnu^`Xm% z>~wKZWVqL`FH-T@4e}yAN80yR(3BfT^Ox^K6v1kT9mt8Me)EpvvO~*=Dzl0TbRG>Y z021OhH){SbYUb?JJhVvyjO_=O!9SzJSr7p`)%p3ee#i#M@JWL}?M@`DqCi*ZE@Tjp F{|Bsk2y6fV diff --git a/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 b/theme/fonts/open-sans-v17-all-charsets-600italic.woff2 deleted file mode 100644 index c99aabe80340fd88a6aeb5729251e76c9a6f35ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42120 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 E9}-z&tN;K2 diff --git a/theme/fonts/open-sans-v17-all-charsets-700.woff2 b/theme/fonts/open-sans-v17-all-charsets-700.woff2 deleted file mode 100644 index 421a1ab25fa88105ab776552d7201205f7899841..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44988 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 diff --git a/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 b/theme/fonts/open-sans-v17-all-charsets-700italic.woff2 deleted file mode 100644 index 12ce3d20d1ce2288206e8b4f31c20f76452efe37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40800 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%0DER>;wf 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%0Deo9y(?}8?riQx3p&>dOY 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

33OR1_N*!%ylDDa|3D1;gP8brBkv%FrMeyX$5% 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�*c5&zVhumMFXrgD>hBXFOLH8AyaTh+=%sw>z=`?O{`F;R^ z+Mmvw(4;1=FgYm8cJ~@72cgPcb&WrKMtnn+1J{Il0JuQy+B?ti&^VMd5U{WN27lX3 zhHX7o^4N&`&0VhL-82k}t^M*!wWQ=kzsH-w&+hA}?YTbYn9`|I^^Hwr9v%_A@tA+i zcfAizcr^6CTuQ7j3QsG^rK97PS&2$Lu*m@%`sG&qUtl83NF^(*81ZmsukwReu_YH-LV*DmdW=AdWjgc2 zAQlYk3||}8xmM3?pM_wFb8AA5MKU4Rg5gGkS{$}MAZym0v#zpW!N0;X+biG1cMgQn zoh=Vr?hk7&8MfGH#ez|smu&JcJ-n^wY=)L5Jc4=y>H&BPTC;^ zsG1dk0EVRkM%nS6P#d@q{LM-~Po{<-jLvyK7iu}Sz zuWZ#(81DKX+{Hg6GXu@6wv$t9MPA6^v7gcYPH1sXk{qLqU^{dt4%qb&d9y5ICwg{S zaaDhOF8*?=`hlDMV->zt9=o&Qv0--n=}}^ux$3AdE|r|}hPf3d?OCB9H2q6o%_KKQ zSDD~1j$|;n3q|mBhzU^7J-R6~su^w-hr2MyGkMpx%jy%|*ft1i>DFw;M+DOR`&MTe zp7ip$NQD;sgPUD2*M>Gt@i=~P$EYo`>JBUi!pmVt_ zC~kC0qjU&tqw@lOH898EWq@53anMI)1jHu*>(qUB1j4 zFHTRF4wpyK3*AFD_+Yb{#9%kRC;A_zQ#%(PS8lP;K^BI5XA_zGTNM&CGmDvZ#y(cI z(p(eO$$MKbzn|%<&X0B3duS?hyQMw;npaHM|9 zGonF=O-ggN4WcujI$$n=#_m}nS{bNw-^z`WP zLF@s)t7o{gKK?JjDte{W3#jWSG@uA#LR!GMx*RR?d5k@E^Ny(brr6^zw4DzB2BK}| z#+2_iTFhT9TbCIvG3+}e8=qa*ASJ-XC(jjWG;Y^8x8^_t1qWD9` zuA@kho#OheL)6e9GJZ?d3T|+B2yfuP454IVA-CImd0>!1qUxKPk>UQ~GE>>9Tpye_ zK1y(c!%uz}!hqxO-Z-H*<`$$$OJmg&h`9CsSC4Hit;KlJSy}>x5J|jo{9pkHF3HKO zDR;`s+YnX@4}~|=vPiYua_8*a4Z+ne(TFBm)@*KVMYb>4PD{N;&2&GX^z3Ko_{g~99}Y*#PllRx87 zb(+okvNa_9(TU5fnIr{xaK_|RIdw=u1k<|*Ed4noQ8YVPp^3Fk3Pm1;9kUEw`CBp- zZ0@DzF0Yy#2vJ_rEr|GFmA*A}2A-7zQT2CMzM~6hUA#m*4d&w+i zFRp4CX{+`zKD|7qx?>FGN0(i%XIzH|MjmXBvL=0*DRQpzfL3+6?Rl*lT;@~M!}?$! z?0@3O^gA}UXD#`q(PbO&4$MzDQE%rmmWIXzlHxjSM3$9mMcJ5w^h{4Dzv+Ti&Q|jw z0gse%7VgD$;U1ah3R!(hOK;UwaeY z!`yG7>)~)`dv0wois;O;vmj+@-k*0bX^udr0lIMTmlj)W(`|tnG}L*wyNeFt1A_gK zc2M7WDj#{Xkz-*c4P2fC>tpu8QVrLu|x7t>w}6 z@HeE~yri<|I>TT_-a>Nn!hCY_wd1(9kf$K}2JHu2!t<%}JXPYAs$`xo(H*hYm$|T7 zpA_gRiAyk}9LyMVj*ebY+m)1+(#3fJ37pv`KeJU{zg2npZ$FYZmrKZyi)vMdL!}M2 zV}x*me9tnIJkDJ|DnTNoD)@l~5(dOJWq z$CYf4H8Yy&(b0?5ehFk1KE;1yxZVwk0cV{)^mDBygBfMr8;p%Q24my4UK!Gb2W&)W zxQXPJ@5?I~+V4pD8;t@GcNa}yw>dBEx3{^PR7hF$`(ysXNt5k(l$~du=l)8kJbSIL zuMH6ZSXWUzuq?EyyDdo9(;iwe&^79hwnBPZq0u|Mkye%vl!2QkK25jlxag93Jtg^k zxQ|tW7@)#9LN~`)AmVN42HgKCbbb@4_xT$z5JMfSuEc^b_FXMQ2b`V6FK}I@ z@>b{Oyt4t9Z(j{cnTXZ(50Kcn(JAg-Ax>dc7M0ZpqyND^x=)l3^dBwY&vk0CPvb)b znGT&b=L5HFn0@NI$^@u)(O-|OC!qA5QdydTU3(+q){k9is)#6axu|xpY;X4hGCxON zS#V4g^RGQ|jSn#gRIi;(@cef_bL+j6YEN!YrTFf03l>U}`&OAd?)cTKPS-h?1(-Jm z{Oy?KC@M`JT5sn#_G@Ew0P*h6JMJ{w6$oWS-Ek_ z+jX4z8II>opCxJvm#>BxbxG3kZl*68*w{m{ju^`cZ2e8!!E$bgb+)p10+`N=z2|Vf zCkH>LbqRpFx%V3rZ!~Gb2L|*b_MrYzNxZQz3%ur(!EZygU-8{w{tfT)w5CMp@xte0 zKbSeFgNdVw51MX*8566lhq$s#O?KA3EUyI$8xe~yNO1OiyN^@^P=bDlbG#Z z5nj2*=v*XEoF#J*c#xrPW)G4)r#Hold+DdA9@>shg~j5+%5e#0xKJhz_BF(tw+haS z(%Pf6vQz%y^%^&;2=D(W^z4RdP+0k{lDp zO!>cOo5A0+gzvO7W1M62kg=8KdY>I^?pQKs;qV1AQ`G{PNZ0>8;|9K#LD|U_0;@m)G*5F*@CkUKl z^YsK*3Gbn$H9lNTW6iDabQSc34Hxwu?$PjB|W zb0H0aK7$6mdu@S+*f*RLKXfvp*|RZDoT|_u zNw>%FWDu(Qqs=YE4VgpLl3W_i70u*zTlFB%9eYO2ZN>yFUox@e_|3lR1@I$#+h+5g za7EskLB#08-ic^O z$Fnfzr+HeZbHqR%u=skZA{!yy;IlizpLm+qa1K!(3e# zhihAMy3;hnoiYY=80_&j1f=IfWAT16X6Tj*dU}paw3pW)VImxzI7Z)ZdkhAfoBIll z^C)?aR|9wQ{3Ce?zN5C;Q}jPsA~Wps-m1?}!%& zrJw>Q44AnOdFlP@(Uw%ff2KVSM+P#ygBg8KSwH)6c(nb=Y>zaZ=kJ&K!JVX`3mCFn zW-gkCHO&>Y;0O`JJAY&wv_Df6L&W6rT=GKIS(2Z|=d; z6+nTE&%_0VS_=JD_jN_Hoti-m42Nqgr6k`W@QYROwN2@s{AwQsZ3s*jHTp?@^Cx4R zwdhNs){sI2*ma%@LumTx- z`e0_}xfMHwdR9}Tmxc`z{zhiT*;{YVmkacO2SzlPdaN#TvL*!OBrrD@rt_m^(iMr0 za|s=3_RC;}-AQTeOMUN0f1*be8~1J`+$34nZ2_z$f4c^n5f_x9an4Y4GZL}eU0Uq+ zt2jRE{rAZ4AaCFAPmQ3Tr3p8Gxi#l+*EpxEx#=2cdR$O?B6hoLvo{@L(C%38j5h&&1#Ry0r7#r)3T2@6u9UJxxe@bsHCVb{>=a?MX|_DXGW4 zyAY8#j}^r94~|tw)WZe7LN=F07pmjJtR21|lhmQLezBgRVuwZ7nwVEX$85JlR%3x#Vu`!EFyM<@ zxk>C&oljO%kx6{9N0NZCU{!9SGL(iZu4JYqcq4KJqLixfsZYa8S4Y}(^aix)lwb|>iZFGwZ3#ObTvI)k)sVn??EN*OJ@{Zv-Ym1X`H5Ud2k3D5EZBpNjik`B3y#+NkU%-r}hTX!|qjhX48ZNlDq>KUu?{` zpqC~R($A>kii`HGLoT;)D_I>sN(t2 zJQvZ-8`KuJ&JRk6_wr`FX>(a1qB7|e5H0?lYwQ0DauHK!* zl{e+fm0zapRXv)`NawQ=tC z9DM+Xw0AiM{|3xp~$6n{OC znp0XP0&annkWIS2x@=_R^*@=mfm`Mtz6?j>w_K};y>(ah-UKK0`cc*N6Bb3m!NPF8 z1u}Bpf*)Dtz!!Oc%L(s(yu7=bKHY5HAC`9M86;lODhWAmSX>(A&#u?S8}E3)vs(7) zH~99%_I7_-*@GsHk{lH6j8K)>GBWniu3jl;;JD&Z5a89rPETHB;oOq~1&#?Nlj~ie zn`@KWqDlU&2^Eei5JAAAf;$2Y&3AjD3=yt5dg*YqsJkf>opB@@Z*T7%X1QdM3RLf&KhdPB0(`_TkCb!9EZ}o0(Z_(*+xa}{e+e5&C``j|rX*iDquLl-# zJPTNeMc8wCuof{pMa${+2uUWg*UffL-BLI->|UO#Y2V5Hx6s-R=Qv<}{odECkY@^< z@oNF0iVdK&mN9vQtUS}pe7rnGmFrwuU5A}3)}4)Q`Pn-&O9r>(1~`?n>ED?MMm>0j z8*C@{jx#2%;)@Ux&<#ShARLiBBE>4#4!&Mw3$(X=hnUn2*2*=&Q{~=5{hIPvjwLY` zQ9&X~@=-v%=v1TPOP)w6b>Y!h1(72hio*=9q56( zOlAPvPdQx}6}kZDMl~UZ7FZ8Z$%NXZu9nh@7#y@R5KWyrv|%s%^d1kL)DnavkGK!L zkhGBl@o20AP`RY#~gT&x)BR z6y9lwkPB=RPVxFJ_{;obLtsp(NWa0YfCJ}5^@LTA%V2!5_du?nR~EHg-&$8;AD@9w zz9!HgE}n;fOJCr=VpM`HU3a*|=;{0uV%<*^`~TVj=Q3`lPgP!Cxl2p2tzf<~aQbH4 z*^aAg540n9y^+lzR3q_=>9a@D?anQJG3fZzlmv(Dm`(G@{g@Qn&JPI}@ecxoDn{KB z(p}BuV2$UoLysoOiG=4~Hb==l9k}AB~|{TcZoFQ12I3pRV-(Y+als5Cz3GBws3hNBC?5>047gVQ9%#;)dI!WT~G1 z|7?wu%1JK+GnzZ1N;HF-jx2v@0^tA$F-Z9AI}{ShXW}mi-#DfDpB@#5KA>qLrk}R7 zF6S>42vpjR8{N25u@3*@?d5K&l?!Pqh$Z$Rr+{ z1|1ocJk003Kdid3$e3k3y+id~Fb9v#yO(!bIkZn1adur(qlV^$W>z_NLIrVZdriAQ z(B8K;HmJxvvpfE;`(oSqwj9~$lH{-ek%-NJhg^kxE!7&dYi7=#&i|3aa5gQ;GPrEzyO|8kWWcXI|SN+=k*KP9GXAYj7?gj#y-Rhc)V1tfr{672V!h@UFlO5n* zDkCT$Fp%$5=yOT0LcrhpbN0sRr(;_+6a9IqIMC-b^FQ z)fAGhUPwOL0Fz;-Y-0bPbOFn_rNcs!p~f+P+PQxE>Bx4;4ayB7b&oabKJPGjCARX%tn)6+Q4!wQ|dY)lU{`vR$&(9AowrBFf#2BV=3F z>?wGoUCdfKNSi7HF?d+YfPIWCK3Yr(j*hUs5};WZ7qfTn>DRms4HlBRxNmSe8`T zMg5NBh4Gwi`%L3QvM*u=a@ikZ`xjaLSi3BGvrEc1Jt+L2lyY;Z4KU9y$1-^}k;VeD z6Y+3QFRRKEVcm^RwXi0bG1}Q}^j_(F^L$nWtZkoOWI#z&wDbOHB-m?jBo~2oG6@=V zs?z1<6Qw9I%AF4ttadIdDZs>F{kM^^i147uyWQBqstql*Ap+Plp&RfdN%z^IO37u2 zc6k_OBX-9Xk3OGG$c-O&$RhSmxwV!QsFDerHB7amk1Otdx?hA&l3ibzn~}m`b_V+f zu<5Sd*a);JWsOU?M+OTHR!%LGu(IlamKE?g$Ve)wP-GMXFk}1R2u%8v_I5u_y@dV) zq7RopVl+ufd2p@Am1tFeU$)(5v&Ql*^nn-YG6y!>DR z#uN&>Jrv)avBMY0Um4bYQ)y}5FPNs{{ud^(C7zK!m#z=)3U)_`GD1DG#pb|X%YR!< z+a%? z$^IAKLGyH`xu~b-Xo}x>4my>!QbePN+dN31i&qE`v*s;ym*HDxCafvG)G;Cd=Q~O# zoL|rQQ5#6~6giaQkZ==IWrhRn;c!!8txKPpFvuj}6l&Gyr~VAb3s{y342WNgUL#DQ zZNWo(Pv5M+OY>1Sh*n9fCl#>3JL@G-822+dY(Rt$1O(h7Kf`eHC2Gsb|o7Ni!=b!&X=V z%U}hpgjKK_*25OH`O~&*uahV=?SbBHp))$Ym?LaT@a1<2P?3{2#kRP!?3T|``PQLkE3BnR?z*O{kPBz z7)ZZN$|)1l44>7YGJ}9!D;hYK92)2NQB3(!nEWt~?1o+n<1U7OMcq=dN$T(CO=LT5 z$RDsxmDJ#*8CIRrLsFQ@l(EBe?+J!?{yz!jP`mf~Zy&41W~5uhTr11BGl`#M5331$ zRg`SOf>tcH5=2M+B_pYa;t^h&-T!*j{}>-KWcz$XNjQ1mJJ;Kl><>F3DN?;8#=Dw0 z9$0tL()$1Rg^OtT!uT8E4HI4!T?~`!_Qgy3JFdJ^mwoK0)c4CQe1g@Q_A7#m$dfX> zBM_JSdZRG%)Z7$h3_VefMlb9M9UMVdiJIU(!li+8yfIuS5wBiPw~w(9XPIel-G+l_ z7*h~3EFkh{9ET0?L5k>2M_AH0%6cZa%N+iR&+#wevXF^uoSiQ_ihhTC+TZfmuL+uPD>n&*-lDQyG3!jxr+Kkl|bEYwOmyF(Lv#;@3iP`V4y0Mhg+2h0r-#T8ptC z!cwiR#lTsSZvkalba0J5Mi!T;L1pXhjB0dXYkPtTNzR%-?H7JZN zkh~VOl&J_P9xh$J#5CKZz0u&9M3Y+8m%>x6+#^Xub)hRj%d&NjM_hv6Yf57*&3gp89xjn>x*)+YQLSESr;I4 zP2)m4c}bJ{QeBEm@+)x=2e#@YV2{9gzyepCMyie+BdwQ0Jg@DeI2f;yWaj#dL!y;l zz-FZGCO#PWku&2npBM6cl zY1?7^cqFYd#?YDtX}vt|-QLlwHpLe3auR!LGqMtz0v!j0GuOt5)i&@vW7j%}gO!g3 zdbH5LtN(y1>zU$EQ%my~>q^@kn7!w=nB985+j;y1NA~PK^^97nQBskktj8c<%t^bx zjwF{l73Z$;5z;>7%;6LFcP|+E!WXMc-a7NIsoBQ{v+k^g!-y%e#5Qs*um!D#1@c5O{ie+hGh$N7;Z+=RXLNyc?ge;xJ89*2Lmhp(@zC$%@} z`NTBbXU?xv5dg+}80*utuIhOm3AnV1!W~xT%&YZv!ZIXR%4gSi){M~TJkd=MakTqC zEU2AV^dk_qu*T`QuOJOdCXuo3bX5o<5?_KcSA(&6j31-C#L zbZ^D5CpIv97#L0LARVcgElR7`YxxDptclX@qSRv-iShwu);S+9S&`||EA$#eS*sk$B!I2NiJgt43;vul?O zu4`P~d-G_{tKu~|Qxq#im%JZHT`V{Zty!aLPHq|H8haSVBk&4L?V!D5 zO%iR$nduIS_XEW~#`JS}Sl4`8$C`dn&KQYDf8w+uiO09%vu^m=&IRn@HueR$-ulbV zHErCIIwuU*2-abDP`{f*ggo~z%eHxlejA&$%MQeExyQqe}WGAG1SFMrJ!ityMT5D$DkYF5j;N+piXG4X6aU2jw zWSXvl!X&2%Zf~<`8X{1Vy8^%I)G;{oVfk8Ox} zh~4CBc|$GA%R0uLD`v0Zv3=6eHHWoS5h^0W6*sHp!_+Y~4cWkt10OqML<`cFj4P~IdG#}1(o9J1fB{AT+oj}= z4ZXO^Kk&mMRvZq4c{r5cI!F_L%7mv(#sB#CyAEl7HXRWf6Hol-f=mfYfxt?$fvMK* zPmrN_Abk%&bRGXrCxrhg5gO!>W}>}YuVZWH8fcR5H3Q)Ba(UG@X;;fQMWjE20$}B| zCW(5~b&G`!ZvF*#%V*sD021k&%$AJB_gojTioXA9NTz>|>0ZS1=OO=Eh#WAIty$|E z+sGt5ymH=4I1Eh#Uc-s68F|Z|j$V%boPSBq82oYnA4CZ}{Py&N4F3NRJF75qd?SsO z0obGc@@M;k%&!EN5tVW5UYh=~-CwBY>$NGKz+z2E*^*9i?B@8=TNZM6V zCwfOwD@qs>$kqTxeLg}UTq0j5TFIGcd%=+sWn46bYvPae|-`SXdoV`0lwoobbbbay;M9OB5C_2&1SP$M2Ful<%#;ns8dknF3A_0Dy@J;XzRa3ElRK7}Y!}LKoKC_KRd5~ZG zOv*!^f4p^w!Qq$kH2&k=hRm2$9W{bUX>^jJ1z>VJl09y)CH+T|&_FV-_z9P>d?6AQ zk|PG2=iV^KRLrb_UD(@<$M`J}28f7VX?6SneT{u*1s;tJCT}CHsIFgGtO@~7%d;Jn znTLt_)v=wfjiDZVyM&J_$O)!%DDNhg1qj_qC~D$?FD*&V@tptCuqGR<4K_KcOG|sH z=bWC&5$fmVoXUP{*VcX~RCVBR!dU}ij%y1iL#{fD(MAGY)eFuuzv9RZ3DAbx=to26 z@+wzX6&gPBR~*x%Rlv0gI-d@gi!81L8W_PVfKq^Elm*HRIyO0FiESBb##DjAoU|fu z2LGXuefj2(e>N*Hj*iWNDuRyf<{C1OVYA`N*h9*$^#}NnjlZpT0J-^gW7(Fr+1w7v zlqm?8gjkOO9-e^?y7mF^7_SK=T_^jgQK_k9zhK{@3mJdT$c3E;oBKK9>z!rYi@^f6HwQZ3T=3bXm)a0TCquZslz<}^9V^MixU zk*9{6&F;BPF~VQbM8oPjY*EJgLci7WZc-Wroy3dwVVH%58rhYlP-CLl+ScQKP1jt- z(XdzWxu-#+xELE+8{ExrR#<_@^>+;Im5A^#nfHtHiYOx9b)!3|VEi%=@Q(-@DMM9p z!*wxWqM_PoGu=(7NQQ<-jr0Yz{jQcbA%Mr@yVng&0`lHj;vGGPfd@YJu%e~xtUWw- zS2JnXIm@SRjioSV?pMUzhy*d>Y7k{X0BEL!s=DU^O&2JA3&Am*JphdtG5et_f)%IW zc#hI7E!Mw=K*O7Fjgux2eD)9m*RWhkyp&gzsF1_WZw~VcxULJ{OR36n)j78Ux|}{f zz6sS?^VO7nGgfw*@C;kO5^ol>;%8U8-AfB|ZmIbJ?v69x^TjuI-Ca2Ex@P&1yH zL^Hzk0!%>k>mMV`b$-Wh0#{P-cR52Kz|gEKaHM-Ibsk&GGuyyGqL{MR2Dzu6dYQ<+(Y+VraL}(ed&L?#QUvl^MvG!IV_YX^?~jJdS-5$DwhOi8*Zi8_@Ed;b-_K`x@bbJja#gKQs*>kDv0UX_ zxXR)|?Wjy3ym=SF3}fT33O4f%f6EvCwSTkFCw|HQfZzH*M*PF;zI1IKwfxg=X}j;h z9XXamr=JzHHiGNKqoGrUTxW4`fS!_a$I}T6JlJICPyc55(^oY2#s-qd7< z*Y3lu`+E?=-6tVSN9~QFZC;r~NYvy0`xBT0o z-t5VbxBmM}YtKtXu+H*$D3!bbrMOE(8BU|5@8)e|6hs|_Ikmm}Z17$*DL?{F1a_DI z9UyU6p2hP!e%Sup9J!-{2KXR%9oKIiuUr=M6kf9)t_45RflqwmYqM_VTVK0NnY$X? zU|Yu+_1N)_?Yd29PvwM>Y#v**t3S)6{enj7S_&_M>aKpy~nRN@yP;uuRK^Mn8{JQeocL$x zic4f^Fw9tNConmeF%PgI5qOr1gDX~xGvu5mph1_}3de{CG0y?YKjOkvV0j@hhzG%{ zhOyvAY7q7(Zi!M~tSKd98qbhfBA&E+)}?_2k}I*^Xw&MG4njLRJZxFM$(+HrYyQLV zeQjJ=t^DErE60p`xz`r3nD!P$4{%o^pneSpGPhZ*imY=AV>R<*sfWg9U_(XAtktp_ zov=2!pczRi7g`+8_KE@+v|-g5isqhi$Y{gte=NSTDCyiJ@<6`e4~x0t*x}#|Lpd0t zBaeK^;D^X2SA4*-p3{mMLQ3&W0<@=L?9r;qWCc}j2}NzzsvbQjROk9O;RtJ?T?P?b zf`*fg6>3)4-izj*E3wDcmRi1?y-}Y&^+8DiX%CSd7!S%nx>0 z1A_WoKA3PM@0aDH>^fj+Y(t%>gQR%~dFM)M5x`&bfJaojPtbf6B9AKz>``Gd*4isC zUFO*NI%}C%vpWk4RA--t5QU~%3&3-L8O zPIgTYY}qmOm5royYdqd)FgoRA-FI#rcILg%PHAuzg zXwG8JKedeWE2o&+_o4mt=+cF2*zyHSPu`DaIfcm;tQBYZ2{5lwCDuIPqOe>LO0^yJ zsXquoMxpkPKn+|h4dxqP8DAFCT6$)a-mzPnL{98&ec9z4y>M;Nzqkua<+M5|C2fTj1*ASf-PRSpyLBh~ zJepw~_9C_#xf<(bU;0?ZLTM@|<;YC0DE{>at!I8v3-p2@>_01k#nh}qIJ*u-y-#C+l*=1LeD8@Vsj!ndP(ubklCz?9c%ji9_Dnt(l^J3-&y1;|=Kbr@D}bB; znG)V7ZgFVm{#Hpl;QLRZ;KA?CK)jza#Ab9heis=YbOi>MLZ*As%5H^rG^>H*==Vm# z7QVCS!_B|c9WD-g^L1EGwf!fWbGglWNbi()C!WUe%;w`2P_V`J z-5sP1M5m)*IPNA@kohh+uv_#PI(f^wMOH~3>UGd^x1ROZlMlNN zo+M+6Wcx1X5PdMAKX1^k-=m{_WNEJ}=isH_18=-0T<8cMs#cV(4p6q}M|K_E=xxm{C`3&>3{v0+7`pIR@Ncj8#5B8NfeIlE6b)(rzyzIUQ{*Ppf%rO^oKvZ;m5Pz<^cQO#n}DzdUeN|CFj!#f|Yl zWd!$i!LFEmydrfo7iAI5OlvZkPJZN-rrNJXMRn>pXWton)ih-+5QeyOu-@!7wA^dU zW7YnYGH&-~lesFulL7s7q!67Tn4PS~R=!<*Wl$YJvn&wY-QC>+2iIW1_2BMKa1Fr; zaB%0K!QI{6U4y%OaC_YE$-VWe_SaPJ%x+E9{MhR4HfhazlezazPXI_A8mRv`(u(mzv2aM3vo-h-LU>5iF1PuE0BEke4c+TM)GI zPVKHe=R38R@?_35r}7%JA2>qtbngxb2y5tv>WkDhn(Cju#tP3}!z)!eTGMlii~eFS zLdi3eBtsfd;FX0%gKZ{X0oNslu1VRES)_5~^?zS34gPMSa;k7TH51^bqZHMV7Q2dQ za6Ot!Yjgh=lfnB77MaHEUzv8dr3nI%i54oRPe@W$YRiNALc&^o)Yho{pg8<`R3bwJ z2vI=YN5Ms8w>ULeY{ELwYPtH{&#R<#)e~^%@!;ipJ?u>cTqg}kKWGTHc&(&!Y#lAB5$gN1~Gml@M+nW zfT;!=kHoD~X<;}Ck-z$B6?XC`ec}#g=^%w}hVc73&iw(SfE1*+fc{O=?fv&!_hKXz zKtac}8x&7_Nn;~3PenZ!8(R~N4&%fGs3|I8OxN}LTJEfS(la$PA%+P8y4JN?9D{=z zQf_z<*6Vg0loPbfjEV8|1N+C0ts&#x=UXb_*G3xX7-O8gEw*Nv`%wC8gy&!epY~`} zlT_(OEd7kbwzh`DmkVHd5d_)Y7_$;Gmu*LeKuWu zT%`sxY&oct1_)_S5=%v7J^UYccdLHNklvP7dK8gK9Dw+|pHG@2h0kuS4<|6M3U6Sc z1i<}gj{1TLnUdek+?{u=t7Mg4N7kIkj;L(s5LK|*^N8^0> zLF^2MeNVRT9t8;6-nfx}$oe3xb?UnGKmY=5w2Na`99Thuh$=^q@cH|Rzt`+}N3gIv zxyfOrBvymXe5n466tMzy>nk9$OQY=o*KJ6`DrkOOSJDS^mocW1RjJ#!fQqO$q4W@J zkwt2DqY?6p6l+oFt?(<-G9J_3!h$a|{*=K?N0DM_?#Epswi+^i}B*QF|9lkkH)X;a;R zCi}AZmOsZ^B66S-|8aNaRIJ-s!6_obA84B*w3R;l z6TGJH$KSDhjJ0yptiTC&>oI3oQQZ}}9gkn!{NBjWu6ZJ+ILA&}ZqG8xdU(3LJi+o| zLZ0tWOjMAaK2^$eQU|WLEz=cReK~`ZA~-h*NoWdAQ_W`g3ijBz8laUn&ME%k6POw; zUOlh7SVG&0COsjn0b~6P(N3jTZL!sX5mPZapo}<7-G%|I@S=v~HirzUsN>0U2Ab8k zX^Dq2PVMntf&+k(TduZ={4{f_1;#bmMbRx*Ke$9_J*h4VYhwgtw{sEYTo3XEeDtxP z{0zj-c)vCD6&BVX-rqs!e7SF9+kD&g_)w*@eZ4@s-hRz{-4Wk(cwkl6{Z;W->FT_` zJ(kYfGnL3XUm7k~h8?!U)c42ByUNKRn=l!hq3=FZg3_kn^*~HEtAI<}>M3Nfew5my zyMcQvfj3Q?#lpuDH8UcB?&pa|YTMH{!u;WrAKN;4e%?t7m&uNe7x!m1HluRa9#`3| z) z*af(_91u3J6y2|H#L?kno14p-v&?HRz{vz^-OoJ4&urr|{Q>zANe|$88{QtUUt{lR zmA|?F{4ePtu$^ z+o&}yT8>sgQLJKtqm(%6(0~_3HeigBHYK0Z#OG+nrG8yS0+r_YIuw3KxjxSgMtI*o zHAMs?E~K(QaU*(4}D>^#%Da4lf%iG^7bR`ddTz;vFN8U8gIa}aX@{0HJTS;BgU-gQ+MvBb5TL60|tgvSC7rP(TCw!6KV5%7S z3P%q@+KT6~L+ZeNiW%S);?*)}HXVCs8hiWqZ`J^X7^h22EcbC82_OEkymDrm7WXBnV869!rd1;t_v<76%U0N!ALMB$rS-hxqE}g@UlE z9UDK1#(!fILZL~eWDZ=SQ3diMja>5P?#ZjHWpJ81fjuO(UCk7$4XI*;vi^nSTsT3Y zjXO*^kd-~C^S~Zq*ESRZn)bLrOhd}n=9(Jrt5IQiETuK7_54J+YQ-nB_}h?;N{Z1k zyutiNyxQFmDrhV4$DlQ_Mqxaw+TFM#d16*o29jEnr6RtU35~m?R@1sPj_A9PIBUDm z>5DF3qsx3POQ-e&UH-uVC@xp;LWEBbvKn!pZ|*b-4}wleKlknzwJHwqfa4e7#ql?3 zyugZS2wu?!`;K?rhYixqg@h%x5u~vHqnq4LnDcp(RJ-o*WFe)Yx+_i`&h$eSVU7y0e)B$TGKJ!$lf;eb{%rb z$AHt{=oNMNnd%f+!U4QNtUFU*G%(}^Ij{~a!w0QPa=4Ak4qHlCaI-cc)qXoq1aBht z3W-Ax$Uq}c*RiEp_x72oY0T&kRk@DvP_}9@yI7SkBw;uCWnTrIx)_DPf!6;V+z&L3 zJ4@p)W>VE6_^&9C^!^ar!to%uAc2z!UF5#*#o`*G!mK1)lFUZ9+^ zIH4qhz`gZyB<&OSQT1Dd7v6!L=TaSNrce?L_!1mN5oyV%d)?njssrsglY~!|rIQ+O z!TM=(265bTbloH9-^7C+M5H(jzRR_ucP1(wo&ismUmX6TEF{A48wUROMCl+uYG}ur z^aXDMlt&pNN;|{YJcM!QWK~THsd|0ms9hShM{$~(xb`TCR;?wa8-l|&t`VO$y#*xi zduf2dnLVJ7lBfWh71JRMNta^Hz&v0upL~z+djZ(-;dRo!{+fzsO2d)WpEfefAhzS| zE1I#QqbsYmc-RrAdgSC=F%zL+8{|eVre&6Sur#rRwunBr%i&2?oN2qrE{f;eQ?tX; zg9o-YpOo=RFylFEfo+Z3W9A883q^f>16e~gNA6yDXqI;tW0i~i*yC(&Pihv7wW`y) z=-gK)?%0ac%z~q4Dm2Tmb=-w?eITw@=MH z?qs?CbpzXyt>fe0rqjJZ%h`pYi!dFb`JP0LrjB}Bu6O;fOa@xeH{ZE*D@oR;yEel9 zId`G0KzDhAbV&(b(PkJE+I43d{MUVr_Mz$@p7YUTc9SF{?5Fa8}6bTfd_4rYpnPS&HRYUol=uO9*4B^ z7N3vSEwz%QC;pN}6Zgi8HeaJQt}QHieLe|0Ysv_O)71wX!9N3TQx>d;>(NGfy(4zD z)?ZA%q7oX%gO?s^TyTyztFvM_13Ee)IOjuya)@aD7$-9l;~H)XZR_pMH6!NFeG)J9 zJJd7FKa9h)Jz(v4ps6GiyV`D2T+aOy5Hrm;`=O6Ogk2NsN=CfCWbGBF9S^d1SBNe~ z(yL4%p1k32k`l*Iy??C0C%#k&9KSnBI-CmpJ9vYN=v0M?a)Ydn zd40k2Tm`P(jRg`E8LOmuh$Ax_Elr^9yMqIn*elh0TV=m-Cn}mwJ>q`#8l&43Y2 z7)-QnkL7@j*lR0Mjs3cOwbsJ& z|D06-D1NmEx9P03GUO#Pa0hktwNBEV!1tYdEFetihZLUJ1NT>hBJH9>>m+lrxu1~@r+Oo?qXlS^PMU%Osc;{*o$m8MoyUUj*j~sogvMnc$i>|qbTEvsA zjb{G&3opw(>mlfj4St%cpzyYP4sw}^?sfl+@o&hU6Im}(HMsj?wHX$v;SGl9$O&;o z@QMq<6Nc&x{%Z))S$mM3DDyXD2@c&DnMp~^_=5J=Gt@_lf!O_oa|85O7-#hJA@SlA!}$H+`bl4|J=DA| zH@}$)_pz$Ng+I6Xp91JIg57`YXDOy)86ZR_xy{P9nw>WWerz=kp<9O&NMM`va!ECf zEk)6+mZdP1k@~#KwYHJbXR#_pDBBBeJs0&G*nJXnFrEYr<&GeQ!8%{BL5wsLO0er>x9S?w^$UR!KI6jSSS(b4hxr zAhCwNHas{s!^Vq3Xjtq^Fa6aIJ#W%|c3qpxJ^45a4DNwN24)`}&v|$;{#2QzleY_V zn*sI}+0+n>ETbW_6EF8r@UIH=If=d*jlbkSJ77>D$b14Np@M1^niO3E5!W-)mOQOt zeh$_tlK*8CoU)@lg&=34O8u1NbakL_esC8O&id=v*@NHOhJz=4F`bZ4kyOU#SxK}6 z`%|KeBI~|{8gY#F^f}5MrlO@tL`)1Ys)+#922tir710s-n)7>8QYyA zc*<|cIVTr2495P(+FC8|P?BS5xT?2R^^Tok%Zs_GjczO#EYP)v-4GTHHy(_}cSC#rz zei~;i=ktX4GxIKqABFkFS#35N}2emgfxdcJ{2m)?3BBel<8^lq_m zUIY;6t4(FZM^e7$q_h6H_aZGDPObe{uBF|ECpd2Rw9ey@(Pk4yDA17sg`nGXEaU8l zp>icm!R>@W)MglwQ}jvHSCZV=`hd5gTZ=0g9O`&A4$wVI4C2AL@yDZu3DI|K@{P%t zkD#AYT6!WtHN_8dZZ9A%PNR_gxkE58+nQP(A6g%7lyH*<_q7#?6MHkn%+DEb5a5jG zP@(CeGLF2|Rt$tKpmU@I7?`ebG8O68%eHb|pp3Z2!xb_r7prn)j77ApmI5)M@&X)Z zi=LxOukvxvh;H-Ce1{@&P|3?Ic!ZvOLq6tRz1JA1i*&>ts}cD-M}2&5^D&rIZYMz{ z;nnKq!GzRFo5~#bheZ%wEXgTtA2^Z8ot$z2_~z4Px#8D?@Z4N#8jCp|}}kui24NYk$?OESlz%>1g+5gIa*K(g{n`5iC27e+#2d~#e; zf~K1-M;17ce}sz^g#xNKmdb-lGz0jfS;A4*fgcikhhDdmXMcif4gF3hJpH zcdh(Zra5BM-Sf^LDxl5R-MFb%`&<1*O9KJ0$D$&GDoct5u+@dtlcf(uQ@>8GP>I+f z%|$J_X~Q;!N|&`l@Cm@EoUdGiS>QUF=<`QBNp`_zf!9c;gCB)ZXte#-qP(QE#P%ox zC@e3h>oHGxguwrd@`v|(T|2#xpP?U8=$~sd{tUL{vIcd##{)f1j@u=_$d-PS=K2 zt;)rWa|eHX7wx7u-m12&hnIqcU*8dvq%55{wCx;Fm8SpC%|p)gFHO%p zPUM&K=hDGu)$3`uadOd@;b+gaSrd3;NqvAb`^Gk*6c!-SznNm3MZ&oXrLLeMjrIDW zxhLn2b+W0Ym)kdn(n6v_bAif3IAd%&>*OGlh7CK9m%eM)P}L%K1a0XmJg3imoY%jypy5%~Yzkg_|AwpFs|qT7A%Hj%8V zhr^ebAoQple8pJoiE3iD@c8oLbcfXB^X4qFU=?t_wn5_OiS$LH=KdS6*`z_mnZ^Rl zSl@PS5i-~k4@NN8lbJ&6rB|F~W*aSa_*+Sq2yh15&?e zWB;a6O(Ry;(q3KuyCT5L&-Y)|Ws?Z!tlYf8?D(JUJl;7u5PsYW;gU-#N_n_Cl`#|n zr5|zI&WuizWsl*j+$d{Y8tUl1#wDb%sy}C|lSz?L3Sk^zeowFHlpG}uKXA?Bu8Ms5y3}b z36bcG~tr<3bZz4sfI6p2~LZ&AUMyyqSJi^mwb2wy&d0QcBd6Iwbq+JxSDF(BbV?!<|U zultQ7i>w0bSk172A{zvMEDJq3FB1xcmslVJu^a=~om^S^9v(JtScScFv}*a$;?r;f zVCIQD?p}R3+(%WCF#?X-iD&UaA9XIq-{H)!1Ef=B15)AT@bJw!bwTuz);pb4dDoci8SObSTI9(y?f~ zG%Tr@hJGjKrQb}AYZ{v6hKJiHUnS8l9*~9QPvas*adVj$kt-g>G3q!gJUC6&b~wZE z>aEJ7PL*wDaUSeLZ!XKi1W}vfVZDW<=QVRlNrJf}It*?ycM?!-WXjs(k+OJa)9#f^ z8uMYW!YUWs01sJDkIc=?4#**nxz3Do?3T8C_e%N_r9lx%6qJ&Fn>nGK=RF&InEK|_ z7*$qUp+=uun26iXDruhHgMS)!o{0}=>I zdHP*(Mtfo&T}X6e@wEShftdeQItdV+Q2`aso*RW!QvYMkj$8CUlcoT)Yhn8dCBRd) z-rZY-{BMB%um6{L5lSLec`!u%FRw$J5X^taaiJuLI?42q{zqAq|C_6Mh44SX`N1D` zZvO*-N8TIE$(ld=8E%01oOSZq35829M4B;ws7dJ(-m15e zC5g$fU7JIyep&L55wFecF2LD~m3yD^gm?4)w)EcHdG`Jy_bUw2n_IP1f>C0O|HRZg znOkyUgRyo%#me9B& zXJ>B=sgk<3MJIJ@iI|NU;^S7Ffr6@uFD9crS>Ol*5r)X}?aA9i55HA)Ywa{D{{dk` m1l+D`T-(b--PwCk*h+wNwrKUml))AZ-%)c{&1xM4#Qy>;reb#h diff --git a/theme/fonts/open-sans-v17-all-charsets-italic.woff2 b/theme/fonts/open-sans-v17-all-charsets-italic.woff2 deleted file mode 100644 index 398b68a0853fbf6368758deb1da49d347e3e7d89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41076 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

  • ~`;p}3;==ZtNy# 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 diff --git a/theme/fonts/open-sans-v17-all-charsets-regular.woff2 b/theme/fonts/open-sans-v17-all-charsets-regular.woff2 deleted file mode 100644 index 8383e94c65478622baf43553262e0e31b8725e2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43236 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⪚aqC6F-jh=?`}zBG zNE$rgasmJvDFU-b3YQ|=f%SQN0PrJ20y6u8#V(zW|LXQ|MEZO=jsF9Plf4GH6xWio z$b2B^$62#Hu^onvtwcNv9TU_FYKS>a))R@PP01DO%}xTMoQNf>gw803<2N_}dkMYi40yn|{h+v5)0a}lth6{X zztO*A%`$sAMEv5F=}#YrR!MnY*)vozr+UcJ@WZqgioRi%#`T(q$eHMOBZsZag%X#4Pb*2*Z#Wx z&ks0sb9yc{CH+Rfw9_>(&}CTMHJhL??8iBWzx1?pl=oW)RP2aC z&OdLF6n#2WDaXnlJM3>KcldwjqVd*crBz-iOwDe;OhGU^v3H(3njP`_B&~t=S;98A zm)vrGUQX$ohd3^}PqKoXS3-$p2u3K>2!{p{SPZRN`l)*Q)EZaY#pKm643AzgS+s@Z zY~bt~u49E$r(CA-OGy0JeVxgJTTs()jG<<;CT^40l7dAWr0Qt}o~B2UVq|{1p$jk5 zhz>=Fj5=f25FI)|$}xVv#fr%B9y0tK#-PrEH~1}4sxgyqvmz?}eHfz2U!PTU+G-n~ zU_l~^bYatd`qLOXu>j^z8plVWX>G({)62)U2agnQ33{6wI!$)Evu4c2 z<~Jg)-5M)jtYKKReHU#~L_JL<@kf05^bUIt=9ZkA^%xs4%ayEJR031*S48$%iIj7J zA_lGyHT3vY-0}6?Q)GCA&*oja>&ymIW!?*o#xY3yYd2Zcrr9J)X-RbhDzVu6#SWR& zRH8Z7T&lYpP+0S|CKPianmRP$iac{G% zy4gD<&5Y$UA@fp^7&>c1bcpq)<=ZpF=^!s%W)er%er)`38a!_|O~HI?P7mqcAR~*t z3~w{|!MO!B#BJ06drDjz6p#8@C3wc97p;7Ywsri<;HP-gsIfkNNV*mem8iaYgfVop z3^ywEcI<3i;N+3=HF_R;tL8loBmADxU#-Haewu9P%dJnI^TMguk&!LUhY#i!-DD4u zxZnE&3x~~)71%J&UcHGH39iy)U|rZ z$ac?qn2`vz=+8I%pY@IO0f5je%57snOlID9=IUIHFmlhUplce>E7Kdj6l4H_<%AjAqJ{6GGWL)%Tnpmg|M@n723~SPuWwx43M$-5Uv$NQ& zCA%#yvC7iP%jcJ{xqNfETahiBE9%N@X5fO+RN0CFn`wsh;=A5fy*(9wb<0k4x_Z`D z`geG72BW!NB1{|(I}rcHtWvdjd=81Zrj&|2+ZU!&c10epC&n@*KN}x9*D_FOeCP?w zz)I_byOx1g<3qzTkY;^w+Gx2NQV|a1!TD>nrFv|U)cS<;g0rTGuIvBb^DYwTy##2t zE>E)f^$|LoOBaTbzJ;k?(3mwdQ2gB>KQ6j8{mQthkC3bH=W9bh8$MHuQ`&{J4&bn9R8hl4{j9T5QLxKz@{(y_5GZD zmyc$B>)v^RN8iJ4FP*1R4MC~2Di!2NxrLeDCG&eqn(Ht>A70CVWo98Skc6{?+p0ld z#W8swf-16eQrFCIj`#WXb{JUd7t1)Kgd7YJCss>H$=4A>Ev4xijjm#_gQJ62cZy-e z;-3yCcJ7%wz{+~%6!3_6%!lUC_r7?yxw~MvgUN%VqXL8+* zT39Ev(sZ*VkKe58YgVo>_Z(1#IP;R>>-c(NV@t`@oGhh*Qc$#x;l8t>7A9YcvZB!x8;HLDrsM=?TvDI1yW$3 zhvy+}TIOr{1-yWOSLYX83x{pPO-~}`Q#uhg{Tx3#S;c&X05mA_FLe{EumKM1vFQ*x zrZn6L#aeWWtYkr`l&$wv?Hfhb@y87Z><&)YgJ7JlVtJ6?wFRe}IIE6VQf%Oah}ZpQ z3(6UpvB_|Y?iqaafO|wn5Q%`RrbZyvv*b!ss^+aE^&pO&lOA}DvPTeV zim$(7E$-UT5N5Un+CtrIp*3#JpGtG{ zeHh!6ou1e8|7aGweLr1xbbXSr@iT<|DcS1_caLZJso&8N$MbIhd$}ORk;26pApguE zrtv=iz?V=IhwZVeMbTOXL|<6AgSQR@dbMDL%j=W|JS&VdG3GUC%-Yo&Y-4skWxvGG zZ}&$QN2ZD@2V< zmD_7OtK`M9U{wBDRhG~)%#=A(rEDr1Wvpt2uPw@mHV{1BWYJX^G7pP2l;hDdiHo&9 zB(@q(Dngr!o)KDUy2-4oLwVck0lKu$><0=(+M$2EYBq1FJ99Yo`R>_znc+<8Q3|4{ z(sW`9TtCqM>dw@ginkMoGsDAqVFsk`=!t%-vvT#C5~|e>LS>0`a>dfz`T-INWS18< z)iS19Iz1^r%mA5z)0ehFBd)*cg8suI`_9}!YbxbXeWX+mF_|wgSQjnH?_M|%?n@mG{Pn6WZ38)nuxZeBjSWN&v>Iw8I(M{x2Rpv7#SXPjnNh3J~W`4gqV- z>NM3!jfTCZTS~xq)%hKW8W43a>(&~JI@wgC&-e9n)YTT$n4RZi_?zfQhJdiEwgvAC z{<7NRg6%cnS-zwp$JETWs~%rxQmc1fsjU8bxt*AFa}O{jdEKi%n82KcK;l*W-l7X`CKiosO_=Yr0MuLZ0T4d%Re~ za6Im~fI~8Jfew6{c&!63wgNVFtXnqGOni_}Z*b022maq?Wz|Kbhc@>-ThPGO9Vx@O ztW2FK9YLxmhCxE&v^Y~ZagwIBbkFxbq(FWRjI$3(BYtm1_xs4_J~x!ajsfFzoW$WU zjvqbpY1(o4b6yRgw;=DNQ&|&T@t}cTs zW5nqaZ@0}T8vB+;hvN>Cqd1J}AV3_`B6!bpsjuIVShvsoMv*quYzv-%atSY%nxlcB zT756{jcz3kx%nUqalf|ROzm2`~BTQV*Ke0{AGu?y6NwT(b0VU7u{v;P5#Qx4ug zswwWX`d@t@o&nw&n+`KY1SU|z6#8TtfS3gToh-q+%WS(}7l;vcOC0p~8a40?m|bFz zSBS;(SGcQMquuy?eF5cEh;&fIDluvUb)6y(+dzmj+mP)b14a9sIe%5H+U`(_@EL0= z;{l{;0hi7+3sU{5)A@`tahG-ou0y6dxaWno#ifsa0 zgM5i82{t4pB`LTItyy6@=D=S8U`CYOF^q|MFvEmkF)W8Yckf#OGvVjK3;E^)Le4Xu z)hp&5c7KN!FYv&}*w|Q#88ljl`ft#{Hxv~pac(Pp4lnSHEoi2Yn)fR*Z5koIJl@_s zh^l~_%nK^!qVNWphTQA(kG z4_o9BQg(Y*8Xno;b==$+Ihb8S5zxyT;E^q=dmb0&TvggA zo7&v<8>j5jz?02%-&tj&+byMJ$UE)K4HUNx7;L&cG%@Dc&bTH5&Kd=C75edmlcHu4 zAZXG^-!W2_?NLj5Pchyrf>exRGIC`cTC;X)R6cZ2wKVZ44S>Q^PX>Je^RVxt$ZYL2 zoevfrOUS7R0LM5vBk>wK$X$1|LX-kW#K0*!^!1!$Z&0xdOcNc5UMnZbK2nigdzNbp@s8gZOK40>~ZMKpp^aFX5- zZqlHqrFX(hoS#_;WxE^@Qm-K(R)|h45?&GVF!O>Lp@NFMRkjOm5uecFjV9}bvlPYP z5D2jm1i@G+ch=uIhb#&*%f=m45+n)W+*>Ck!@+|=l7_}5FlCoKV$BxC11pQH6|Xu< z<`i16q{s&*w<@D@$w$Ux4@MCvaKajmdRZDhNag;~58d8HP~wFL0{emqG0BbzXdP=H z4PYXHaUb^-DQ!Vxck*jj@a884@7Wt&pSMhBE1aq{6&5}%kq)ODbO}SjZp==E`EJ~&<_%T(&6vScUrbucjtRR9ftQdE9 zLskg#M5d+{5d}~xqR9TEmx{Z9OwCYs%jT?ZDmpoM%$2*yx&kq?2|~aiF$m&qW-oS4 zTVx!uQ!YFxwya&<7Th+y!y8t-pd4kjASG!Qq6!=~(#GmRog=L8meQAr?8=ohUz z05W0;z9_u`+$1I#8D(tJ?;F9 z+Z~fspzYE?NHp&FAsMH(qdJGsN+mPSjXbFgxjNy3qBBGX--6wz&f@gG;wm6X+}BRK zbIDqFE3DS_dVo^KOsRHp2PonT=_G>y4^r`3#(1BlEDf3Eir!RJ?00E8eXl+|mT3{D z9+HUndJ=9);75>jwY4~OH>EXgZ(?+AF0X{}dRH_)#$DAgw1YHEn{qmnH{?H8vG5dZ zi|h?UpqT7gbu&iaoe_H}RcodJn6kL|B4KKf$p;Zkg_! z7j^+Rh#gx7&GZf|8&KRzy}!zZp{s)LKv_4qC_O=HGwEQ#PT+N+q+>kyjVs)@361qh zc3I}G0L9K2ZNQsKc9ocWqFbAxJJmP90|4TOC>e%tLfb)E26<=Tsg70z7X-IZ+Cu@B zEfwB>z($RM|6t&K2P}Dge!aI}L`{Sur2=5Q?szIHKKE5ERzmaymFW(TWoqc|BrTSq zU}*!ajLy7O+G|+sRYUH=o=V+ZF$Jf4#`959H9#!zi#R% z8ccYfrZMB~^QRWr5UR(b1>+nHb4{F_Z81$?=n?I;)Jmt_Q-j0}j+ZHugLX>7ZUjR5 z+8DIf2_b11Ag~DGtbv$+1W7(r&(pN>3_OrO9V7hvr^O|?x9?Xs+z-3T76Ka%uK2#; z&KVXPh$N*rYFfD5eO2C(DIm3X(4X7gUKDUHba}69Ut&|_*U!Dm0CEqS)oH7R2AxT*Ng>w7Bj0H1nZKe`X}lO$HM_pXAJp*1Ip3_9n&W^k)bdjZEgqqGho zu>#*0tC#Nx(xP=wQALu}XyU|?@h(6B4 zI|3)V1G@0J&uYSG8W7l08a6q@ZsYY|+n(Maqyeq=VqyhLs$ZVg5;#72@+H}4L#h2Z zEKj|gs~#Qcu@CjPEtDwYP05$b=AP%u-K*(=B)0zazyG{JOL@wSXV^W_LejYGt@+Bd zN07pk)4}IFA#hPugNHHOo%AymRhCburTXe9gWOQA&>_y*cROk_p#)?IBNt!PLR6aR z-&}M*-1QVi7A1hL8`{#4SaUTM`_=q!`?u_6c0g-Mq~0P(qisi9Cm0bMqRXb3eim9` zX>Bbb{Ot4@R#1tG$-!=PWwgUmt4cqHg);**>OknPYh1Ode}ASliwUbwxI1I;pW=>w zD^!Q`D8m9UR41p9f3`Mzq?H93;k=LB@JyfbPZnB$iU-A7s(Tnzw7jwD#%=J*p|G;x=eqGBQIfRUHGA()mJogqGG6rQ08Uku#wjE8 zy2+x1adyKfQ_V+?1t)HI=ybK`@g6|6kI6+Gqh|mR5UA0rvM0%TZ$*&>WtnaFBMR>r z^6K0?is!_d*-E4J?{rvkDNsW_MjKqHLf=vqTrIxI3$BW;L}w^gVJPGZ#{YrghFrQw zIMO%0gv@eD;8Y1a&~2mQOn-Za7`~~IQ#sx}G?w<_KE{$;VV6*cktecK8E8@*PTBmd z)umSTS($XfHp(Sm`%{sEwGNeL$GPalh8#$t<|RPh=!{WTxYz@a2$QiOAx7Pl@JcKz z7CG#*rWmqQUHz2Z94e({+~>l{gJN!;S`vuG;CsYQOEnLYh}H}!x%-yV9}4$ZtcF#d|qZW=kR%NOm0m&<2(brs1LIc(&Qa3S!>+`A#(d% zSLCx7_QE7g!j*8PmD9gOHm_2END{N=%AH*DceWIajcC*^3lR?5fZ!ddLVlyjJolU) zspYe|se(nuH|%}z->e~+=@bm!yprf3SSE36Y#U7la&%e^dihfLn;%?#Zye zss?$@MBXtKRK`MgLK6kb1x|Y|MA~TeCl{1TCX-wcOtoOg(a!~u%DAs8&$Ytxn(w>P ziT+|AV+9t+7L^t_+ZBez1LSTpXd|;pXx#&BTo>dVYH)+)%eV|aX|jgxJacpjg zBcgXrI&)X)llk?IouR|K2N=w4$7{_a9+J`|lS|bgyg%jAC`Zz?j)h7C{giEDIl}=! zVlvh}S^b2r(UUz2VnAHe9+700gDtMJA6UK?HeVG5-edpM8j049O$JSh#dz9H5K4lT zYZl%E4~F&HNy@>9AS}b~lYfxGfP3X@XYMx5k)HzkyO~#H$AaKp#qQ!FBhRrDy6+Ot zi7Gsa7T5{lR@Hn-0g9jz`#aYn4`0*I`sy@gu!&UHMItbkbpQg`9SEp|#kv}6%$!B{ z!8#3YVN--CxJ7WdQ*-Fbau5SKLFHni#!;@O@fNjlCdGF2o_x^zrrSqHh`ejnfr7|i zp*Vvhb);7{nc8^|qJu#VoU(P~mm znm##q*D?rb*WbrPoLue3R$9M7CXb?0U~T4OE{t+ju1&#W$oNIVqm-9Or<<;%`0*m4 zFY9&eHDQAP&Kf-Mm5)&=5#D4PD6|)>8!dH(PnJVIGvmXK<$X7kAA$!L!eJ%^bObO4 zB*0^;y6@dDq?mf>h^Wj(9en>dU#36pQ^D|U9NU0L!@gBI{<@b_6ev#-8|(2)gBkAkjwZg-WGK}Oi=_Z{ym3<@q3 zC`ZgSRyYBcW_aQYfpq|M_3QCB`CsMifTlo@ARI1drsZ zZ1cou3G`*~HN^W^IW_Pjz(XQuwxz0TaD&;LtzbZyLz)d%l*Qn(#d{e%Ef3od9&n(q zy3p>jE(__!R|r_GxB25#T%j-Mn=fD3ax*N4nP*^q*w(KMhki6Z*v@cw6E8~Gsicci z!Z0AdD3##YlTnAL!xp~>2W~2YIZv}2S)Bu31!Tr;;>fav5t#>kZuKS-cdKB|R^5lm zAiIoO%n(=`A;( z38KcX6B#_+C5Z<+DZwOqSg>Mwd607FshGXZsusutivXvIoxXM1Ivz=7o>gmX*3iwG z^QM~VKuQ2gDBvN~`Qco+wq=nh=N%>QOUH*I19PTo$I_WpW7>~LKONIk9-pOTY11%_ zubU<3P>{0tkS-qHJ@DFBqBMDtyvu#!gas~lw?fT7B7wK)^AhCZ4tc1R$vD-q&pyjS zTf_y=vKmUxhtTm1#T+E<;ut4oaEd*i^j(IH5$w!!2--PQ7H&e$T!Ar<-Ja+AEdV8a z9FqRbwz*48t`-dSmeBNr$IpL9!aQ4wDy0dJ765Y7VJ4|R)g=VuWEI!+Mt8+Wm4k?+ z1iY9GbMp($k))MgIfqL@s@S9yCS-k(pGFg6a~b5m#Ly@J$QYA1$TGjChGDdBU=wmHwsTDzag z*IPdcJ@GtiU5tn;u5yE7q9mmeK(T6`N<@4UO@WpT=_$2{1mcN8^j2GPoOjZAYFQN< z0%#7-k-!VTm`mTejv6Z(d0v~Ph1MiUF2Q8uDj_-ol5ks&1yF04ej7LfVcZYO5t*`O9EOcli&KGBu|)e(r0B|cL&N)`5G=WnQwjuBd2qIGRR)`? zg_j1FPKvo1N>ZW;fDA59I|{5doSmek(qafu>iSrP56j}pbBG`u8SNqr#~3+6!7;l4f!%QrJUdk{s zCVgFvfYy-mrIdJsKDmFQhP%lq++|Y6jRAKkh}WGKnH)pxb4j)f?mE^vCxlYGO``zJ z)IR8RlF~2t)BBXw{;Y+iRlxTRo17N}1#)m`fEi)z7A|m7aie@p4AoMrOP3*le zXuSgPh%q@Tex5ZENm38vy{HLhgc9f7dFXAUTwq^_Tn(ZCT!2<c{m&-n3G-C9V+w=KvH0Z2KMH(9&3^xio=g zCR=bJGkSi5&RvD>GV3Qg0++1|Bb3msWvgvikIkeF=mpFlpEzH9| z&0JvkoA*#ch^k9wEe5+7U#MIBg(}5O(omY@CJ#dyYrHz18}l#)DIeImpxkK+XQGQJ zMHgzNjpwKm0A_vG9_>4*u>J^a z3yxO3-B(ZIT|)F1x;$9~!b&+dI$gtpMpkl7-e1FT0(2+})z^RRA!o9cjBkySh(p|@ z=46wSFmu4dxC0JB3C^ULa+lB5d^O`+JNI?K{yEcM;(z}CwhFI2OKlfSyWRYW(TUa$ zy;7Ed(2!09n1eCafg?O-|;&oc*%If&^<8Md@2 z49M(;Dd=8oc1~8z;R2kBVEE$XFpMyEy5VgAfz6L1XuceP+wd>%Jp3Wu)x)s+Wb}@? zGV9wr{(M>=Q=HC+!{vL9aLh)?Znnd4u!vY_d?b{75z-`$MjK~Y!8Yl`E=Mri0bP9Y z*Y9acAGe|fZ59GBRI_KPms_y?Ewp%}K?z9M*Bmgc6RO6Rn>@V6{Ufx?(;Y6m%-*N0 z6K{BfqX&>3L)>WBHBaLQ7qs--s6=m@ue(5!Bqt)z|wsm`K?`^tx6XOS> zK!taxd_e;#&|sWE-KUc2ilSU97KXm930t`(*{2OJ9mkognP#@&x|1ogTDvMyA7Uj&S(P86RkW(BvBEY^ zs-%)#2X}O)4DOKW=oF5!e#o0`A46RSXRGDp;~Mx< zV)?E25#TBH==0bW1t-$!D{yTF$qZ*vkja{eXuGC0A4kkwo&u#2?)mjv4!9sJv#P4( zN8lUxX?xl|mL-QF%wra%>z2Hee%jk9zquGRCK`cTosWJsWC?p?jDSq%w#xr`ff%y^ zm|0afh|dHaxjFLL@PF{G7$s=3Rywz}Nm*K68vuYmwf{#XHr@fS4L|DX?wX(EZ0we5{QuM}CFFz63M|AokOx~noyVp417tr3kx<;^w zqCp>2iH(@0%yp>EAKvV|(RhM^Deh9~7ynuA@X@r$Rr==hXw;^0-|~${ zi=@td54E=qdlsMTO5%p+#Z^{aAsZPY5nzzCnp%~llC4&8T)36GrCAcen63wdYl|s*%4*cs zi33o?U`7?2$2M}NIz(q?CR6Oo3jN)ZvXb<1NUX{}08zx*fo-3>4~r8^l4U0+B_*?K z0;9`|vPcstsCRh&RqS!Zg(*T`p+Ig=2*bI>&>b|TwVy_U zMcY;@-|;I(x@>Z`R)v|nQ&~7FAB=|c8t`cRts|-sORrZ)zmy)D*7rhI zbrd@-#KA}f9So&iH|BX> z*m_NSJjdJBXbZjMvGL;sby}aPuWLzm`lmq-zSJNxKNpl}9+~7;@H6wN&Lbb1L$m~3 zr~rO8>(R{_Hmjp1P+8ny3ecf2C*WrY-2MzWa79CDx0LKVnr@7VKF+A6h4u;Fv>_xPV`sta8#MQ&}qROcI8%!npZAQ4tO@UkD3MjJ7Co+aYQ zSJlO69R}1E@jiOOLl>fEi?>R~rA3;;@gl&DRc9fkYJk73k~Y_89CpIa2esB5$hIr1adCLVNJiZ?nB#{97f zAL08NZhIRl(~wCPeTCY(ZqEdw6t{F*Std1RRx&m@(?qUdgn9Z~L|IoKn=8hB zH-|-yx~A!7cpxfqL$6g;(oh;t#KsSvR9lwSvZqX24ah_**5!Rt*_(Bb7R$x*j0lRh zIJ45)wp!pCC(NoQ((jINi<6Mo&HP+5w#T;J5wxZRmm7AS<_KhaOy{<9eD-c}TU@TC zdpA1Ax18nS@uQ6=)VRks-fvHhvJj%>C`)#f#CCDZR(I?(4rBNX>q93nK@~za#vndU zWjF(~g#CBe>5mStack)qHddRb?w+y6#ewzW`c&MwH{JJMysa>90Q&ar+mW}`Hh#Oj z%x3y>CYY|L>zQRgP5lx#FJ3&Kv0kvIlNUG0byhYxqmUi*Zjh#bdRtyUrCbMbWtH$} zD>hM4%4g-{%5|il%gVXAF$N|a3dLv2S}QH!s<8L-ZdV~SfOK!ZS)}4{Ya-7EJuN6l z(!gDMYNeasZb;SG)v0)05$ZQ&xo3WZIL*;CX!olGhYkI$9#zJ z0|4ITb~K;I^{}HKXGWv7sdD=;V-TBmRDjsN9DX-b?{;W84}Rq3C%tFR!#dJ5(`4R{ zRbRf_Ai?EZ(PP1=IJJ+S*+I=-Kpi@)}NZr{q*{+ z9OC`)RnXqK@5xqk!K>J6@|FUjQ9;_&o^Qb;`A zcnkCGdT_bAJX1Y;)~*cO_D@Fo(rRM&bhOexF}2f~tR00{_CGk>8?=e)hoT+|=K`H5 z?{lx2A1~HXa2w-Ew6owL7j)XTF=;}5Cz4|kKb(SFD&eeCH0D9O&LNW3bzX3d?FHj5 zQ#tURDWo!@@xXMX9U7QSU;XCgJVFV0B897&yu_dy9N!@Jkg9?4mDDi8kaWgzCojvk zD1;mkm|YsEGfP969wGyliWAE}7!as7iUGWSR8JpiSkn9S`n|jEg_oJ(kEMTac=a25 zzyA*ATQ9qB-@pIfi@Wu&{L0V&_OE~XXMeA{xEQ9fTjQrpnfJrr{=Mm`QctJfd%C+f zE!z*Be0g*>zyqNDmnnXrKQaz|&v8X+XkNT!pv^^HTtBgWc03h!=Kd)qZ5ow)T+zoV z;CP~#f?NGOCm(Ij(ltGYNn?9{>_b6#5=INaoQc%Db4@q26_J@&vEYC7o4*=5frw(d zh!yMdR>*kkQK`zJl32cPaIT!@!u3`o`&`h0Mk@3IUptT|Q;tQybkhhm!(-C-xwT`g z6&gA*K&+L9;3&na!PjxD1aru|)p9y!Iuv>jF3cq>5fce_oWPquE#lBG{i2=LRvjNU z0AgIokfG~us#q4xJKl2Ga8ZL%Bt(4(>QW*x^#uF%=06K|>x&Rk91f~m^p^jy8@jZi zyO|gQ%}R$e4900BkP=Zv^EfF<_c>hz5B+<-{fv9c13gt?6ZtS4%nixIAzMuVI@N;4qq2SwDV zxwd98xm66a(t%3VY+Y}NB@7EgaZM$Zu5Zd{jeg>03u436L(3bef?yyl*bYGvxn0>> zdp2Qq8vCj2IU1oR`5a2c!*~&5c2pUf+#FBvSp=Ke5A?*K;4)4CI!(gX-@v%mXe3V7k*f@k%36PH+NYm;;CY&L0im)yGp#xU8kW#J&eU$ zhzPr=5TbU@l8x6^O-1?M)u4+b^8#@Q4T_m;5XVgH0MzQIhL}z@i{7q!boPU5#bzf0 zTUcPa-A*F%Q?~m|%T2$jRPb6?Atg%&Zk?ORXxcQ&)D8ze_8YJOm!{|DFP|RYkb$8Uli?&CU~BrM6N#}{L=SW5F(&o2`b!tP`$M7@ z$VFP&g?XLI1Scrr+_V#&W4W$*)8onkYvnar(+y!pHP_-c{L{U8k6cu7F&L*3F zVAtb_0GXf!iZ(_2J5{xjP*U#TJl|a+)`m*wPq|n4xcVYBw9BTYS<>n5c0rlg4+yYwhPU2k%w0>25iFXFd}R5 zC(c-`U8@ekQs9x@Vu`o~<0Jx<-v|UJ5n>~7sD)6!@nppq!W82zr5*PfgA*pg2}fCJ zv?UrsIpIuCT-eUFQ0nPQH=U#jz_iHIA5r6CAY5x*v#JBUoE~a*XA%KLLA|&w+cCl; z=hkUpEU7?$-SEmhoq4p{>VtO(&m6jUeDt%;rS;siy#Y42w z!o-`IsX}VTvFYPdkJljPS*ZZ;yHy-l9h^SD>l&$!J~^I~6E0|?KbvwC>~8^jD?nHv zjOcmp>0EW!E~BZX#m(Ec?dq6);VH9QsnHQCDfWtLh3zzjkyo=1viMo&n@TUtHgz?8 zm#-_kYv?IvUDzg49XA?Ib&OSfQw8%(KIq3A?0$xA08GI}34cW|LT83cJ9$xeLBf6kJUeMHev>m#xf3c=5WAqIo0!?qvleu>dT`Yn?>vWK0$~EE zAJ&j+dT8+{S^bQ6ncF~69CR+07Cd0m3u*d4abg8J5TE&|{T=;3AnKpmHK=iH%PxK! zU3bXqqlsM~JAn=x$^~`F&fd;Z@fkZ0Z3~92nPf za!0!M0sW!}RpfojhNt_K#HlZOLe(d4#e~>}<3TBAQy~By0}QJy z{~!=l#H2OW4L2sLL@KFEvw(#Wdc!@@v1_-ejv07TZXDwYZ;rPQw22<$<3JA7`(`Ss zU}3z2=9U36a*RAQfd?5Ri(h>Ee3IT>Q)Wxln`entEAVR;>r~@-YmmF3XZ_hN*zc-H z7!qUV5w{S}YWg~@yDm;8O6KE*(v;ADr|-_#fepo(r_Su}s@}i~9mKP?%6Zh7AFC$V z$n&bD+3PO~f<1L&_9;D73ohJ3dq8$s)wfL(XT4s@`92b z@KB5@)P_hj9BPK)ba#?kV&!)QEzodu)q)Bu-sl=J>zquIGF=hF6oW3UgQm;TqMHhe z)3>#K5_S=#nVY8L&ZK>AhMD0&D2M}P=|dnUr4$1+?V=ub122oyqfNDLnDxZ4yE2_?(M;%fA?&J~- zOFONK?KrTr3_CvFEZz$?MmY(ps3%=`I-X5(agWAz_jY6VTyJ4%WtaY<;;PhOsZ?up z1{GgM%yk@kIazck2mm5VK6cT0A<}tE@TA%>5fIK5CQc-#^1qO508a-IA5u*Ta~zNW zZ2+i=ir^B#ZLH%NlOS_UNE`$$c8G9%jA% z!_i-8#H^4TUBO}kC zm+5+vP6NuO^JkGl1mxkw6RT7=zj5hmt+jjpq?&cc)hDOmeq4<^B zi)aSJ&>YOTZ{fTo490jF9U$Pnh44u@3{v>w>T17TF4qne+~6^+_vFdr-J=D*94|Lx z->(ZNw06h4(lFc@J~iXS-ee;i9VVw`M1FZi;O6Pn7~f)1NAqN1{y2upSE#0HE|grCR?yQ7R1omgpP9gO2apE7P(HE^6GGMj@+Tky|klhhYM+OtAR_(P@b>3vR z3p%_6%e57!L~_@kTy1}&^H$j|Ww-x|U{RH!{j{8x&|umTF;7~pYu}wjI@eA3mxu;L z4NG(KK&tVG3uj*Ep(9EfdX&9I6FqD~oqI?!PjZM~{?0n&_B6)WNJj4oWo66~i26BF@Kjw?IXr&>JqN(dD$S ziWBOEnFBzTrr~7uM%IsX17S7Vwo!}3IRc~zGex}#3|l>*5(jy24|?R zMRl}Ai(ld+%}+a+=o(k<*CoX>EDOkh$$JUDXDl17txGftq}TfY#FcT_!>`#0*>+A^ z0NckiGU`&PrC~esBbCSm2U$@s#&i}WDfxyjQD+!w$PYw{(%{zrkcZE3ML*E(8s&bB z)7G5!-G!b~^E~@r7uYk5G(-U+MQOm042Y}PAL+P`Glz22iR6fZ!Q*_4PD9Bk>QIi# zanA|GuD~UI%>iuRe+ij!KZ~qvBuT)8^lK9_wi0H9du5D z)F>OZxfi{o?f!6~bvmKeGV<(APa13+*_`1}2aQ7uEvg2*di49aR!;4<&GYQQ4R_BQ z$zrOKZ=*1rLvEbl8JDkuVg+rOXS^~sl9#NPf}2HIsTJ%2x&&M4$>6l(h#`eC^}C&v zSNB9EcS(pp)y+Py$7nbg(vLS@%~sO*LjB2=To6MDvX+qu-8mk2^((@IzhURsT7L`O zq0wFHMLlDN1t2C|1%~EduPZQ!i&}5G4WJ#Kk{1Oh5#2>7TjOr5*QkkrOFe+3j!P*a zgMfuhUBP5TFBVwBu;H3!zhCLpGwJOyzM0za>v~nPEq}yKv2M>LQk=mHnzWfKY$~*k z$}Y`^DAp)r@^M*Jik+=^`Q#~FO-46RVlQ>!=xHL#~R}#AyI;gz&j~p^Oya9_hkP#2 zs>^1nXqpsw9F45j-ao0VI82Qs*sj&_@1U*7Hz|WOsee#8vK-YEe7HLc)$rCm8q_ba zJ>afHwxV0@AmV zfVcqG7y5X!CuhAjW2fG3)75Iqy-H4iZW`mP2W!PJ$b%+Tjkka7PEa*L&EUid?5MRu z(D7irOsekiQ?Ex(w@EqD{{INq5 zDei7pHhAn%`U(l);Gb})ToiR{r+Gov=#kg{?8F%Q;U0dA@mVa($MdUf1^n$^BGQ~Mb-nc{lO-c4#c}* zPW@7l1`Ts8H_aRp$?gDikAZnR=HBXj^>{PPRHvJ!BK(j{A+Ule{;byA77vt7{*#Rh zkLs9GUm>rmGseE0mK>`m_sgXkl>-F7+3%%!2$s=p%RLz z8S&+(fj1D~v-%Ar0`UGDScu}oH&9r>#W%1qkMG_4p%p{P7K@xb%F`?j~7{^J}RxTAXa%Xy4EWphQIw!Gscqns78k5J?o#EGC8}#Ih7E%ZTH3bi|W@9s@=aNy3DgWKu{ajpd}X zf($aTkVQ78zn_0VU{ElN9TFNA9x-i1g-R!Mc&$pKI{hY$#@mMYYS-$EuNri!w(6nJ z229$s>ziSRth?Z_$f#z~8)7cH6e zflwrtNM-W)nJZOljaH{O7)@r2wI`lsX?HkXZjaaJ;OOKGV45)-0EZ_KNn{F@)^C42 z_abWslf~w6d3=FTB$h~Jpj@F;sXLym7Si?7t85aaWP}lu*<$UsC+@oEz6Tz=<59M# zi>sTvho_gfkFOsP1cpFia0C*C#$cBdXlN;c{x1Rslf~vJtEj4}YiMd|>*(s~*PDT% zk+F%XnYo3fm9>qnoxOvjle3Gfn}?^Dw~sFZi9%zrI6Q$!B2%a|I)lk#bGSUd06?Kg zERo9O3Z+V|(dzU7B1|abLMm;n|EPqbYPw-sw&Qw2`aw60;v~)TqBLhYP!rmERTiwh zm3iPB`jnoNuA^4QeCN@4GM%Yc9bYV0Yh8LQrk^nqM;A|_+Rtov`@`{czFcqj$Mg06 ze1C`I=?oZ_;{{QY6;;y>)3P1c^Mf#olQe^QQC4-+qOKoCOs08RH+s3=?vLl|{rUbt z2u4s0CrFBBSdJG&Nmf)%H%!ZR%9U!Z-e|Vkoo=r`7>>r1>1@7OuGX9FZhttQmd?xd zc7Hry@6VSYDVkw9UJxZ&Q8nE#E!%NDKL8A)I7zd-D66_@yB?5O)I73!R)5zJkz_^H zbi=f4$Mpa%2*C)7;RH$149nvSgd(v-Dw8XeDz!$d(;JK?v&Cw&JDe`J$Ln)&baDnT zSR9@}B#|jp8lAypu{m5GUmz5TB~lqES146#jTX}B4MrF-nJrcu>f-9=?%^4X7qK|} z&h+;24ZkR*%9N{6sS01UPXpXdI*vqf_xW_wkxR87#j;m)7`fP&nV@kA5BaZHoFJ5( zx+ZgPMFt_945wdf!u?fDCqiNBHK%epP4Ox4TyWT++;wt>>wFT3YE>pMs@Q`&%)+mG zP^(6q8!{EMVjw7jYH%{JiOp>)ENvDe`n94qN@h# znk<4&%rmW((~*s>eq}0AwFVx51HUq*e53B*dw9LYH#?4Cvi%YHX2*g}NTWK(ztV0p z+WWq*W>vG>e01;oWl96IS=7_(fQ8ehv2dnk^Q;Kk186`O7B`cXK zg(?qGGJguCA#Jn^n5dapTkxX9np$hC>ZE*aDkzsacXM_5UG;GMCt{VeRcV(E7bf3V zC@(hyR`N;{z&wjJs8T8qT2;1|LF8-n#vpippVLs7sv9DbV_h%Z^Kor|;mDJ27Nrv{ z$dmx7`;l1j<8Eo6h@@ll=t7V`4%S^~T0tTKRE-HxA=j!-IOJfplM)x>kmfO=j3*T# z0D%UOF#!O8Qc5YMl+w#FIOqHsBoLsC3%OQJ!USjvQc9_mQc5ZH6}UIhVnUbzWn9P< z@Jj*J=tq9J&7=RUqwC<^y?>M|PK&8~#xJH9k+otBa&0uLVg<56um~ z^cXj6n%nBf1wC08i?HU7Q5Vab<_#k;7i{D!`bj~_(%a?fdO==^(FM%0v~SYb1uy~1 zxR6RuXAM4tI}Qsbw*p?e%DD@M$>cZq@UkVE`MWx#zr}Akk8j8Ir=A@d5dZa4ZLg2Z zlqj=3(FgTLv5WY?$NcAdJcj!suOn@>jq|%OSylf9)0+ewfm3Ca?WqX+bWn4(5 z9oOV_2os=;3#qi@8ZX;Nm;hy5NTnUuc-byt0+ewfm3Ca?&AS*8CO{b%QfbFEUbak_ zym4PR8vqc35fsA-l4e+rPv`+41S2Sh6C};B9G}n&KnO-q3?~_u;}bdngkS{4aDt>6 zmg5up00_Ydis1xFGc3m^bODH<7*1f2&r9;U|7D>4|H8tR^6$zw?1E=w4(4=tP8oF& zJ``~fR1cm4+Z*+Q1|^VW(%K7EYo1-Y zFZIbbltugpER)Y7{?ntyZ}39Of3VOKXtLnH8}QyR7EEw&E=9$eGn;avVutnRW5F8|&$`EwXKi3csh z51Ofs!>QsU{yfGv?X>=1D)v+Na5d!*CsXvWkLbhRvqI~9%e6Lgct#VzXG<2lZXO+nlj4W@_=F9JpVwbL sKA>_s$7x|9PP@q8#SEVgNs+jhFSVY2`RcXSI9}qeG9P$E3pY^Y0k^?P^sPuHs*^98f*i-(>UYFZ_TcJeCTwOy%dZ@Vy4Pu~2M( zKSFWOm9)c#9LYv2G$rw#U$b*Z&veP2SbwwvLG$h01Lr5{lE>|5&02mWU5)3ZAvl2bKagq?*I^Dn+55$glFL7Tm=Eu&ET2V>7C{+Yd!SL9Qm z9y8ZK*exR_r(kcvlatJ?^hE_{`Nv2thC-dN7fWw=2pjH3O6Q3t;_Nq6a3KQ~`#Uim z$BWMYi5%X#c`H6Qav_~#C9Jfjo>Qz`A|LM3U@P=v@JlPAP_8l%iyfMU9@0x`C96b_+?UcXOxp7{Ot zzxK?WOI^Y!+GvcZ2WAs?Vt`R#)eFS`jYy0RB#Z>35$*ulw(-wA*gy8<=l!1iGamQ{ z1Vj|U4Vr6VY8tMcn&sNLR!h^}uyRz|vNAIrpt*G$QEBqDq@dI*@{~B|91$r35=%De z1+_8C5jKO_#6*}QYh+H5FN^{xY>=DT-TP0Ieu>9<;z8jMM%G9KL0KHf^VDI!-P@UH zDaBd`%~>kdLKLABj!?!!eE%oi`k?*)u2gkSrMjZuZMhbe5G(>7v;9OA-pugNKZodj zKZ9aP2iBlKrP^FpE_Vy`ctaep(%4`hRk(u6LG?TeJoRh(c8^ME6W(7JTVMwaM&yK# z?$qcSSp}%fK?4Mo*erm6`FGP`{k)FmL_|qlz92Ost-~er*h)o9tW6qUE!Sh=$Je`za$!TY6w(t@f!C zqDpKehPo_z&w6+O~k7f}!rYKdR2Qo-PxoRtmdjYCWi5Wa zU+4l0#JFB#Y>>%CQV``zl2JBF1^-{mUgwcD zPqVEUipSuP(YK+Em;kb&30xCx4_fFmr3Mi~giWO%7-2l$RJIzZ5UJDn+;`#P(92&c z7bCP_!@L-}ycd)5)l z0fH9c%Q{%|8c7ETRS;{SI$fI9Wf8jyL7k%OQr)Bu{C_|7U;2->&(r_5Q>rGc0TKY$ za{^Ep@{_Laofk=?wC)K^2h?)fNmqgz3WA@|AQT>+->XW;zb8{K*{rmL|G0p}WkpQu zIbK(uuWL-1bxa|ZIk1S$qyd?XiUCTN{q+A$f;ee8rb;QIBJ1WHX_c`;%{M8t@y z9%Jf%4lmGm1EVDI{AOh;^pTAkh?%(O>PPPeryuhc0mC9iYiYIUEfNwsUl@lT{g93Qx}NlKy(En9EjdPL;@2- zSV~w&*i6_>NFW?0+#ozAq!2PrAyXE?u}=^|i4G#RAmUPrUF`Cy(gmU7imIcyy2@zW zwISq4y#SV00VM4LNV*2FbPFIEQ6$ndlf{TJ$4v7&4uX;uL1c4*T|RTkk-i2$Fml~- zl-zUymEouwwZJK!a)xKNJAQV-!UgxAU17r&kMD-Y2{%0PdI}vpj1ZSHo{F)%hRiKO_z!RLVg zeH$ng8W0TNjD-y+oN>VwH|&7mjtBlkOeTXEXXn%JS@dT5vUy=%(;rU|KyXHALX=ip zK`!)gjG~CMP#i2t_=3<9s!+NFlor`1&8rChxL3?+gdliCWK=YC3{1kJu8u)gc+WwH z9Cb>rv#z`Ao*&%zz`y;+fBot2@GDC>DR-4Ua*>Zh6r&X7s6tz1sxZU ztPDBqs9e`vcf&1r#G3l_d47j}_KRQr>5<1uYv}S+*&-WNY0XqutgJtoK*1jRWp}%0 zs0t?nWllAt=#24!!f8a6#Sja4uGo5iUlDvba7W0XJ~uuh;)j;_3;o6Z6FcHw*=iK^ zt*|WPv-QfzQ&?U~v!hCFbE;`*>F604ftifV&T3)V%qzQLapbhBTqecM!<)~Z_yq+2 z9AZinexyU6qRc2`vf2h4ZL--GTW#~$6Hhf^Xx4&hm)-U|;GhJD9Ch4Dr<``iWp{gK zNvMxqmvS=fmc37*NiJ)$={_@OQK$~#FpCIRGV-DB=f#RaTLUR4R$22OzxZpit9X0y zz-ldF)!|Rp*`Njc9E)*cTx=XGX}?mLvtX8|D&c5j?X!3!9kRx%JtLkwt3#H@E}!)` z16L66-1Fim#EvKlQc~=4tukTctYT$OkAGNL-jE_CzjYH8BdFC#&*}-L*NxW{Juj@a zE_UWF8Z~VJJ=g5m_utqzM{QhX;|Xmgt<@YW|_8+QjIsKY+r#mGV#fV0Xux;I5ua8+-9Tunsv1kJXR>`e*CTXc+_oT#YMDrVI4xLoGZ-qnKY z2{ja`ylc3`NWUXXbu}i6H5I_*83ZdT=WZ@m1RoE#;tKYSsFtfXzh~XhmmM&3xB?qB2cm&SPIUf}kB@*3hvDoDT}4 z#h!6V&Jo*E#;=CNjxi6ElY?2{@PW1c@_OQ>3Je?q8Ws)#5ox7aqtNUiAc$L zwK*&^6=CL>=d|-Ky6lGto3WV4h>;`>LiRC*^=6uHT}zXFP~Ke2q*-abt;w>-!IU}S zj7!H9Zn)=(6tAWE>JR^YoUW$I<5>uZP3*RX%Brj;o-3l90Fh7tMEtf`qpfU}c*n$T zyqI#|9O*rP&I*p=lUXBTDj82F38UJSDXvRY*Gv;4oS zRu5*~7$~!6ZMd1k>m+;YUN^br;3tP{vdBTMd?DLfq{)_W^7Wfy<)&P=RMb_kS=w}~ zl|I8#Wdt&1UZ*Ta)@#y|B$Qb(8gYv>abc2@t1`6`(<_V7e>_bSo>JeRm9FzL&lKWR zr$3A1KmEij`n`^GML&qe2EPjEetSVkn*@6B^Sc}muJJs`s%c$K<6BiWNG=J8+J(j(z=4r{SBvg`3LS z?c9DY9?bQd?!WtXM+2fhuqasi;&^pB@Ff3WQd}{jIWPQP-+@kaCzJ?!G2kr-V@wKF z3dAgAGjG(ejFqIL^ngw6*#4X;O0AO+>3Hv9=&dekWP5_F4TMAcmpiB3@yE=8jWs2^&FisB;u zYTa=*)_>T-MHk(2c;ycDaL0+uR-*+w^vkVbcWa!l3@UplxB6Y}nk2NWsgtL=RM+}E z$(OcSAi4OyweRpnp@$|k?i96m7jM_)j0ZW@uE)IZCo=!y`D=$i4qZFb;01y6l{R*V zJmngDX>qb;UG5_CD>Ouw%R^*kGQ2{rMlMFckUFRT>i?l>?K^s^PxQl zv8NqqU$*@EC4PB>M+o?C0qaeu2-0i8;EMf=uOkUiQT2MFIG~Nc`7|m%A@F_|<$lFY z>7#dGhj{AG=tJ+}`Wh10#80Xv>&id(uT1RnH`-)S)OC993J;8l8fvwpBbbRkRI_`i zj6rWjqEw2A_0lz1pPq&$c{@+?8HLSEI_Naz%%tUxFpg$x-V1z|9fypb15|)0$q;fZwAxlDTyjUE*91ddV6*GDy*G{2 zrlex7a|E<*fW-H#&3kxEKO}ZqQ2R%fAz1XjUFyks+C3zByuDT6A=hOGb&79RI#Q@T zF1`6mMT>TB{Hp9C%K1Txb_)+sMfoVsvvcsRTpM881BbM<9p6um9NbX&$fB|YRkeKC zsh7^)1etsx3^I&ipAxpBo!$(6lfx937eESWCqlsiXn=e&r z&G!EI(cL#RGBzUvMArrimK^` zY1xh&gkBD(qfpwnI%Me%^+en{V{?B*ha!mCly+Z{lkHg3CVlTUZ+g=n)E)w55`VY; zTYuR-JkTg|!pWvco2$ya+rB8Pky=AO%6u^6PCXJrp^{O)BbBW9yE%+S`zXwjs7E83 z)kEdbfLmx+m%Wq7HzVWo8_X7 zR>}mD^CLjj4)D)gwchpmEddD3aZS5|pdTpn3jnPEkff9Wfgpedph3js?60KZK9cG zn{Tn@)+c4kEVa<3u5?vv*wek(n{|x6iOp|wy#2lZive%OJMmt803X8F;A`=#@aynL z3HgKy0+K)`a0wcMlMp7P3EhMlgyn=agnx;rh@TO^A^u8yL&_(WlL#aVi9r&Pq$D}1 znq(kZNKVoy(s(* zl;_Kj=fWM%<1((~5XU*gWv+6IJ>Kyt8_bqxF^u(>t=iTd+8OM{VI0GG+^Nafuua;m z&D*(M*{wafLAU9yU1q*A%3Hc{Qhm}zhC2FkbR7YKM5=*&1Hgcb>T?h>Y^PDJO1grtHhLK7p4bibZ4QNtF6e2tK_SQPDa*P zZyh?NOCOm9FSdE+m@P_#p@#hbZ631Dx#vgoBJ0!G8!;AI2t9esw#G>RZ=fsp=P;s! z=+H;ipdIwno!%K=gLwISYHDfWelt`_Nli|1fLhI|`(ziPQ7>JhyoX9fS1xhwq6R*E z?XnTyc=@F(F-leDp(SN4rAWtLNs%Wj`2ytRZ^>!NZ5pgMUAnto*qr{ybx-VrgveHq3m~^Z z9=Qgfm$$Zb&@0>7uCmK%Z>ItDJpla{aJVpr(HwP8=|R6t@{XIFaM##br32$% z`$9WAgPG1|m*zN+K?WUsJ_}pK;+6owwhY4|sNU*JU*-@iSoNOoi>eS{%KYmB9nZMM~zTST%$KPv>58Ju**%;Wuh7l5*2xBl~k{`;(i8h zm@sBipmZaRvD<}8-NrSlstSFk6d6*6xiJRpaS;!~$L{x2jZjchQLCoo1?4Y5pkOFy z7*l0fZk5&6SZm!OK!TfYx$Ukrf1(N&Ek-P{iHqb@(?8TzPXk?a)y=C88fAisCV9)` zfh0zHlmFkFM&CN*J8BdmY8GMYCQjS5h@?%dlSDf~yi?SsLvx0tGa}PDS~8|FeMWYX zQQ6RwEu*tzT$e!R3^sRgd63@?a)N*l#<5&ub~h;ut~bPdAm;}uU&;%ntRQHGQ&Tim zMHsQ%k3#XV6gtY|NckMEfTI<1Ix=S}=3J$mt%NI8ayc3|y2qUwxYvE|_kagI zg9VqR;bsJ0sUw=UjBjWmo)&kbP1URTsp> z%LjQ){!_fyZ!rIQ>T7gk>#nyJ*CNXIz<^Q6*yzbB1|Trz^rWXX#ek3h*X>1z+x)Hm zvHvp|ipElZxaH^T9bGKjalz^Q@u3&|_wW5@Wx$D(a@H=!)pE1BJ9#*Jx_G&I2l!O% zTZx~ul@3S$%6Y2bt&*=Q{$K*Z1w#mh6b>~o`wtvFeyVewk1$%NK~1MgbcSSS8Id)8 zIgptn8C@nTClLKbQJxU;qBws_3ZS$=D1|^Rl#0TrErxr=LNAWi&~#SBi3psG$f-zN zsGN&YxK=gStKoHTcvCBHYvX+#e5#9|_3^8IemCG1YpIt6^^>GQQZ!5&Yckl9#hx6F zNK~%4I9z)bLt&^|+BRQ&!r}I9WI6sd$^dmcRYBx}A#7&d5S$B2XCYo%FSK43L45 zNsBNs2{|Px8HFazEMtKWB6Ns|YSV6*en;iX(`DPNMN>AdS*L2OzmKPhzx^{`ELZF8 zZhs?rl^H8`oTSO(#*3dIRHP{0ZdX}FKzVf;p*u`iHg>_Z={PvkXW-(_k};5nH&bRl z{;b)nP1!hsYy}II%$vXG(gGmb4FCXG86bG<&rlaiYIm`Vqn4A6yR0X;Z5pg-B{iNO~m zdZR|YtBawIuINqxgrdU%2t#)UAROZgM4;OM(Cs#TjPBQX!}o|ncL5+89R|PzbXNc- zV(h@mHf;s8$|^xtTkVcD*0^b{wXR!domaB#pX|g=$zhjWTnyc&j^;W~8!m8(FkPlQSGdMRU1zFp zkfEC_=N9)^)!k2qo(ClGus!~~J;7Z)B~6L^>7Lz^e~}c=AM2DCUU2c!OZmL=ioe(1 zD(0Pcg1ncev2^L0`{<)fKKZ1d&%PVdKN5@pKSyHtCBsU8{IOQ1Oh;wOa=9Ir9RHdM z2SR&9C}cus#G;f7gOLoa@~|~h5KtMmM=FAkcPJ9@2Wl&5@6`{%~s)pkpxH9);){4tGWodPc*; zQH+suffP@e6eYxBF=bMmW|oL)lajPBC}vGc(bm!tGbuwW%f|FcIoh4__Z#~w;F=X< z_M{T+tsHYERp{_krL)yy{-ioxtPu+*H3_v=ESS`$t99b=$ zlgT}{ct4&_93OPI=+p~lXpb=HHJ>UQQe=h zZ1Rgf{*Ky{3|##aEhd?Gn-zy94*W;#TjhoGQ2CIhpuFKKln)XQs!B^N4NO`+6><|) z>suar7HXrDTRIE%Sh&8P>8GE!1{mO-frdykRHQG)ijrZ1i5w=^bVRJhY?k_4uIoSE zXIzj+pq7tJM;?LU4?HAyGDGc;=M#$;UU=_~H~O_|HP~%t{&W=U z5unpMLArGd(Q8!1*y(fc!cn1{JG`VukkSEV9`SQ(Epuhr!3Joe!WHA6>sba;J zDN|-hxpMESP+_G?l~$`#Wi1qv^{5!OV`BOU3(Ib79DDKb>?a_0fQ-x$YC1=mn0&&@ z>Xej})0#9nqxa}rYJ>?U=rLfxaMR5&(o8cc%`!`u+2&H2Z$7Ps7Sb6s$Y7C0TD)sL zqK!TvvfXwXJM5sh(?{xj>|?EVJH_a<(`uY?Nzi4NHM-)8w5zUZ@~KZ{eC`VgU-?R{ zTW)D{#~s7mb5FYm9_ZNL`EKeqS<95w#waH=jY!I;nl;-iE$xjSJ@y%Gw6}Wo+AlGE z!AJq#$au|)3B*e9hLsYSQP9e$#K$UXIiVqbR*802MFNbD4pvt^?s{uiyTNKRPv9+k zTAijDI$29KyP4MN_A{&BJclm!qFUastsU++R@Z3NAHh?sSSKY)(3C3GS(!3)<;rzYp#lQ}!VpMEY9u71k&zkE z(2Pe%XTiWQ4il3Z3riF>HX9C(Xk1)&5)yMsNyW*?%p)gPLqTB?C8c^QDvPP9HK4y7CKJEejAF5fSgopUHc`7>jl-embb8}*>AT%pJstzE zSDVjgt>t!wVbtpWaAux=a=?H-QG&i;NZ%+) zKQN+Sl%hWv(?3cR(3Hml0?B|trcMqFWeI^9p(sZf%n3(%B49xzDi8%rqEV3;SP_d# z#KD?)R3-s7B%%pPuq7EyNr4@yXhs_BNk?-s;6Nr?kOfC_q9wWDL~cA!9ypU1t;h!# z^5b<1z?Fgsr4ZaGjCUvkcZy;<#o$44%%B83DT$esf)}MRi!$)0EFvfeACyNV72u1C zh@}#IQyH_V0zXtm9M#~L>WHTX{81C{Qme^H8@5oV$xjzDsn;NV_?!lfREF>cjT+gE z;Y*q{B{GGtXx5a=9KNPSlbX z-Gm z{vnI}xnpQlsX}jr(HM}B#v&n^fP!LtGmIf1Ai(H=(SH*Z@}IDz=V~?h#~gF~Z_%-2 z8K$M)Bel#Bu5GrF``q=P@clvpQH~ra5D+AJ^5B&zLsg*yr7N$|Z-Ik*+-Q%H-54o2 z1O%0ch$^tLmE+<rt`2j+faeys2;mvB&miqh+7%&)UHOJD820Lv}c8*Xqc9%UE!X;}|(%C$skO ziJi*E#A!Q|wQqG+GS*q)^8?v5F1f_+vdd~+afQ-VSB>+T&nWt~paWSHz7vcsi^7lI zv^9$&<)1#6BjDg7s%ZpiX(bsM)i5zhXw)bmEzPGz3$IqK{5o_V?tjs$B)EixRLjT+ zdlU^kxyi_EX;c_#C#6t2>2Z^K$iTHWp$obuTiuKYyMwStP>(DuA}GnWdIUuBKPxz- zIC}`XPW+qXv+X+ZJ<0d$34FMozf})eOGbG0PmW=rAL}o(;SL*bvWXTuH`$fWZZvjl zut$kK$=qOtyLMW#Pc6CUR-nDLt>6B-XNYyzpsUaNFHK7?u`{)^w9G_WW+8Uw0`^ys zIa6HLZ@wb)JFDa~q8iTqaDhH?TUR7QBKu~EoNp*9a|lV1>x#~h9MN@Kf0~__Y}Jl&18yDr2(pH3Ltr%p2vyF9`Sz=kssw*xT_h4#U9&78I z|Hj`xF4#WO~_b+nvu>Uld3n(;#Lav>%RN^mmQ8Q}NKT~dV zOdp#IE9`fmj6Sm_;tOo!zVOU$FKmh0;gx>dE8N+n{cW#KdZ(H;)RW%U)3$0syUmVm z6wfFZ`^#N$qI^0Zd-YlD2lsE zz*(aHpwS45Xj0iNtv$6jaRV5w+kYiTnagMr-qr?3T2)?VL;o1eGp$g56Ndo0L6MLY z+#HF|G|=`_8EotRa94{A@0l7~D5A}wCwuo_CkBd`R9f#}D08rbPB7PY>xipLi``KM zt8r1<>g?6pRP2dhp)H}Q_VpRWvz3}~`o7ezacN76t86wCu1PrkRt-Wa{gk~Z(WeED zoUqLZ<5O|(q7jfSb>g4d`=}euk1RKiNk-Dtm=RO2wAZBO^?56Y6Q`Z|zbw6R1xfIa z75YRWkavmobqO|}-BrR*e{&@WvwlGgGj^V__XGV3~9(itittC^hg-b@&a(xLf^F|}JQXb`1dA1o- zs$T5ik#HnSk92G0Xreu2epDlx=IGC8qE>4<$Is(@wr^!)mkP*V6R@D>*xGJpE-qJw zPY==8+>0B1)z#fSFT6KqrQ`BIW-O{RoaXCgNkNFt2+>y6GI_6@`k61=R;Am8=iap^ zePKSg>NDqM2_ewZ@QDz0aKHc{=~)vWwFH6>`#|8}63(lk$v5uqHoKyTTYa7W540Vt z#Pu#j%a@PW*;%t+QFBhi;ZT;UE?)0LpCh6-iON!01y)T}aO!-zP_=5QRzdxiN&b48 zbGg++A2$<~LQ!2`rMBKl%JYH->onxm?KG=Of!%c8NYL7 zf{`S>>tfUClW3?N>Hac5i+rPSdjvQEL_7c{%oYYzhx0EnjW2|c8rNR@gVSLhfqp3VewJP}^Iv?>fagmcs=yarM-5O6=u#Qo0xI3*8nWEhby#z>NR+00e5ZFTcnoKFAK3n+POFas> z^ME)-+>$gwg)a1;0%=kpj3Jj<5S)lS6JdFGyAF{5;$JKd2K=t0#MY8AYK2uvMBKoz z-HH2X0{9|tAxnmn9HXp4fnj)pCN@7Ka5yG37_{RR!U#hr4bd|v8PkhCa1sLxkv@;u zGiQK;Nmh8)p2kTJQgCbH={Y1!&Ic#;rZhQVGUA4$T!Lw?G!U)ElnVuqo&5+iD~1O9}qiact(Z;Z2Vez zS&{YBKG5Ksu;Zf`uZec3kr=M{wH z`@byF^dbfhDO1anr0zW}!FDGReiJBBCrew%IaPPq{CeXr7Y-sPFA;aZeRtNJL7hBK zx|L<3t*^}Ua95D<`eY{u0%dxf;lOVND<|bqQ;o(;?M9p-b!SHSi--8G&cz&UE#U3+H zURNOIZr7mpIk1kLpqI!592c-@!hKwXThtb-lp2+S=yi5QLhJ|5}HBF8-8ON zSAbJ02J!?ZpI!kQ9AteBZEGjQGvVhp!UBu!3h+)ok#iaB-Hb{_j8EcN%)D-y5FZ}q zt`8CdW}fjJ*f2d0PMPBlS-@e$fox2Ph4BF3FG->rG5JW2I85=2TuPXH^Ar0pk!P;| zki((cqcK3ye*qL2v*=s5Bo8nR&QDZsT*ld->G#^4L}~jh);IaE(y! zNyH?fX=F)X-)-x?r`>f511o@suA(RR>6y<`tWndtvW;Fevmm`28I1{rYi4BpZ zGj00#FawppV^(!fed%N;aTkq1i($3i++l=rgjrjn9it;7oRj_eAL6Eo`{|oDG8JGq zA<4HyF*?#bq}`^j0x1{IAv5F&F#Q_EG~H63Z6YYuJ(30(Z8By*q}(0D_K=b1A{ln+ z03?eZ5b%%j6p~>JEa4Jx+ve>eNT~C#0L2WNTiA2Mgu4fa^N6O1*Qc5QLPuQ8(r*Yi zyx;CUlW!)gBif8swl|CIMnwkx@xwq4x%-8YMvGFAUPUL2)z2n9>awHVW+4jO-eKE( zjU?;8tQ5LDHssObgR8LyqZ946ln$Tu?r^(U=#7epMJrc>SYy;PWujhBX8duNfEaqS~WsEkBxxCC86@{2B! z@=ADPbB)9H-sAeZMj6u;N!%$=Fl^)tKqujNv>38TF%B5ug_vT9- zqzVMj;t+Fm|7(b(=1FmR=#{IzaQ%s682m_s=xtR6l+FjIj0vQKB9~X%j-%!kXJdXV z8)sS2`ZU2{;KZ1Cx9?J}XjG!G%~In_mhWmT$@!7<@Gqq>K#YRDA~1i&ZLM$Pz&tsC zI^y280QG%DndK;-@>D;eeoFGyITZ;qUblK&lugX9G@)kGXJf)vv>Zb@LL4n=*b7g{ zy&A4jD2@$;hb;#TPTbX)7G83g9j0ttS9KyMw9{d?<%i6Zk(neu37<>`Y8qi?zWeAj zVTUj6K2!@j&v*Np37pua1$~OX;P{q(Sc#=C(yZ#0!JFQ8e7&9OuWaHQI7qksZ;V2DrXG>rTv> z9&Px#-jgV(9~#*9pELVhb6{E7Ku^oDCVBv@X?`-p#hx|vf+zw8E0T|M40L*v$WkQC zNkzAYiN(K#lIVvTTT?)UrMl_6mD;BJ<=J<_z)gZv<$YE~nCmIjI(S@`0Y02)hx83e zSWW<5CjU?Jym12O9hx=>mFD)T1zP|FXxhFIJ-30;LkvFGyMR?bgnSONXBe{PNrK7P z?BN{!+8%!Eoc3+Q{mUztW4vS_a?};wp8p~&&_YreETge^ba*o;hs{f&#g=gvlx;_Gn7yjCx?MBNl^{@4=s;TX90*Z(qiCnaK0E{){!ban#tk zRI)g+WnIv2I9ZFLY|dD5J#96OvQPX_&spD({Nn-Hny36%EG{lgn5{g9X|Y58q}4{F zh$<0u#1m~I&SVR3D_Pa}F~7Fa<1y=|Xa=>&@H|J{D*yilHur9_2VF z#V)368OIfcY=H)=OvQ$-Izoz|q*_#0jQ^s9S#}5hr#mRptg-C^Iv) z04~>c46}1%v?l|Q!k#bAAZRt%8rda^qlHuf&AIj`ffY& z6uh*|T=!JKGLcP_cB{C0`TwU@8W8PIEgyW}$S5h%rM5;d->X#aZCZIo+)fP%J>?%o zUMP!9j)NZWwac`_Xk_JjIOqO7qx`IZX^T?OWrZ2zW<7nBU~UHLR4U2y2z|bwtt9+Y zvraWuMV@t}3g!Y&sqPoLDyi-4W>6+OIgy0aLsl6)JT!HrcOB7qJ>K^cfZahS0!>Ab zJtX}Klde+TCYu8Np!77zz}>-s6LC)=QolO*_vwN3qP`1GCYxMddBd` zg7^GATa49n10F(Ehqzd%a2%3YNV!P`lcu<6w74Mj|#l>yg`Do$XlS~`K6dUp$t9C))FT9 zYnk13!6kwub&of8 z&WyEKomANn+MnU!r81T814~`x(rdf_b<5g?{@DZ2J1RP7&ep3ma63<5f>Kiq&|w+x zi^Q>d3ej24U(KI6_%QXt0($9dIC>cz2>B4V1NCZj_wKf%(&G?p<$lfZSabOMCDT_P z)CH93<-6U4w?k#s45AXIz`qzLdv;LT0i8Nm0NBb-@MMH{yWolmu2_{@VN}Vgq{S~h zsX=BL%5!k+qjII47aWs$_s0*}?&cwtxxc<+4v=#f;G|{`@^`@Cxc8`c$0pQbSInkU zb`l;y?hx*ZhV}ofNYe7iY9!R-dX0MjQ!M|A?Ml%?ROnu%rn}Fp=E#edTC)u^+&oYX zd3d%D;=@FHe))F=gQ-Tb!A}ky!(m{X`;a%)xrKa^qyz-Ej@Pc4$437r6x9HU1yi-J z6Fi>=obI)FrbNK*{uFWn%}rhZ%Ind`#g1}RoLRO7tk`nEXFYGZHZZ(g+>?J?L)$0i ztxRD}hVFZu$%FQE7^(*}ouR%CH&%5tD$jI!9UC7(fyB+jXhK|>jf?EVe!(&9gOkFr zYE|{Sv#X1wIKy1yC>(l@Gg=z%!d~&#^}F<7$EU=?nkqK%RX9L1#rPz6tx8?PbO@pi zZsPi64Yb|(oP*${su_~`MR`IXg&iw4^2m;ul#DDcUR5EV4jkLa3D+pmm|JZvh3jx7 zP*6ifwB*x;@z#)|`UAf@M>-R-r-I7$4F(KELMBmrIEZ7ZBw%eKj9Ocrn5l z93J>i_8_w)Fxd0!Mb8EUaFzD89Fy(|pjxc7^U7Y|FCn z%{iM!it-dhZb*J&5^}Y z%GKfNHbWPhir-06*;dccc`6tXv^3_T)vW?nLRznxL%`>3WL$%d=tSFfmNeJIHSmWS zn22U(uc^AWSDn!<%Mhr3+&hqyrwOaeyQ?#qv4!e=mA z^YY;20aZlKggrHv0c?=ZQMfyJOl}XHVS_VaZtsi`uccHx-aX(kipt@4!|sh>e0~v% z+}~@$V59}5!scb%Qk2-ytheJcq^SXuJkgHl3S=s9zi*QVfB_?@BTrhXE?O8_9#9QH!@yQ&rxj~abRa>$VJMIMQfCBP^TVFW?f@Oi^!8`kOC&` zl0k2_cggTKI02zZt?AXHSBc><1*ebi;9y{=3vF3g!Il?70nls|zFclTDa|WR5$zD>ixkZe~Er&x-6FEI8qM4Jt2^WtnPqgmrnvu4W<}qCRp4SkO%Ctl^ur#_l z1>O0zqn*k!G>WR-#E^|YXn zclJxU7e$u~-1>UK)0(Ak&%kQ6&!0Zs_zVmo4$SAUYu-RFCWP1%q@(o8b^2QsG6fxZ z|2i=%_kE1Z1plr!WX~(^sq@VPGZ0!asfAr{H@8^>g8%d9Em^AM$06Iy&r}*nIV5~G zC^1fvcFHI!-F6Q5Gu8zjq>O24wl%f1Rp{!5Wfz=%!>CwK1dN{h?NrNIv?G+bwHBbF zF!$zEooKVg>B`ixif{0ITE6c@8pvXv6&sVG_z@w(rn}cijBFqug>{!Y1{^lbC@K2r zHerX0$REZ1_V8Fg?+ZCUY{R!~^5)&ou4%vp**erdyRKV3h z|Ew?Y=tbqI{rd~dnKRJd^!L`XF_kQci4RXe&sf>w-7$N$xgdCj(Mx~r4iqd~)OI7< zp|(>%(F4S9o>Vyz1GzXE@oxG)I+zAmCa&ikL8DJo47dQ#H(O$>E{D*6Q){4Y>^IB2%|uyq{(U2kOoviz4#rxX0l6H~&MP=BL7c@joR_u0MhCFZsu!Ec&65 zHX9ZVie;ll-Qm0l!_|mP=X4YMar}5fUEd7R6N0mV)fTWjbpFVyIGl9T=N@ z^}8|E7$Xqmjg!tZq_e}4MwPZoPU=R4AC#L@G>|6s_*U?y=08v! zhGnd;Gv5#))$xfVSuxTAlRZrVi zk$m${+(`Oz!~!X~t>J`tWQKr}5~LLwR~RvEVE#}5G5!jV0D0)CkwzGAL*B+_8&KTW zuz?MeL|~f*#{=^cm7lv$%9{i@FW$zk?I01L$khswyI!G)K^nch85%$P=~t&to>XD&NRajd*`;=TS>Q*fRTZIb_Sz zqYOQQ9Fb4$i%pc%_O%b@sk|_-?(wW$wzz(;8LP16eIY^yN^D|{8x*sFsqwu6Rtisi znGm>+c@oi65q9>QI_tcmk9d_(Bp}f+BOX+FG}x7 zjAewR{0k&mI(JieXWu^~;@@!TmzjsFdyG@)sIiHz;M@!{&#z6w7eq+>y(ZvhGb?KS zNqH_ujrgHiex5SbB1wK9y?8c@`XJXapAS;yxQu0&Hd@RrAg7ltprlk9HY5gmOp$)z@`k6f)yspvT}-M(19hU6lPpXi$?N@p2f5EBB@+;`8qV#i2=msw5!2}6qtVlQ>D};$DD2=d z?R^#;gzRH4*h)futn7b;qjwT0I2UCB3<3|NuFF05)*j=`I&wC0B1lwbhuSjD)M}Zd zC6{3f|r@3p8C0El`mK&=FD& zm~@+C8av-sWZ`T&+MFrRrn0)MXYogagnC<@igL;%2b)1iFiA_fJ|o(Wb>S7LUgN*n zJbiJ<3fj5cJu;^O+IV!vP+~$EjcDd&M1A`*`Dq*D2T}=D5A89`48O^8_Vn#P z|K8kAoRW0YXp}IcXY#k|%e^}DIlPRUkVh%g0_yM4!87fdplv2m1XHsa(5x=9d+eIc z$@!u3ie}8&Zd{eLoo8++6*NyY(IcasN=NlI&$)_>>BekzwXuwPqLt!%o=kWRGrC=P z=thD%84hzevFfy7raDw=q|OS%yO&=wc*Pb&k-~vfp=o?=D0w= zHVwh|*4%!7c75LUvoLv3$dk{?Ug4UBCz`Z+dDW=9B<6Pz7H?zPbfXYG=+)?1Iu#Hp zyJytfX?4Hmq7R;-3PXU$&WF|UTjZ&gW2<2NFup+1)|~Z#$&feASFl@F{>2Q_kZbpJ zTO0$L7eofBVUQUQi;*_4)JiW^Np|LgMUgOGkFc!YCSRP6RHR0d+x!5%(RA9J+^>UK3;XWg zGv(cc9H)nlgV|;z?M5WnA`-Wrts?k;0w4<_1#cR(%R9GUPt!G@)IMH^h^*A8ROA3v zb4Hweq=WxqB>vxl6g^#P-r(Q-)Wun{Z$8q(#4QSc(<1-l?|rnDg|#pAGoNG!V&q}! zm`_N0O)V7i;DIFF45kvnZVSMUws8|{02znp#MA8qq8y~oY@ENprztCL6~-R@YTu%s z=UwZbhgEn?ymJk)$edD9u4E$9ydF_p|VmA3pe zWLk9esX}g+(kr%m2XdHgy+6abK8Ah|W>d7gY_O;s&DiFUY_I5UdX%NhK0@7s9@zIw zmEFRn60Rm$jHP2LQk1DG0W?(d+>|NjJSY9@-IoU|19Z?uJ^!NR(vBeY`z^nh?q}xz z7Jl>l-{J4sp@tN3KV+%bSfN;~E=?385JP*b`G}j{w$u=a+enja|7ODc?wiSPXpFyn z5jmNlEGE90lux@qsowHenR!J`#N-l1qJEYS=*!&_?QA>C*RmlCNj##*E$O6MNWJu1 zK5IsMy-7#EHu_Y~NPxu92Z1}_1c50fy#c%@BR5f3(-|EPUI?o)OpCsDEB$cBjg2(| zQ<7{d%05T^{uptBr{np$Xc9enUI=LrD?9+rV6raXLJ&Z~3whkuUy3` zuPot%Z_vKkL!rh$P40$&9P$hw=dPmQ4i8`1Zc1eD5hS;XYTi}<-QPGjyK`Jvub`en)T!mM0-55x&3aR;jbVo9j>4;RO`EQ_7J4-RBbrS! zD6J#;if?#EaeLx<=}UfQZ|@?d4}8|9OFe&);`hp?X*UQL>KFBCdRjGD{(hd+EL?9& z`t~Pc`8{|suz0CG&7OD~2#>vJvbyh9f;{(_&B=$5zy-+2ck80C z>w{+Ef8>f7yYsZ%v$xwCQw~8o-vSW`08;QeiVAO5j^aLpI@8b2e$VsEC~e;RoG%1i zK=x7n+zUtl_$V4FPWsPt6Ys6{*7tw5Do2{Ndk*UqJCvo(Qt>N8z8L>?B-wV<(p$C5 zc8Oco0lsPFb||~jgtM8uL^x|Cy!^HH%n7T%Z8b^GkCT<-3QGz)W6FNJTb{;n-|87v zO1(k2Mmc_9K$&`o7CQIt?~Rw}pH;lqsn0d%kZ)h+yFtcXeu0hTJY@WK?PGM~~^lS2E(Py*MZ>UWk_NWZWvHo!QS_m-Br4{*y>XI+o%qlb>G^>~Bh|(nDoK(lvZ-ep$SQbGpMN z=GVq$$`b*7dq~kI0MItWYtk!Ro=iCbJ$|@Zp<;5H5Od1PDz9I_^Dyyd-|i4Z_`jF5 zzay9J%;ehBnYL^gS+sb#28@zf$&1rs_-)wwkt$Umn63qh)qO<&N;j6@?`svKuNQX9 zUBqsd1BlJZw^xpK_ME)>pLOm0DERvKy+l538CCD&gXlrIqjUNKuNe|xs2L)ujjG0y zbE>^em~RmaIFrs~)#vkEa}1e1d>-XY%;n4Bk7&)P=xem2(SjPcYQl6j(IhL4Iw_rz z-mA#Ug(!qO(4iakm4`RIYg!G~s6l}b%?qxK`lW|2Pp46x@T5Rhb=-4sNw2(<7iWj7WNU?g0wAFoUv|^DgAl7D^fQ$zbQJ+Hv^x)Zr;xZUCG+<7h*V*qSB{=Bf3^DKgGSR1`1o{U5-FK!YZudwgG2i9DIe1 zVf9^sJ&vc{i_Ukd)y7v-rCJyo`=c%E)gVwm1@4QO9-5qU*vA0Xgdz+zasLz z_!9wqQ!B&wJ^8EL?4;K>p1+0!iN6AqoKE1a7uVJ+&k-*8vj0GTy7jyK;nvfT-aydp z!IHy8$7rvijE#VwER6kIp_%c0Qa?A2xuie^A(jvjZm+X0RcMyRPA|XS)-Gbjl%K2b z751#nQ?s|x440XpB$!+gt{sEdWn`oBu@`#dxiP+bMrITUt#Tzw;N`BK)DMzK7nMCxWTH{6Iy(+4G@Zpns|NyHFA$v0cmJ z4EFXZm;SW0-SouJC(1y@nKAk?cg8Gk+YA-dtJ=O&wY4niyK_MIQ${thACvft*m(u1zcN8eA1o9W96y+&00y1A{9fiYxii ze5^SH=-YXo7-v#2z#Z_$JNX7MA-OgXb&}7qQpDM79n&VZ1oyo|$$Lk`SdOIFi2`Gn4)K?GNSu~T@>`RqIMjaI*0=g(go*ZmZL;hEd zy87Sui%0IZw+>tiqX*L(O@wP1?2Q!RTA;X=NKx-#9TN>PL#YXfdZZ6NV$O#! zphl=Q$Bbsy`vyBtOxMnVkc&nrRE;azDMiEO)lM#;s^^xDR2oUhE-N1tOoe5Zh zgC@i!D!hM>bJq=Cmqsgpq1fdfSM9@fh*3)mJBw=54tKRy>lQiEQ2}5dFL|amhf*Ac z!6ad$%5E*5Q_Grz8#j~2Ac7wSFk)RhH){CLMUcv#vEYKgr_|Iie%23*(U?T*^|*%f zmF9XxG;&=dd)U>AtyO{G-P>=u_C;!PYKP3S5d1N^M=(9j#2;9wL=H-&g)nG zQ_nvYe5LJF3-rGCb#P_Je(;nhp?1^l4bPwt7GF#>*1vjmds|215S;8{Kp9jQ zJa(w<_O?e#gSP%{EOJEG@Fo+{{RU9a?3+encZIl9v9)=)Zjc`#%V;JIYT6Z2YfD!X zBRBx*YUCk&Oc%MK*PffIoIe^tA8fM#R3EtvGQ)Q+&4MH#Z-aD>$W4(LF|}#~wMlF8 zQFXy;Z(WU7lQ0oLLeAr#|DI3-sGG@lkkz2maZ_%vnXJ+#SohytxJzS#sAp&+lZi4u zd&%V6$QM3Zl4huj0Fj5R1n~_zEv-Qd`luYPiFh9ZjU7mz3uZyC`t@KzlL~xt@sH;JfkH$WE) zcxQQ1JHg$sz{WHZQY(CL^d0*V#MRElnp3j-#1%I{~Z ziSNEVeqncTBBU(Jmp} z;#o;$kmB$c>WTQHU zD|zqXsQE^@I*W?9(dvautA{Zh4;Uc~Uv&n9e_)q9=E0xA;fP<&4k4Vg0EG*GuF562 zJ<~l0TD&5(@^N7Iwt;UZC5NgUMb7fzuRz?NX%eO>;C&V22aP}dG$<5+sw0x{-xr=_ zA_{My>}Q~7koFs`BB?V^l%44(%_hao1tt^JRBY;z{ZM1}Lyx4%1P$ezLgM1O#wQbv zze|rD=l9S(Xy@+6Hw~ZXKS~*bD7#&*N+SXr<<)6R;A}VV zb{yvSaCo-|`-Xh1i#jrA>LJ(>H0lTpb{U1f908Ia`BZ>>IpwF@XiZD2Q4#%GD(W$; zY~rjvM5x3@8=6a4NAaEYzl{E4x$;H;kk@QuI ztHdGZ(`j52yEvw>MShJbTX6aJH>4{kB;~3>p;3f6i9AdTtbebqQ*K8~$4l;K2F*XrU0Z(01ix&4*)6x=;pdH2M~+;2T~@WLu;{;GW%G?G&fJY3 z2iB)WmxpWoGSH!kta-@Qf5-n?z&iTg(i){Ei63kA(9c7=)uI5Ln`XH!grUWh!(gVfTb@vEKkpIUgWt4tW-V$S zpiBsjamplbK}p_x=!ig%i}7Zd(DIhBwAFQdFh=S3`)U1PO`Sj))dw>9?d-e`PuklD zz_#2%#HYzhs~**eH@U2p4XgqJ#U)<$bB5I9d=U_e1YU~DPaLSNM@;30OpJKzU}kXf zHcZ=%O3#MA652xkyvzc|8{TZCb}(7pAH~2)M;Y|PB=RLXBs7*kEH{mgfQ!!wbt zKp-*scJua7bI75y=Zb=pAlCxor3uyGjk_~(ct*08?l(s#Zv0NTOT?H|9RE09#RNBK zFHy>3dRa-;pI=mB*~s#_%U6>qQ)derM{SL0lIXP#(&TnQ)y4e6rb~?vlrS~~PtheL zL-zu9Ple4-)Blow|FygG%uQO?=I@7vP6^A5m-k*qBb?>^VVfU-%=Zy@HC>h*tIegS zAt5KU$|IKfoXrigG*drENHx=9Z13ZL6>iE|fHFj-AE)wUW`ox^Hf8#bze~iLH!UYj z*MgL!TE|S8z#6hh#GFZL)L4S@T>h!?)`xhE8dkYt)`BvroNjVA1XTwPIyY{i^8Tdy zFOsymv4~+_m_yeC(ldipYQXo-L}-7Eq?bj=fPJ zuKj@%lhnQ{aQ^MzYDT6K_30nFIVUYFexuLN01`J9^g)9d0s8L(5YwR5VNycy4|1l68$V<=kJJh9j@KN30(oK6z5qP93l~MZn9*W46YuN&s)inrkEQmj8mJL~0 zdK(_IXC-RUaSD0u&#Q@)1$3#(X8k*zEx>wg9=wF}0uE;;3cw2gbyFBlZ^%p?x4gw0zpx;E z8WKh-0GAf2;`F1PltXinE<+$`aL9U?iPv>A6O1L_`+M@hLCmllm98b3QfiZcBY0;_ z3*m*RV3vXS_SRF^S&qtU1V_8vEHrA@-3!?L#IN!c1c>ssr)i$ZiVxzyzwN*h49b3^ z(zQ5JOdY|iOjj^|L^O3 z=k##4y|zPBRr5w8=u=os7o}m88K8PYA@?)@^^WR^6g*PV&9%}6@kkF0td(B^;8+gw37$zWFFIqdXVcascVO5Y!muP>FX5BByS+wL3T=~V>j5rCbGN(l8Uu+x~2k3v{4bjP1T| zmgiG`x_q*q^r6MzF=QtpJJXIJk42M9?hg{L7Vke99~9xH=kZrus7$gmfmdA7PZHe zYa$eZezS9rx}Fp#KrC>!z1f-X?nRZBN=cFX(Gv<$j0%GElvc}Xup1jG-ojA>l$ms( zkILiZN!-&>sKCUsrHYMb0ICRO7d|E{y5K5K!M2({X+!5e_kN-o5Bxzs5+hnY0_A~J|@V+7V_^I8W9qD;e!US>uedYdS_ zy;PQj5=a#aT&)~*(F7i;HfSx$ExMQL+c{YWNTXF}ku>Q)IOs=@sg&Or`O8GwCepkV z!-*93TTHW5PMgC)WCWHA{TSTZo5M8YW90q1|v6RH#U%@Yf^iZXL+lhHU{i~0PR;b`u>djY$9YpiQ7pWI~- zuKH5Yh#jJu72YbU3Dm)!eH0GINID9^k@Ao+`fmFEY#C_{ z>rq`sOB2VSHhpzvGai@k^3c83_+;31K{I*|#cK0aQB5`jEGG^*>Z8Gmn{14t7Vf9; zICk=L$aLSI4dXg9T(G;|djuRZIlK$C$KMG8iWJFiV5baPZpsNZQWRj6_1`Z`ck!u@ z{>PfQ929u%77br67&g)R<<0+_7z+M9t;wvWQY?EuRtsnP*NMMU|OW@U2mgmw znpIknlU{r<6cK(lk4>{(m2y*1)e6sj`ZrBI?7Ayh_~!ZhR*Dq+WtEsz4I0#__wqvr z|0o(tpGz-Im+$?h!iA%vtt>e;bjXVvz2Iq@Mh|eQPu_1ihxW?X!MO`t^O~WRKXGiZ z5S=%F)tYus|L7o`v9H3#sKUQu439Aua5W6~U7ZSzwQHga)d%6oO_i=5XdzC`eiP~+ z8d2VXVPP#r-iLP-62<@9m%H+jO?52 zM-V}7l5wO#(*9NTO{gI^!948b0^&HyWMDKHjEt1Y=s2-w0JHH7A;1k*w6EG@Edpsp zpvS6iGx&UYc21t%=kq=XIBufaNKP3H z-BXXsMCNF+-W=+i`66ga$Wk&>!s!nTRle-(+Tf*rL`iC@DYd(7%7zEADa5dC36-`#Mpn8t z|9!$rzmOcEm0Z{acjjMia61T+Zrd%m-h8HP1K&(`!Ksy(nET(D8PocC_M&a@$g3ZT zCIR8yH~ThIXjf+%t5;O-CRJOpgkaZIn@8& z`R9#l30ww4CAAh3n(Lra9b7cYBB@P-mjmHBZyvw!+5uub)9WYtkKN!bn}9j&E&x;_JIprN2D+B|n3Eq(?Mk$-nGM z7@c<-GawjKFoAkVITot>^}36W7|%Od|6ZUuPs`o!v|n)0mHdMY#=p17ghshET@hF< zm!(xLY^TKjEUatkF&23?#9zqyX&^9H&Pz91va_&Gms`LA`6|CF#I89MT16GX%Za71 zvHV*6b&jcQ{3-JD|ARaYarE@jByGU#Dr=TI&YAarCk9r@?>~81CidZaa8{0j88NG3 z_~3_DB>mGLZ#{)GMD_kKyHIUNig2)**8rqzFN#Ol5(H zdaVZCz%wr)rRc!LXGiS-m_Uz2+4zs_ZZ0UWBD`|X zJr)B*Z&5Z*Mqz$J!*&k+ynHL0x@=i}mDbG}qW)BYJFo`3_ynblKm3s%l(l89BkgD5 zaYac!-sw}XdH1QM=g(F+6+dBE!+6ga|24{r*N=l!;F)6W`)t@h`zoD1&_c!)jl|8n-}UcAC@#(+R5(PzfKsT(5IOGeKdjNu{=#ObV~?xFCB&2Ux}whEQKp z-BNNQh~2QnbmpbA^yO)t8*1Bt4JOD^s{3?ES;Pd(l6xxjANqs}lij3N#hZe{k4@`e zI$vF=d#c+G?S9E2hGxSKaK}fxX-8c>7f>d+h9qTfDoL4Ts7>&d$^_rQ^wmqID02!l2R-SqQf0Pbg|6!#IG?K93g|jWC*y7ebzRV?QErIsth2I zm_QJ3#>Vhop$iyazb*);zTDxmyN7umz!a|+Dr1zX-XBihJ>(#VmB(>-{4 zutoDyBXwx+mEFqIei#v*{N?n&fk<$)E9gpt`MqGCtFhbXcQ+dIdX4$+^uw~aIm*zP zNex;JsZIw*>E>80W{%QzAgNBHB{k^GQHD95`2Sf(VASZI1F7B1#scAn@K|8k?$m*v zp3&*tXNl9nUZ^CBH&q6NR%#CzsuyUg8w6m8+G7<~2Jog93bZ$P%NZ5JfTdoMv?@BH zhfePqQ5BVnO1&5`Hq04(n?xlxArn7hQg@+0p;EV2Tv|B#(!vhO(a)tv_2WT+&P@XG zD}(yT4@dV!_T7FS=@jiE6wxz-$&$4t$#o!iE%zdn5Ii0k@puFbjC4QlhJDb}?5zj* zZoWK@9|(r={ql&L!{@s=iiqRG;j@||=Hl^U;_3<0r&W&;OPHTF9TRQ|(rE&lAFbb3 zYdmxZX+HG&1IuO?-^|^RLftzQ*@nGFq<1lC{xW|d# zQEn=5@jI0hq*B#{PCjI*Fs;Npzfb*7p8A&n&rTBH>a+%Glg8wwa!~i??0?W-WR)e#^>zcQuh?ZT(FBF^ z4J?^DoYhus*^F`Fx?k)r!(d5pC1t*Pk!#MhG;%-`^4sj zxrRfUI94tojN(BxBPi$MZ45K3es`|30grI3F;?&tW2#IDgvW|(hjEzIm6anGZIatQ zyMQutWyHw+_z8KyV)NT^!j~H+d&}cBR&rmj)N2Ap40!CaN3WqL50fc>Eb^C$6wSod zbR*l1;AsD#5FVPgxpmgMb}9ymarxHoF3OpdJt1pkd9YOk zQ^9D}V7dXHW3wgl>mZq^R1+{aH#}<82jo$%CP|u`+CS+)XXm5?`%|R3nq-tKn}>Z` z4X@8O7iXK{_0>-?)wm}bcvH5$G}{hu(me4JfEs6g;`zD&v>-d09nSVqr1ymthmuI= zif`0k7AS9j!?RGn-u(ru$}YjwH{f$z&CM1ac@Fdo7d&jK72YkZt3}rNjFbV270FbJ zZjcKDpd;n?vlZk&7341gP-+Fsvq14>M;Uw4d0*rWYt9AQ3qETI^H`xj1icYCHQ6Ds z3=>7>?s=!!x#@h+bN5z|+W0)ADeCH-)@PtLRhv9i7Tb&Yi;&ZSoA?j*v98L*^J)`j z>|bg>XY3z&#eXJ=fG|S(l~$)SGV4KI1TR2EmRKQ+pclpUCKV-qEJPFp)b_ZSQd;&i zQSA!E{m!IrJYZLO9c9PdHt2hS6WPw}c?QZ=eAzi@iHph7(Sczjh7Y4dT=f0wQ@PQ} zB3ELGL^#<{avZI3*EUNk+I=a62GOTAky~`O7*+YY;w++1E@Gf=;Qy1_-tqqN3~(vh zt7<|n{TDjv*|1mU>#iW=`f_OS?b-T(hf<6Tif7?-thNRxiVQ2^<(C*_J}tMFvs718 zkEKq3@^KR3tr}$-=$h9G-O_jhuqG!?bcts=;&lC!>NPYQ(@Vli4Me9Z%9sCL5{^%qJ^}Rx9VbpnazYjmS9bVkiy&!K}fb@hB)@nFOhdxD;X`}T2 zOYe+1OFMsgKAko5?0H+;blgoW2Jchb0ZtTUQE_Tbd16#V>!Zl&7Fd#Gww~_IH%dC58;75RFYVH##w# z$y1K($`I#k6ERl&*pbl%aa;Vb^5U;t^Wmxjb!6JPpxKcM1sn}#vNZ%k&I|m{?KAC6 zKOv^r_m7K{#p3v?k>jHVD{Ce$+g;&1vfqPWJGZJh7+AwR93bDM`;>ZCtwYm2x~y!SGp3lnxb{QAnPFxHDfp|8VQ-tuGxQa}BOe>RpL;+ZpcR<3 zj7*LfveJYQSCr%yJNG>%)D5nSXpi>EYN}q*tP(ld^<7+1J}%hlb4v{xuh7@-#T_lY zt|d%U%i*zI10_Dd1B9AQ8n?FadJSvDvDTkTe8djX>&J^?Yv&glV>wgn>F>qvJ^vv; zcRg5E-_uhBV?ABHiMNSgR#V33ZCbkE4hvSap{J}KT%TKTEJVyc(XO zi95&v>|=Noh2?`7RY^?scjDC%dC==ohip=b*dkQ$-NgT-V5F0)7Y7jYp0lJv@8{4? zdk_@SU7#d^4!Z^$REok8Q9x*Pd2Q3F zT!1drU38Og*T)~>rg%;Fs?OY~N;aJ?C}vA5&4-p$HkCJ)r{6OTwrCcWM9{0tBBdT; zbIp(7GXVM5jjDJLwL;l_?d#tFL05R)&#L=Gvm;WL zD-uWG52$vrg5+HvLP+I)p4F}fRW5~t;gt*~bBQ7^YyrV8Q4qYNd zf;6Z-4u52?sQbMW=;t`cu`SSr@q+>Deuzqj(-<57DpE zV7#AhOf&(84z?%49f(ADlYP-njzQNT{!DIM@hvOR)?Cz>7b(c?Y3YjdZS>C@kZFq@I#+bEJ)rhtaH0vUlB0al9 zxhSCv?#0@rH=3t4yS1=Q5S8CCn9*cuGK0Gdj)sqUhW?r!m_8;m=3ZcN;DRDiX=GDD zp@QuBHLjpA_!J(O3{<;CL6Pe<499D+5fTd7BlTQhxTYxh#&26FdCIUc&|1(WTVPWd zvdnGzpd%Fk;PC!(t<50wFDAXpo*>fys;*Xf4OVq!=4@pWyk3Ay$xB`HpDe zTaHFKo9Wm2pp4lO>X#c#8<>8?(PPZ!d}X(u4&J2Gg+guN^(}9&?3&TU+kPx4gpDa-r^4# z-`!W&u!gJUwY7jv_`Bo~{Q&o}qTIi^jgq5#?KM&`LhE&YSNGN0bQ?V`*c(dU)+He1 z#~~Ls!)xZk#6c0{wKVj4Egx zcgirUEgf8GZ@h*HsQBAJXfI+G#pfS|@oCd#^>L8a=o9x{!>8Iaw>?OKS zDUAK|AkpB_JPiGZCbu%)T+$dVnMlN`CxoYIduZf+x`FuIr&9yOA>obed?PYi^u4q0 zpr!Dr5wjHfs??hNis<__c&!e`Ew=jDSXweKO=hdY^F;)^x?VrEz8 zVK!`kNiCS4SAO;kAv}g;rgeI?Tp+y0rb53{0ER)FRYCjTzzh}ceXrD zb9yb?-aP(?g{Wkd*9PCouR3TG#CE-1Iq$1pZj%d8mflp60N3ZEUWW?36+;Ey(9<++ z{p8ZglM$Oh_0uuX8y`C7Lw7n?`)`cl)v+t^VnZc#XZKG3r)KDbDYHylsPzkf)H6aV}k0f*&NVB2n0N!7wxV3!POT_mUDE;&IY9 z53bbk(zKgH=^=-);Am{8XYlx!>Ew?q#onqqoK@PN?pJ?dRqo3?Nb^ARrzu+3Pz~Es zPtBOxKlvUTMX(##jV2?r!ER_GI;R5E%Qx{s zx%1N|UekM*Xj?<8m1QEnMK^**bn1S~3d_V*9=PCd}Q;N+NX ze-eqDi&RS~>&4UW-%eRRMLLSj8W(k5ha)#vI(uXQdWZ;CjH)q~)jYmUq|A!xn#B%X zJD;uAG@{KN4u$%q(uU@h?|0*tD&k(+umn)uM6?@N4MvdL=rUx8Ds7DR-?alEnq^Iy zicSAGU*)?SoqnE^aG+~yn&R!m)KnzEck(Lk_KLa-mq9~sk3CqXiWl2CoSlD}Dp>79 z5hz$NyU+r-KqoAbr>w=Vn=&sdds^S!+g;y`3N<;x(I#i8?~C4v&%ILeJPsEsFN>z0 zrfD~Z(oa_u?TA2jSdQ#n8d%zu?)o_J@i@~qI{@@nSGc<6w>?i@IQD!(ePomx=78sR)uOi&GhKO#)G>kXo7dO9X)Y$>q_{guL zG7_VTcI7?=t0O?+#?b#4PJQ-kOL)!=v||r+56W?)1>AV?*Hg+yjW<`ecWb6K=PR^b z8Djrx_dnb^30!_L-QO^?V<+vKy6)P)%iHMj8$-r|qrJ0^e;E#0R4MXQxv&=T)bv!v zNi#AUd5}Jmem_KZ)-eFC7r&Jfknl0KJTqg}l-e7;>w884?|>eKx+-#l`6+a_KHx#Ofpwp_b%pUHCf)W&(WpLdOpI7 zio$)RddM8veQ<~A2z~kA6#IB4taHmiX@lfHKv+&5p zFL@je@1Mm;8+&~Clf~W0ZmIOe{ZA47F71cfS-$`RCsu?tF-f%I&5bIAn@VQJj$~KwrPo8NHVk9V9!J@$)*U43%a?V+l=J!R?c5KG%T+aZa(2;@v zqO>O%e3hpIy6P%|LZ&_66+`C@w{p za!l#Va01<_OR`?qwU&4XzA3wdXW#0O%=6-T(j?vFt|E24YvNphA>pv442G1=k)ZB< zwezXYgA^4&sVp|DnkEuE!P?XWpcx_t6hD|%LJ&uMGU zX)Csq{v|(SFn%GEe}Utl@n7xBX)U&!B0;Mt=dmKsz8}OtKMN`1mRXmf7-BK)+WXUJ zbpj2?3P&EHQx+%ovy6HgMS&yvWKO_Phe@*NGsFwq-Xm8Db)~eF_!tck#(tmEH?Xkn zIRacSPiE13ePiv^TmQ;k-;;c#S5O$ofj?VK7J#%jhtZ4bHOS07>Tx=Chyt9YDBS-7 zb-dN9o0nrR3_KXv3cTW-Uzrsbj%xt^>%rDw$&H}b3m={-cLcF-`B*Y}?D9S$f93$U ziFWbmJSuhG(TlX8Rv}m=60H*WFEVodq)J#Nu%w$O;{7c-asC8y<|N2QUe0nu5TL6Y zax9dyHiRzzyp3J5zR?5WZE9|0BYcUy9}+rN5X4Sj4!4?d8d8O;qzLC&K}>>7R=4NS z=Oud@Gr=420H4^$V~~Dv>@#{LbeE3g2sq0C0?iB(2%wop2-d3lWW3k-63x58Z-eWk znYM3jtM7;xO-X0c-`8WfkNY?EE&7v5)Nx zS5|`t<+PAmOAY=JMMyaN ztMRQo`>)=mry%Y^sXNaGw}$)sapQ6eTXs6%XYiJFeSKE^S*|~v)lzCcf3_Zl<=s@X zO@vRUIokMIz6+7KOk;g8>3Sp`L;aU{iqnX9ack;Tnm4cW-VwC&>a-Hk)T>JL;gY+} zYu-m!RVC?W)zxj@Z%aN}UT0Bmc)mfIr{F*5|77PYfu*i}#6I@B@Lh$eVQ zmhbY8wE*Vj0hOz}O1OpUw7?l-Pw;wJ&lySc)oL){1drFpu`qFgB*<2~i0z<}IE-vT zrUWVG(Zh@&vHil|f|Vpel+PeJfqY%gK+DxXWnbdw7IlT#2?aP@;KYKXJ3tiwr z@GA`i`JGVkV7;JV3-+?n!5&Gm}nqIGxO=Gmhk_W=b3$ zuf)n^0`K*}PhRAXy~c^pI?indr|4|mM&jDNu6&oCx&uz##=!hiaB!N7#Rq*x1Gf8} z8H5jwMAk`Jh~1ORb(5&S6G$H$1x^CYz>algg5I$HEqf~HCI(&LQ{ak<_!XS#=O0B`A6p@C14Sjbc9ck|$S^WI8 zpb}L}B65+~*OliP8_^ZHpLwl5;-mWHl!|QU3zbgVLLtp6`GRS}fBC8&Dbks9E#@%6 zV6iB1fv}9=tr=EI%~)<2`pE(`2-vw?z>YR9{G{H9(Q7hMCLsWY4i|Ds(Dm`cuqpoM zG`IlZ0z^g9%k=r9dc8mDV|tT{C-~{=>M3~qlxp>K7U5ygm^M(akrMW?or;i~guaTc zf`4(ogUwL>Enyn%xBKmQT!3Om9mfCm2!s9;DNJ%ag39Tbil%2c=|42lH75Su%lS3} z-!9g=Z0qU6ugCm8u1%R!QnA!l%>$TEF5$Bd;4v69rVv+oP@zA-%?y=%<~(yoSX(`RWmsN+;@XQ~2{F;!ZxY z@u%n0HnA%D4eof5H84?u!!H)mCb)0vLOEjADmLtW0k4u;AXRM98v5x*#H(E_=B|4O zNp5$<0#xR`81b4fUA~~%ho+1ff53g#EH$Ihr}XBaszJL0b34ABi-0lcWb~x!NrhJW zUsgYd%k<{lQo|}zSO_o&k8^q7w&UY7mEJj5D-gqDP|PT zslIO3orJuLMBZD_&-wqv`r$v!eRd`*kb9c}a--&#xh>kfOLoR4*eLEw_RYBI*2`JE zEIjF*IiCc>27d|5PwZFw)f}H@sGYP814MqfEn^~$GtAY)A@Vn5b4RO`tPt4LR~+56 zHWGg5d%;H@kI$fMfV8IQDydbT<=lSKvLkC)thGm$kt|w^*2w>39TiKCvesaUcy?PL z=X54W(18ann=vzve+E9xeqdwTVPL5JQRw}7hFO>Egv3A&19tAwb7*fBeoOZrqqv{r zMeoHgN>k~KilSd9?Y*$BMR;Kxhup;Ydos>*0z>_wtmr|ayQ*FK z*>0sTr=VG%o?ktGHVeV2{O7B$l!ah!zfub7uejKZjbxNL@wMx+wlSxDg!;{l@g|RY z+qhrHfyaF_&U%}@&m^2RBW`lBwpY|aV0FCh2H|#C9i*y`vE3Rm#Ti3YiJZy=bI9@D zj1k*fhXVawn10B;pZLDE4I|bDxW<0%f}H;1ex{Lr{%xsr@h#(I9-jDqWR}6LU)TF) zOitg47R5TpKuG?LaPbW0#qai1W2w{mteVB@r!ODxpa505f7b2bh?g%|^aqu8{>mB_ zbIq~kC<=4hB~I(m#r4o|t4PFU>)U0i*!-;!!Z$^3>~PI;{KX<7~JYWiit)6)DVfkTDeEDN54nDVvnjdye^9f z=0I~uU{>3e>Ak9z^1b@KioGk-V}Z=<{;EDuvN6A`prAZoBQZjU1WBttL6S=ooQE@K zEu>k(@e&_aNzN-RD5%K)SNTVYHxx6nzc@Lqu3p%6O{P}{_|<%6uw!ZKSFY1_xQJXv z2oHDC5434A8@_G%6ntSl^-{R{l1(ez5}(TYho(8TqoYC4I`f=e}vjA^ZXukj^hkelfGSv%eN! zGvx$H1d2C&=x>m@a&+#}x}0UHig!hMWYx%R$_=6kY5aCp;c}UJ`M+O5DYx|XPd~ei zoKWM~<1bCVKX>fA_Z?;qBX`+9H~IY3`SClvzh=-r+3Mdsusoryfo@*S_f{Mj;cNDxTq)CVh5>ooA2&vVn@WvuWL2U?UFL*nS9FG$Sv}EePj+Nnv>8mRvF>iN?s# zf3%_hP@phj0>-GZ5g8MR3?`nT^gw|b1z~o6cxzd=C)rrX!GR@D$P7gW0`(GBDp%^m zdauL--D2s0jJ;ZE!TvRV(X>T4c=tZXO-u2i_cAwH`1kEfk;8Hzq#ahpV{1x;=CT@!CV%mr0v})QDt|`L)y33T0+@=?+V6 z(6deR7%G9s@P5jG`}sPK8Bw%@hQ7Eyu9_>l*08RmeFH%<8x4HEJ8K`~EmN(|qsjiywp?({gVfV!9HZEMfi22aZx0W5sT_HZSj1d@>E+1d&(q~VUW_@|Ew%W>3mM8r@7m)D z%SPX#X5QTuJK$UFw1RA1u*%2*Ky|9kun^zh_ve&V&NCO?hwh8-Ptz_~<+AktW%_mI z#WdaEDyK#I>hp_|7<9Gr;^$ne@`ci{d~J_p6ja|M9R(Hdl|-t3qL_sus`clHyf~_V zt$e-KXjCqjpATRA-HD4>^Xl{QDI9^^bVHda5P>u*6ovLaX4RsV zArWn1o#vMw1WnS$Bag24H6WEsZsyc}$Np0uUj-kaI}SKXmX4P#Td{0NFe{g>#6!*? zWo+<bP0)G3Ikf-1I4U9+ z!CV$}7JK8MOx*weBg955Gwjys%bmGpf53j&b9l9H$(nhe#xe}`{`AOlly;+V1{5|j zqrKWSDdSuad-n&YghkL|ojh;z)YpWk{oZh7I_uF*4yTGe*xj6c4{Lvwn1?f`+MN#+ zmIN||2ORCEN)nmZVnT47hbR!RHI9xIzxMp*cKCHV_~(!NH%uUN*^6y=mYi6q@X1C% z*YD=6MdMH|2bqm9PHH2GLB%lW3vac8JZH^hCLd{AygksMq4~T1!I9hP^!2W6&K;Hz z%_pzg^K?;?y9x79Y{V0cl7|@VLy3`qH;Nx_B+sML=95YDY1Dbhe^%jw!HOq6D$`tET|qe_7OkMdv+q4ihxatBTc2cqW%Qwt=m3a4 z7aq8SJ{gWW;d>iKM&6r4(Yr&QhRo(hFPi#!*M248NO|WrJG&1!-m2*}@y{bM-UJs= zH_Kc}&Ul-RnPD!amOn%a)O-Xi&q_f z1?{WJ|00NU5|jcgJW=>2>q|OfiK*F>Qda-Uj6DsO z$|}iPt@U30;sekFi}l`52^qV(bn9EM5}nY_JHV8cX@F%E83y*ztJYwq|A+3mRhu$n z_F~n(>u`+{z6yG4&;A*`@1V6G>)4Y(s#)y$*7GS5vsMW=BMDRPlfz;$Tla0NL|PNz z*2oi7qmdey$*`Nzkf6!s%ows|3?FM}8nM4&%q$jJzu8u%#5an1+Kcjcv*WpH`$m(a&0BWB_Id%ZIGXz$3_q4O@}$xo2{GYlkY zLbG_Z!#Lpt^WDTaI_I;-W=lLFtTWDf$#-E~QY0AF#8-CqxYo;E`!fveto<2MyIzB? z{`URb&mht$+)VM#YU*EoP)|2VOXQtNq4`N#}AEIE1JtZ*Ighd;vu)GYcTHXJA zlmYVEM;q`gg#CQi9S2sZ3%xs!ivE@$ zKm9CFYdLHRm?t)zJc%K{Q| z2@bae=}&){sj1IduNgmVxbZ!o|NV^yhI2vvoj+7qIF!$(UkRP5l3xt%x9bCvpx9_) zHP}Qrr`U$(nj-2-JG9asQJc6nv>4|U*;oxmQ&1d`IQ00xsm4};BgI_Ol3J3PK6bXZ z%(cR5wK0Fyno$f^mmK748b!-E=cb9U!Zp?QKHtdhzKA#+QWZw48D*p?M9FDs1dT11Mkbdg2_{sx^}QA?=p zQZJvXEUAQNb1JK@jYP`ZX_U2eajCWQBjoVgFZAdbMAOpL$dL@jIVMV<{5AkV?MaC= zN-!9y%@z$QaxSi{RK`)~ND+HNL?b!Fx2^53(K z2oedg*(lec;-9kG(!!fafzTntJD(%qKK>O80*{O*OoC_Mxxpju)eS8TmYSh+aB#OKk z(jCf+MfM9Xo~xJ^iFIVTYz}^Lu?dkEg6iJUOwvr$O@&HO@R7;+!)}NpNEr5kHCC9M z?Hvbg0M+H+qSdN?4yRwGZpf+gS*_d$IR?$anAY4cB)9Jne&bLhw{FE>l3 z^3rCqOILMWQdQWrI?So8gluv{FjyKAD`4~rScUm?mPe$b%3K-~D`W*j3R?g`W6kHa z@(n{4)1n=KYv0-)1-Nu7P|CAjN=wtO0T_7~ClXM+Z}$~k>jO4{sfhcF9M~=I>zE6u?AyJmSaz^!I~kW}CfQ@)%_LLy0XzoZ<-DUu%` zxf;&FVT>|A1cT!9Q5Zjjh!}Pd$vt6rxZ*>ht8Dhw5H0R>oodeAWFizsAQdGHMoC2k zf-W^}LUQe-WuzPJ0QVd|jK_uW_z(^s2F}~nsxX);ES9>4Q9p{sGUb)?=(lL}8#D^x zEpE$;p(ylPi7lvJmHEDk9fYJ@*>0HtNy`5aS#WS==3xab2wCEZLH za=Hujg8Wla6Z_CYRBriG1?-PUS@kPGx_SYtVTF;7{a3$bV8DHE2mbF*=6nLW;197k z{(oxcSWe)aqGe0nfY^s^DB;9jK017Xk{VWwMnOi9UcUl+K~e9q?2QplzCNex$j^=q z#T_oY%{g7CkRmRg#bEJ`Wco!_sG#Zz8hxkAr|J1HkAxJurLOE$5W=qdKBJV&rM>=^ z){|fL7>&LQ$FmtszOl;x$~Iat+NL{Qa{1M19WK@qmo_;CvfSxv+$6$-2}S2mmB#bA64x22d*{j>D@W{vkkmPALm3p8QMo+WTFf6gk#@L@1s2HTZwl?jAaDRS3? zREtkJShDN)ZLhYS=FSh!M;`p;fL~&lVmkVB`a3XEiQRud-HSlVsW1hMDn}xE?Z3#x zw{MG{JQ1x87C)gUuL^oaJQq*|RPal3^WWLFF+w}L%kyeK z3wDL0aQHDe;ut!P?m=KE0)~h>SU400&l{E8**788Ii{P;K0kS+#&=Z3sr&t~_u=s6 zu&U*7`1^HO@S;nKdCetV6%kqmn@o6_l1Ui-sa+Kn5ylJ7eg@`Ell*bZ*($4&F)fnv z-=C2JrpB;G9>}SSbj0fh@4$qt8L(7&he^{5DuS0I|dV+fXewLopOn1))X{9CvblN$GVN%q5|<;OJ6^ zTMU|`IEohwLP0N*uzq1_MJ}C=O>-bi9*vI4fJb|;}PdJ%IeqMvV zMm@Tp$(ea;;=Ii`A0K@tD}3A?s)3U^vaRP@H;KN}lj$6Jr<*MHF1Gf}l1?eBtQ<9d zCNu~qoT=3}?%&Y73F-h;L)&V|G!;PVeS9dw1xh?_H;pgxwh=Bm$ zJ71SvJy4&B#}e`SIx95WXEiAuD(fJZJ7`roOiK8LG~>46?%A0G$jj-c!P+L?J8cJ% zzZiTXJD6CR^AUW!W5t}z{AiDrF4Iq`pE_C)Ym zY2k3lfr;*FUCyX(MU^`ZD`=yu=yr(9m~H2AkQL{>O!&$i+%b6~13pjcxMn<)G-><1 zvvN9Qcwy-?Fw2EJKqVNID_#)Q3MiqAItqadJu8g%A zwufmLTLY*7pW)%IiSd)KbvHkz{@Y7Gdi8wF{o@>j(>Hp&5^D>Wj4i zmI@QqJY+O(gnx8tx#$qfjK@1dx5xs;491oLgI=S>wj=|jWF>cU1ye)~AeeFJCwwUS zheY0w^Fj+f0!xw3#gLIufih%ZTj4-FOWmR}F2I?^MIGG(+k{4p24sII|w6V#~IQ)lO|Y%4la78IO{ej&>7fakG$(=1>0$Obed76?AMBIio&r`ia5|Il_rTDto+(xu z9p17yst-yEtz%-;$yyr{N)6^4A{De`vG}3f%9=I>raxnOf>!CE1mY9Xj1)GfpF-ZX zQV9ls#FS!^qv{jd>0tP1I}|wRC$+X~9p9Yl_8isi+<=E9Guul9fdsp&k+K&pVyV&gM{yO zvlSJtLQShN^KA1hX<@ad1@F7JqhUc-i9bytYfRzbtE>vhi-!ZBVS`X!%QTyrb+SbzwTl`S$q+ny9aDCR9WjVQ z&OJ)td!Oir%Ibn^<-+TD%gC9v7p!H<)19SQ9I|0|DFDPg-H5|v-~_1Le}3&D$og;` zAIWNh*9~(UN?yNy*YFWQBhZ6G1)m<7d*oyZ;QyK)G&OWVF!y)Z=u=*T05}mCLU6Xc z9zqfU;2oox~kXkPQ!+US=t~xn37aS4Jo!MGuPLdR-`l4#vj`qU=QM_tTNjk?eY1K(HIG z^KAGI#_u9LI}szDPI*q@*XshA-*DTXyo2$!hl@n@*)6en@C;-CgoNjD2Yt!w!-Wa% zWf>F4pjZ{>c5uG)%i@C(%y?X`R-!I67}lXr6~iwcew07s55R=6t^D=n91 z(FrI=o5EAbz&fk|@-js$tM*4b|8E||5o`Lm>H7Tu`@ve<3e|eQD=MDE`AC`H1m3Ts zczoUTC`|pjCg1zPESia~N!^skdE#f;jQ`vJ5M;-Y$qhmc9!FgOeK@bmxdUrT7&C#) z&}UuxFFuu7P47;&LEQoWFX=#fhzKZnMolzb3;VVZn%@LCr!Ad&1lf$yV!}seZ=A6g zW0&6@-FRigmC^s{FyW(fHcsDzvB_38Y3?@b`VM|uL%r+lt6xb!ng~VS+Env(=D|29 z;_@yXY7{@@$dVQtKRbpe%*Nl(JO0j{!Rd?E)2#EX@7+c2?}5)cFhJ-R8a76DV3P@m zB!<}}63={=*3^e1zwqs(5H)fJ$2rOAn)^@YW28981un&v{OkFebwaL%gdYUs861R@ zM7|Sq3=l~SsVa)H6&rcizAl^LlyvfUKEEFVf0(1&rBL)l5<@D9#53QEQWK;lHfx%PS@O9`($4us}1>A$Py95d=@o~0+AYvcqm(e1_Qu}rRQb)Gt-9SmTQ%$rh|%# zii%1q7I{*gynvMQa!Qk=S-BZ-%qKV@RnT?p;%{Iq@;Zkd$kN$^F}W{NZaa z=Y}c%$m9Q$bGQ}Rd(ol>MNUWsfSIH+yI}yBiegK_UXy^RJ48)QP3`*3v7Gr%Ehw9l z&n%3Zn)-#bP8%|NW|F+me)ly>v=J|fjB$b>l|_3-A_+=RNo zYopIqfCiw;uI74Mkg>hWj`ig=kszjYB1dmyrzLMk#d~2Al+e^=%n&n3A$HI3 z5*glgv7||2V{bF`jtHWOC4o4WIi*-di8`r89CMuDl+Sc?@^w9 z7KXOTF}#5xU>e3rL`rNbM0$SNP}*L$QC?otlT1Szoe&c6M3d6Agn)+O2OcPtt^5wc zlNnhNWmYYVXwR6L_;kO;jr!L!1bZLw$FcU=-`){HG_fQQ$6S`Mj1&%$!x8UG)tE?* zR;1URXGDZ&Tukq=pBEz2cpxB7%nK(tk(>zQ6gNmu1kogTVJdpM|93U&q)ut)G~FQ5 zkitSoC&59YmT9`{Ch>_29*+Reb_TC4!gyVy^{#nlfA?#*e}GdEAdrMy)+ z6;)EXAJ0B}r<`jw2_}avDmyx&sz;~T#yPx)2%`roj5mP4B1F%$oSWYFtoLCj&b}fi z{hp^YM8O-|LFuo1~u zC%^Vxs3PuoVnDLyL{CePI+%CVh7jT^Eb}N)Rt2)lmD(|11!7h3Ixy?9ajRndSDE3< zv%9OwUgiRZ&weN`rh+QszLpoFp%)waG?Wfa+2q&WD=WgAoVdrfEE`>T5glPzzK-5t z3vzyobI*pN!ZPwiTi#K_cN*$kO%HjOs=Y_S5<8H}rcy=XVts}?U)o8ulrdcPR#wKj zJueOSCnk({($;vLOk^U{MliML9UzU;VY2zx3Rzcjx0Dx?r`kRybH&@5(5(*S5LO?`9R;)y+vX%0SVkoF8&{V2YtwybT=;|s@ z^{)x?y{NqI{>gX#z7yrPKQ~ygKv9j4d@RL|o=zK5LA+P7V}j=@dZ=hdUTI=_#dO*v z#Z{eAX`{ayu4a10^vdbglN47geUQck=3~0e9wm;8PaIcPIS%0G6+4C_lViHoCm#33 z^_`GE#gkuZTGWk6J84@^UDc-c28EO8*VXLcOCK;W+x{ez9{_%mo06r4lq2Hy= zud`4MziZ3J0GMR}kmqyT?0{kx{9wP&`h`*bbd%Qq=z@rV^+Y*co$0cGkYE5%%-8;x z%fJ0vRRV(Vt2kf?5oB5V@giR2fB$rEI`Xy`vKj8fa9*}9RG%G=h#?>jEB*qSEX)Pg z3zEGX_g;w~`;kw+IoHMiOkf@OXTl3*rYt?xU2P>LLws*}Jhv6f%O_-+?AlqFg{})# zWg>YE1rpEAdp0yiap z0Ag3Tv!cmeiX_*Rnc5!;>u6W(#<_!vov3ui(_1{kgUL5y`q;_40=je*lq& z#se6PVO!8MX=c<%$cr1bHgdS1`z^-mw=9c-6iA%|y?UX$I-@uxDw8zho_v#Vd1+ZC zjG^bLvo@v(+CYiF)6GwHrQ}2@vOR@W4*wDwoz|+I9@G(9lx!N>(HKu1oXDkWP6kkC z1$EV^hfu%yJ@whvfjFXR1+H<=&$$Bm%t4bXp&8(yG*YOilCH29WDB8R1h2G(N2;OO>y@OPL+` z($vp%s`W2&P_NSLZmoIU-BS0wQ{=v!syU2y<@#)EMjX*}#DSe$N;v4?$tuAc;3{ci zu<@jHx3X4P?foB62byb$lX$<5YT2w>*^{{#)!O1ZdNr)Bo^>P@RZ&OwNzFjRXn?1( zm2-WzIWX1Khy~zIgw%a>s-`rZAH0w&=iyaca1oCx*JoQZ;)tdd{nk-;(D$_98?QT~ zmv;?>i^Z>U9cW%U!1f1}4!xV_PM}&>eouY2uY^OXn8l!SeYVAcYdZJjL7;bM2nML! z8mZ5LxVD{^EYJO91VAF!kku{F7+rxE9VIHIbvLG=siJp7-Dn-K z`c+KN1_drcN_DLGMp+RAPS1F;^eAm_25!(6ToF)Eca zF{>b0a7qSO35S|O-BWi;7J5VjBGz0p^`e|wJ^aNh7OX}G9IC-*(lU_LdCRb@UosTZs`(mSpy zVM%jlr_NC=htVo+aHu8PM#e0mW?eKJg<)wmcc#^9NYhq>A!SHAw6k!;E$%lbVx#-4 zBZIk_X4>W9x3m+^j_}>^-PN#=S;9NQccUQ;D_Abmk;=%{Z*R9;hTtUyxHDd!;mZJt zv7MzWC}(ppdoQNnQ_HL}9IFyLyX!{9m=6lk?PG3KDc(h!aly%A3F%{H^pK^nV-URm z{*%lts2`(7(*M_{YJ0*N>8#Q5=CQ>i#S>Mkq^@YnqKVOhcontgur*OI`2Ah?%FP>Y z8n^!YN9qQf$4A?WwG&r_lAQ_WGJL6gh}AwxIfqtoh%D7GDC(dQZCN&_6h(H(u$@RH zOV||3v%3)>(`~1<_7RfDM%>=astHbrBO4*&t8p^VXt|S~lSeUGs%%IUlBFu9ieUDY z1e_lIP}LWFCpX%#x>$knsx>uOprQ+!VzeyiE5Z|(Sp z5>`}J+)+uc{mfbO$}N628cHCtt#@ z*8O_l*N8B%Ilcy(UTg!QunV3EhN?xOdShg$YCXTZb64>p+|`KWu5%k6Dk7A-A(D1; z=%&3I*ULTsRy4YKkd*nFKya`9Gy8ss=}wJ)?rkjO>t~<0Yq6l4?9M*FiyiqtJ2T@Z z)0zHnzzqG)3l8Ms1${j5Rcww;*~`da3Dsx^ffsfGl(X}xR@(8>sIS0oPbM=xUHgUH zOzgCm{*yQ6I{=+a#!W%ID~h$ej|gn?_kcFE`Hk0YHJShvrajGvGtvMKv=Z0Mc)(hL zd6TS>jP1hgN(gL8y>HovrwD&0CVXdE&gZULQU=1LUk52Uq(vz7HYX z<*Ui~E_~XhY5JMNy@c&M?gwQ!?8kHy_yv2lo%@z+G3fea>c;uV+3*7Wy{J@N&65j| z2LAvpGD?x*4EJI9`05X(0CxuN+SO)soMviE(a0mz6#H1R>T9WpaClsSdD`N_6%*}@ z27O=XqcBiv06Hw_n%rf+>&M8%R~N#RBMK0%_z3R(J3vJZe3+)H*DKK8P4swBafiNB zmhF$r@02C5+aMVLT@Wi8x70Z~V3Yta~y<1~0h`%IQ1e6doGXL;8C5MgI zS?Wnfg1ndg*Ydvxty1Nqro405Mx<9dh@z&ed7+$7 z2%11>MRJ>n1`;7J2VLY5M_lHSJIwGwc8^l|Ac0Q|OdSg9k-5p*0oxK;ewkM%Ih6a! znAND0#laAeMorVN?$jV=o_JhN_B8J3{6z;9((^Yb2=y4^BOSDJs47WKengzry5nNU)1(h^=?NB~* z_Nt!!^ZCzHdY+qx46K^KxX>(4MZEy925i@o+L0~6cZVE)WB>JGrltzP%c`NDv2g zBh?^&7?~9w&`K2kK>ws%1-vz=>ca!_%QHUskc;VB%kGwfivQ`+9{Cv59f5E^f)jwB zD&*9{PzUM8$Xur|1UVx4M{-_4T99whtlQlHXhKH|BzDcJpkM6f?)rpY0drP;_I8?4 z&|B5pzHf^!WkO&Oq*ti0QYkzbWFugK>}%mp3Kj#|4dKf6@r6$SaFYD-y9EOaDX6bC z<-wY_?$wh?efR_0XsJF2k$2lNnp|9$AE(~$Pq>1PX!GOL^}NOSb^PkCpUeT;xtl=> z+cstZl|fu9vb@@5s||7T3gA>(gC{sXbw~THb(HPC)}3G$vC}rzaRSI*Pa->Z%{8a{ zj&icxXSQYBAna^|$$i$1cUghL_NIstfqz1!bN)kR-JwJIg(ySNfHRcei`Lc+N^Z%* zIW<+8ArlTD^d(^c-E*?&6L$EcMqZ$b*mo_GDUE_xI|H*kH~xjGat9gBX!!>a0;*NB zhpGcK7&fDrAG4ZXPu@AL<y6s&GQ5Qo-}j!b>O0Vl#9i`Vk7b4V2Bn|@s3TPk z6*gjuZL`?i7SvPf2)g;`8grEvxc&BC8ePv0S9tV4`OKPK8{Z(;MNBm@*~{3AUzFD? zFC)E}pWzFxFZ8kUg?I&T!pkPB$Mo2mv?>ROr~^ttQ2pr;;hRS>tA7_ZN|`G_Atz4;Lrw2^hMZT0nj~vcOOL| zaV@)R?`Y<+6!%J++oq@%U{AZX$v00nneFIrwl-t#^y1T=QJL&&=Rb0zgNGDa>_FpX z*6z|ahqK$R`PZm@6>~1Y@30jR@DkAh7{hy74!+uV9d}j$z=RG%E1leVzRmaf!JWSv z9e%?Gi;=$28a-t)Sfm6|=aCTwP4@{lM$w{4ujprtZ-lbg+0?Ig+apd>f#FBVY%>ss&qIFpQwIVg;lcv<|uw3x>`eL)gm*+IftII<=5ElY3|ta5hBg z54omn+5r?KI+n9W}vc%8IRgb(coiS&7~($E?rg67dJC-Q}co<6zFfq$qw1# zmMG;e)kzA=1Z#_6PZli&v{ek}0|u&fK@zJj=V#s55VQT7zJ)d7{l_MtXBbu6F&7MD zYFZT&tyT|wSj&U>M2Sa2@WKed(EeG-Jt?jOl)z2}$#;K3%k=CM4f^Vxt376eFB4!d z9wb0=UGni?lp&7}BQ@GBJ8yP*(EvRm)Yh~lmu$xiL@R?fczf!0gYgD=+e0yk4Y(sY z{z^ig!{cb{c!3n7i~%9jq5+thnhwOvk+T1uay1>Y36;;29SU1Avjs!?VLY z!3RFQNiS~DG6U^lNKyE9hBbh7I+PzVhh~BcJ@~)s7#d_VOAVWBRT|;*A3`5-lVlM( zkfcz|Xgzl;-zaG13!2}EtZ`FtmTy`{WZNJ$iUl1x)=(h!PPwWNu%KF@dU;S+p!_+C zYLy!{l}@XU%yJw}HwLpen0hB^c8O9hTHEG22nz3$70tWt_^mzuxoVof3+q!oz@bRO zs7V}HZKk)R*<{Oh4MIHEfrDV?-BmlC)Zk&wUdLav@9y`qWJfy2oRqQZ_#g>yZ65|oN46)_=W0|vKu)0o=GtwT(f9E`k zu-s+EVF3YPnMk#3uNK~OTDbk9>>2OMphdnpmq#Y|D{<7rP$1ZF{z`?xs!q3I#!(D3 z?IW0B7};5hE_C-8m`X7d^n~F2?0@a?2QB%p>jr`EpUxt($$-{k6}F& z4aeSJ9YZ5Faifn(S>2DE>r<`^>`m3}$~PD4oQzVQwwLkM>EXnM)K9)ZX=hDjf1+t2 zi6Tl7!NgMfdAAd%+B*_D6ecl;jM`{lvhQlX#OaYO_N9Iy}3M{#Rbn76{2QrAboq zS4t1oMz_xtRuB@|4GYZktxHsGrhfiRF-7zR`PG3doeWHp3tz_0uNOR(og4Ek)srz}YIH0xkgb{f0) zwkE+o$%tGNnbDG@!NX|w+vC>boEEjWw6Dh3SH^~_g2>tnvZaP7D2K^Z+QF^1vzF@Z zXXwY1*-+#RDKg=TT(M0YqJ|dZ#oo_t+qJ?P#o{SnxGrj?eSQhpnz*~)a9gVtT$>bxue)X$BN2@gq&aZ_SuBxYb zclEK_d9YXsy%u@m5sem47xXAfp3E60u}<cia`2$Rj}d;sD`de@GcoMiAA;BP`{OYnULAw-apE5sLId ziLmww1!`CeO^o1~B!wpq?{Pi!onM%pBP4kbUKQB&!B9wO{Q+|&3j}Wy z9v{JZE@QJyh?zFpoTDh)Si~7Sbce6 zV5<@P5+zDU+^GieJO;Qi!2I7A^vAC?l`(^c&y3I{Ra#BP$#>rW{J^AOAR{DT~bCG*R2l!(5 zt*&v6NXOM+f)55JWKrKWn-_%)au@sFeTb{XR=Rwy8G1Oo!$>JJx};eRnl<*Bceu+y{S7XdF6YfygAX91|B3FDqF zgqcs6AWKF?rjaadVd^H67id43yrQ`wO(-O%g+iLYrMsswQ_be284`^7<|8o=GBP&c z9wnW$9&#$(ln(I`T(`5XU+w;c1BCH=Z;1i&@f|~zE#mTnxPi$wHr9fI^$F(;i*vHU zGgqwk@}q`k`mi8+LR>T|W48&bb!a$bwqvfg{f=`T^~$rG(U&a()cfN|w+AOIsWb$i zED+^k@x~jSl8_hh(MDgRTTXhIYRv8l_Msl9i+2CK7$%Jh4^_{z4s4PL8tUon1C9*{w;Mi^oka4deF*@Zgzh!2yX zxrqRrPlu8_w`q(b82vOmVHg^I#$X0^y8 zB6vA;?d{lWNk2S@&qMpbs|~rXT)#uMd|?L4pg^m{>5uMf|Rft-qcC!pj0J;dDLA1yeC z894Hx3#!v?e5s8`A&cE^cgkhP2NQWS*-(ZuuU)d;zU)i@#&C#F_c2|Xt-RCu!uAz! z&=#3a@`2dHH6P3~e*;|TkJ$JBsZTd5YUjLhwNAqiX9ItMol-qy@m>`_&QCl5dyk194_Ta# znChg<)5stXGdQTE5TKyIb4%@ALTF2z@!~-=Am}$3Ay7mFS4J#|2|TmIMMS}g{%V|U zs5&f)x&$`Vt==EYC0%m~Q; zg#2M{Ozh7wA};O(LHBxf;S^Ba{BdMK7glE;O-gS&ucmCt zORr^&o+-V;JwNh#mu*ys%C=m18|W4`HW$GavqT`e)k=+R1PvTPV0!DD&CDXRu{R$eYwkIXVfLYasjItOG0BdnbH z6MUAcM>6QHP!F>_a*40KIze>{A8S)2l9i#{3VmwpOGyPhTz9{G1HWMY?ELU)!q@XC z{l?L7Hv-1$Q^xTS|3ieQ6-L0qUg5w<@OGq$V#}U&ku_5S-orkz!%`RjWp`O081NB1 zq_)4x3oCt(>j_EDp;o!=v1ZZp3N(qhI5LDM@+@(cnYb3lv*bTHp_=n51}uNvj(yuo zYk~R>%p(%#h3cP}V7=?a+)wK0_zBUHcCT+Y^>&Qg+X)|uv2=`ai0_&d<2$_65bxy% zwohSPxb#fjezDw1WN;D=z!Y>xaY(WXwz7eSB}Mv0W`=pI_Ib@}@&tHx6ZMx}yZw((gaeT0$HBm7SME9BI?UFmt{G2&&Cp*r+)v(`+bS)cU@VfRoj;)a zw;AZLdV*dYjyE7yy2fvgN(O?7)8Z%IM$O6JFoKSWr9kjA#2{H$uI%3qHJFUuPWNrw zh~hq|MFYZTETE~PD+~W)h^vbReOUh=5R2McAt=TYIo}oD_ z9NzB&Xt*(X=T6_S<5f8K^;Lkuf$qF5OfqSNW2 zwvcUFwgB7FfcoJP)7hY}f@a~|xG2R6zDx-w@|eng!fX+PS6gc^8s?2nIAr}uL#$)C zsw&X8p$^uoq|yL^!9fbwrxSO&vk=`E1y!8$b`9d-pnelF^=q0qyd#eBxZPfQE1JU@y1Do`7k9yt4c(i_&cCQZf(YS4e_cDK;=UYEE&QkTJ#VB zw2zZaq)Z}3S;tQEjSZ^uvzQ^EWH}IBeM=VnM^WG6kF%p+*kOcW7!&zl1mu3zo;vOy z??@Cc*`c;B`mC5OguDrD*4gYtu z9EH7I!I2bGUOq5LP4BxAsIj`h-zc}NID!2~Uup}SxMMamq+lS6lF_cvkoA9C8h0g9 zMr}%yJj%;o(ovJtj-&jfXQ~KgjOqn%IoBs$u;l?zrFMpZO8r?oN180|+JyQneBc_n-YnFY|(wQVT>R4VvX=5N55 zCR34!b7D zQ$RGlS7ExVQnL&P#%qu%Yp^~t>vv*{C|~R)ddOGjrx{_$6Or4JHJd>3iWT=pp}g*G z`EAyl1lTR1z_gm`-y0DKax-FR$_qVA+%JPRUXt-r56ez>-n{TKkB_srR2GV9p~u5P zX~%CGt2A8rD=aiAki+0JqsJ!J(lrvt->?v!HBuqplC^F9DAMU(k!Pn44{I9s~oP zu6HT&M&-_6R#A0KmY_OpR@meruS)e#lz4pM_41J|j8^IWp7ul)Tpa8#KiNfj{8gep zXkaHS`D(U6h{?yEXCw%Y{p7`+T@cLJLnQR&Pf|K1+dfrg;TvDeA!8b5_UAFmtVJz_ zJd@@9uWdu1-O9jJ54Qe2e&Kp6cIH4%6O4Lx_85VNs`ZBPJjO)cjefI^4ae9_eaja}{@VM}9azzI@m(?`+x-pEMA)79nxMvTi_ zwT~&Q?-;g`5;GXgswaeL?B?B-9pz_J2TsSo8Yx#hwbT}~%x9}E6V)Q-;b0ecA6bs# zUN->Owm5^KWD9w2n`DypF$>fllMZMxvNMONEsc|&=M6^4q{oee@31DVJOamDcTqqT z{=Yd`HT(EUF@JF9yfBH9)e7aECxcqKyv~Xfqo3U;b#6O`)nuyt0AG+UdUd&nzx>Ra z-pUL@Ej$c>207soE*>Bd@8=fDHy#4RznC`k34*%X+NcGjE^&zS^KlG8S!2R`Jlqf= zWlJ%#S-nm?$&8A2vR?TzxuRRACl?t0J#YbYmb?c;q)0QBd4W*8VQfCAnBmUeV5T7W z+xBrH{OOgChbRpFr~DfHXLUi_vRj4`}I>8&gi5YKihcA>6hMChuj`8T?^LE#PnLq<-k=exnE3CnCw`}-r_H>a-5+^ z8CDd&6YRZnTE*RaX4{yq3MtiK)L8c~YtD}~z6P!5((u)VM6@HnEq=8~GmzC9A!6r{ zVL_IUy8g6Mg%82;zlC;$*qT8ps|SWbDOzB?wg%f{Hy^yy>aWOH>?YzMdDNJ;cncB; zV`w)$X6J1x=a*=%xCqwB6@M4_3c};#h){iUIpm{hi_1m}7oE0aGzv0EJk?5X=khlH z_-VJHG4N~({&Q2RC22?Vb*1UoUWOoR>>Ra7gBxq%V~;r3V6dF@z?R>aBIY%s_*2S*d&>3g8YQby-XV zscdjQ5mn-l6hn_TVm}O4p}e&!wKXd~08xBJKw|}T6cfd79_LMC%E{;@URj=sdKjC? zVV>Q3M2CuS-Nee|Nvb$i^{2V=wQefS&~JGsMX#JWblVNXImbt%L#BxiJCYRlms{%( zF;!)T)egO^pS^X{RdcRCib%^Cl7B$WLdFZki4aP_Um(=b1X*5Hfn*B-x=Tu)Q$D zLAUgM99SO49=v?Q(X4m_^y9~gpb}|Ga+jU|g^E~^f%c-Y2xA>Yl2|fWs9tZg211*Q zyq__1Jpcr<1~W``3VBz_<+K3i0;kk9n^Q{Av_wgd{>WmJ8(^kFdeOnpC&N)lC!u4N zuK84{^w4y(KKj_>&QP}VzH7#Av0sHieQMv2Av?dCy$(=hfWy2bo3kCE9C#Y{Pn9a| zqxG>W`s3$Zpo`$ap%%O$j>i4Wg9TZ^BOL66k;jHCqmxsBM@fbMx5E9dg;ro_twXrT1n0(PNL= zgyT!2=#l6>Z_%8ur6|qn7QJ5AK_)#+2xV5QnEFK&sslxOO=DqGqJIZK`O> zAy?fR27<>7KcRB_A-h(%*m2xU+bUP|;+`<^&Z~}XT;?ZR(JqorIRNVZvk}cqq>mI3 ztT4A6Vfj%xCM%w0jiPO;q&WYWD6NaA} z0_7G2?}$)lucJ?V8K!1RvC+amfagnIvhhtrqvR~^`yREF*OuSCub*$8F<|d2p;Lk6 zmcTtk5hh0lRAu2NCHT(_J9sI%LWs?o&`ioy@rpQE3wouT%0v#2dxr-Lu0~4fAe(0F&Hyp-&_yU_C%u6Tc*FWI z(7cObe?Exp;lD z9j-8{#(_{gl{Mp1oqlQPXrULhGU}ySj*Mx&P?ucgtex^z{~Tra3a{F%mc7LWl>z@X zBsHxT{o*U&WvF~LlM z>7eCC_7n`qyp(l3lYE@;?nrX#%UUu1fxN4_i2Awe5(!{pPK7_tz_~?~q|FK4{ej&0 zOFwMNIsDwnE=>a_`Zy=(qA)O_uo^DLholpzA)ND-VHRfcXEWk8MXVSOL5`(EC3sjM zq>IH1LWP)p1MBzU`tn;GsH=SoOdmmJ)0EDOUk`}q3|LsLw;c~%mQ@#wT1Grp zMNI1}k%780a1UZrGPIvSfJO?$t4ii`C12wpZdX@4bJOp#6koQ4*DD}O;$@1A__Ynq zAR-rm^A0DOfPpjs>>z8uSt52VJ(}|blNWZHtrP^pm=C0l@sS-u{tPsgue$0QF;Fds zaMneu2!TXKHK*=VR$FYd|Nef7lkQmaY@uh?PIbi8HfXzH+V<(WMxFC}RP!}c@Y1O3 zA|m1L2;Q}854vYe_aIf0)`7c6S)j-e$MyN{*WPCxrek<>dX{;V_nBUOF@Sp?Y$xz6#<=ospQMXo+8r%!Fe-&ch-C0P@Mnh? zOWR2-UglV}anVrY%ZzzA>sA%Lw3x{9B$2w=kF&{#3UP`vHedRdw8E#fBykId>#xfyi+-f&}b*X^B{m)ERjIj3%1ZY znUd3*k^CNFIh4MlPZi04y|dEdyaz4x~-5kO6;dm=*-x*D&>*A ztGyDO7?oW5gUXOI+B&AZQfY5A4s3w!H<&mMIJy!>G!h1nru=V`@@Q0I;yd|eX4YcE znyPRwOP=j110-WOT>h{9f?Mjr2i7SWa_8_DeQ;ZIY6JpNpf}GKk`dsXCr!Bujs(KZZnEEIM)a%5rGqokssT4YUM-U8@mYjD;n3NJ`~qN6gAjbU0g5y?noKnaXp-l>!}gYhj1oZMPlV1^8R%+ z7r`R@fy>P2*h3s7xq=b-aePx#VZM;`MeAC?`~DO~>_o#k8UCJs`A$7mW4ATD^nnIn z0UuHNc*-qYk)=8z%mSo$_~9gw$Fi~ge#b#gq4%wIJ)!&Nra;cJxy!FeM)UJEH7;Mb zZ^^Dr(yei#;|9s!$z)5tV9w^Bg9kr8P3-Nj6rUoFFZ`-x zB+M}D`LCs7;4xsshm))r^JU7Hv+S6SXw#?DZ007g`0(d6d%juPHwX{jo4i{IWJRMf zY4&y!&r>~kb?G{`_q-o^@fp=~KfE4a=oFVs(^U8N1^h&INulIzPwHC$ws`J;K)|37 z3AsFM-eLHQuKr#y8mtWHmXc3ek7ldmJ8k5W=DgnTKQ0r$9hH8j)2X^J(tkO1ieuTm z{y1D>6vw8N7|7RfB}6S$X`CY)H)2i!nzjLnE+f+Mj2lL5`AKjv4L&AadPQi_Bf^7$ z5rUH^@MUs!OP3GOB~x}yTa%z3BZsfA10`!8TEg&g))^rq7%z(wBIIh79DE_NrU4IQ zkEs4VCBPb##J<}QR(6F(Ub&WDTDI=@o$@Og6vlyP4i->5$ImA*}?W`!V@x@F9!g+G^B#8l;e@)Fo1lMW86X8ljWzcVLqKL8qa zsxw&{*ZT9{?vRvozlv)w%dcKca?i|npN@O4&)@x{EwtltBxE(!6}c5=JoKIZ)qDKx z6Hs^#V}eOTJ2!bLJXPIo&A*It{O>-D0HMZ^V@|=PR^g{!qNyjfv=d_%+F)?*hG;IU3yx?G zn^kkPBB(laPx(%k)oP}1v`!1KIU-`BBZKJI0S>T{GLxc;aO^%d0wLUPi2vD;#(x&O zfHF+0w9LpdUG1<{pMmNEw2PEf2^5VR7{G7a`BQasi2H0LlQok~krJI~rorisq{w8S z$0Ik1m`b>!_ijFbPdxG13cSvLY6)mWmWG-~i|B8CJD+*G#xqg zu9UdFeEhw?`+oj;d-;I#eIIh-$d_0F`ZdLBf#y6iexk$+EB&J@;0;=TJX6iFL74}g z^JYD`xVbtxTK9DVV@jPbW$qMVOtnk3ZjInCidL>3VMdm`*z@La%E2TUe0a}8Zfy}>a7{E#xNAr(H{W|XL-Ty}beqos|RdoqnPhAVb5C*a4 zJ>6ZtUOwKhe_oy;B3X-K5vp37=Krz1bvll@2Dkmj|1tczyYS6#wg2CBgIAti`gTbc zHeMkFg<(s0ME{PVs{iX_GQzPdy|vr^eqgAwG9ke?Z_E~(iWJ9Ha;Hev zhyj9VjA~Us@6$0!h5F&4D_3izkP7-OdYUr6t>u1Y!VCI%S3%zsYf~Psyq(D3QK{wLT%<3387VE4e7S2Nu45j$Gec0r~3=eC0M%Ad_$HJzJzV5WqU=S z5pbWSo52p#AHT)^r({;yOm;ETHcoU|!EAw4GkpCjqTP081H-P=Yq3jxUMu%KlW%d2 zjH2Qk<@>6>QgB%L3j7G@!VUL8ZYIlK68L+!o1jN=SnmBqV5c9AbcpB2AR2hdCkmI< zvTn}8EdpY8RkobI*_!mYwp>9W_V$T#bqNvSr+)!x7HYEsPl#LM=1uFJkTI63eBuv& z?_zI!3{Z~YTe47^5jTkKnCsnUjw+K@(#Y@qZ8B{|GI{r+bIniPL8<)Q-OLBts1cgK zb1@L#?HH97Rn`nXO^OCpmN==;I8#3ua_6dJ|NaKn?%cXpYyfd)Gi>C&l`kf?5l;`R zbXh`+4^@_2Z!C&gd!1isgCy>J7RhfcD37T>r7Jliy%BMzQX2gSvRmVjFw$5Ze95C) ze8DnH)`{t5KBOW=d{?rX%`IRI|+EzA@VJb$ESnb5zkcWpiDNe@!^ zHyfROMfY^n2DUY_gbQ~EVNgyw39nTWdBd{zpX5Tfl&0_G2}X&PEx|eD*+v!#=aQJ} z2Dnf*>y2?X@QeEu3WxtLm-5Sbhe^f%nd>e9w}J_4B8Jxi4uf{CPH%sN`48k6{ZI|; zB-1z9#^knn)74Z6Nryw(t#QlU^yhMCCH+7)xr0U>hm@-RiHby7WzbUk~QU{ec5 z`(L~-J|=qfl6$=D9?c*#dfD=7py6)c%WJ;zo{VX@cw=>SY`6KIUh8u=jpc-HXXpoQ zOEtmovo6L+G4pllqq0Ry!t^rYU>IDPNg`+OJzNgw1-ij&eSw1yXL3#OhQuSOXkS&= zEpuo0H?s~T{+rc^(~_*V-sB>-Kr3_7DLo}KI@v_$j6IY*-m6`k$m;%!(l2I?W3?N1 znVo6ki$DHaMzX$?gww}$8(CeM0YMSgqwFaeqC%!^G0Em)c+CUEx_H5DZ6nd6=yxX) z7mre+4nOL%_#a6ql$&5e7G8UcvT%?Rz| z6R7nO2jiT+v={ps5Ze!t!y{2YxhsUHUSMK3!nNCV^(}9om|Q`X0DaWs52TEjJgv*# zz^9|?2$k=gdx$vRQRs+g)jc-4r?;B~5Lg_LTPAAdJOx$M)*`XvA%U{>XD?tI0*yA4*)3IBjAHf0AoNp>?Roi@DVmh1s)if2j_+aroMgRi%P91 z_o3EvF9z154d{ddAP%B~@k0Uz2T(gD0H}>$g6hcvZ30OU2eq(A;$KIaIu8GNvp^7dEJ7Z=dRCzjhZNeKJW0D@~%5 z8fef$JpTFHDICssr5FpHTwMa$MXt_aK%$alKjG(&`31YfO%!IN=Hrxy>JJq$dNv2R zXY5|*sqS~LcIep$C(5}X)h64=B%3wLD9lw&%v(?AmaOaNe4wHV7Wp!EfkirpXieaS z(P&&Y$()5cN%4V?uoJYLa45#hj=cRVhH`~mr749P1}#t5<(EbKggZTYsg=`naKlD4 z5Q+LDd*8$kP4$iSXkBD8Sh3)|8DnqpYD<8_!TL2`;?L@&h+;Xhh=guKgZQhln4aAE zdpstt&3u@&pb26QMEsO#IH(&=!#YH+Li`}@{7$m$@hSO9Zis{fFq$L61D|qKl=zdl z7Aa&Cfn~;3O*dnonFvbM_9cIWw1}{aQ^hdZmzIaE5DL7Ut01mwnT*+llPe}y`xZ>} z3bc6H^j3J)t2x3&W-=a2dJFn*9~BE;y!YnR;IaSp_HYy zVQ%jXwYtmVb=`zn|32sJ_{`-gZoi^cSDBlrjTMe}m#&VNj^mU216Lr{v*6ZOD`m0LVlnshK1U46f+ z5ZCJ^*|d4%M?XZ>kC?Pbg-jcay_(}H==W<4LGtb7;d^ceQ|Ic8z zioCnKgr%EdpOlFvvUbQ|(K0~sz_BrMaVZ6)Xj&^0Rz$yE4?G-pu$&GL&0/g, ">") - .replace(/"/g, """) - .replace(/'/g, "'"); - } - function r(e, ...n) { - var t = {}; - for (const n in e) t[n] = e[n]; - return ( - n.forEach(function (e) { - for (const n in e) t[n] = e[n]; - }), - t - ); - } - function a(e) { - return e.nodeName.toLowerCase(); - } - var i = Object.freeze({ - __proto__: null, - escapeHTML: t, - inherit: r, - nodeStream: function (e) { - var n = []; - return ( - (function e(t, r) { - for (var i = t.firstChild; i; i = i.nextSibling) - 3 === i.nodeType - ? (r += i.nodeValue.length) - : 1 === i.nodeType && - (n.push({ event: "start", offset: r, node: i }), - (r = e(i, r)), - a(i).match(/br|hr|img|input/) || - n.push({ event: "stop", offset: r, node: i })); - return r; - })(e, 0), - n - ); - }, - mergeStreams: function (e, n, r) { - var i = 0, - s = "", - o = []; - function l() { - return e.length && n.length - ? e[0].offset !== n[0].offset - ? e[0].offset < n[0].offset - ? e - : n - : "start" === n[0].event - ? e - : n - : e.length - ? e - : n; - } - function c(e) { - s += - "<" + - a(e) + - [].map - .call(e.attributes, function (e) { - return " " + e.nodeName + '="' + t(e.value) + '"'; - }) - .join("") + - ">"; - } - function u(e) { - s += ""; - } - function d(e) { - ("start" === e.event ? c : u)(e.node); - } - for (; e.length || n.length; ) { - var g = l(); - if ( - ((s += t(r.substring(i, g[0].offset))), (i = g[0].offset), g === e) - ) { - o.reverse().forEach(u); - do { - d(g.splice(0, 1)[0]), (g = l()); - } while (g === e && g.length && g[0].offset === i); - o.reverse().forEach(c); - } else - "start" === g[0].event ? o.push(g[0].node) : o.pop(), - d(g.splice(0, 1)[0]); - } - return s + t(r.substr(i)); - }, - }); - const s = "", - o = (e) => !!e.kind; - class l { - constructor(e, n) { - (this.buffer = ""), (this.classPrefix = n.classPrefix), e.walk(this); - } - addText(e) { - this.buffer += t(e); - } - openNode(e) { - if (!o(e)) return; - let n = e.kind; - e.sublanguage || (n = `${this.classPrefix}${n}`), this.span(n); - } - closeNode(e) { - o(e) && (this.buffer += s); - } - value() { - return this.buffer; - } - span(e) { - this.buffer += ``; - } - } - class c { - constructor() { - (this.rootNode = { children: [] }), (this.stack = [this.rootNode]); - } - get top() { - return this.stack[this.stack.length - 1]; - } - get root() { - return this.rootNode; - } - add(e) { - this.top.children.push(e); - } - openNode(e) { - const n = { kind: e, children: [] }; - this.add(n), this.stack.push(n); - } - closeNode() { - if (this.stack.length > 1) return this.stack.pop(); - } - closeAllNodes() { - for (; this.closeNode(); ); - } - toJSON() { - return JSON.stringify(this.rootNode, null, 4); - } - walk(e) { - return this.constructor._walk(e, this.rootNode); - } - static _walk(e, n) { - return ( - "string" == typeof n - ? e.addText(n) - : n.children && - (e.openNode(n), - n.children.forEach((n) => this._walk(e, n)), - e.closeNode(n)), - e - ); - } - static _collapse(e) { - "string" != typeof e && - e.children && - (e.children.every((e) => "string" == typeof e) - ? (e.children = [e.children.join("")]) - : e.children.forEach((e) => { - c._collapse(e); - })); - } - } - class u extends c { - constructor(e) { - super(), (this.options = e); - } - addKeyword(e, n) { - "" !== e && (this.openNode(n), this.addText(e), this.closeNode()); - } - addText(e) { - "" !== e && this.add(e); - } - addSublanguage(e, n) { - const t = e.root; - (t.kind = n), (t.sublanguage = !0), this.add(t); - } - toHTML() { - return new l(this, this.options).value(); - } - finalize() { - return !0; - } - } - function d(e) { - return e ? ("string" == typeof e ? e : e.source) : null; - } - const g = - "(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)", - h = { begin: "\\\\[\\s\\S]", relevance: 0 }, - f = { - className: "string", - begin: "'", - end: "'", - illegal: "\\n", - contains: [h], - }, - p = { - className: "string", - begin: '"', - end: '"', - illegal: "\\n", - contains: [h], - }, - b = { - begin: - /\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/, - }, - m = function (e, n, t = {}) { - var a = r({ className: "comment", begin: e, end: n, contains: [] }, t); - return ( - a.contains.push(b), - a.contains.push({ - className: "doctag", - begin: "(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):", - relevance: 0, - }), - a - ); - }, - v = m("//", "$"), - x = m("/\\*", "\\*/"), - E = m("#", "$"); - var _ = Object.freeze({ - __proto__: null, - IDENT_RE: "[a-zA-Z]\\w*", - UNDERSCORE_IDENT_RE: "[a-zA-Z_]\\w*", - NUMBER_RE: "\\b\\d+(\\.\\d+)?", - C_NUMBER_RE: g, - BINARY_NUMBER_RE: "\\b(0b[01]+)", - RE_STARTERS_RE: - "!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~", - SHEBANG: (e = {}) => { - const n = /^#![ ]*\//; - return ( - e.binary && - (e.begin = (function (...e) { - return e.map((e) => d(e)).join(""); - })(n, /.*\b/, e.binary, /\b.*/)), - r( - { - className: "meta", - begin: n, - end: /$/, - relevance: 0, - "on:begin": (e, n) => { - 0 !== e.index && n.ignoreMatch(); - }, - }, - e - ) - ); - }, - BACKSLASH_ESCAPE: h, - APOS_STRING_MODE: f, - QUOTE_STRING_MODE: p, - PHRASAL_WORDS_MODE: b, - COMMENT: m, - C_LINE_COMMENT_MODE: v, - C_BLOCK_COMMENT_MODE: x, - HASH_COMMENT_MODE: E, - NUMBER_MODE: { - className: "number", - begin: "\\b\\d+(\\.\\d+)?", - relevance: 0, - }, - C_NUMBER_MODE: { className: "number", begin: g, relevance: 0 }, - BINARY_NUMBER_MODE: { - className: "number", - begin: "\\b(0b[01]+)", - relevance: 0, - }, - CSS_NUMBER_MODE: { - className: "number", - begin: - "\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?", - relevance: 0, - }, - REGEXP_MODE: { - begin: /(?=\/[^/\n]*\/)/, - contains: [ - { - className: "regexp", - begin: /\//, - end: /\/[gimuy]*/, - illegal: /\n/, - contains: [ - h, - { begin: /\[/, end: /\]/, relevance: 0, contains: [h] }, - ], - }, - ], - }, - TITLE_MODE: { className: "title", begin: "[a-zA-Z]\\w*", relevance: 0 }, - UNDERSCORE_TITLE_MODE: { - className: "title", - begin: "[a-zA-Z_]\\w*", - relevance: 0, - }, - METHOD_GUARD: { begin: "\\.\\s*[a-zA-Z_]\\w*", relevance: 0 }, - END_SAME_AS_BEGIN: function (e) { - return Object.assign(e, { - "on:begin": (e, n) => { - n.data._beginMatch = e[1]; - }, - "on:end": (e, n) => { - n.data._beginMatch !== e[1] && n.ignoreMatch(); - }, - }); - }, - }), - N = "of and for in not or if then".split(" "); - function w(e, n) { - return n - ? +n - : (function (e) { - return N.includes(e.toLowerCase()); - })(e) - ? 0 - : 1; - } - const R = t, - y = r, - { nodeStream: k, mergeStreams: O } = i, - M = Symbol("nomatch"); - return (function (t) { - var a = [], - i = {}, - s = {}, - o = [], - l = !0, - c = /(^(<[^>]+>|\t|)+|\n)/gm, - g = - "Could not find the language '{}', did you forget to load/include a language module?"; - const h = { disableAutodetect: !0, name: "Plain text", contains: [] }; - var f = { - noHighlightRe: /^(no-?highlight)$/i, - languageDetectRe: /\blang(?:uage)?-([\w-]+)\b/i, - classPrefix: "hljs-", - tabReplace: null, - useBR: !1, - languages: null, - __emitter: u, - }; - function p(e) { - return f.noHighlightRe.test(e); - } - function b(e, n, t, r) { - var a = { code: n, language: e }; - S("before:highlight", a); - var i = a.result ? a.result : m(a.language, a.code, t, r); - return (i.code = a.code), S("after:highlight", i), i; - } - function m(e, t, a, s) { - var o = t; - function c(e, n) { - var t = E.case_insensitive ? n[0].toLowerCase() : n[0]; - return ( - Object.prototype.hasOwnProperty.call(e.keywords, t) && e.keywords[t] - ); - } - function u() { - null != y.subLanguage - ? (function () { - if ("" !== A) { - var e = null; - if ("string" == typeof y.subLanguage) { - if (!i[y.subLanguage]) return void O.addText(A); - (e = m(y.subLanguage, A, !0, k[y.subLanguage])), - (k[y.subLanguage] = e.top); - } else e = v(A, y.subLanguage.length ? y.subLanguage : null); - y.relevance > 0 && (I += e.relevance), - O.addSublanguage(e.emitter, e.language); - } - })() - : (function () { - if (!y.keywords) return void O.addText(A); - let e = 0; - y.keywordPatternRe.lastIndex = 0; - let n = y.keywordPatternRe.exec(A), - t = ""; - for (; n; ) { - t += A.substring(e, n.index); - const r = c(y, n); - if (r) { - const [e, a] = r; - O.addText(t), (t = ""), (I += a), O.addKeyword(n[0], e); - } else t += n[0]; - (e = y.keywordPatternRe.lastIndex), - (n = y.keywordPatternRe.exec(A)); - } - (t += A.substr(e)), O.addText(t); - })(), - (A = ""); - } - function h(e) { - return ( - e.className && O.openNode(e.className), - (y = Object.create(e, { parent: { value: y } })) - ); - } - function p(e) { - return 0 === y.matcher.regexIndex ? ((A += e[0]), 1) : ((L = !0), 0); - } - var b = {}; - function x(t, r) { - var i = r && r[0]; - if (((A += t), null == i)) return u(), 0; - if ( - "begin" === b.type && - "end" === r.type && - b.index === r.index && - "" === i - ) { - if (((A += o.slice(r.index, r.index + 1)), !l)) { - const n = Error("0 width match regex"); - throw ((n.languageName = e), (n.badRule = b.rule), n); - } - return 1; - } - if (((b = r), "begin" === r.type)) - return (function (e) { - var t = e[0], - r = e.rule; - const a = new n(r), - i = [r.__beforeBegin, r["on:begin"]]; - for (const n of i) if (n && (n(e, a), a.ignore)) return p(t); - return ( - r && - r.endSameAsBegin && - (r.endRe = RegExp( - t.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"), - "m" - )), - r.skip - ? (A += t) - : (r.excludeBegin && (A += t), - u(), - r.returnBegin || r.excludeBegin || (A = t)), - h(r), - r.returnBegin ? 0 : t.length - ); - })(r); - if ("illegal" === r.type && !a) { - const e = Error( - 'Illegal lexeme "' + - i + - '" for mode "' + - (y.className || "") + - '"' - ); - throw ((e.mode = y), e); - } - if ("end" === r.type) { - var s = (function (e) { - var t = e[0], - r = o.substr(e.index), - a = (function e(t, r, a) { - let i = (function (e, n) { - var t = e && e.exec(n); - return t && 0 === t.index; - })(t.endRe, a); - if (i) { - if (t["on:end"]) { - const e = new n(t); - t["on:end"](r, e), e.ignore && (i = !1); - } - if (i) { - for (; t.endsParent && t.parent; ) t = t.parent; - return t; - } - } - if (t.endsWithParent) return e(t.parent, r, a); - })(y, e, r); - if (!a) return M; - var i = y; - i.skip - ? (A += t) - : (i.returnEnd || i.excludeEnd || (A += t), - u(), - i.excludeEnd && (A = t)); - do { - y.className && O.closeNode(), - y.skip || y.subLanguage || (I += y.relevance), - (y = y.parent); - } while (y !== a.parent); - return ( - a.starts && - (a.endSameAsBegin && (a.starts.endRe = a.endRe), h(a.starts)), - i.returnEnd ? 0 : t.length - ); - })(r); - if (s !== M) return s; - } - if ("illegal" === r.type && "" === i) return 1; - if (B > 1e5 && B > 3 * r.index) - throw Error( - "potential infinite loop, way more iterations than matches" - ); - return (A += i), i.length; - } - var E = T(e); - if (!E) - throw ( - (console.error(g.replace("{}", e)), - Error('Unknown language: "' + e + '"')) - ); - var _ = (function (e) { - function n(n, t) { - return RegExp( - d(n), - "m" + (e.case_insensitive ? "i" : "") + (t ? "g" : "") - ); - } - class t { - constructor() { - (this.matchIndexes = {}), - (this.regexes = []), - (this.matchAt = 1), - (this.position = 0); - } - addRule(e, n) { - (n.position = this.position++), - (this.matchIndexes[this.matchAt] = n), - this.regexes.push([n, e]), - (this.matchAt += - (function (e) { - return RegExp(e.toString() + "|").exec("").length - 1; - })(e) + 1); - } - compile() { - 0 === this.regexes.length && (this.exec = () => null); - const e = this.regexes.map((e) => e[1]); - (this.matcherRe = n( - (function (e, n = "|") { - for ( - var t = /\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./, - r = 0, - a = "", - i = 0; - i < e.length; - i++ - ) { - var s = (r += 1), - o = d(e[i]); - for (i > 0 && (a += n), a += "("; o.length > 0; ) { - var l = t.exec(o); - if (null == l) { - a += o; - break; - } - (a += o.substring(0, l.index)), - (o = o.substring(l.index + l[0].length)), - "\\" === l[0][0] && l[1] - ? (a += "\\" + (+l[1] + s)) - : ((a += l[0]), "(" === l[0] && r++); - } - a += ")"; - } - return a; - })(e), - !0 - )), - (this.lastIndex = 0); - } - exec(e) { - this.matcherRe.lastIndex = this.lastIndex; - const n = this.matcherRe.exec(e); - if (!n) return null; - const t = n.findIndex((e, n) => n > 0 && void 0 !== e), - r = this.matchIndexes[t]; - return n.splice(0, t), Object.assign(n, r); - } - } - class a { - constructor() { - (this.rules = []), - (this.multiRegexes = []), - (this.count = 0), - (this.lastIndex = 0), - (this.regexIndex = 0); - } - getMatcher(e) { - if (this.multiRegexes[e]) return this.multiRegexes[e]; - const n = new t(); - return ( - this.rules.slice(e).forEach(([e, t]) => n.addRule(e, t)), - n.compile(), - (this.multiRegexes[e] = n), - n - ); - } - considerAll() { - this.regexIndex = 0; - } - addRule(e, n) { - this.rules.push([e, n]), "begin" === n.type && this.count++; - } - exec(e) { - const n = this.getMatcher(this.regexIndex); - n.lastIndex = this.lastIndex; - const t = n.exec(e); - return ( - t && - ((this.regexIndex += t.position + 1), - this.regexIndex === this.count && (this.regexIndex = 0)), - t - ); - } - } - function i(e, n) { - const t = e.input[e.index - 1], - r = e.input[e.index + e[0].length]; - ("." !== t && "." !== r) || n.ignoreMatch(); - } - if (e.contains && e.contains.includes("self")) - throw Error( - "ERR: contains `self` is not supported at the top-level of a language. See documentation." - ); - return (function t(s, o) { - const l = s; - if (s.compiled) return l; - (s.compiled = !0), - (s.__beforeBegin = null), - (s.keywords = s.keywords || s.beginKeywords); - let c = null; - if ( - ("object" == typeof s.keywords && - ((c = s.keywords.$pattern), delete s.keywords.$pattern), - s.keywords && - (s.keywords = (function (e, n) { - var t = {}; - return ( - "string" == typeof e - ? r("keyword", e) - : Object.keys(e).forEach(function (n) { - r(n, e[n]); - }), - t - ); - function r(e, r) { - n && (r = r.toLowerCase()), - r.split(" ").forEach(function (n) { - var r = n.split("|"); - t[r[0]] = [e, w(r[0], r[1])]; - }); - } - })(s.keywords, e.case_insensitive)), - s.lexemes && c) - ) - throw Error( - "ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) " - ); - return ( - (l.keywordPatternRe = n(s.lexemes || c || /\w+/, !0)), - o && - (s.beginKeywords && - ((s.begin = - "\\b(" + - s.beginKeywords.split(" ").join("|") + - ")(?=\\b|\\s)"), - (s.__beforeBegin = i)), - s.begin || (s.begin = /\B|\b/), - (l.beginRe = n(s.begin)), - s.endSameAsBegin && (s.end = s.begin), - s.end || s.endsWithParent || (s.end = /\B|\b/), - s.end && (l.endRe = n(s.end)), - (l.terminator_end = d(s.end) || ""), - s.endsWithParent && - o.terminator_end && - (l.terminator_end += (s.end ? "|" : "") + o.terminator_end)), - s.illegal && (l.illegalRe = n(s.illegal)), - void 0 === s.relevance && (s.relevance = 1), - s.contains || (s.contains = []), - (s.contains = [].concat( - ...s.contains.map(function (e) { - return (function (e) { - return ( - e.variants && - !e.cached_variants && - (e.cached_variants = e.variants.map(function (n) { - return r(e, { variants: null }, n); - })), - e.cached_variants - ? e.cached_variants - : (function e(n) { - return !!n && (n.endsWithParent || e(n.starts)); - })(e) - ? r(e, { starts: e.starts ? r(e.starts) : null }) - : Object.isFrozen(e) - ? r(e) - : e - ); - })("self" === e ? s : e); - }) - )), - s.contains.forEach(function (e) { - t(e, l); - }), - s.starts && t(s.starts, o), - (l.matcher = (function (e) { - const n = new a(); - return ( - e.contains.forEach((e) => - n.addRule(e.begin, { rule: e, type: "begin" }) - ), - e.terminator_end && - n.addRule(e.terminator_end, { type: "end" }), - e.illegal && n.addRule(e.illegal, { type: "illegal" }), - n - ); - })(l)), - l - ); - })(e); - })(E), - N = "", - y = s || _, - k = {}, - O = new f.__emitter(f); - !(function () { - for (var e = [], n = y; n !== E; n = n.parent) - n.className && e.unshift(n.className); - e.forEach((e) => O.openNode(e)); - })(); - var A = "", - I = 0, - S = 0, - B = 0, - L = !1; - try { - for (y.matcher.considerAll(); ; ) { - B++, - L ? (L = !1) : ((y.matcher.lastIndex = S), y.matcher.considerAll()); - const e = y.matcher.exec(o); - if (!e) break; - const n = x(o.substring(S, e.index), e); - S = e.index + n; - } - return ( - x(o.substr(S)), - O.closeAllNodes(), - O.finalize(), - (N = O.toHTML()), - { - relevance: I, - value: N, - language: e, - illegal: !1, - emitter: O, - top: y, - } - ); - } catch (n) { - if (n.message && n.message.includes("Illegal")) - return { - illegal: !0, - illegalBy: { - msg: n.message, - context: o.slice(S - 100, S + 100), - mode: n.mode, - }, - sofar: N, - relevance: 0, - value: R(o), - emitter: O, - }; - if (l) - return { - illegal: !1, - relevance: 0, - value: R(o), - emitter: O, - language: e, - top: y, - errorRaised: n, - }; - throw n; - } - } - function v(e, n) { - n = n || f.languages || Object.keys(i); - var t = (function (e) { - const n = { - relevance: 0, - emitter: new f.__emitter(f), - value: R(e), - illegal: !1, - top: h, - }; - return n.emitter.addText(e), n; - })(e), - r = t; - return ( - n - .filter(T) - .filter(I) - .forEach(function (n) { - var a = m(n, e, !1); - (a.language = n), - a.relevance > r.relevance && (r = a), - a.relevance > t.relevance && ((r = t), (t = a)); - }), - r.language && (t.second_best = r), - t - ); - } - function x(e) { - return f.tabReplace || f.useBR - ? e.replace(c, (e) => - "\n" === e - ? f.useBR - ? "
    " - : e - : f.tabReplace - ? e.replace(/\t/g, f.tabReplace) - : e - ) - : e; - } - function E(e) { - let n = null; - const t = (function (e) { - var n = e.className + " "; - n += e.parentNode ? e.parentNode.className : ""; - const t = f.languageDetectRe.exec(n); - if (t) { - var r = T(t[1]); - return ( - r || - (console.warn(g.replace("{}", t[1])), - console.warn( - "Falling back to no-highlight mode for this block.", - e - )), - r ? t[1] : "no-highlight" - ); - } - return n.split(/\s+/).find((e) => p(e) || T(e)); - })(e); - if (p(t)) return; - S("before:highlightBlock", { block: e, language: t }), - f.useBR - ? ((n = document.createElement("div")).innerHTML = e.innerHTML - .replace(/\n/g, "") - .replace(//g, "\n")) - : (n = e); - const r = n.textContent, - a = t ? b(t, r, !0) : v(r), - i = k(n); - if (i.length) { - const e = document.createElement("div"); - (e.innerHTML = a.value), (a.value = O(i, k(e), r)); - } - (a.value = x(a.value)), - S("after:highlightBlock", { block: e, result: a }), - (e.innerHTML = a.value), - (e.className = (function (e, n, t) { - var r = n ? s[n] : t, - a = [e.trim()]; - return ( - e.match(/\bhljs\b/) || a.push("hljs"), - e.includes(r) || a.push(r), - a.join(" ").trim() - ); - })(e.className, t, a.language)), - (e.result = { - language: a.language, - re: a.relevance, - relavance: a.relevance, - }), - a.second_best && - (e.second_best = { - language: a.second_best.language, - re: a.second_best.relevance, - relavance: a.second_best.relevance, - }); - } - const N = () => { - if (!N.called) { - N.called = !0; - var e = document.querySelectorAll("pre code"); - a.forEach.call(e, E); - } - }; - function T(e) { - return (e = (e || "").toLowerCase()), i[e] || i[s[e]]; - } - function A(e, { languageName: n }) { - "string" == typeof e && (e = [e]), - e.forEach((e) => { - s[e] = n; - }); - } - function I(e) { - var n = T(e); - return n && !n.disableAutodetect; - } - function S(e, n) { - var t = e; - o.forEach(function (e) { - e[t] && e[t](n); - }); - } - Object.assign(t, { - highlight: b, - highlightAuto: v, - fixMarkup: x, - highlightBlock: E, - configure: function (e) { - f = y(f, e); - }, - initHighlighting: N, - initHighlightingOnLoad: function () { - window.addEventListener("DOMContentLoaded", N, !1); - }, - registerLanguage: function (e, n) { - var r = null; - try { - r = n(t); - } catch (n) { - if ( - (console.error( - "Language definition for '{}' could not be registered.".replace( - "{}", - e - ) - ), - !l) - ) - throw n; - console.error(n), (r = h); - } - r.name || (r.name = e), - (i[e] = r), - (r.rawDefinition = n.bind(null, t)), - r.aliases && A(r.aliases, { languageName: e }); - }, - listLanguages: function () { - return Object.keys(i); - }, - getLanguage: T, - registerAliases: A, - requireLanguage: function (e) { - var n = T(e); - if (n) return n; - throw Error( - "The '{}' language is required, but not loaded.".replace("{}", e) - ); - }, - autoDetection: I, - inherit: y, - addPlugin: function (e) { - o.push(e); - }, - }), - (t.debugMode = function () { - l = !1; - }), - (t.safeMode = function () { - l = !0; - }), - (t.versionString = "10.1.1"); - for (const n in _) "object" == typeof _[n] && e(_[n]); - return Object.assign(t, _), t; - })({}); -})(); -"object" == typeof exports && - "undefined" != typeof module && - (module.exports = hljs); -hljs.registerLanguage( - "css", - (function () { - "use strict"; - return function (e) { - var n = { - begin: /(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/, - returnBegin: !0, - end: ";", - endsWithParent: !0, - contains: [ - { - className: "attribute", - begin: /\S/, - end: ":", - excludeEnd: !0, - starts: { - endsWithParent: !0, - excludeEnd: !0, - contains: [ - { - begin: /[\w-]+\(/, - returnBegin: !0, - contains: [ - { className: "built_in", begin: /[\w-]+/ }, - { - begin: /\(/, - end: /\)/, - contains: [ - e.APOS_STRING_MODE, - e.QUOTE_STRING_MODE, - e.CSS_NUMBER_MODE, - ], - }, - ], - }, - e.CSS_NUMBER_MODE, - e.QUOTE_STRING_MODE, - e.APOS_STRING_MODE, - e.C_BLOCK_COMMENT_MODE, - { className: "number", begin: "#[0-9A-Fa-f]+" }, - { className: "meta", begin: "!important" }, - ], - }, - }, - ], - }; - return { - name: "CSS", - case_insensitive: !0, - illegal: /[=\/|'\$]/, - contains: [ - e.C_BLOCK_COMMENT_MODE, - { className: "selector-id", begin: /#[A-Za-z0-9_-]+/ }, - { className: "selector-class", begin: /\.[A-Za-z0-9_-]+/ }, - { - className: "selector-attr", - begin: /\[/, - end: /\]/, - illegal: "$", - contains: [e.APOS_STRING_MODE, e.QUOTE_STRING_MODE], - }, - { - className: "selector-pseudo", - begin: /:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/, - }, - { - begin: "@(page|font-face)", - lexemes: "@[a-z-]+", - keywords: "@page @font-face", - }, - { - begin: "@", - end: "[{;]", - illegal: /:/, - returnBegin: !0, - contains: [ - { className: "keyword", begin: /@\-?\w[\w]*(\-\w+)*/ }, - { - begin: /\s/, - endsWithParent: !0, - excludeEnd: !0, - relevance: 0, - keywords: "and or not only", - contains: [ - { begin: /[a-z-]+:/, className: "attribute" }, - e.APOS_STRING_MODE, - e.QUOTE_STRING_MODE, - e.CSS_NUMBER_MODE, - ], - }, - ], - }, - { - className: "selector-tag", - begin: "[a-zA-Z-][a-zA-Z0-9_-]*", - relevance: 0, - }, - { - begin: "{", - end: "}", - illegal: /\S/, - contains: [e.C_BLOCK_COMMENT_MODE, n], - }, - ], - }; - }; - })() -); -hljs.registerLanguage( - "json", - (function () { - "use strict"; - return function (n) { - var e = { literal: "true false null" }, - i = [n.C_LINE_COMMENT_MODE, n.C_BLOCK_COMMENT_MODE], - t = [n.QUOTE_STRING_MODE, n.C_NUMBER_MODE], - a = { - end: ",", - endsWithParent: !0, - excludeEnd: !0, - contains: t, - keywords: e, - }, - l = { - begin: "{", - end: "}", - contains: [ - { - className: "attr", - begin: /"/, - end: /"/, - contains: [n.BACKSLASH_ESCAPE], - illegal: "\\n", - }, - n.inherit(a, { begin: /:/ }), - ].concat(i), - illegal: "\\S", - }, - s = { - begin: "\\[", - end: "\\]", - contains: [n.inherit(a)], - illegal: "\\S", - }; - return ( - t.push(l, s), - i.forEach(function (n) { - t.push(n); - }), - { name: "JSON", contains: t, keywords: e, illegal: "\\S" } - ); - }; - })() -); -hljs.registerLanguage( - "markdown", - (function () { - "use strict"; - return function (n) { - const e = { begin: "<", end: ">", subLanguage: "xml", relevance: 0 }, - a = { - begin: "\\[.+?\\][\\(\\[].*?[\\)\\]]", - returnBegin: !0, - contains: [ - { - className: "string", - begin: "\\[", - end: "\\]", - excludeBegin: !0, - returnEnd: !0, - relevance: 0, - }, - { - className: "link", - begin: "\\]\\(", - end: "\\)", - excludeBegin: !0, - excludeEnd: !0, - }, - { - className: "symbol", - begin: "\\]\\[", - end: "\\]", - excludeBegin: !0, - excludeEnd: !0, - }, - ], - relevance: 10, - }, - i = { - className: "strong", - contains: [], - variants: [ - { begin: /_{2}/, end: /_{2}/ }, - { begin: /\*{2}/, end: /\*{2}/ }, - ], - }, - s = { - className: "emphasis", - contains: [], - variants: [ - { begin: /\*(?!\*)/, end: /\*/ }, - { begin: /_(?!_)/, end: /_/, relevance: 0 }, - ], - }; - i.contains.push(s), s.contains.push(i); - var c = [e, a]; - return ( - (i.contains = i.contains.concat(c)), - (s.contains = s.contains.concat(c)), - { - name: "Markdown", - aliases: ["md", "mkdown", "mkd"], - contains: [ - { - className: "section", - variants: [ - { begin: "^#{1,6}", end: "$", contains: (c = c.concat(i, s)) }, - { - begin: "(?=^.+?\\n[=-]{2,}$)", - contains: [ - { begin: "^[=-]*$" }, - { begin: "^", end: "\\n", contains: c }, - ], - }, - ], - }, - e, - { - className: "bullet", - begin: "^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)", - end: "\\s+", - excludeEnd: !0, - }, - i, - s, - { className: "quote", begin: "^>\\s+", contains: c, end: "$" }, - { - className: "code", - variants: [ - { begin: "(`{3,})(.|\\n)*?\\1`*[ ]*" }, - { begin: "(~{3,})(.|\\n)*?\\1~*[ ]*" }, - { begin: "```", end: "```+[ ]*$" }, - { begin: "~~~", end: "~~~+[ ]*$" }, - { begin: "`.+?`" }, - { - begin: "(?=^( {4}|\\t))", - contains: [{ begin: "^( {4}|\\t)", end: "(\\n)$" }], - relevance: 0, - }, - ], - }, - { begin: "^[-\\*]{3,}", end: "$" }, - a, - { - begin: /^\[[^\n]+\]:/, - returnBegin: !0, - contains: [ - { - className: "symbol", - begin: /\[/, - end: /\]/, - excludeBegin: !0, - excludeEnd: !0, - }, - { - className: "link", - begin: /:\s*/, - end: /$/, - excludeBegin: !0, - }, - ], - }, - ], - } - ); - }; - })() -); -hljs.registerLanguage( - "plaintext", - (function () { - "use strict"; - return function (t) { - return { - name: "Plain text", - aliases: ["text", "txt"], - disableAutodetect: !0, - }; - }; - })() -); -hljs.registerLanguage( - "python", - (function () { - "use strict"; - return function (e) { - var n = { - keyword: - "and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10", - built_in: "Ellipsis NotImplemented", - literal: "False None True", - }, - a = { className: "meta", begin: /^(>>>|\.\.\.) / }, - i = { - className: "subst", - begin: /\{/, - end: /\}/, - keywords: n, - illegal: /#/, - }, - s = { begin: /\{\{/, relevance: 0 }, - r = { - className: "string", - contains: [e.BACKSLASH_ESCAPE], - variants: [ - { - begin: /(u|b)?r?'''/, - end: /'''/, - contains: [e.BACKSLASH_ESCAPE, a], - relevance: 10, - }, - { - begin: /(u|b)?r?"""/, - end: /"""/, - contains: [e.BACKSLASH_ESCAPE, a], - relevance: 10, - }, - { - begin: /(fr|rf|f)'''/, - end: /'''/, - contains: [e.BACKSLASH_ESCAPE, a, s, i], - }, - { - begin: /(fr|rf|f)"""/, - end: /"""/, - contains: [e.BACKSLASH_ESCAPE, a, s, i], - }, - { begin: /(u|r|ur)'/, end: /'/, relevance: 10 }, - { begin: /(u|r|ur)"/, end: /"/, relevance: 10 }, - { begin: /(b|br)'/, end: /'/ }, - { begin: /(b|br)"/, end: /"/ }, - { - begin: /(fr|rf|f)'/, - end: /'/, - contains: [e.BACKSLASH_ESCAPE, s, i], - }, - { - begin: /(fr|rf|f)"/, - end: /"/, - contains: [e.BACKSLASH_ESCAPE, s, i], - }, - e.APOS_STRING_MODE, - e.QUOTE_STRING_MODE, - ], - }, - l = { - className: "number", - relevance: 0, - variants: [ - { begin: e.BINARY_NUMBER_RE + "[lLjJ]?" }, - { begin: "\\b(0o[0-7]+)[lLjJ]?" }, - { begin: e.C_NUMBER_RE + "[lLjJ]?" }, - ], - }, - t = { - className: "params", - variants: [ - { begin: /\(\s*\)/, skip: !0, className: null }, - { - begin: /\(/, - end: /\)/, - excludeBegin: !0, - excludeEnd: !0, - contains: ["self", a, l, r, e.HASH_COMMENT_MODE], - }, - ], - }; - return ( - (i.contains = [r, l, a]), - { - name: "Python", - aliases: ["py", "gyp", "ipython"], - keywords: n, - illegal: /(<\/|->|\?)|=>/, - contains: [ - a, - l, - { beginKeywords: "if", relevance: 0 }, - r, - e.HASH_COMMENT_MODE, - { - variants: [ - { className: "function", beginKeywords: "def" }, - { className: "class", beginKeywords: "class" }, - ], - end: /:/, - illegal: /[${=;\n,]/, - contains: [ - e.UNDERSCORE_TITLE_MODE, - t, - { begin: /->/, endsWithParent: !0, keywords: "None" }, - ], - }, - { className: "meta", begin: /^[\t ]*@/, end: /$/ }, - { begin: /\b(print|exec)\(/ }, - ], - } - ); - }; - })() -); -hljs.registerLanguage( - "rust", - (function () { - "use strict"; - return function (e) { - var n = "([ui](8|16|32|64|128|size)|f(32|64))?", - t = - "drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!"; - return { - name: "Rust", - aliases: ["rs"], - keywords: { - $pattern: e.IDENT_RE + "!?", - keyword: - "abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield", - literal: "true false Some None Ok Err", - built_in: t, - }, - illegal: "" }, - ], - }; - }; - })() -); -hljs.registerLanguage( - "shell", - (function () { - "use strict"; - return function (s) { - return { - name: "Shell Session", - aliases: ["console"], - contains: [ - { - className: "meta", - begin: "^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]", - starts: { end: "$", subLanguage: "bash" }, - }, - ], - }; - }; - })() -); -hljs.registerLanguage( - "typescript", - (function () { - "use strict"; - const e = [ - "as", - "in", - "of", - "if", - "for", - "while", - "finally", - "var", - "new", - "function", - "do", - "return", - "void", - "else", - "break", - "catch", - "instanceof", - "with", - "throw", - "case", - "default", - "try", - "switch", - "continue", - "typeof", - "delete", - "let", - "yield", - "const", - "class", - "debugger", - "async", - "await", - "static", - "import", - "from", - "export", - "extends", - ], - n = ["true", "false", "null", "undefined", "NaN", "Infinity"], - a = [].concat( - [ - "setInterval", - "setTimeout", - "clearInterval", - "clearTimeout", - "require", - "exports", - "eval", - "isFinite", - "isNaN", - "parseFloat", - "parseInt", - "decodeURI", - "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - "escape", - "unescape", - ], - [ - "arguments", - "this", - "super", - "console", - "window", - "document", - "localStorage", - "module", - "global", - ], - [ - "Intl", - "DataView", - "Number", - "Math", - "Date", - "String", - "RegExp", - "Object", - "Function", - "Boolean", - "Error", - "Symbol", - "Set", - "Map", - "WeakSet", - "WeakMap", - "Proxy", - "Reflect", - "JSON", - "Promise", - "Float64Array", - "Int16Array", - "Int32Array", - "Int8Array", - "Uint16Array", - "Uint32Array", - "Float32Array", - "Array", - "Uint8Array", - "Uint8ClampedArray", - "ArrayBuffer", - ], - [ - "EvalError", - "InternalError", - "RangeError", - "ReferenceError", - "SyntaxError", - "TypeError", - "URIError", - ] - ); - return function (r) { - var t = { - $pattern: "[A-Za-z$_][0-9A-Za-z$_]*", - keyword: e - .concat([ - "type", - "namespace", - "typedef", - "interface", - "public", - "private", - "protected", - "implements", - "declare", - "abstract", - "readonly", - ]) - .join(" "), - literal: n.join(" "), - built_in: a - .concat([ - "any", - "void", - "number", - "boolean", - "string", - "object", - "never", - "enum", - ]) - .join(" "), - }, - s = { className: "meta", begin: "@[A-Za-z$_][0-9A-Za-z$_]*" }, - i = { - className: "number", - variants: [ - { begin: "\\b(0[bB][01]+)n?" }, - { begin: "\\b(0[oO][0-7]+)n?" }, - { begin: r.C_NUMBER_RE + "n?" }, - ], - relevance: 0, - }, - o = { - className: "subst", - begin: "\\$\\{", - end: "\\}", - keywords: t, - contains: [], - }, - c = { - begin: "html`", - end: "", - starts: { - end: "`", - returnEnd: !1, - contains: [r.BACKSLASH_ESCAPE, o], - subLanguage: "xml", - }, - }, - l = { - begin: "css`", - end: "", - starts: { - end: "`", - returnEnd: !1, - contains: [r.BACKSLASH_ESCAPE, o], - subLanguage: "css", - }, - }, - E = { - className: "string", - begin: "`", - end: "`", - contains: [r.BACKSLASH_ESCAPE, o], - }; - o.contains = [ - r.APOS_STRING_MODE, - r.QUOTE_STRING_MODE, - c, - l, - E, - i, - r.REGEXP_MODE, - ]; - var d = { - begin: "\\(", - end: /\)/, - keywords: t, - contains: [ - "self", - r.QUOTE_STRING_MODE, - r.APOS_STRING_MODE, - r.NUMBER_MODE, - ], - }, - u = { - className: "params", - begin: /\(/, - end: /\)/, - excludeBegin: !0, - excludeEnd: !0, - keywords: t, - contains: [r.C_LINE_COMMENT_MODE, r.C_BLOCK_COMMENT_MODE, s, d], - }; - return { - name: "TypeScript", - aliases: ["ts"], - keywords: t, - contains: [ - r.SHEBANG(), - { className: "meta", begin: /^\s*['"]use strict['"]/ }, - r.APOS_STRING_MODE, - r.QUOTE_STRING_MODE, - c, - l, - E, - r.C_LINE_COMMENT_MODE, - r.C_BLOCK_COMMENT_MODE, - i, - { - begin: "(" + r.RE_STARTERS_RE + "|\\b(case|return|throw)\\b)\\s*", - keywords: "return throw case", - contains: [ - r.C_LINE_COMMENT_MODE, - r.C_BLOCK_COMMENT_MODE, - r.REGEXP_MODE, - { - className: "function", - begin: - "(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|" + - r.UNDERSCORE_IDENT_RE + - ")\\s*=>", - returnBegin: !0, - end: "\\s*=>", - contains: [ - { - className: "params", - variants: [ - { begin: r.UNDERSCORE_IDENT_RE }, - { className: null, begin: /\(\s*\)/, skip: !0 }, - { - begin: /\(/, - end: /\)/, - excludeBegin: !0, - excludeEnd: !0, - keywords: t, - contains: d.contains, - }, - ], - }, - ], - }, - ], - relevance: 0, - }, - { - className: "function", - beginKeywords: "function", - end: /[\{;]/, - excludeEnd: !0, - keywords: t, - contains: [ - "self", - r.inherit(r.TITLE_MODE, { begin: "[A-Za-z$_][0-9A-Za-z$_]*" }), - u, - ], - illegal: /%/, - relevance: 0, - }, - { - beginKeywords: "constructor", - end: /[\{;]/, - excludeEnd: !0, - contains: ["self", u], - }, - { begin: /module\./, keywords: { built_in: "module" }, relevance: 0 }, - { beginKeywords: "module", end: /\{/, excludeEnd: !0 }, - { - beginKeywords: "interface", - end: /\{/, - excludeEnd: !0, - keywords: "interface extends", - }, - { begin: /\$[(.]/ }, - { begin: "\\." + r.IDENT_RE, relevance: 0 }, - s, - d, - ], - }; - }; - })() -); -hljs.registerLanguage( - "yaml", - (function () { - "use strict"; - return function (e) { - var n = "true false yes no null", - a = "[\\w#;/?:@&=+$,.~*\\'()[\\]]+", - s = { - className: "string", - relevance: 0, - variants: [ - { begin: /'/, end: /'/ }, - { begin: /"/, end: /"/ }, - { begin: /\S+/ }, - ], - contains: [ - e.BACKSLASH_ESCAPE, - { - className: "template-variable", - variants: [ - { begin: "{{", end: "}}" }, - { begin: "%{", end: "}" }, - ], - }, - ], - }, - i = e.inherit(s, { - variants: [ - { begin: /'/, end: /'/ }, - { begin: /"/, end: /"/ }, - { begin: /[^\s,{}[\]]+/ }, - ], - }), - l = { - end: ",", - endsWithParent: !0, - excludeEnd: !0, - contains: [], - keywords: n, - relevance: 0, - }, - t = { - begin: "{", - end: "}", - contains: [l], - illegal: "\\n", - relevance: 0, - }, - g = { - begin: "\\[", - end: "\\]", - contains: [l], - illegal: "\\n", - relevance: 0, - }, - b = [ - { - className: "attr", - variants: [ - { begin: "\\w[\\w :\\/.-]*:(?=[ \t]|$)" }, - { begin: '"\\w[\\w :\\/.-]*":(?=[ \t]|$)' }, - { begin: "'\\w[\\w :\\/.-]*':(?=[ \t]|$)" }, - ], - }, - { className: "meta", begin: "^---s*$", relevance: 10 }, - { - className: "string", - begin: "[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*", - }, - { - begin: "<%[%=-]?", - end: "[%-]?%>", - subLanguage: "ruby", - excludeBegin: !0, - excludeEnd: !0, - relevance: 0, - }, - { className: "type", begin: "!\\w+!" + a }, - { className: "type", begin: "!<" + a + ">" }, - { className: "type", begin: "!" + a }, - { className: "type", begin: "!!" + a }, - { className: "meta", begin: "&" + e.UNDERSCORE_IDENT_RE + "$" }, - { className: "meta", begin: "\\*" + e.UNDERSCORE_IDENT_RE + "$" }, - { className: "bullet", begin: "\\-(?=[ ]|$)", relevance: 0 }, - e.HASH_COMMENT_MODE, - { beginKeywords: n, keywords: { literal: n } }, - { - className: "number", - begin: - "\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b", - }, - { className: "number", begin: e.C_NUMBER_RE + "\\b" }, - t, - g, - s, - ], - c = [...b]; - return ( - c.pop(), - c.push(i), - (l.contains = c), - { - name: "YAML", - case_insensitive: !0, - aliases: ["yml", "YAML"], - contains: b, - } - ); - }; - })() -); -hljs.registerLanguage( - "cairo", - (function () { - "use strict"; - return function (e) { - var n = "([ui](8|16|32|64|128|size)|f(32|64))?", - t = - "Copy Send Serde Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert assert! assert_eq! assert_ne! assert_lt! assert_le! assert_gt! assert_ge! format! write! writeln! get_dep_component! get_dep_component_mut! component! consteval_int! array! panic! print! println!"; - return { - name: "Cairo", - aliases: ["cairo"], - keywords: { - $pattern: e.IDENT_RE + "!?", - keyword: - "as break const continue else enum extern false fn if impl implicits let loop match mod mut nopanic of pub ref return self struct super trait true type use while", - literal: "true false", - built_in: t, - }, - illegal: "" }, - ], - }; - }; - })() -); diff --git a/theme/index.hbs b/theme/index.hbs deleted file mode 100644 index 7cec24cf..00000000 --- a/theme/index.hbs +++ /dev/null @@ -1,393 +0,0 @@ - - - - - - {{ title }} - {{#if is_print }} - - {{/if}} - {{#if base_url}} - - {{/if}} - - - - {{> head}} - - - - - - {{#if favicon_svg}} - - {{/if}} - {{#if favicon_png}} - - {{/if}} - - - - {{#if print_enable}} - - {{/if}} - - - - {{#if copy_fonts}} - - {{/if}} - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - - -
    - - diff --git a/translations.sh b/translations.sh deleted file mode 100755 index 384aaa43..00000000 --- a/translations.sh +++ /dev/null @@ -1,67 +0,0 @@ -PARAM1=$1 -PARAM2=$2 - -# Function section -function serve_book() { - LANG=$1 - - # Rebuild english version, updating the `messages.pot` file where all chunks of texts - # to be translated are extracted. - MDBOOK_OUTPUT='{"xgettext": {"pot-file": "messages.pot"}}' \ - mdbook build -d po - - # Build available LANGUAGES. po file must exist for the languages listed - # in the LANGUAGE file. If it's not, you can add a language by running (xx replaced by the language code): - # msginit -i po/messages.pot -l xx -o po/xx.po - for po_lang in $(cat ./LANGUAGES) - do - echo merging and building "$po_lang" - msgmerge --update po/"$po_lang".po po/messages.pot - MDBOOK_BOOK__LANGUAGE="$po_lang" mdbook build -d book/"$po_lang" - done - - # Serving the language, if any. - if [ -z "$LANG" ] - then - echo "" - echo "No input language, stop after build." - exit 0 - fi - - # Serve the input language, if available. - MDBOOK_BOOK__LANGUAGE="$LANG" mdbook serve -d book/"$LANG" -} - -function build_new_language() { - LANG=$1 - FILE=po/"$LANG".po - - # Stop if no language parameter. - if [ -z "$LANG" ] - then - echo "" - echo "No input language, stop." - exit 0 - fi - - # Build a new LANGUAGE .po file if not exist . - if test -f "$FILE"; then - echo "" - echo "File $FILE already exists. Ensure you're initiating a new translation. Alternatively, use './transaction.sh $LANG' to serve an existing one." - else - msginit -i po/messages.pot -l "$LANG" -o po/"$LANG".po - fi -} - -# Main section -if [ "$PARAM1" == "new" ]; then - # The first parameter is 'new', PARAM2 is set to $LANG. - LANG=$PARAM2 - build_new_language "$LANG" - -else - # The first parameter is not 'new', PARAM1 is set to $LANG. - LANG=$PARAM1 - serve_book "$LANG" - -fi diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d2636aac --- /dev/null +++ b/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/vocs.config.ts b/vocs.config.ts new file mode 100644 index 00000000..992fb468 --- /dev/null +++ b/vocs.config.ts @@ -0,0 +1,238 @@ +import { defineConfig } from "vocs"; + +export default defineConfig({ + rootDir: ".", + title: "Starknet by Example", + topNav: [ + { + text: "GitHub", + link: "https://github.com/NethermindEth/StarknetByExample", + }, + ], + sidebar: [ + { + text: "Getting Started", + items: [ + { + text: "1. Basics of a Starknet contract", + link: "/ch00/basics/introduction", + collapsed: false, + items: [ + { + text: "1.1. Storage", + link: "/ch00/basics/storage", + }, + { + text: "1.2. Constructor", + link: "/ch00/basics/constructor", + }, + { + text: "1.3. Variables", + link: "/ch00/basics/variables", + }, + { + text: "1.4. Visibility and Mutability", + link: "/ch00/basics/visibility-mutability", + }, + { + text: "1.5. Counter Example", + link: "/ch00/basics/counter", + }, + { + text: "1.6. Mappings", + link: "/ch00/basics/mappings", + }, + { + text: "1.7. Errors", + link: "/ch00/basics/errors", + }, + { + text: "1.8. Events", + link: "/ch00/basics/events", + }, + { + text: "1.9. Syscalls", + link: "/ch00/basics/syscalls", + }, + { + text: "1.10. Strings and ByteArrays", + link: "/ch00/basics/bytearrays-strings", + }, + { + text: "1.11. Storing Custom Types", + link: "/ch00/basics/storing-custom-types", + }, + { + text: "1.12. Custom types in entrypoints", + link: "/ch00/basics/custom-types-in-entrypoints", + }, + { + text: "1.13. Documentation", + link: "/ch00/basics/documentation", + }, + ], + }, + { + text: "2. Deploy and interact with contracts", + link: "/ch00/interacting/interacting", + collapsed: true, + items: [ + { + text: "2.1. Contract interfaces and Traits generation", + link: "/ch00/interacting/interfaces-traits", + }, + { + text: "2.2. Calling other contracts", + link: "/ch00/interacting/calling_other_contracts", + }, + { + text: "2.3. Factory pattern", + link: "/ch00/interacting/factory", + }, + ], + }, + { + text: "3. Testing contracts", + link: "/ch00/testing/contract-testing", + }, + { + text: "4. Cairo cheatsheet", + link: "/ch00/cairo_cheatsheet/cairo_cheatsheet", + collapsed: true, + items: [ + { + text: "4.1. Felt", + link: "/ch00/cairo_cheatsheet/felt", + }, + { + text: "4.2. LegacyMap", + link: "/ch00/cairo_cheatsheet/mapping", + }, + { + text: "4.3. Arrays", + link: "/ch00/cairo_cheatsheet/arrays", + }, + { + text: "4.4. loop", + link: "/ch00/cairo_cheatsheet/loop", + }, + { + text: "4.5. while", + link: "/ch00/cairo_cheatsheet/while", + }, + { + text: "4.6. if let", + link: "/ch00/cairo_cheatsheet/if_let", + }, + { + text: "4.7. while let", + link: "/ch00/cairo_cheatsheet/while_let", + }, + { + text: "4.8. Match", + link: "/ch00/cairo_cheatsheet/match", + }, + { + text: "4.9. Tuples", + link: "/ch00/cairo_cheatsheet/tuples", + }, + { + text: "4.10. Struct", + link: "/ch00/cairo_cheatsheet/struct", + }, + { + text: "4.11. Type casting", + link: "/ch00/cairo_cheatsheet/type_casting", + }, + ], + }, + ], + }, + { + text: "Components", + items: [ + { + text: "5. Components How-To", + link: "/components/how_to", + }, + { + text: "6. Components Dependencies", + link: "/components/dependencies", + }, + { + text: "7. Storage Collisions", + link: "/components/collisions", + }, + { + text: "8. Ownable", + link: "/components/ownable", + }, + ], + }, + { + text: "Applications", + items: [ + { + text: "9. Upgradeable Contract", + link: "/ch01/upgradeable_contract", + }, + { + text: "10. Defi Vault", + link: "/ch01/simple_vault", + }, + { + text: "11. ERC20 Token", + link: "/ch01/erc20", + }, + { + text: "12. Constant Product AMM", + link: "/ch01/constant-product-amm", + }, + ], + }, + { + text: "Advanced concepts", + items: [ + { + text: "13. Writing to any storage slot", + link: "/ch02/write_to_any_slot", + }, + { + text: "14. Storing Arrays", + link: "/ch02/storing_arrays", + }, + { + text: "15. Struct as mapping key", + link: "/ch02/struct-mapping-key", + }, + { + text: "16. Hashing", + link: "/ch02/hashing", + }, + { + text: "17. Optimisations", + link: "/ch02/optimisations/optimisations", + collapsed: false, + items: [ + { + text: "17.1. Storage Optimisations", + link: "/ch02/optimisations/store_using_packing", + }, + ], + }, + { + text: "18. List", + link: "/ch02/list", + }, + { + text: "19. Plugins", + link: "/ch02/plugins", + }, + { + text: "20. Signature Verification", + link: "/ch02/signature_verification", + }, + ], + }, + ], +}); From dcfb3dec2dccaddd6f20e6ab920750b4fce05a1c Mon Sep 17 00:00:00 2001 From: julio4 <30329843+julio4@users.noreply.github.com> Date: Thu, 31 Oct 2024 17:20:57 +0700 Subject: [PATCH 2/2] temp: remove pages --- package-lock.json | 8627 +++++++++++++++++ pages/ch00/basics/bytearrays-strings.md | 56 - pages/ch00/basics/constructor.md | 29 - pages/ch00/basics/counter.md | 35 - .../basics/custom-types-in-entrypoints.md | 34 - pages/ch00/basics/documentation.md | 47 - pages/ch00/basics/errors.md | 77 - pages/ch00/basics/events.md | 25 - pages/ch00/basics/introduction.md | 10 - pages/ch00/basics/mappings.md | 30 - pages/ch00/basics/storage.md | 57 - pages/ch00/basics/storing-custom-types.md | 22 - pages/ch00/basics/syscalls.md | 288 - pages/ch00/basics/variables.md | 90 - pages/ch00/basics/visibility-mutability.md | 42 - pages/ch00/cairo_cheatsheet/arrays.md | 36 - .../ch00/cairo_cheatsheet/cairo_cheatsheet.md | 10 - pages/ch00/cairo_cheatsheet/felt.md | 17 - pages/ch00/cairo_cheatsheet/if_let.md | 24 - pages/ch00/cairo_cheatsheet/loop.md | 25 - pages/ch00/cairo_cheatsheet/mapping.md | 14 - pages/ch00/cairo_cheatsheet/match.md | 16 - pages/ch00/cairo_cheatsheet/struct.md | 16 - pages/ch00/cairo_cheatsheet/tuples.md | 22 - pages/ch00/cairo_cheatsheet/type_casting.md | 17 - pages/ch00/cairo_cheatsheet/while.md | 19 - pages/ch00/cairo_cheatsheet/while_let.md | 25 - pages/ch00/env_setup.md | 5 - .../interacting/calling_other_contracts.md | 56 - pages/ch00/interacting/factory.md | 42 - pages/ch00/interacting/interacting.md | 10 - pages/ch00/interacting/interfaces-traits.md | 76 - pages/ch00/testing/contract-testing.md | 113 - pages/ch01/constant-product-amm.md | 14 - pages/ch01/erc20.md | 37 - pages/ch01/signature_verification.md | 1 - pages/ch01/simple_vault.md | 24 - pages/ch01/upgradeable_contract.md | 47 - pages/ch02/hash-solidity-compatible.md | 9 - pages/ch02/hashing.md | 31 - pages/ch02/list.md | 70 - pages/ch02/optimisations/optimisations.md | 10 - .../ch02/optimisations/store_using_packing.md | 35 - pages/ch02/plugins.md | 14 - pages/ch02/signature_verification.md | 17 - pages/ch02/storing_arrays.md | 26 - pages/ch02/struct-mapping-key.md | 22 - pages/ch02/write_to_any_slot.md | 25 - pages/components/collisions.md | 55 - pages/components/dependencies.md | 136 - pages/components/how_to.md | 87 - pages/components/ownable.md | 40 - pages/getting-started.mdx | 3 - pages/index.mdx | 57 - pages/indexdasds.mdx | 16 - vocs.config.ts | 100 +- 56 files changed, 8677 insertions(+), 2211 deletions(-) create mode 100644 package-lock.json delete mode 100644 pages/ch00/basics/bytearrays-strings.md delete mode 100644 pages/ch00/basics/constructor.md delete mode 100644 pages/ch00/basics/counter.md delete mode 100644 pages/ch00/basics/custom-types-in-entrypoints.md delete mode 100644 pages/ch00/basics/documentation.md delete mode 100644 pages/ch00/basics/errors.md delete mode 100644 pages/ch00/basics/events.md delete mode 100644 pages/ch00/basics/introduction.md delete mode 100644 pages/ch00/basics/mappings.md delete mode 100644 pages/ch00/basics/storage.md delete mode 100644 pages/ch00/basics/storing-custom-types.md delete mode 100644 pages/ch00/basics/syscalls.md delete mode 100644 pages/ch00/basics/variables.md delete mode 100644 pages/ch00/basics/visibility-mutability.md delete mode 100644 pages/ch00/cairo_cheatsheet/arrays.md delete mode 100644 pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md delete mode 100644 pages/ch00/cairo_cheatsheet/felt.md delete mode 100644 pages/ch00/cairo_cheatsheet/if_let.md delete mode 100644 pages/ch00/cairo_cheatsheet/loop.md delete mode 100644 pages/ch00/cairo_cheatsheet/mapping.md delete mode 100644 pages/ch00/cairo_cheatsheet/match.md delete mode 100644 pages/ch00/cairo_cheatsheet/struct.md delete mode 100644 pages/ch00/cairo_cheatsheet/tuples.md delete mode 100644 pages/ch00/cairo_cheatsheet/type_casting.md delete mode 100644 pages/ch00/cairo_cheatsheet/while.md delete mode 100644 pages/ch00/cairo_cheatsheet/while_let.md delete mode 100644 pages/ch00/env_setup.md delete mode 100644 pages/ch00/interacting/calling_other_contracts.md delete mode 100644 pages/ch00/interacting/factory.md delete mode 100644 pages/ch00/interacting/interacting.md delete mode 100644 pages/ch00/interacting/interfaces-traits.md delete mode 100644 pages/ch00/testing/contract-testing.md delete mode 100644 pages/ch01/constant-product-amm.md delete mode 100644 pages/ch01/erc20.md delete mode 100644 pages/ch01/signature_verification.md delete mode 100644 pages/ch01/simple_vault.md delete mode 100644 pages/ch01/upgradeable_contract.md delete mode 100644 pages/ch02/hash-solidity-compatible.md delete mode 100644 pages/ch02/hashing.md delete mode 100644 pages/ch02/list.md delete mode 100644 pages/ch02/optimisations/optimisations.md delete mode 100644 pages/ch02/optimisations/store_using_packing.md delete mode 100644 pages/ch02/plugins.md delete mode 100644 pages/ch02/signature_verification.md delete mode 100644 pages/ch02/storing_arrays.md delete mode 100644 pages/ch02/struct-mapping-key.md delete mode 100644 pages/ch02/write_to_any_slot.md delete mode 100644 pages/components/collisions.md delete mode 100644 pages/components/dependencies.md delete mode 100644 pages/components/how_to.md delete mode 100644 pages/components/ownable.md delete mode 100644 pages/getting-started.mdx delete mode 100644 pages/index.mdx delete mode 100644 pages/indexdasds.mdx diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..fede6103 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8627 @@ +{ + "name": "starknet-by-example", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "starknet-by-example", + "version": "0.0.0", + "dependencies": { + "@types/react": "latest", + "react": "latest", + "react-dom": "latest", + "typescript": "latest", + "vocs": "latest" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.9.tgz", + "integrity": "sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.25.9", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.9.tgz", + "integrity": "sha512-yD+hEuJ/+wAJ4Ox2/rpNv5HIuPG82x3ZlQvYVn8iYCprdxzE7P1udpGF1jyjQVBU4dgznN+k2h103vxZ7NdPyw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.9.tgz", + "integrity": "sha512-WYvQviPw+Qyib0v92AwNIrdLISTp7RfDkM7bPqBvpbnhY4wq8HvHBZREVdYDXk98C8BkOIVnHAY3yvj7AVISxQ==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helpers": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.9.tgz", + "integrity": "sha512-omlUGkr5EaoIJrhLf9CJ0TvjBRpd9+AXRG//0GEQ9THSo8wPiTlbpy1/Ow8ZTrbXpjd9FHXfbFQx32I04ht0FA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.9.tgz", + "integrity": "sha512-TvLZY/F3+GvdRYFZFyxMvnsKi+4oJdgZzU3BoGN9Uc2d9C6zfNwJcKKhjqLAhK8i46mv93jsO74fDh3ih6rpHA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.9.tgz", + "integrity": "sha512-oKWp3+usOJSzDZOucZUAMayhPz/xVjzymyDzUN8dk0Wd3RWMlGLXi07UCQ/CgQVb8LvXx3XBajJH4XGgkt7H7g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.9.tgz", + "integrity": "sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", + "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.9.tgz", + "integrity": "sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@clack/core": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.3.4.tgz", + "integrity": "sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==", + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.7.0.tgz", + "integrity": "sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==", + "bundleDependencies": [ + "is-unicode-supported" + ], + "license": "MIT", + "dependencies": { + "@clack/core": "^0.3.3", + "is-unicode-supported": "*", + "picocolors": "^1.0.0", + "sisteransi": "^1.0.5" + } + }, + "node_modules/@clack/prompts/node_modules/is-unicode-supported": { + "version": "1.3.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", + "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.25", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.25.tgz", + "integrity": "sha512-hZOmgN0NTOzOuZxI1oIrDu3Gcl8WViIkvPMpB4xdd4QD6xAMtwgwr3VPoiyH/bLtRcS1cDnhxLSD1NsMJmwh/A==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "license": "MIT" + }, + "node_modules/@hono/node-server": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.13.2.tgz", + "integrity": "sha512-0w8nEmAyx0Ul0CQp8BL2VtAG4YVdpzXd/mvvM+l0G5Oq22pUyHS+KeFFPSY+czLOF5NAiV3MUNPD1n14Ol5svg==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mdx-js/rollup": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/rollup/-/rollup-3.1.0.tgz", + "integrity": "sha512-q4xOtUXpCzeouE8GaJ8StT4rDxm/U5j6lkMHL2srb2Q3Y7cobE0aXyPzXVVlbeIMBi+5R5MpbiaVE5/vJUdnHg==", + "license": "MIT", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@rollup/pluginutils": "^5.0.0", + "source-map": "^0.7.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "rollup": ">=2" + } + }, + "node_modules/@noble/hashes": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@radix-ui/colors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", + "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.1.tgz", + "integrity": "sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collapsible": "1.1.1", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz", + "integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.2.tgz", + "integrity": "sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.6.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", + "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", + "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz", + "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.1.tgz", + "integrity": "sha512-egDo0yJD2IK8L17gC82vptkvW1jLeni1VuqCyzY727dSJdk5cDjINomouLoNk8RVF7g2aNIfENKWL4UzeU9c8Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.2.tgz", + "integrity": "sha512-u2HRUyWW+lOiA2g0Le0tMmT55FGOEWHwPFt1EPfbLly7uXQExFo5duNKqG2DzmFXIdqOeNd+TpE8baHWJCyP9w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.6.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", + "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", + "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.1.tgz", + "integrity": "sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, + "node_modules/@remix-run/router": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.22.1.tgz", + "integrity": "sha512-bqAhT/Ri5ixV4oYsvJNH8UJjpjbINWlWyXY6tBTsP4OmD6XnFv43nRJ+lTdxd2rmG5pgam/x+zGR6kLRXrpEKA==", + "license": "MIT", + "dependencies": { + "@shikijs/engine-javascript": "1.22.1", + "@shikijs/engine-oniguruma": "1.22.1", + "@shikijs/types": "1.22.1", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.3" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.22.1.tgz", + "integrity": "sha512-540pyoy0LWe4jj2BVbgELwOFu1uFvRI7lg4hdsExrSXA9x7gqfzZ/Nnh4RfX86aDAgJ647gx4TCmRwACbnQSvw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.22.1", + "@shikijs/vscode-textmate": "^9.3.0", + "oniguruma-to-js": "0.4.3" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.22.1.tgz", + "integrity": "sha512-L+1Vmd+a2kk8HtogUFymQS6BjUfJnzcWoUp1BUgxoDiklbKSMvrsMuLZGevTOP1m0rEjgnC5MsDmsr8lX1lC+Q==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.22.1", + "@shikijs/vscode-textmate": "^9.3.0" + } + }, + "node_modules/@shikijs/rehype": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/rehype/-/rehype-1.22.1.tgz", + "integrity": "sha512-Uuuqj/poMLj1Z02sJsS1qEqpfUNp2hV2YFVt/SY5+Ielo5Ms1bRfYQHs3hTbsEDB6FmYuOu5ieqNumPlWBmrng==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.22.1", + "@types/hast": "^3.0.4", + "hast-util-to-string": "^3.0.1", + "shiki": "1.22.1", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/@shikijs/transformers": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-1.22.1.tgz", + "integrity": "sha512-KvG49YFV6gV116sC4L3Sn1Rp6HXsioMKBBG373j088rw849440hm8s2r+/dgjsGLvT4p+QB7newev+5a3ARM6w==", + "license": "MIT", + "dependencies": { + "shiki": "1.22.1" + } + }, + "node_modules/@shikijs/twoslash": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/twoslash/-/twoslash-1.22.1.tgz", + "integrity": "sha512-Gs3eRsq0P3wOWJkLRQEsf6fjBcCOVcBSt+xPPhgIWqrBkpUf/L65VaGHR8LRWX3L9yhoyvX9PE/vtMVRwe8sNg==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.22.1", + "@shikijs/types": "1.22.1", + "twoslash": "^0.2.12" + } + }, + "node_modules/@shikijs/types": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.22.1.tgz", + "integrity": "sha512-+45f8mu/Hxqs6Kyhfm98Nld5n7Q7lwhjU8UtdQwrOPs7BnM4VAb929O3IQ2ce+4D7SlNFlZGd8CnKRSnwbQreQ==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", + "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "license": "MIT" + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", + "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@typescript/vfs": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@typescript/vfs/-/vfs-1.6.0.tgz", + "integrity": "sha512-hvJUjNVeBMp77qPINuUvYXj4FyWeeMMKZkxEATEU3hqBAQ7qdTBCUFT7Sp0Zu0faeEtFf+ldXxMEDr/bk73ISg==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" + }, + "node_modules/@vanilla-extract/babel-plugin-debug-ids": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.1.0.tgz", + "integrity": "sha512-Zy9bKjaL2P5zsrFYQJ8IjWGlFODmZrpvFmjFE0Zv8om55Pz1JtpJtL6DvlxlWUxbVaP1HKCqsmEfFOZN8fX/ZQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.9" + } + }, + "node_modules/@vanilla-extract/css": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.16.0.tgz", + "integrity": "sha512-05JTbvG1E0IrSZKZ5el2EM9CmAX0XSdsNY+d4aRZxDvYf3/hwxomvFFEz2b/awjgg9yTVHW83Wq19wE4OoTEMg==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.0", + "@vanilla-extract/private": "^1.0.6", + "css-what": "^6.1.0", + "cssesc": "^3.0.0", + "csstype": "^3.0.7", + "dedent": "^1.5.3", + "deep-object-diff": "^1.1.9", + "deepmerge": "^4.2.2", + "lru-cache": "^10.4.3", + "media-query-parser": "^2.0.2", + "modern-ahocorasick": "^1.0.0", + "picocolors": "^1.0.0" + } + }, + "node_modules/@vanilla-extract/dynamic": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@vanilla-extract/dynamic/-/dynamic-2.1.2.tgz", + "integrity": "sha512-9BGMciD8rO1hdSPIAh1ntsG4LPD3IYKhywR7VOmmz9OO4Lx1hlwkSg3E6X07ujFx7YuBfx0GDQnApG9ESHvB2A==", + "license": "MIT", + "dependencies": { + "@vanilla-extract/private": "^1.0.6" + } + }, + "node_modules/@vanilla-extract/integration": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@vanilla-extract/integration/-/integration-6.5.0.tgz", + "integrity": "sha512-E2YcfO8vA+vs+ua+gpvy1HRqvgWbI+MTlUpxA8FvatOvybuNcWAY0CKwQ/Gpj7rswYKtC6C7+xw33emM6/ImdQ==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.20.7", + "@babel/plugin-syntax-typescript": "^7.20.0", + "@vanilla-extract/babel-plugin-debug-ids": "^1.0.4", + "@vanilla-extract/css": "^1.14.0", + "esbuild": "npm:esbuild@~0.17.6 || ~0.18.0 || ~0.19.0", + "eval": "0.1.8", + "find-up": "^5.0.0", + "javascript-stringify": "^2.0.1", + "lodash": "^4.17.21", + "mlly": "^1.4.2", + "outdent": "^0.8.0", + "vite": "^5.0.11", + "vite-node": "^1.2.0" + } + }, + "node_modules/@vanilla-extract/private": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@vanilla-extract/private/-/private-1.0.6.tgz", + "integrity": "sha512-ytsG/JLweEjw7DBuZ/0JCN4WAQgM9erfSTdS1NQY778hFQSZ6cfCDEZZ0sgVm4k54uNz6ImKB33AYvSR//fjxw==", + "license": "MIT" + }, + "node_modules/@vanilla-extract/vite-plugin": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@vanilla-extract/vite-plugin/-/vite-plugin-3.9.5.tgz", + "integrity": "sha512-CWI/CtrVW6i3HKccI6T7uGQkTJ8bd8Xl2UMBg3Pkr7dwWMmavXTeucV0I9KSbmXaYXSbEj+Q8c9y0xAZwtmTig==", + "license": "MIT", + "dependencies": { + "@vanilla-extract/integration": "^6.3.0", + "outdent": "^0.8.0", + "postcss": "^8.3.6", + "postcss-load-config": "^4.0.1" + }, + "peerDependencies": { + "vite": "^2.2.3 || ^3.0.0 || ^4.0.3 || ^5.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz", + "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.5", + "@babel/plugin-transform-react-jsx-self": "^7.24.5", + "@babel/plugin-transform-react-jsx-source": "^7.24.1", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chroma-js": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.6.0.tgz", + "integrity": "sha512-BLHvCB9s8Z1EV4ethr6xnkl/P2YRFOGqfgvuMG/MyCbZPrTA+NeiByY6XvgF0zP4/2deU2CXnWyMa3zu1LqQ3A==", + "license": "(BSD-3-Clause AND Apache-2.0)" + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/create-vocs": { + "version": "1.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/create-vocs/-/create-vocs-1.0.0-alpha.5.tgz", + "integrity": "sha512-/Nr9taHX1SxL5t72DLFPYujqD8d5PDk0T8bJ9Fb/m7ck1lP20PBxHzF5IYnHI0BeTpIuGk/MQoLfT6JKpY6xnw==", + "dependencies": { + "@clack/prompts": "^0.7.0", + "cac": "^6.7.14", + "detect-package-manager": "^3.0.1", + "fs-extra": "^11.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "create-vocs": "_lib/bin.js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-selector-parser": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.5.tgz", + "integrity": "sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-object-diff": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz", + "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/detect-package-manager": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/detect-package-manager/-/detect-package-manager-3.0.2.tgz", + "integrity": "sha512-8JFjJHutStYrfWwzfretQoyNGoZVW1Fsrp4JO9spa7h/fBfwgTMEIy4/LBzRDGsxwVPHU0q+T9YvwLDJoOApLQ==", + "license": "MIT", + "dependencies": { + "execa": "^5.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.45", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.45.tgz", + "integrity": "sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", + "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-classnames": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-classnames/-/hast-util-classnames-3.0.0.tgz", + "integrity": "sha512-tI3JjoGDEBVorMAWK4jNRsfLMYmih1BUOG3VV36pH36njs1IEl7xkNrVTD2mD2yYHmQCa5R/fj61a8IAF4bRaQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-select": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.3.tgz", + "integrity": "sha512-OVRQlQ1XuuLP8aFVLYmC2atrfWHS5UD3shonxpnyrjcCkwtvmt/+N6kYJdcY4mkMJhxp4kj2EFIxQ9kvkkt/eQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.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.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree/node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==", + "license": "MIT" + }, + "node_modules/hast-util-to-estree/node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", + "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.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.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hono": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.6.6.tgz", + "integrity": "sha512-euUj5qwvtkG+p38GFs0LYacwaoS2hYRAGn9ysAggiwT2QBcPnT1XYUCW3hatW4C1KzAXTYuQ08BlVDJtAGuhlg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "license": "MIT" + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "license": "MIT" + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", + "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.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "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.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.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.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/media-query-parser": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/media-query-parser/-/media-query-parser-2.0.2.tgz", + "integrity": "sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "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" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.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.0", + "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" + } + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "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.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minisearch": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-6.3.0.tgz", + "integrity": "sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==", + "license": "MIT" + }, + "node_modules/mlly": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.12.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + } + }, + "node_modules/modern-ahocorasick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz", + "integrity": "sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/oniguruma-to-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/oniguruma-to-js/-/oniguruma-to-js-0.4.3.tgz", + "integrity": "sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==", + "license": "MIT", + "dependencies": { + "regex": "^4.3.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/ora": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", + "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.9.0", + "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" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/outdent": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", + "integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==", + "license": "MIT" + }, + "node_modules/p-limit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", + "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", + "license": "MIT" + }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/react-intersection-observer": { + "version": "9.13.1", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.13.1.tgz", + "integrity": "sha512-tSzDaTy0qwNPLJHg8XZhlyHTgGW6drFKTtvjdL+p6um12rcnp8Z5XstE+QNBJ7c64n5o0Lj4ilUleA41bmDoMw==", + "license": "MIT", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz", + "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.6", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "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 + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "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 + } + } + }, + "node_modules/react-router": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "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 + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regex": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/regex/-/regex-4.3.3.tgz", + "integrity": "sha512-r/AadFO7owAq1QJVeZ/nq9jNS1vyZt+6t1p/E59B56Rn2GCya+gr1KSyOzNL/er+r+B7phv5jG2xU2Nz1YkmJg==", + "license": "MIT" + }, + "node_modules/rehype-autolink-headings": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz", + "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-class-names": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/rehype-class-names/-/rehype-class-names-1.0.14.tgz", + "integrity": "sha512-eFBt6Qxb7K77y6P82tUtN9rKpU7guWlaK4XA4RrrSFHkUTCvr2D3cgb9OR5d4t1AaGOvR59FH9nRwUnbpn9AEg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-classnames": "^3.0.0", + "hast-util-select": "^6.0.0", + "unified": "^10.1.2" + } + }, + "node_modules/rehype-class-names/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/rehype-class-names/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-class-names/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-class-names/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-class-names/node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "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" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "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.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx-frontmatter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-mdx-frontmatter/-/remark-mdx-frontmatter-4.0.0.tgz", + "integrity": "sha512-PZzAiDGOEfv1Ua7exQ8S5kKxkD8CDaSb4nM+1Mprs6u8dyvQifakh+kCj6NovfGXW+bTvrhjaR3srzjS2qJHKg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-value-to-estree": "^3.0.0", + "toml": "^3.0.0", + "unified": "^11.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shiki": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.22.1.tgz", + "integrity": "sha512-PbJ6XxrWLMwB2rm3qdjIHNm3zq4SfFnOx0B3rEoi4AN8AUngsdyZ1tRe5slMPtn6jQkbUURLNZPpLR7Do3k78g==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.22.1", + "@shikijs/engine-javascript": "1.22.1", + "@shikijs/engine-oniguruma": "1.22.1", + "@shikijs/types": "1.22.1", + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stdin-discarder": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "license": "MIT", + "dependencies": { + "bl": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/string-width": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", + "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^10.2.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, + "node_modules/tailwindcss": { + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", + "license": "MIT", + "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.0", + "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.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toml": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz", + "integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==", + "license": "MIT" + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD" + }, + "node_modules/twoslash": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/twoslash/-/twoslash-0.2.12.tgz", + "integrity": "sha512-tEHPASMqi7kqwfJbkk7hc/4EhlrKCSLcur+TcvYki3vhIfaRMXnXjaYFgXpoZRbT6GdprD4tGuVBEmTpUgLBsw==", + "license": "MIT", + "dependencies": { + "@typescript/vfs": "^1.6.0", + "twoslash-protocol": "0.2.12" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/twoslash-protocol": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/twoslash-protocol/-/twoslash-protocol-0.2.12.tgz", + "integrity": "sha512-5qZLXVYfZ9ABdjqbvPc4RWMr7PrpPaaDSeaYY55vl/w1j6H6kzsWK/urAEIXlzYlyrFmyz1UbwIt+AA0ck+wbg==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz", + "integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "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 + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "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 + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/vocs": { + "version": "1.0.0-alpha.62", + "resolved": "https://registry.npmjs.org/vocs/-/vocs-1.0.0-alpha.62.tgz", + "integrity": "sha512-WidbX8M33lPlDjOvvjQyZaYGtn3hRZ3iViFuwvlmgAqCX1yGXaQs1tLdS1Cy5ki+q0BIUqXvvy8jo9rBQ+fM6w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.26.24", + "@hono/node-server": "^1.13.1", + "@mdx-js/react": "^3.0.1", + "@mdx-js/rollup": "^3.0.1", + "@noble/hashes": "^1.5.0", + "@radix-ui/colors": "^3.0.0", + "@radix-ui/react-accordion": "^1.2.1", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-navigation-menu": "^1.2.1", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-tabs": "^1.1.1", + "@shikijs/rehype": "^1.21.0", + "@shikijs/transformers": "^1.21.0", + "@shikijs/twoslash": "^1.21.0", + "@vanilla-extract/css": "^1.16.0", + "@vanilla-extract/dynamic": "^2.1.2", + "@vanilla-extract/vite-plugin": "^3.9.5", + "@vitejs/plugin-react": "4.3.1", + "autoprefixer": "^10.4.20", + "cac": "^6.7.14", + "chroma-js": "^2.6.0", + "clsx": "^2.1.1", + "compression": "^1.7.4", + "create-vocs": "^1.0.0-alpha.4", + "cross-spawn": "^7.0.3", + "fs-extra": "^11.2.0", + "globby": "^13.2.2", + "hastscript": "^8.0.0", + "hono": "^3.12.12", + "mark.js": "^8.11.1", + "mdast-util-directive": "^3.0.0", + "mdast-util-from-markdown": "^2.0.1", + "mdast-util-gfm": "^3.0.0", + "mdast-util-to-hast": "^13.2.0", + "minimatch": "^9.0.5", + "minisearch": "^6.3.0", + "ora": "^7.0.1", + "p-limit": "^5.0.0", + "postcss": "^8.4.47", + "react-helmet": "^6.1.0", + "react-intersection-observer": "^9.13.1", + "react-router-dom": "^6.20.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-class-names": "^1.0.14", + "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.16.2", + "shiki": "^1.21.0", + "tailwindcss": "^3.4.13", + "toml": "^3.0.0", + "twoslash": "~0.2.12", + "ua-parser-js": "^1.0.39", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vite": "^5.4.8" + }, + "bin": { + "vocs": "_lib/cli/index.js" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, + "node_modules/vocs/node_modules/hono": { + "version": "3.12.12", + "resolved": "https://registry.npmjs.org/hono/-/hono-3.12.12.tgz", + "integrity": "sha512-5IAMJOXfpA5nT+K0MNjClchzz0IhBHs2Szl7WFAhrFOsbtQsYmNynFyJRg/a3IPsmCfxcrf8txUGiNShXpK5Rg==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/pages/ch00/basics/bytearrays-strings.md b/pages/ch00/basics/bytearrays-strings.md deleted file mode 100644 index fc59f9c0..00000000 --- a/pages/ch00/basics/bytearrays-strings.md +++ /dev/null @@ -1,56 +0,0 @@ -# Strings and ByteArrays - -In Cairo, there's no native type for strings. Instead, you can use a single `felt252` to store a `short string` or a `ByteArray` for strings of arbitrary length. - -## Short strings - -Each character is encoded on 8 bits following the ASCII standard, so it's possible to store up to 31 characters in a single `felt252`. - -Short strings are declared with single quotes, like this: `'Hello, World!'`. -See the [Felt](../cairo_cheatsheet/felt.md) section for more information about short strings with the `felt252` type. - -> Notice that any short string only use up to 31 bytes, so it's possible to represent any short string with `bytes31`. - -## ByteArray (Long strings) - -The `ByteArray` struct is used to store strings of arbitrary length. It contains a field `data` of type `Array` to store a sequence of short strings. - -ByteArrays are declared with double quotes, like this: `"Hello, World!"`. - -They can be stored in the contract's storage and passed as arguments to entrypoints. - -<<<<<<<< HEAD:src/getting-started/basics/bytearrays-strings.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/bytearray/src/bytearray.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/bytearrays-strings.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/bytearray/src/bytearray.cairo:tests] -``` - -::: - -### Operations - -ByteArrays also provide a set of operations that facilitate the manipulation of strings. -Here are the available operations on an instance of `ByteArray`: - -- `append(mut other: @ByteArray)` - Append another ByteArray to the current one. -- `append_word(word: felt252, len: usize)` - Append a short string to the ByteArray. You **need to ensure** that `len` is at most 31 and that `word` can be converted to a `bytes31` with maximum `len` bytes/characters. -- `append_byte(byte: felt252)` - Append a single byte/character to the end of the ByteArray. -- `len() -> usize` - Get the length of the ByteArray. -- `at(index: usize) -> Option` - Access the character at the given index. -- `rev() -> ByteArray` - Return a new ByteArray with the characters of the original one in reverse order. -- `append_word_rev(word: felt252, len: usize)` - Append a short string to the ByteArray in reverse order. You **need to ensure** again that `len` is at most 31 and that `word` can be converted to a `bytes31` with maximum `len` bytes/characters. - -Additionally, there are some operations that can be called as static functions: - -- `concat(left: @ByteArray, right: @ByteArray)` - Concatenate two ByteArrays. - -Concatenation of `ByteArray` (`append(mut other: @ByteArray)`) can also be done with the `+` and `+=` operators directly, and access to a specific index can be done with the `[]` operator (with the maximum index being `len() - 1`). diff --git a/pages/ch00/basics/constructor.md b/pages/ch00/basics/constructor.md deleted file mode 100644 index f751c0c6..00000000 --- a/pages/ch00/basics/constructor.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Constructor - -Constructors are a special type of function that runs only once when deploying a contract, and can be used to initialize the state of the contract. Your contract must not have more than one constructor, and that constructor function must be annotated with the `#[constructor]` attribute. Also, a good practice consists in naming that function `constructor`. - -Here's a simple example that demonstrates how to initialize the state of a contract on deployment by defining logic inside a constructor. - -<<<<<<<< HEAD:src/getting-started/basics/constructor.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/constructor/src/constructor.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/constructor/src/constructor.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/constructor.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/constructor/src/constructor.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/counter.md b/pages/ch00/basics/counter.md deleted file mode 100644 index 7ba0493e..00000000 --- a/pages/ch00/basics/counter.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Simple Counter - -We now understand how to create a contract with state variables and functions. Let's create a simple counter contract that increments and decrements a counter. - -Here's how it works: - -- The contract has a state variable `counter` that is initialized to `0`. - -- When a user calls the `increment` entrypoint, the contract increments `counter` by `1`. - -- When a user calls the `decrement`, the contract decrements `counter` by `1`. - -<<<<<<<< HEAD:src/getting-started/basics/counter.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/counter/src/counter.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/counter/src/counter.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/counter.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/counter/src/counter.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/custom-types-in-entrypoints.md b/pages/ch00/basics/custom-types-in-entrypoints.md deleted file mode 100644 index 97e8ce79..00000000 --- a/pages/ch00/basics/custom-types-in-entrypoints.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Custom types in entrypoints - -Using custom types in entrypoints requires our type to implement the `Serde` trait. This is because when calling an entrypoint, the input is sent as an array of `felt252` to the entrypoint, and we need to be able to deserialize it into our custom type. Similarly, when returning a custom type from an entrypoint, we need to be able to serialize it into an array of `felt252`. -Thankfully, we can just derive the `Serde` trait for our custom type. - -<<<<<<<< HEAD:src/getting-started/basics/custom-types-in-entrypoints.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/custom_type_serde/src/contract.cairo:contract}} -``` - -> Note: The purpose of this example is to demonstrate the ability to use custom types as inputs and outputs in contract calls. For simplicity, we are not using getters and setters to manage the contract's state. -======== -The purpose is to only show the capability of using custom types as inputs and outputs in contract calls. -We are not employing getters and setters for managing the contract's state in this example for simplicity. - -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/custom_type_serde/src/contract.cairo:tests] -``` - -::: ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/custom-types-in-entrypoints.md diff --git a/pages/ch00/basics/documentation.md b/pages/ch00/basics/documentation.md deleted file mode 100644 index 81b14b37..00000000 --- a/pages/ch00/basics/documentation.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Documentation - -It's important to take the time to document your code. It will help developers and users to understand the contract and its functionalities. - -In Cairo, you can add comments with `//`. - -### Best Practices - -Since Cairo 1, the community has adopted a [Rust-like documentation style](https://doc.rust-lang.org/rust-by-example/meta/doc.html). - -### Contract Interface - -In smart contracts, you will often have a trait that defines the contract's interface (with `#[starknet::interface]`). -This is the perfect place to include detailed documentation explaining the purpose and functionality of the contract entry points. You can follow this template: - -```cairo -#[starknet::interface] -trait IContract { - /// High-level description of the function - /// - /// # Arguments - /// - /// * `arg_1` - Description of the argument - /// * `arg_n` - ... - /// - /// # Returns - /// - /// High-level description of the return value - fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return; -} -``` - -Keep in mind that this should not describe the implementation details of the function, but rather the high-level purpose and functionality of the contract from the perspective of a user. - -### Implementation Details - -When writing the contract logic, you can add comments to describe the technical implementation details of the functions. - -> Avoid over-commenting: Comments should provide additional value and clarity. diff --git a/pages/ch00/basics/errors.md b/pages/ch00/basics/errors.md deleted file mode 100644 index 7d6df40b..00000000 --- a/pages/ch00/basics/errors.md +++ /dev/null @@ -1,77 +0,0 @@ -# Errors - -Errors can be used to handle validation and other conditions that may occur during the execution of a smart contract. -If an error is thrown during the execution of a smart contract call, the execution is stopped and any changes made during the transaction are reverted. - -To throw an error, use the `assert` or `panic` functions: - -- `assert` is used to validate conditions. - If the check fails, an error is thrown along with a specified value, often a message. - It's similar to the `require` statement in Solidity. - -- `panic` immediately halts the execution with the given error value. - It should be used for complex condition checks and for internal errors. It's similar to the `revert` statement in Solidity. - You can use `panic_with_felt252` to directly pass a `felt252` as the error value. - -The `assert_eq!`, `assert_ne!`, `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros can be used as an `assert` shorthand to compare two values, but **only** in tests. In contracts, you should only use the `assert` function. - -Here's a simple example that demonstrates the use of these functions: - -<<<<<<<< HEAD:src/getting-started/basics/errors.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/errors/src/simple_errors.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/errors/src/simple_errors.cairo:tests] -``` - -::: - -## Custom errors - -You can make error handling easier by defining your error codes in a specific module. - -<<<<<<<< HEAD:src/getting-started/basics/errors.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/errors/src/custom_errors.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/errors/src/custom_errors.cairo:tests] -``` - -::: - -## Vault example - -Here's another example that demonstrates the use of errors in a more complex contract: - -<<<<<<<< HEAD:src/getting-started/basics/errors.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/errors/src/vault_errors.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/errors.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/errors/src/vault_errors.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/events.md b/pages/ch00/basics/events.md deleted file mode 100644 index 3267b6d8..00000000 --- a/pages/ch00/basics/events.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Events - -Events are a way to emit data from a contract. All events must be defined in the `Event` enum, which must be annotated with the `#[event]` attribute. -An event is defined as a struct that derives the `#[starknet::Event]` trait. The fields of that struct correspond to the data that will be emitted. An event can be indexed for easy and fast access when querying the data at a later time, by adding a `#[key]` attribute to a field member. - -Here's a simple example of a contract using events that emit an event each time a counter is incremented by the "increment" function: - -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/events/src/counter.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/events/src/counter.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/introduction.md b/pages/ch00/basics/introduction.md deleted file mode 100644 index 0c3367aa..00000000 --- a/pages/ch00/basics/introduction.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Basics of Smart Contracts in Cairo - -The following chapters will introduce you to Starknet smart contracts and how to write them in Cairo. diff --git a/pages/ch00/basics/mappings.md b/pages/ch00/basics/mappings.md deleted file mode 100644 index cc0f0b16..00000000 --- a/pages/ch00/basics/mappings.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Mappings - -Maps are a key-value data structure used to store data within a smart contract. In Cairo they are implemented using the `LegacyMap` type. It's important to note that the `LegacyMap` type can only be used inside the `Storage` struct of a contract and that it can't be used elsewhere. - -Here we demonstrate how to use the `LegacyMap` type within a Cairo contract, to map between a key of type `ContractAddress` and value of type `felt252`. The key-value types are specified within angular brackets <>. We write to the map by calling the `write()` method, passing in both the key and value. Similarly, we can read the value associated with a given key by calling the `read()` method and passing in the relevant key. - -Some additional notes: - -- More complex key-value mappings are possible, for example we could use `LegacyMap::<(ContractAddress, ContractAddress), felt252>` to create an allowance on an ERC20 token contract. - -- In mappings, the address of the value at key `k_1,...,k_n` is `h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)` where `ℎ` is the Pedersen hash and the final value is taken `mod2251−256`. You can learn more about the contract storage layout in the [Starknet Documentation](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables) - -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/mappings/src/mappings.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/mappings/src/mappings.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/storage.md b/pages/ch00/basics/storage.md deleted file mode 100644 index 7d621c2b..00000000 --- a/pages/ch00/basics/storage.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Storage - -Here's the most minimal contract you can write in Cairo: - -<<<<<<<< HEAD:src/getting-started/basics/storage.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/storage/src/minimal_contract.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/storage/src/minimal_contract.cairo:tests] -``` - -::: - -Storage is a `struct` annotated with `#[storage]`. Every contract must have one and only one storage. -It's a key-value store, where each key will be mapped to a storage address of the contract's storage space. - -You can define [storage variables](./variables.md#storage-variables) in your contract, and then use them to store and retrieve data. - -<<<<<<<< HEAD:src/getting-started/basics/storage.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/storage/src/contract.cairo:contract}} -``` - -> Actually these two contracts have the same underlying Sierra program. -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/storage/src/contract.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/storage/src/contract.cairo:tests] -``` - -::: - -> Actually these two contracts have the same underlying sierra program. ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/storage.md -> From the compiler's perspective, the storage variables don't exist until they are used. - -You can also read about [storing custom types](./storing-custom-types.md). diff --git a/pages/ch00/basics/storing-custom-types.md b/pages/ch00/basics/storing-custom-types.md deleted file mode 100644 index 43820f76..00000000 --- a/pages/ch00/basics/storing-custom-types.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Storing Custom Types - -While native types can be stored in a contract's storage without any additional work, custom types require a bit more work. This is because at compile time, the compiler does not know how to store custom types in storage. To solve this, we need to implement the `Store` trait for our custom type. Hopefully, we can just derive this trait for our custom type - unless it contains arrays or dictionaries. - -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/storing_custom_types/src/contract.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/storing_custom_types/src/contract.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/syscalls.md b/pages/ch00/basics/syscalls.md deleted file mode 100644 index bac7a1c2..00000000 --- a/pages/ch00/basics/syscalls.md +++ /dev/null @@ -1,288 +0,0 @@ -# Syscalls - -At the protocol level, the Starknet Operating System (OS) is the program that manages the whole Starknet network. - -Some of the OS functionalities are exposed to smart contracts through the use of syscalls (system calls). Syscalls can be used to get information about the state of the Starknet network, to interact with/deploy contracts, emit events, send messages, and perform other low-level operations. - -Syscalls return a `SyscallResult` which is either `Success` of `Failure`, allowing the contract to handle errors. - -Here's the available syscalls: - -- [get_block_hash](#get_block_hash) -- [get_execution_info](#get_execution_info) -- [call_contract](#call_contract) -- [deploy](#deploy) -- [emit_event](#emit_event) -- [library_call](#library_call) -- [send_message_to_L1](#send_message_to_L1) -- [replace_class](#replace_class) -- [storage_read](#storage_read) -- [storage_write](#storage_write) - - -#### get_block_hash - -```cairo -fn get_block_hash_syscall(block_number: u64) -> SyscallResult -``` - -Get the hash of the block number `block_number`. - -Only within the range `[first_v0_12_0_block, current_block - 10]`. - -#### get_execution_info - -```cairo -fn get_execution_info_syscall() -> SyscallResult> -``` - -Get information about the current execution context. -The returned `ExecutionInfo` is defined as : - -```cairo -#[derive(Copy, Drop, Debug)] -pub struct ExecutionInfo { - pub block_info: Box, - pub tx_info: Box, - pub caller_address: ContractAddress, - pub contract_address: ContractAddress, - pub entry_point_selector: felt252, -} - -#[derive(Copy, Drop, Debug, Serde)] -pub struct BlockInfo { - pub block_number: u64, - pub block_timestamp: u64, - pub sequencer_address: ContractAddress, -} - -#[derive(Copy, Drop, Debug, Serde)] -pub struct TxInfo { - // The version of the transaction. Always fixed (1) - pub version: felt252, - // The account contract from which this transaction originates. - pub account_contract_address: ContractAddress, - // The max_fee field of the transaction. - pub max_fee: u128, - // The signature of the transaction. - pub signature: Span, - // The hash of the transaction. - pub transaction_hash: felt252, - // The identifier of the chain. - // This field can be used to prevent replay of testnet transactions on mainnet. - pub chain_id: felt252, - // The transaction's nonce. - pub nonce: felt252, - // A span of ResourceBounds structs. - pub resource_bounds: Span, - // The tip. - pub tip: u128, - // If specified, the paymaster should pay for the execution of the tx. - // The data includes the address of the paymaster sponsoring the transaction, followed by - // extra data to send to the paymaster. - pub paymaster_data: Span, - // The data availability mode for the nonce. - pub nonce_data_availability_mode: u32, - // The data availability mode for the account balance from which fee will be taken. - pub fee_data_availability_mode: u32, - // If nonempty, will contain the required data for deploying and initializing an account - // contract: its class hash, address salt and constructor calldata. - pub account_deployment_data: Span, -} -``` - -`starknet::info` provides helper functions to access the `ExecutionInfo` fields in a more convenient way: - -- `get_execution_info() -> Box` -- `get_caller_address() -> ContractAddress` -- `get_contract_address() -> ContractAddress` -- `get_block_info() -> Box` -- `get_tx_info() -> Box` -- `get_block_timestamp() -> u64` -- `get_block_number() -> u64` - -#### call_contract - -```cairo -fn call_contract_syscall( - address: ContractAddress, entry_point_selector: felt252, calldata: Span -) -> SyscallResult> -``` - -Call a contract at `address` with the given `entry_point_selector` and `calldata`. -Failure can't be caught for this syscall, and if the call fails, the whole transaction will revert. - -This is not the recommended way to call a contract. Instead, use the dispatcher generated from the contract interface as shown in the [Calling other contracts](../interacting/calling_other_contracts.md) chapter. - - - -#### deploy - -```cairo -fn deploy_syscall( - class_hash: ClassHash, - contract_address_salt: felt252, - calldata: Span, - deploy_from_zero: bool, -) -> SyscallResult<(ContractAddress, Span::)> -``` - -Deploy a new contract of the predeclared class `class_hash` with `calldata`. -The success result is a tuple containing the deployed contract address and the return value of the constructor. - -`contract_address_salt` and `deploy_from_zero` are used to compute the contract address. - -Example of the usage of the `deploy` syscall from the [Factory pattern](../interacting/factory.md): - -<<<<<<<< HEAD:src/getting-started/basics/syscalls.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:deploy}} -======== -```rust -// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:deploy] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md -``` - -#### emit_event - -```cairo -fn emit_event_syscall( - keys: Span, data: Span -) -> SyscallResult<()> -``` - -Emit an event with the given `keys` and `data`. - -Example of the usage of the `emit_event` syscall from the [Events](../basics/events.md) chapter: - -<<<<<<<< HEAD:src/getting-started/basics/syscalls.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:emit}} -======== -```rust -// [!include ~/listings/getting-started/events/src/counter.cairo:emit] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md -``` - - - - -#### library_call - -```cairo -fn library_call_syscall( - class_hash: ClassHash, function_selector: felt252, calldata: Span -) -> SyscallResult> -``` - -Call the function `function_selector` of the class `class_hash` with `calldata`. -This is analogous to a delegate call in Ethereum, but only a single class is called. - - - -#### send_message_to_L1 - -```cairo -fn send_message_to_l1_syscall( - to_address: felt252, payload: Span -) -> SyscallResult<()> -``` - -Send a message to the L1 contract at `to_address` with the given `payload`. - - - -#### replace_class - -```cairo -fn replace_class_syscall( - class_hash: ClassHash -) -> SyscallResult<()> -``` - -Replace the class of the calling contract with the class `class_hash`. - -This is used for contract upgrades. Here's an example from the [Upgradeable Contract](../../applications/upgradeable_contract.md): - -<<<<<<<< HEAD:src/getting-started/basics/syscalls.md -```cairo -{{#rustdoc_include ../../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade}} -======== -```rust -// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:upgrade] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/syscalls.md -``` - -The new class code will only be used for future calls to the contract. -The current transaction containing the `replace_class` syscall will continue to use the old class code. Note that you can explicitly use the new class code in the same transaction by calling `call_contract` after the `replace_class` syscall. - -#### storage_read - -```cairo -fn storage_read_syscall( - address_domain: u32, address: StorageAddress, -) -> SyscallResult -``` - -This low-level syscall is used to get the value in the storage of a specific key at `address` in the `address_domain`. - -`address_domain` is used to distinguish between data availability modes. -Currently, only mode `ONCHAIN` (`0`) is supported. - -#### storage_write - -```cairo -fn storage_write_syscall( - address_domain: u32, address: StorageAddress, value: felt252 -) -> SyscallResult<()> -``` - -Similar to `storage_read`, this low-level syscall is used to write the value `value` in the storage of a specific key at `address` in the `address_domain`. - -## Documentation - -Syscalls are defined in [`starknet::syscall`](https://github.com/starkware-libs/cairo/blob/ec14a5e2c484190ff40811c973a72a53739cedb7/corelib/src/starknet/syscalls.cairo). - -You can also read the [official documentation page](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/) for more details. - - diff --git a/pages/ch00/basics/variables.md b/pages/ch00/basics/variables.md deleted file mode 100644 index 9ad59a6e..00000000 --- a/pages/ch00/basics/variables.md +++ /dev/null @@ -1,90 +0,0 @@ -# Variables - -There are 3 types of variables in Cairo contracts: - -- Local - - declared inside a function - - not stored on the blockchain -- Storage - - declared in the [Storage](./storage.md) of a contract - - can be accessed from one execution to another -- Global - - provides information about the blockchain - - accessed anywhere, even within library functions - -## Local Variables - -Local variables are used and accessed within the scope of a specific function or block of code. They are temporary and exist only for the duration of that particular function or block execution. - -Local variables are stored in memory and are not stored on the blockchain. This means they cannot be accessed from one execution to another. Local variables are useful for storing temporary data that is relevant only within a specific context. They also make the code more readable by giving names to intermediate values. - -Here's a simple example of a contract with only local variables: - -<<<<<<<< HEAD:src/getting-started/basics/variables.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/variables/src/local_variables.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/variables/src/local_variables.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/variables/src/local_variables.cairo:tests] -``` - -::: - -## Storage Variables - -Storage variables are persistent data stored on the blockchain. They can be accessed from one execution to another, allowing the contract to remember and update information over time. See [Storage](./storage.md) for more information. - -To write or update a storage variable, you need to interact with the contract through an external entrypoint by sending a transaction. - -On the other hand, you can read state variables for free, without any transaction, simply by interacting with a node. - -Here's a simple example of a contract with one storage variable: - -<<<<<<<< HEAD:src/getting-started/basics/variables.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/variables/src/storage_variables.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/variables/src/storage_variables.cairo:tests] -``` - -::: - -## Global Variables - -Global variables are predefined variables that provide information about the blockchain and the current execution environment. They can be accessed at any time and from anywhere! - -In Starknet, you can access global variables by using specific functions from the Starknet core library. - -For example, the `get_caller_address` function returns the address of the caller of the current transaction, and the `get_contract_address` function returns the address of the current contract. - -<<<<<<<< HEAD:src/getting-started/basics/variables.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/variables/src/global_variables.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/variables/src/global_variables.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/variables.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/variables/src/global_variables.cairo:tests] -``` - -::: diff --git a/pages/ch00/basics/visibility-mutability.md b/pages/ch00/basics/visibility-mutability.md deleted file mode 100644 index 24cfab47..00000000 --- a/pages/ch00/basics/visibility-mutability.md +++ /dev/null @@ -1,42 +0,0 @@ -# Visibility and Mutability - -## Visibility - -There are two types of functions in Starknet contracts: - -- Functions that are accessible externally and can be called by anyone. -- Functions that are only accessible internally and can only be called by other functions in the contract. - -These functions are also typically divided into two different implementation blocks. The first `impl` block for externally accessible functions is explicitly annotated with an `#[abi(embed_v0)]` attribute. This indicates that all the functions inside this block can be called either as a transaction or as a view function. The second `impl` block for internally accessible functions is not annotated with any attribute, which means that all the functions inside this block are private by default. - -## State Mutability - -Regardless of whether a function is internal or external, it can either modify the contract's state or not. When we declare functions that interact with storage variables inside a smart contract, -we need to explicitly state that we are accessing the `ContractState` by adding it as the first parameter of the function. This can be done in two different ways: - -- If we want our function to be able to mutate the state of the contract, we pass it by reference like this: `ref self: ContractState` -- If we want our function to be read-only and not mutate the state of the contract, we pass it by snapshot like this: `self: @ContractState` - -Read-only functions, also called view functions, can be directly called without making a transaction. You can interact with them directly through an RPC node to read the contract's state, and they're free to call! -External functions, that modify the contract's state, on the other hand, can only be called by making a transaction. - -Internal functions can't be called externally, but the same principle applies regarding state mutability. - -Let's take a look at a simple example contract to see these in action: - -<<<<<<<< HEAD:src/getting-started/basics/visibility-mutability.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/visibility/src/visibility.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/visibility/src/visibility.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/basics/visibility-mutability.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/visibility/src/visibility.cairo:tests] -``` - -::: diff --git a/pages/ch00/cairo_cheatsheet/arrays.md b/pages/ch00/cairo_cheatsheet/arrays.md deleted file mode 100644 index 8e7a30ba..00000000 --- a/pages/ch00/cairo_cheatsheet/arrays.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Arrays - -Arrays are collections of elements of the same type. -The possible operations on arrays are defined with the `array::ArrayTrait` of the corelib: - -```cairo -trait ArrayTrait { - fn new() -> Array; - fn append(ref self: Array, value: T); - fn pop_front(ref self: Array) -> Option nopanic; - fn pop_front_consume(self: Array) -> Option<(Array, T)> nopanic; - fn get(self: @Array, index: usize) -> Option>; - fn at(self: @Array, index: usize) -> @T; - fn len(self: @Array) -> usize; - fn is_empty(self: @Array) -> bool; - fn span(self: @Array) -> Span; -} -``` - -For example: - -<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/arrays.md -```cairo -{{#include ../../../listings/getting-started/cairo_cheatsheet/src/array_example.cairo}} -======== -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/array_example.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/arrays.md -``` diff --git a/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md b/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md deleted file mode 100644 index 57761760..00000000 --- a/pages/ch00/cairo_cheatsheet/cairo_cheatsheet.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Cairo Cheatsheet - -This chapter aims to provide a quick reference for the most common Cairo constructs. diff --git a/pages/ch00/cairo_cheatsheet/felt.md b/pages/ch00/cairo_cheatsheet/felt.md deleted file mode 100644 index b71778fd..00000000 --- a/pages/ch00/cairo_cheatsheet/felt.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Felt252 - -Felt252 is a fundamental data type in Cairo from which all other data types are derived. -Felt252 can also be used to store [short string representations](../basics/bytearrays-strings.md#short-strings) with a maximum length of 31 characters. - -For example: - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/felt_example.cairo:sheet] -``` diff --git a/pages/ch00/cairo_cheatsheet/if_let.md b/pages/ch00/cairo_cheatsheet/if_let.md deleted file mode 100644 index f7edd7e7..00000000 --- a/pages/ch00/cairo_cheatsheet/if_let.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# `if let` - -A `if let` statement is a combination of an `if` statement and a `let` statement. It allows you to execute the block only if the pattern matches. It's a cleaner way to handle a `match` statement with only one pattern that you want to handle. - -<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/if_let.md -```cairo -{{#include ../../../listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet}} -======== -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/if_let_example.cairo:sheet] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/if_let.md -``` - -### See also - -[while let](while_let.md) diff --git a/pages/ch00/cairo_cheatsheet/loop.md b/pages/ch00/cairo_cheatsheet/loop.md deleted file mode 100644 index 7efb6193..00000000 --- a/pages/ch00/cairo_cheatsheet/loop.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# `loop` - -A `loop` specifies a block of code that will run repetitively until a halting condition is encountered. - -For example: - -<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/loop.md -```cairo -{{#include ../../../listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet}} -======== -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/loop_example.cairo:sheet] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/loop.md -``` - -### See also - -[while](while.md) diff --git a/pages/ch00/cairo_cheatsheet/mapping.md b/pages/ch00/cairo_cheatsheet/mapping.md deleted file mode 100644 index b3bd0c19..00000000 --- a/pages/ch00/cairo_cheatsheet/mapping.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Mapping - -The `LegacyMap` type can be used to represent a collection of key-value. - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/mapping_example.cairo] -``` diff --git a/pages/ch00/cairo_cheatsheet/match.md b/pages/ch00/cairo_cheatsheet/match.md deleted file mode 100644 index 2d517def..00000000 --- a/pages/ch00/cairo_cheatsheet/match.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Match - -The "match" expression in Cairo allows us to control the flow of our code by comparing a felt data type or an enum against various patterns and then running specific code based on the pattern that matches. -For example: - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/match_example.cairo] -``` diff --git a/pages/ch00/cairo_cheatsheet/struct.md b/pages/ch00/cairo_cheatsheet/struct.md deleted file mode 100644 index ee96a1e1..00000000 --- a/pages/ch00/cairo_cheatsheet/struct.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Struct - -A struct is a data type similar to tuple. Like tuples they can be used to hold data of different types. -For example: - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/struct_example.cairo] -``` diff --git a/pages/ch00/cairo_cheatsheet/tuples.md b/pages/ch00/cairo_cheatsheet/tuples.md deleted file mode 100644 index 6d2935b9..00000000 --- a/pages/ch00/cairo_cheatsheet/tuples.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Tuples - -Tuples is a data type to group a fixed number of items of potentially different types into a single compound structure. Unlike arrays, tuples have a set length and can contain elements of varying types. Once a tuple is created, its size cannot change. - -For example: - -<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/tuples.md -```cairo -{{#include ../../../listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet}} -======== -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/tuple_example.cairo:sheet] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/tuples.md -``` diff --git a/pages/ch00/cairo_cheatsheet/type_casting.md b/pages/ch00/cairo_cheatsheet/type_casting.md deleted file mode 100644 index ecb1ceb0..00000000 --- a/pages/ch00/cairo_cheatsheet/type_casting.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Type casting - -Cairo supports the conversion from one scalar types to another by using the into and try_into methods. -`traits::Into` is used for conversion from a smaller data type to a larger data type, while `traits::TryInto` is used when converting from a larger to a smaller type that might not fit. -For example: - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/type_casting_example.cairo:sheet] -``` diff --git a/pages/ch00/cairo_cheatsheet/while.md b/pages/ch00/cairo_cheatsheet/while.md deleted file mode 100644 index b5bf0897..00000000 --- a/pages/ch00/cairo_cheatsheet/while.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# `while` - -A `while` loop allows you to specify a condition that must be true for the loop to continue. - -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/while_example.cairo:sheet] -``` - -### See also - -[loop](loop.md) diff --git a/pages/ch00/cairo_cheatsheet/while_let.md b/pages/ch00/cairo_cheatsheet/while_let.md deleted file mode 100644 index c5ec9813..00000000 --- a/pages/ch00/cairo_cheatsheet/while_let.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -showOutline: false -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# `while let` - -A `while let` loop is a combination of a `while` loop and a `let` statement. It allows you to execute the loop body only if the pattern matches. - -<<<<<<<< HEAD:src/getting-started/cairo_cheatsheet/while_let.md -```cairo -{{#include ../../../listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet}} -======== -```rust -// [!include ~/listings/getting-started/cairo_cheatsheet/src/while_let_example.cairo:sheet] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/cairo_cheatsheet/while_let.md -``` - -### See also - -- [while](while.md) -- [if let](if_let.md) diff --git a/pages/ch00/env_setup.md b/pages/ch00/env_setup.md deleted file mode 100644 index e07303af..00000000 --- a/pages/ch00/env_setup.md +++ /dev/null @@ -1,5 +0,0 @@ -# Local environment setup - -The current version of this book use `{{#include ../../.tool-versions}}` - - diff --git a/pages/ch00/interacting/calling_other_contracts.md b/pages/ch00/interacting/calling_other_contracts.md deleted file mode 100644 index 2768dffe..00000000 --- a/pages/ch00/interacting/calling_other_contracts.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Calling other contracts - -There are two different ways to call other contracts in Cairo. - -The easiest way to call other contracts is by using the dispatcher of the contract you want to call. -You can read more about Dispatchers in the [Cairo Book](https://book.cairo-lang.org/ch15-02-interacting-with-another-contract.html#calling-contracts-using-the-contract-dispatcher). - -The other way is to use the `starknet::call_contract_syscall` syscall yourself. However, this method is not recommended and will not be covered in this chapter. - -In order to call other contracts using dispatchers, you will need to define the called contract's interface as a trait annotated with the `#[starknet::interface]` attribute, and then import the `IContractDispatcher` and `IContractDispatcherTrait` items in your contract. - -Here's the `Callee` contract interface and implementation: - -<<<<<<<< HEAD:src/getting-started/interacting/calling_other_contracts.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract}} -``` - -The following `Caller` contract uses the `Callee` dispatcher to call the `Callee` contract: - -```cairo -{{#rustdoc_include ../../../listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:callee_contract] -``` - -```rust [tests] -// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] -``` - -::: - -The following `Caller` contract use the `Callee` interface to call the `Callee` contract: - -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:caller_contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/calling_other_contracts.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/calling_other_contracts/src/caller.cairo:tests] -``` - -::: diff --git a/pages/ch00/interacting/factory.md b/pages/ch00/interacting/factory.md deleted file mode 100644 index 90dd5681..00000000 --- a/pages/ch00/interacting/factory.md +++ /dev/null @@ -1,42 +0,0 @@ -# Factory Pattern - -The factory pattern is a well known pattern in object oriented programming. It provides an abstraction on how to instantiate a class. - -In the case of smart contracts, we can use this pattern by defining a factory contract that has the sole responsibility of creating and managing other contracts. - -## Class hash and contract instance - -In Starknet, there's a separation between contract's classes and instances. A contract class serves as a blueprint, defined by the underlying Cairo bytecode, contract's entrypoints, ABI and Sierra program hash. The contract class is identified by a class hash. When you want to add a new class to the network, you first need to declare it. - -When deploying a contract, you need to specify the class hash of the contract you want to deploy. Each instance of a contract has their own storage regardless of the class hash. - -Using the factory pattern, we can deploy multiple instances of the same contract class and handle upgrades easily. - -## Minimal example - -Here's a minimal example of a factory contract that deploys the `SimpleCounter` contract: - -<<<<<<<< HEAD:src/getting-started/interacting/factory.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/factory/src/simple_factory.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/factory.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/factory/src/simple_factory.cairo:tests] -``` - -::: - -This factory can be used to deploy multiple instances of the `SimpleCounter` contract by calling the `create_counter` and `create_counter_at` functions. - -The `SimpleCounter` class hash is stored inside the factory, and can be upgraded with the `update_counter_class_hash` function which allows to reuse the same factory contract when the `SimpleCounter` contract is upgraded. - -> Note: This minimal example lacks several useful features such as access control, tracking of deployed contracts, events etc. - - diff --git a/pages/ch00/interacting/interacting.md b/pages/ch00/interacting/interacting.md deleted file mode 100644 index 67dc71eb..00000000 --- a/pages/ch00/interacting/interacting.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Deploy and interact with contracts - -In this chapter, we will see how to deploy and interact with contracts. diff --git a/pages/ch00/interacting/interfaces-traits.md b/pages/ch00/interacting/interfaces-traits.md deleted file mode 100644 index b94760da..00000000 --- a/pages/ch00/interacting/interfaces-traits.md +++ /dev/null @@ -1,76 +0,0 @@ -# Contract interfaces and Traits generation - -Contract interfaces define the structure and behavior of a contract, serving as the contract's public ABI. They list all the function signatures that a contract exposes. For a detailed explanation of interfaces, you can refer to the [Cairo Book](https://book.cairo-lang.org/ch13-02-anatomy-of-a-simple-contract.html#the-interface-the-contracts-blueprint). - -In Cairo, to specify the interface you need to define a trait annotated with `#[starknet::interface]` and then implement that trait in the contract. - -When a function needs to access the contract state, it must have a `self` parameter of type `ContractState`. This implies that the corresponding function signature in the interface trait must also take a `TContractState` type as a parameter. It's important to note that every function in the contract interface must have this `self` parameter of type `TContractState`. - -You can use the `#[generate_trait]` attribute to implicitly generate the trait for a specific implementation block. This attribute automatically generates a trait with the same functions as the ones in the implemented block, replacing the `self` parameter with a generic `TContractState` parameter. However, you will need to annotate the block with the `#[abi(per_item)]` attribute, and each function with the appropriate attribute depending on whether it's an external function, a constructor or an L1 handler. - -In summary, there's two ways to handle interfaces: - -- Explicitly, by defining a trait annotated with `#[starknet::interface]` -- Implicitly, by using `#[generate_trait]` combined with the `#[abi(per_item)]` attributes, and annotating each function inside the implementation block with the appropriate attribute. - -## Explicit interface - -<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/explicit.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/interfaces_traits/src/explicit.cairo:tests] -``` - -::: - -## Implicit interface - -<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/interfaces_traits/src/implicit.cairo:tests] -``` - -::: - -> Note: You can import an implicitly generated contract interface with `use contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not be generated automatically. - -## Internal functions - -You can also use `#[generate_trait]` for your internal functions. -Since this trait is generated in the context of the contract, you can define pure functions as well (functions without the `self` parameter). - -<<<<<<<< HEAD:src/getting-started/interacting/interfaces-traits.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract}} -======== -:::code-group - -```rust [contract] -// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/interacting/interfaces-traits.md -``` - -```rust [tests] -// [!include ~/listings/getting-started/interfaces_traits/src/implicit_internal.cairo:tests] -``` - -::: diff --git a/pages/ch00/testing/contract-testing.md b/pages/ch00/testing/contract-testing.md deleted file mode 100644 index 66c80731..00000000 --- a/pages/ch00/testing/contract-testing.md +++ /dev/null @@ -1,113 +0,0 @@ -# Contract Testing - -Testing plays a crucial role in software development, especially for smart contracts. In this section, we'll guide you through the basics of testing a smart contract on Starknet with `scarb`. - -Let's start with a simple smart contract as an example: - -<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md -```cairo -{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:contract}} -======== -```rust -// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:contract] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md -``` - -Now, take a look at the tests for this contract: - -<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md -```cairo -{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests}} -======== -```rust -// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md -``` - -To define our test, we use scarb, which allows us to create a separate module guarded with `#[cfg(test)]`. This ensures that the test module is only compiled when running tests using `scarb test`. - -Each test is defined as a function with the `#[test]` attribute. You can also check if a test panics using the `#[should_panic]` attribute. - -As we are in the context of a smart contract, you can also set up the gas limit for a test by using the `#[available_gas(X)]`. This is a great way to ensure that some of your contract's features stay under a certain gas limit! - -> Note: The term "gas" here refers to Sierra gas, not L1 gas. - -Now, let's move on to the testing process: - -- Use the `deploy` function logic to declare and deploy your contract -- Use `assert` to verify that the contract behaves as expected in the given context - - You can also use assertion macros: `assert_eq!`, `assert_ne!`, `assert_gt!`, `assert_ge!`, `assert_lt!`, `assert_le!` - -If you haven't noticed yet, every example in this book has hidden tests, you can see them by clicking the "Show hidden lines" (eyes icon) on the top right of code blocks. -You can also find a detailed explanation of testing in Cairo in [The Cairo Book](https://book.cairo-lang.org/ch10-00-testing-cairo-programs.html). - -## Using the contract state - -You can use the `Contract::contract_state_for_testing` function to access the contract state. This function is only available in the test environment and allows you to mutate and read the contract state directly. - -This can be useful for testing internal functions, or specific state mutations that are not exposed to the contract's interface. You can either use it with a deployed contract or as a standalone state. - -Here is an example of how to do the same previous test using the contract state: - -<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md -```cairo -{{#include ../../../listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state}} -======== -```rust -// [!include ~/listings/getting-started/testing_how_to/src/contract.cairo:tests_with_state] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md -``` - -## Testing events - -In order to test events, you need to use the `starknet::pop_log` function. If the contract did not emit any events, the function will return `Option::None`. - -See the test for the [Events](../basics/events.md) section: - -<<<<<<<< HEAD:src/getting-started/testing/contract-testing.md -```cairo -{{#rustdoc_include ../../../listings/getting-started/events/src/counter.cairo:test_events}} -======== -```rust -// [!include ~/listings/getting-started/events/src/counter.cairo:test_events] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch00/testing/contract-testing.md -``` - -## Starknet Corelib Testing Module - -To make testing more convenient, the `testing` module of the corelib provides some helpful functions: - -- `set_caller_address(address: ContractAddress)` -- `set_contract_address(address: ContractAddress)` -- `set_block_number(block_number: u64)` -- `set_block_timestamp(block_timestamp: u64)` -- `set_account_contract_address(address: ContractAddress)` -- `set_sequencer_address(address: ContractAddress)` -- `set_version(version: felt252)` -- `set_transaction_hash(hash: felt252)` -- `set_chain_id(chain_id: felt252)` -- `set_nonce(nonce: felt252)` -- `set_signature(signature: felt252)` -- `set_max_fee(fee: u128)` -- `pop_log_raw(address: ContractAddress) -> Option<(Span, Span)>` -- `pop_log>(address: ContractAddress) -> Option` -- `pop_l2_to_l1_message(address: ContractAddress) -> Option<(felt252, Span)>` - -You may also need the `info` module from the corelib, which allows you to access information about the current execution context (see [syscalls](../basics/syscalls.md)): - -- `get_caller_address() -> ContractAddress` -- `get_contract_address() -> ContractAddress` -- `get_block_info() -> Box` -- `get_tx_info() -> Box` -- `get_block_timestamp() -> u64` -- `get_block_number() -> u64` - -You can find the full list of functions in the [Starknet Corelib repo](https://github.com/starkware-libs/cairo/tree/main/corelib/src/starknet). - -## Starknet Foundry - -Starknet Foundry is a powerful toolkit for developing smart contracts on Starknet. It offers support for testing Starknet smart contracts on top of `scarb` with the `Forge` tool. - -Testing with `snforge` is similar to the process we just described, but simplified. Moreover, additional features are on the way, including cheatcodes and parallel test execution. We highly recommend exploring Starknet Foundry and incorporating it into your projects. - -For more detailed information about testing contracts with Starknet Foundry, check out the [Starknet Foundry Book - Testing Contracts](https://foundry-rs.github.io/starknet-foundry/testing/contracts.html). diff --git a/pages/ch01/constant-product-amm.md b/pages/ch01/constant-product-amm.md deleted file mode 100644 index e13d7dec..00000000 --- a/pages/ch01/constant-product-amm.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Constant Product AMM - -This is the Cairo adaptation of the [Solidity by example Constant Product AMM](https://solidity-by-example.org/defi/constant-product-amm/). - -```rust -// [!include ~/listings/applications/constant_product_amm/src/contracts.cairo:ConstantProductAmmContract] -``` diff --git a/pages/ch01/erc20.md b/pages/ch01/erc20.md deleted file mode 100644 index dbc21402..00000000 --- a/pages/ch01/erc20.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# ERC20 Token - -Contracts that follow the [ERC20 Standard](https://eips.ethereum.org/EIPS/eip-20) are called ERC20 tokens. They are used to represent fungible assets. - -To create an ERC20 contract, it must implement the following interface: - -<<<<<<<< HEAD:src/applications/erc20.md -```cairo -{{#include ../../listings/applications/erc20/src/token.cairo:interface}} -======== -```rust -// [!include ~/listings/applications/erc20/src/token.cairo:interface] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md -``` - -In Starknet, function names should be written in _snake_case_. This is not the case in Solidity, where function names are written in _camelCase_. -The Starknet ERC20 interface is therefore slightly different from the Solidity ERC20 interface. - -Here's an implementation of the ERC20 interface in Cairo: - -<<<<<<<< HEAD:src/applications/erc20.md -```cairo -{{#include ../../listings/applications/erc20/src/token.cairo:erc20}} -======== -```rust -// [!include ~/listings/applications/erc20/src/token.cairo:erc20] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/erc20.md -``` - -There's several other implementations, such as the [Open Zeppelin](https://docs.openzeppelin.com/contracts-cairo/0.7.0/erc20) or the [Cairo By Example](https://cairo-by-example.com/examples/erc20/) ones. diff --git a/pages/ch01/signature_verification.md b/pages/ch01/signature_verification.md deleted file mode 100644 index afd2f847..00000000 --- a/pages/ch01/signature_verification.md +++ /dev/null @@ -1 +0,0 @@ -# Signature Verification diff --git a/pages/ch01/simple_vault.md b/pages/ch01/simple_vault.md deleted file mode 100644 index 7f9138fc..00000000 --- a/pages/ch01/simple_vault.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Simple Defi Vault - -This is the Cairo adaptation of the [Solidity by Example - Vault](https://solidity-by-example.org/defi/vault/). -Here's how it works: - -- When a user deposits a token, the contract calculates the amount of shares to mint. - -- When a user withdraws, the contract burns their shares, calculates the yield, and withdraws both the yield and the initial amount of tokens deposited. - -<<<<<<<< HEAD:src/applications/simple_vault.md -```cairo -{{#include ../../listings/applications/simple_vault/src/simple_vault.cairo}} -======== -```rust -// [!include ~/listings/applications/simple_vault/src/simple_vault.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/simple_vault.md -``` diff --git a/pages/ch01/upgradeable_contract.md b/pages/ch01/upgradeable_contract.md deleted file mode 100644 index 48388029..00000000 --- a/pages/ch01/upgradeable_contract.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Upgradeable Contract - -In Starknet, contracts are divided into two parts: contract classes and contract -instances. This division follows a similar concept used in object-oriented -programming languages, where we distinguish between the definition and implementation -of objects. - -A contract class is the definition of a contract: it specifies how the contract -behaves. It contains essential information like the Cairo byte code, hint -information, entry point names, and everything that defines its semantics -unambiguously. - -To identify different contract classes, Starknet assigns a unique identifier to each -class: the class hash. A contract instance is a deployed contract that corresponds to -a specific contract class. Think of it as an instance of an object in languages like -Java. - -Each class is identified by its class hash, which is analogous to a class name in an object-oriented programming language. A contract instance is a deployed contract corresponding to a class. - -You can upgrade a deployed contract to a newer version by calling the `replace_class_syscall` function. By using this function, you can update the class hash associated with a deployed contract, effectively upgrading its implementation. However, this will not modify the contract's storage, so all the data stored in the contract will remain the same. - -To illustrate this concept, let's consider an example with two contracts: `UpgradeableContract_V0`, and `UpgradeableContract_V1`. -Start by deploying `UpgradeableContract_V0` as the initial version. Next, send a transaction that invokes the `upgrade` function, with the class hash of `UpgradeableContract_V1` as parameter to upgrade the class hash of the deployed contract to the `UpgradeableContract_V1` one. Then, call the `version` method on the contract to see that the contract was upgraded to the V1 version. - -<<<<<<<< HEAD:src/applications/upgradeable_contract.md -```cairo -{{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract}} -``` - -```cairo -{{#include ../../listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo}} -======== -```rust -// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v0.cairo:contract] -``` - -```rust -// [!include ~/listings/applications/upgradeable_contract/src/upgradeable_contract_v1.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch01/upgradeable_contract.md -``` diff --git a/pages/ch02/hash-solidity-compatible.md b/pages/ch02/hash-solidity-compatible.md deleted file mode 100644 index 7ffc7e8b..00000000 --- a/pages/ch02/hash-solidity-compatible.md +++ /dev/null @@ -1,9 +0,0 @@ -# Hash Solidity Compatible - -This contract demonstrates Keccak hashing in Cairo to match Solidity's keccak256. While both use Keccak, their endianness differs: Cairo is little-endian, Solidity big-endian. The contract achieves compatibility by hashing in big-endian using `keccak_u256s_be_inputs`, and reversing the bytes of the result with `u128_byte_reverse`. - -For example: - -```cairo -{{#include ../../listings/advanced-concepts/hash_solidity_compatible/src/contract.cairo}} -``` diff --git a/pages/ch02/hashing.md b/pages/ch02/hashing.md deleted file mode 100644 index 78c4b8f6..00000000 --- a/pages/ch02/hashing.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Hashing - -Hashing is a cryptographic technique that allows you to transform a variable length input into a fixed length output. -The resulting output is called a hash and it's completely different from the input. -Hash functions are deterministic, meaning that the same input will always produce the same output. - -The two hash functions provided by the Cairo library are `Poseidon` and `Pedersen`. -Pedersen hashes were used in the past (but still used in some scenario for backward compatibility) while Poseidon hashes are the standard nowadays since they were designed to be very efficient for Zero Knowledge proof systems. - -In Cairo it's possible to hash all the types that can be converted to `felt252` since they implement natively the `Hash` trait. It's also possible to hash more complex types like structs by deriving the Hash trait with the attribute `#[derive(Hash)]` but only if all the struct's fields are themselves hashable. - -You first need to initialize a hash state with the `new` method of the `HashStateTrait` and then you can update it with the `update` method. You can accumulate multiple updates. Then, the `finalize` method returns the final hash value as a `felt252`. - -:::code-group - -```rust [contract] -// [!include ~/listings/advanced-concepts/hash_trait/src/hash_trait.cairo:hash] -``` - -```rust [tests] -// [!include ~/listings/advanced-concepts/hash_trait/src/hash_trait.cairo:tests] -``` - -::: diff --git a/pages/ch02/list.md b/pages/ch02/list.md deleted file mode 100644 index e3f8725c..00000000 --- a/pages/ch02/list.md +++ /dev/null @@ -1,70 +0,0 @@ -# List - -By default, there is no list type supported in Cairo, but you can use Alexandria. You can refer to the [Alexandria documentation](https://github.com/keep-starknet-strange/alexandria/tree/main/src/storage) for more details. - -## What is `List`? - -An ordered sequence of values that can be used in Starknet storage: - -```rust -#[storage] -struct Storage { - amounts: List -} -``` - -### Interface - -```rust -trait ListTrait { - fn len(self: @List) -> u32; - fn is_empty(self: @List) -> bool; - fn append(ref self: List, value: T) -> u32; - fn get(self: @List, index: u32) -> Option; - fn set(ref self: List, index: u32, value: T); - fn pop_front(ref self: List) -> Option; - fn array(self: @List) -> Array; -} -``` - -`List` also implements `IndexView` so you can use the familiar bracket notation to access its members: - -```rust -let second = self.amounts.read()[1]; -``` - -Note that unlike `get`, using this bracket notation panics when accessing an out of bounds index. - -### Support for custom types - -`List` supports most of the corelib types out of the box. If you want to store a your own custom type in a `List`, it has to implement the `Store` trait. You can have the compiler derive it for you using the `#[derive(starknet::Store)]` attribute. - -### Caveats - -There are two idiosyncacies you should be aware of when using `List` - -1. The `append` operation costs 2 storage writes - one for the value itself and another one for updating the List's length -2. Due to a compiler limitation, it is not possible to use mutating operations with a single inline statement. For example, `self.amounts.read().append(42);` will not work. You have to do it in 2 steps: - -```rust -let mut amounts = self.amounts.read(); -amounts.append(42); -``` - -### Dependencies - -Update your project dependencies by in the `Scarb.toml` file: - -```rust -[dependencies] -(...) -alexandria_storage = { git = "https://github.com/keep-starknet-strange/alexandria.git" } -``` - -For example, let's use `List` to create a contract that tracks a list of amounts and tasks: - -```rust -// [!include ~/listings/advanced-concepts/using_lists/src/contract.cairo] -``` - -istings/advanced-concepts/using_lists/src/contract.cairo diff --git a/pages/ch02/optimisations/optimisations.md b/pages/ch02/optimisations/optimisations.md deleted file mode 100644 index 8fd04b1e..00000000 --- a/pages/ch02/optimisations/optimisations.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Optimisations - -A collection of optimisation patterns to save gas and steps. diff --git a/pages/ch02/optimisations/store_using_packing.md b/pages/ch02/optimisations/store_using_packing.md deleted file mode 100644 index 48f256aa..00000000 --- a/pages/ch02/optimisations/store_using_packing.md +++ /dev/null @@ -1,35 +0,0 @@ -# Storage optimisation - -A smart contract has a limited amount of **storage slots**. Each slot can store a single `felt252` value. -Writing to a storage slot has a cost, so we want to use as few storage slots as possible. - -In Cairo, every type is derived from the `felt252` type, which uses 252 bits to store a value. -This design is quite simple, but it does have a drawback: it is not storage efficient. For example, if we want to store a `u8` value, we need to use an entire slot, even though we only need 8 bits. - -## Packing - -When storing multiple values, we can use a technique called **packing**. Packing is a technique that allows us to store multiple values in a single `felt252` value. This is done by using the bits of the `felt252` value to store multiple values. - -For example, if we want to store two `u8` values, we can use the first 8 bits of the `felt252` value to store the first `u8` value, and the last 8 bits to store the second `u8` value. This way, we can store two `u8` values in a single `felt252` value. - -Cairo provides a built-in store using packing that you can use with the `StorePacking` trait. - -```cairo -trait StorePacking { - fn pack(value: T) -> PackedT; - fn unpack(value: PackedT) -> T; -} -``` - -This allows us to store the type `T` by first packing it into the type `PackedT` with the `pack` function, and then storing the `PackedT` value with it's `Store` implementation. When reading the value, we first retrieve the `PackedT` value, and then unpack it into the type `T` using the `unpack` function. - -Here's an example of storing a `Time` struct with two `u8` values using the `StorePacking` trait: - -<<<<<<<< HEAD:src/advanced-concepts/optimisations/store_using_packing.md -```cairo -{{#include ../../../listings/advanced-concepts/store_using_packing/src/contract.cairo}} -======== -```rust -// [!include ~/listings/advanced-concepts/store_using_packing/src/contract.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/optimisations/store_using_packing.md -``` diff --git a/pages/ch02/plugins.md b/pages/ch02/plugins.md deleted file mode 100644 index e2bb86ca..00000000 --- a/pages/ch02/plugins.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Plugins - -Compilers plugin in Cairo are a way to generate additional code for specific items during the compilation process. - -There are already a set of core plugins that you may have already used, such as `#[derive]`, `#[cfg]`, `#[generate_trait]`, etc. - -It is possible to create your own plugins in rust. You can learn more about how to do that in the [hello-cairo-plugin](https://github.com/piwonskp/hello-cairo-plugin) repository. diff --git a/pages/ch02/signature_verification.md b/pages/ch02/signature_verification.md deleted file mode 100644 index c7f46de0..00000000 --- a/pages/ch02/signature_verification.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# ECDSA Verification - -This is the Cairo adaptation of the [Solidity by example Verifying Signature](https://solidity-by-example.org/signature/) -Messages can be signed off chain and then verified on chain using a smart contract. - -```rust -// [!include ~/listings/advanced-concepts/ecdsa_verification/src/ecdsa_verification.cairo] -``` - -[Click here to interact with the deployed contract on Voyager](https://goerli.voyager.online/contract/0x070bad62072d2a30fd08a95e9de99828955cfcffc40eac8adf3b21e9970590be#writeContract) diff --git a/pages/ch02/storing_arrays.md b/pages/ch02/storing_arrays.md deleted file mode 100644 index ce5c940c..00000000 --- a/pages/ch02/storing_arrays.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Storing Arrays - -On Starknet, complex values (e.g., tuples or structs), are stored in a continuous segment starting from the address of the storage variable. There is a 256 field elements limitation to the maximal size of a complex storage value, meaning that to store arrays of more than 255 elements in storage, we would need to split it into segments of size `n <= 255` and store these segments in multiple storage addresses. There is currently no native support for storing arrays in Cairo, so you will need to write your own implementation of the `Store` trait for the type of array you wish to store. - -However, the `ByteArray` struct can be used to store `Array` in storage without additional implementation. Before implementing your own `Store` trait, consider wether the `ByteArray` struct can be used to store the data you need! See the [ByteArray](../ch00/basics/bytearrays-strings.md#bytearray-long-strings) section for more information. - -> Note: While storing arrays in storage is possible, it is not always recommended, as the read and write operations can get very costly. For example, reading an array of size `n` requires `n` storage reads, and writing to an array of size `n` requires `n` storage writes. If you only need to access a single element of the array at a time, it is recommended to use a `LegacyMap` and store the length in another variable instead. - -The following example demonstrates how to write a simple implementation of the `StorageAccess` trait for the `Array` type, allowing us to store arrays of up to 255 `felt252` elements. - -```rust -// [!include ~/listings/advanced-concepts/storing_arrays/src/contract.cairo:StorageAccessImpl] -``` - -You can then import this implementation in your contract and use it to store arrays in storage: - -```rust -// [!include ~/listings/advanced-concepts/storing_arrays/src/contract.cairo:StoreArrayContract] -``` diff --git a/pages/ch02/struct-mapping-key.md b/pages/ch02/struct-mapping-key.md deleted file mode 100644 index b0eec8b1..00000000 --- a/pages/ch02/struct-mapping-key.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Structs as mapping keys - -In order to use structs as mapping keys, you can use `#[derive(Hash)]` on the struct definition. This will automatically generate a hash function for the struct that can be used to represent the struct as a key in a `Map`. - -Consider the following example in which we would like to use an object of -type `Pet` as a key in a `Map`. The `Pet` struct has three fields: `name`, `age` and `owner`. We consider that the combination of these three fields uniquely identifies a pet. - -<<<<<<<< HEAD:src/advanced-concepts/struct-mapping-key.md -```cairo -{{#include ../../listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo}} -======== -```rust -// [!include ~/listings/advanced-concepts/struct_as_mapping_key/src/contract.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/struct-mapping-key.md -``` diff --git a/pages/ch02/write_to_any_slot.md b/pages/ch02/write_to_any_slot.md deleted file mode 100644 index 50dd24ba..00000000 --- a/pages/ch02/write_to_any_slot.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Writing to any storage slot - -On Starknet, a contract's storage is a map with \\( 2^{251} \\) slots, where each slot is a `felt252` which is initialized to 0. -The address of storage variables is computed at compile time using the formula: `storage variable address := pedersen(keccak(variable name), keys)`. Interactions with storage variables are commonly performed using the `self.var.read()` and `self.var.write()` functions. - -Nevertheless, we can use the `storage_write_syscall` and `storage_read_syscall` syscalls, to write to and read from any storage slot. -This is useful when writing to storage variables that are not known at compile time, or to ensure that even if the contract is upgraded and the computation method of storage variable addresses changes, they remain accessible. - -In the following example, we use the Poseidon hash function to compute the address of a storage variable. Poseidon is a ZK-friendly hash function that is cheaper and faster than Pedersen, making it an excellent choice for onchain computations. Once the address is computed, we use the storage syscalls to interact with it. - -<<<<<<<< HEAD:src/advanced-concepts/write_to_any_slot.md -```cairo -{{#include ../../listings/advanced-concepts/write_to_any_slot/src/contract.cairo}} -======== -```rust -// [!include ~/listings/advanced-concepts/write_to_any_slot/src/contract.cairo] ->>>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/ch02/write_to_any_slot.md -``` diff --git a/pages/components/collisions.md b/pages/components/collisions.md deleted file mode 100644 index c3caeee8..00000000 --- a/pages/components/collisions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Component-Contract Storage Collisions - -Components can declare their own storage variables. - -When a contract uses a component, the component storage is merged with the contract storage. -The storage layout is only determined by the variables names, so variables with the same name will collide. - -> In a future release, the `#[substorage(v1)]` will determine the storage layout based on the component as well, so collisions will be avoided. - -A good practice is to prefix the component storage variables with the component name, as shown in the [Switchable component example](./how_to.md). - -#### Example - -Here's an example of a collision on the `switchable_value` storage variable of the `Switchable` component. - -Interface: - -<<<<<<< HEAD:src/components/collisions.md -```cairo -{{#include ../../listings/applications/components/src/others/switch_collision.cairo:interface}} -``` - -Here's the storage of the contract (you can expand the code snippet to see the full contract and tests): - -```cairo -{{#rustdoc_include ../../listings/applications/components/src/others/switch_collision.cairo:storage}} -======= -```rust -// [!include ~/listings/applications/components/src/contracts/switch_collision.cairo:interface] -``` - -Here's the storage of the contract (you can expand the code snippet to see the full contract): - -```rust -// [!include ~/listings/applications/components/src/contracts/switch_collision.cairo:storage] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/collisions.md -``` - -Both the contract and the component have a `switchable_value` storage variable, so they collide: - -<<<<<<< HEAD:src/components/collisions.md -```cairo -{{#include ../../listings/applications/components/src/others/switch_collision.cairo:collision}} -======= -```rust -// [!include ~/listings/applications/components/src/contracts/tests/switch_collision_tests.cairo:tests] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/collisions.md -``` diff --git a/pages/components/dependencies.md b/pages/components/dependencies.md deleted file mode 100644 index bbf15ceb..00000000 --- a/pages/components/dependencies.md +++ /dev/null @@ -1,136 +0,0 @@ -<<<<<<< HEAD:src/components/dependencies.md -# Component Dependencies -======= ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Components Dependencies ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md - -A component with a dependency on a trait `T` can be used in a contract as long as the contract implements the trait `T`. - -We will use a new `Countable` component as an example: - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#rustdoc_include ../../listings/applications/components/src/countable.cairo:component}} -======= -```rust -// [!include ~/listings/applications/components/src/countable.cairo] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md -``` - -We want to add a way to enable or disable the counter, in a way that calling `increment` on a disabled counter will not increment it. -But we don't want to add this switch logic to the `Countable` component itself. -Instead, we add the trait `Switchable` as a dependency to the `Countable` component. - -#### Implementation of the trait in the contract - -First, we import the `ISwitchable` trait defined in chapter ["Components How-To"](./how_to.md): - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#include ../../listings/applications/components/src/switchable.cairo:interface}} -======= -```rust -// [!include ~/listings/applications/components/src/switchable.cairo:interface] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md -``` - -Then we can modify the implementation of the `Countable` component to depend on the `ISwitchable` trait: - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#rustdoc_include ../../listings/applications/components_dependencies/src/countable_dep_switch.cairo:impl}} -======= -```rust -// [!include ~/listings/applications/components_dependencies/src/countable_dep_switch.cairo:impl] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md -``` - -A contract that uses the `Countable` component must implement the `ISwitchable` trait: - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#rustdoc_include ../../listings/applications/components_dependencies/src/contract_countable.cairo:contract}} -======= -:::code-group - -```rust [contract] -// [!include ~/listings/applications/components_dependencies/src/contract_countable.cairo:contract] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md -``` - -```rust [tests] -// [!include ~/listings/applications/components_dependencies/src/contract_countable.cairo:tests] -``` - -::: - -#### Implementation of the trait in another component - -In the previous example, we implemented the `ISwitchable` trait in the contract. - -We already implemented a [`Switchable`](./how_to.md) component that provides an implementation of the `ISwitchable` trait. -By using the `Switchable` component in a contract, we can embed the implementation of the `ISwitchable` trait in the contract and resolve the dependency on the `ISwitchable` trait. - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#rustdoc_include ../../listings/applications/components_dependencies/src/contract_countable_switchable.cairo:contract}} -``` - -#### Dependency on other component's internal functions -======= -:::code-group - -```rust [contract] -// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable.cairo:tests] -``` - -::: - -#### Dependency on other components internal functions ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md - -The previous example shows how to use the `ISwitchable` trait implementation from the `Switchable` component inside the `Countable` component by embedding the implementation in the contract. -However, suppose we would like to turn off the switch after each increment. There's no `set` function in the `ISwitchable` trait, so we can't do it directly. - -But the `Switchable` component implements the internal function `_off` from the `SwitchableInternalTrait` that set the switch to `false`. -We can't embed `SwitchableInternalImpl`, but we can add `switchable::HasComponent` as a dependency inside `CountableImpl`. - -We make the `Countable` component depend on the `Switchable` component. -This will allow to do `switchable::ComponentState` -> `TContractState` -> `countable::ComponentState` and access the internal functions of the `Switchable` component inside the `Countable` component: - -<<<<<<< HEAD:src/components/dependencies.md -```cairo -{{#rustdoc_include ../../listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo:contract}} -``` - -The `CountableContract` contract remains the same as in the previous example, only the implementation of the `Countable` component is different. -======= -```rust -// [!include ~/listings/applications/components_dependencies/src/countable_internal_dep_switch.cairo] -``` - -The contract remains the same that the previous example, but the implementation of the `Countable` component is different: - -:::code-group - -```rust [contract] -// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo:contract] -``` - -```rust [tests] -// [!include ~/listings/applications/components_dependencies/src/contract_countable_switchable_internal.cairo:tests] -``` - -::: ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/dependencies.md diff --git a/pages/components/how_to.md b/pages/components/how_to.md deleted file mode 100644 index 0d11115c..00000000 --- a/pages/components/how_to.md +++ /dev/null @@ -1,87 +0,0 @@ -# Components How-To - -Components are like modular addons that can be snapped into contracts to add reusable logic, storage, and events. -They are used to separate the core logic from common functionalities, simplifying the contract's code and making it easier to read and maintain. -It also reduces the risk of bugs and vulnerabilities by using well-tested components. - -Key characteristics: - -- Modularity: Easily pluggable into multiple contracts. -- Reusable Logic: Encapsulates specific functionalities. -- Not Standalone: Cannot be declared or deployed independently. - -## How to create a component - -The following example shows a simple `Switchable` component that can be used to add a switch that can be either on or off. -It contains a storage variable `switchable_value`, a function `switch` and an event `Switch`. - -> It is a good practice to prefix the component storage variables with the component name to [avoid collisions](./collisions.md). - -<<<<<<< HEAD:src/components/how_to.md -```cairo -{{#include ../../listings/applications/components/src/switchable.cairo:component}} -``` - -A component is really similar to a contract and can also have: -======= -```rust -// [!include ~/listings/applications/components/src/switchable.cairo:component] -``` - -A component in itself is really similar to a contract, it _can_ also have: ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md - -- An interface defining entrypoints (`ISwitchableComponent`) -- A Storage struct -- Events -- Internal functions - -It doesn't have a constructor, but you can create an `_init` internal function and call it from the contract's constructor. In the previous example, the `_off` function will be used this way. - -> It's currently not possible to use the same component multiple times in the same contract. -> This is a known limitation that may be lifted in the future. -> -<<<<<<< HEAD:src/components/how_to.md -> For now, you can view components as implementations of specific interfaces or features (`Ownable`, `Upgradeable`, ... `~able`). -> This is why we called the component in the above example `Switchable`, and not `Switch`; the contract _is switchable_, it does not _have a switch_. -======= -> For now, you can view components as an implementation of a specific interface/feature (`Ownable`, `Upgradeable`, ... `~able`). -> This is why we called it `Switchable` and not `Switch`; The contract _is switchable_, not _has a switch_. ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md - -## How to use a component - -Now that we have a component, we can use it in a contract. -The following contract incorporates the `Switchable` component: - -<<<<<<< HEAD:src/components/how_to.md -```cairo -{{#include ../../listings/applications/components/src/switchable.cairo:contract}} -``` - -## How to test a component - -In order to effectively test a component, you need to test it in the context of a contract. -A common practice is to declare a `Mock` contract that has the only purpose of testing the component. - -To test the `Switchable` component, we can use the previous `SwitchableContract`: - -```cairo -{{#include ../../listings/applications/components/src/switchable.cairo:tests}} -======= -:::code-group - -```rust [contract] -// [!include ~/listings/applications/components/src/contracts/switch.cairo:contract] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/how_to.md -``` - -```rust [tests] -// [!include ~/listings/applications/components/src/contracts/switch.cairo:tests] -``` - -::: - -## Deep dive into components - -You can find more in-depth information about components in [The Cairo book - Components](https://book.cairo-lang.org/ch16-02-00-composability-and-components.html). diff --git a/pages/components/ownable.md b/pages/components/ownable.md deleted file mode 100644 index 3d44f6e9..00000000 --- a/pages/components/ownable.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -content: - horizontalPadding: 50px - width: 100% - verticalPadding: 30px ---- - -# Ownable - -The following `Ownable` component is a simple component that allows the contract to set an owner and provides an `_assert_is_owner` function that can be used to ensure that the caller is the owner. - -It can also be used to renounce ownership of a contract, meaning that no one will be able to satisfy the `_assert_is_owner` function. - -<<<<<<< HEAD:src/components/ownable.md -```cairo -{{#include ../../listings/applications/components/src/ownable.cairo:component}} -======= -```rust -// [!include ~/listings/applications/components/src/ownable.cairo] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/ownable.md -``` - -A mock contract that uses the `Ownable` component: - -<<<<<<< HEAD:src/components/ownable.md -```cairo -{{#rustdoc_include ../../listings/applications/components/src/ownable.cairo:contract}} -======= -:::code-group - -```rust [contract] -// [!include ~/listings/applications/components/src/contracts/owned.cairo:contract] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/components/ownable.md -``` - -```rust [tests] -// [!include ~/listings/applications/components/src/contracts/owned.cairo:tests] -``` - -::: diff --git a/pages/getting-started.mdx b/pages/getting-started.mdx deleted file mode 100644 index 99b8616e..00000000 --- a/pages/getting-started.mdx +++ /dev/null @@ -1,3 +0,0 @@ -# Get started - -Hello world! \ No newline at end of file diff --git a/pages/index.mdx b/pages/index.mdx deleted file mode 100644 index e7903161..00000000 --- a/pages/index.mdx +++ /dev/null @@ -1,57 +0,0 @@ -import { Callout } from "vocs/components"; - -# Starknet by Example - -Starknet By Example is a collection of examples of how to use the Cairo programming language to create smart contracts on Starknet. - -Starknet is a permissionless Validity-Rollup that supports general computation. It is currently used as an Ethereum layer-2. Starknet uses the STARK cryptographic proof system to ensure high safety and scalability. - -Starknet smart contracts are written in the Cairo language. Cairo is a Turing-complete programming language designed to write provable programs, abstracting the zk-STARK proof system away from the programmer. - - - ⚠️ The examples have not been audited and are not intended for production use. - The authors are not responsible for any damages caused by the use of the code - provided in this book. - - -## For whom is this for? - -Starknet By Example is for anyone who wants to quickly learn how to write smart contracts on Starknet using Cairo with some technical background in programming and blockchain. - -The first chapters will give you a basic understanding of the Cairo programming language and how to write, deploy and use smart contracts on Starknet. -The later chapters will cover more advanced topics and show you how to write more complex smart contracts. - -## How to use this book? - -Each chapter is a standalone example that demonstrates a specific feature or common use case of smart contracts on Starknet. If you are new to Starknet, it is recommended to read the chapters in order. - -Most examples contain interfaces and tests that are hidden by default. You can hover over the code blocks and click on the "Show hidden lines" (eyes icon) to see the hidden code. - -You can run each example online by using the [Starknet Remix Plugin](https://remix.ethereum.org/?#activate=Starknet). - -## Further reading - -If you want to learn more about the Cairo programming language, you can read the [Cairo Book](https://book.cairo-lang.org). -If you want to learn more about Starknet, you can read the [Starknet documentation](https://docs.starknet.io/) and the [Starknet Book](https://book.starknet.io). - -For more resources, check [Awesome Starknet](https://github.com/keep-starknet-strange/awesome-starknet). - -## Versions - -<<<<<<< HEAD:src/starknet-by-example.md -The current version this book uses: - -``` -cairo 2.8.2 -edition = "2024_07" -sierra: 1.6.0 -{{#include ../.tool-versions}} -======= -The current version of this book use: - -``` -cairo 2.6.3 -edition = '2023_11' -// [!include ~/.tool-versions] ->>>>>>> 261b110 (feat: migrate frontend framework from mdbook to vocs (#185)):pages/index.mdx -``` diff --git a/pages/indexdasds.mdx b/pages/indexdasds.mdx deleted file mode 100644 index b2bfc909..00000000 --- a/pages/indexdasds.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -layout: landing ---- - -import { HomePage } from 'vocs/components' - - - - My Awesome Docs - - This is a description of my documentation website. - - Get started - GitHub - - \ No newline at end of file diff --git a/vocs.config.ts b/vocs.config.ts index 992fb468..f2b944a1 100644 --- a/vocs.config.ts +++ b/vocs.config.ts @@ -15,134 +15,134 @@ export default defineConfig({ items: [ { text: "1. Basics of a Starknet contract", - link: "/ch00/basics/introduction", + link: "/getting-started/basics/introduction", collapsed: false, items: [ { text: "1.1. Storage", - link: "/ch00/basics/storage", + link: "/getting-started/basics/storage", }, { text: "1.2. Constructor", - link: "/ch00/basics/constructor", + link: "/getting-started/basics/constructor", }, { text: "1.3. Variables", - link: "/ch00/basics/variables", + link: "/getting-started/basics/variables", }, { text: "1.4. Visibility and Mutability", - link: "/ch00/basics/visibility-mutability", + link: "/getting-started/basics/visibility-mutability", }, { text: "1.5. Counter Example", - link: "/ch00/basics/counter", + link: "/getting-started/basics/counter", }, { text: "1.6. Mappings", - link: "/ch00/basics/mappings", + link: "/getting-started/basics/mappings", }, { text: "1.7. Errors", - link: "/ch00/basics/errors", + link: "/getting-started/basics/errors", }, { text: "1.8. Events", - link: "/ch00/basics/events", + link: "/getting-started/basics/events", }, { text: "1.9. Syscalls", - link: "/ch00/basics/syscalls", + link: "/getting-started/basics/syscalls", }, { text: "1.10. Strings and ByteArrays", - link: "/ch00/basics/bytearrays-strings", + link: "/getting-started/basics/bytearrays-strings", }, { text: "1.11. Storing Custom Types", - link: "/ch00/basics/storing-custom-types", + link: "/getting-started/basics/storing-custom-types", }, { text: "1.12. Custom types in entrypoints", - link: "/ch00/basics/custom-types-in-entrypoints", + link: "/getting-started/basics/custom-types-in-entrypoints", }, { text: "1.13. Documentation", - link: "/ch00/basics/documentation", + link: "/getting-started/basics/documentation", }, ], }, { text: "2. Deploy and interact with contracts", - link: "/ch00/interacting/interacting", + link: "/getting-started/interacting/interacting", collapsed: true, items: [ { text: "2.1. Contract interfaces and Traits generation", - link: "/ch00/interacting/interfaces-traits", + link: "/getting-started/interacting/interfaces-traits", }, { text: "2.2. Calling other contracts", - link: "/ch00/interacting/calling_other_contracts", + link: "/getting-started/interacting/calling_other_contracts", }, { text: "2.3. Factory pattern", - link: "/ch00/interacting/factory", + link: "/getting-started/interacting/factory", }, ], }, { text: "3. Testing contracts", - link: "/ch00/testing/contract-testing", + link: "/getting-started/testing/contract-testing", }, { text: "4. Cairo cheatsheet", - link: "/ch00/cairo_cheatsheet/cairo_cheatsheet", + link: "/getting-started/cairo_cheatsheet/cairo_cheatsheet", collapsed: true, items: [ { text: "4.1. Felt", - link: "/ch00/cairo_cheatsheet/felt", + link: "/getting-started/cairo_cheatsheet/felt", }, { text: "4.2. LegacyMap", - link: "/ch00/cairo_cheatsheet/mapping", + link: "/getting-started/cairo_cheatsheet/mapping", }, { text: "4.3. Arrays", - link: "/ch00/cairo_cheatsheet/arrays", + link: "/getting-started/cairo_cheatsheet/arrays", }, { text: "4.4. loop", - link: "/ch00/cairo_cheatsheet/loop", + link: "/getting-started/cairo_cheatsheet/loop", }, { text: "4.5. while", - link: "/ch00/cairo_cheatsheet/while", + link: "/getting-started/cairo_cheatsheet/while", }, { text: "4.6. if let", - link: "/ch00/cairo_cheatsheet/if_let", + link: "/getting-started/cairo_cheatsheet/if_let", }, { text: "4.7. while let", - link: "/ch00/cairo_cheatsheet/while_let", + link: "/getting-started/cairo_cheatsheet/while_let", }, { text: "4.8. Match", - link: "/ch00/cairo_cheatsheet/match", + link: "/getting-started/cairo_cheatsheet/match", }, { text: "4.9. Tuples", - link: "/ch00/cairo_cheatsheet/tuples", + link: "/getting-started/cairo_cheatsheet/tuples", }, { text: "4.10. Struct", - link: "/ch00/cairo_cheatsheet/struct", + link: "/getting-started/cairo_cheatsheet/struct", }, { text: "4.11. Type casting", - link: "/ch00/cairo_cheatsheet/type_casting", + link: "/getting-started/cairo_cheatsheet/type_casting", }, ], }, @@ -174,19 +174,19 @@ export default defineConfig({ items: [ { text: "9. Upgradeable Contract", - link: "/ch01/upgradeable_contract", + link: "/applications/upgradeable_contract", }, { text: "10. Defi Vault", - link: "/ch01/simple_vault", + link: "/applications/simple_vault", }, { text: "11. ERC20 Token", - link: "/ch01/erc20", + link: "/applications/erc20", }, { text: "12. Constant Product AMM", - link: "/ch01/constant-product-amm", + link: "/applications/constant-product-amm", }, ], }, @@ -195,42 +195,42 @@ export default defineConfig({ items: [ { text: "13. Writing to any storage slot", - link: "/ch02/write_to_any_slot", - }, - { - text: "14. Storing Arrays", - link: "/ch02/storing_arrays", + link: "/advanced-concepts/write_to_any_slot", }, + // { + // text: "14. Storing Arrays", + // link: "/advanced-concepts/storing_arrays", + // }, { text: "15. Struct as mapping key", - link: "/ch02/struct-mapping-key", + link: "/advanced-concepts/struct-mapping-key", }, { text: "16. Hashing", - link: "/ch02/hashing", + link: "/advanced-concepts/hashing", }, { text: "17. Optimisations", - link: "/ch02/optimisations/optimisations", + link: "/advanced-concepts/optimisations/optimisations", collapsed: false, items: [ { text: "17.1. Storage Optimisations", - link: "/ch02/optimisations/store_using_packing", + link: "/advanced-concepts/optimisations/store_using_packing", }, ], }, - { - text: "18. List", - link: "/ch02/list", - }, + // { + // text: "18. List", + // link: "/advanced-concepts/list", + // }, { text: "19. Plugins", - link: "/ch02/plugins", + link: "/advanced-concepts/plugins", }, { text: "20. Signature Verification", - link: "/ch02/signature_verification", + link: "/advanced-concepts/signature_verification", }, ], },
    - - - - - - - - - - - - - - - - - - - -
    - -
    - {{> header}} - - - - {{#if search_enabled}} - - {{/if}} - - - - -
    -
    - {{{ content }}} -
    - - -
    -
    - - - -
    - - {{#if live_reload_endpoint}} - - - {{/if}} - - {{#if google_analytics}} - - - {{/if}} - - {{#if playground_line_numbers}} - - {{/if}} - - {{#if playground_copyable}} - - {{/if}} - - {{#if playground_js}} - - - - - - {{/if}} - - {{#if search_js}} - - - - {{/if}} - - - - - - - {{#each additional_js}} - - {{/each}} - - {{#if is_print}} - {{#if mathjax_support}} - - {{else}} - - {{/if}} - {{/if}} - -