From d9ab9c33e61d5d2db13382758d42a8ec73e8bc0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 12 Nov 2025 14:31:28 -0800 Subject: [PATCH 001/162] fix title location --- docs/stylus/gentle-introduction.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 6662a24ab3..20eb3faf4a 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -11,8 +11,6 @@ displayed_sidebar: buildAppsSidebar import ImageZoom from '@site/src/components/ImageZoom'; -# A gentle introduction: Stylus - ### In a nutshell: - Stylus lets you write smart contracts in programming languages that compile to WASM, such as **Rust, C, C++, and many others**, allowing you to tap into their ecosystem of libraries and tools. Rich language and tooling support already exist for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). From e11335b6342ae1d3fb672121b2ecf571baf5135d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 14:02:30 -0800 Subject: [PATCH 002/162] remove deprecated overview file --- docs/stylus/overview.mdx | 81 ---------------------------------------- 1 file changed, 81 deletions(-) delete mode 100644 docs/stylus/overview.mdx diff --git a/docs/stylus/overview.mdx b/docs/stylus/overview.mdx deleted file mode 100644 index 10b1700705..0000000000 --- a/docs/stylus/overview.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -id: stylus-overview -title: Write Stylus Contracts -sidebar_label: Write Stylus contracts -displayed_sidebar: buildAppsSidebar ---- - -import Card from '@site/src/components/Cards/Card'; - -# Write Stylus Contracts - -Let's learn how to write contracts with Stylus! - -
- - - - - - - - - - - - -
From 8d14fb4289ec99d793ec9a7f90608963829b42f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 14:07:58 -0800 Subject: [PATCH 003/162] resize multivm diagram --- docs/stylus/gentle-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 20eb3faf4a..b6f1695509 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -21,7 +21,7 @@ import ImageZoom from '@site/src/components/ImageZoom'; Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. We call this paradigm **MultiVM** since **everything is entirely additive.** - + This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a modern binary format popularized by its use in major web standards, browsers, and companies to speed up computation. WASM is built to be fast, portable, and human-readable. It has sandboxed execution environments for security and simplicity. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fully functioning fraud proofs. From 0493ac838600c93044e1babf3e938a7e990e39e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 14:09:45 -0800 Subject: [PATCH 004/162] refactor: integrate markdownlint into format workflow Add lint:markdown:fix to the format script to automatically fix markdown linting issues when running yarn format. This ensures markdown files are both formatted (prettier) and linted (markdownlint) in one command. The new format workflow: 1. Format docs with prettier 2. Format app files with prettier 3. Auto-fix markdown linting issues 4. Verify all files pass prettier check --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4779955263..4bb9a5a5dc 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "find-orphan-pages": "tsx scripts/find-orphan-pages.ts", - "format": "yarn format:docs && yarn format:app && yarn format:check", + "format": "yarn format:docs && yarn format:app && yarn lint:markdown:fix && yarn format:check", "format:app": "prettier --write --config \"./.prettierrc.js\" -- \"./*.{js,json}\" \"src/**/*.{tsx,ts,scss,json,js}\"", "format:docs": "prettier --write --config \"./.prettierrc.js\" -- \"docs/**/*.{md,mdx}\"", "format:check": "prettier --check --config \"./.prettierrc.js\" -- \"./*.{js,json}\" \"src/**/*.{tsx,ts,scss,json,js}\" \"docs/**/*.{md,mdx}\"", From 19480b189600bd76e4d0284615d83fd98b1f10eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 16:02:14 -0800 Subject: [PATCH 005/162] remove deprecated stylus content map --- docs/stylus/stylus-content-map.mdx | 93 ------------------------------ 1 file changed, 93 deletions(-) delete mode 100644 docs/stylus/stylus-content-map.mdx diff --git a/docs/stylus/stylus-content-map.mdx b/docs/stylus/stylus-content-map.mdx deleted file mode 100644 index 3aa5044cc7..0000000000 --- a/docs/stylus/stylus-content-map.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -id: stylus-content-map -title: Write Stylus Contracts -sidebar_label: Write Stylus contracts -displayed_sidebar: buildAppsSidebar ---- - -import Card from '@site/src/components/Cards/Card'; - -# Write Stylus Contracts - -Let's learn how to write contracts with Stylus! - -
- - - - - - - - - - - - -
From b25495c97bf17ca891f229748cefe71f84977c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 16:16:40 -0800 Subject: [PATCH 006/162] remove irrelevant link --- docs/stylus/how-tos/adding-support-for-new-languages.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/how-tos/adding-support-for-new-languages.mdx b/docs/stylus/how-tos/adding-support-for-new-languages.mdx index 03f167dc7b..3dd295f010 100644 --- a/docs/stylus/how-tos/adding-support-for-new-languages.mdx +++ b/docs/stylus/how-tos/adding-support-for-new-languages.mdx @@ -13,7 +13,7 @@ displayed_sidebar: buildAppsSidebar This is possible thanks to [WebAssembly](https://www.infoworld.com/article/3291780/what-is-webassembly-the-next-generation-web-platform-explained.html) technology, which all Stylus contracts compile to. Stylus smart contracts live under the **same Ethereum state trie** in Arbitrum nodes, and can fully interoperate with Solidity or Vyper EVM smart contracts. With Stylus, developers can write smart contracts in Rust that talk to Solidity and vice versa without any limitations. -Today, the Stylus testnet also comes with two officially supported [SDKs](/stylus/overview.mdx) for developers to write contracts in the [Rust](../reference/rust-sdk-guide.md) or [C](https://github.com/OffchainLabs/stylus-sdk-c) programming languages. +Today, the Stylus testnet also comes with two officially supported SDKs for developers to write contracts in the [Rust](../reference/rust-sdk-guide.md) or [C](https://github.com/OffchainLabs/stylus-sdk-c) programming languages. However, _anyone_ can add support for new languages in Stylus. **As long as a programming language can compile to WebAssembly**, Stylus will let you use it to write EVM-compatible smart contracts. Note that in order to be deployed onchain, your compiled program must fit under the 24Kb brotli-compressed limit, and should meet Stylus gas metering requirements. From 44bdffa132715953d9b9ac370af4ebf4c1a37cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 16:20:22 -0800 Subject: [PATCH 007/162] remove SBE from stylus content --- sidebars.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sidebars.js b/sidebars.js index 2fdcd5db43..c59cdb9834 100644 --- a/sidebars.js +++ b/sidebars.js @@ -3,8 +3,6 @@ // Use the generated SDK sidebar for API reference const sdkApiSidebar = require('./sdk-sidebar.js'); // Use the generated stylus-by-example sidebars -const stylusByExampleBasicExamples = require('./docs/stylus-by-example/basic_examples/sidebar.js'); -const stylusByExampleApplications = require('./docs/stylus-by-example/applications/sidebar.js'); // Create a custom SDK sidebar that combines manual intro pages with generated API docs const sdkSidebar = { @@ -1217,7 +1215,6 @@ const sidebars = { id: 'stylus/reference/project-structure', label: 'Structure of a Contract', }, - ...stylusByExampleBasicExamples, { type: 'doc', id: 'stylus/how-tos/using-inheritance', @@ -1304,7 +1301,6 @@ const sidebars = { label: 'Examples', collapsed: true, items: [ - ...stylusByExampleApplications, { type: 'link', label: 'Awesome Stylus', From ff150ec52f1259938fe7a4e661c201eb87e7a74f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 13 Nov 2025 18:14:28 -0800 Subject: [PATCH 008/162] first iteration content restructuring --- docs/stylus/reference/contracts.mdx | 22 +++++++++++ .../reference/data-types/compound-types.mdx | 17 +++++++++ .../data-types/conversions-between-types.mdx | 11 ++++++ .../reference/data-types/primitives.mdx | 15 ++++++++ docs/stylus/reference/data-types/storage.mdx | 20 ++++++++++ .../global-variables-and-functions.mdx | 18 +++++++++ sidebars.js | 37 +++++++++++++++++++ 7 files changed, 140 insertions(+) create mode 100644 docs/stylus/reference/contracts.mdx create mode 100644 docs/stylus/reference/data-types/compound-types.mdx create mode 100644 docs/stylus/reference/data-types/conversions-between-types.mdx create mode 100644 docs/stylus/reference/data-types/primitives.mdx create mode 100644 docs/stylus/reference/data-types/storage.mdx create mode 100644 docs/stylus/reference/global-variables-and-functions.mdx diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx new file mode 100644 index 0000000000..771b25cea6 --- /dev/null +++ b/docs/stylus/reference/contracts.mdx @@ -0,0 +1,22 @@ +--- +title: 'Contracts' +description: 'Contracts' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +6. Contracts + 1. Calling other contracts + 1. Call + 2. Raw call + 3. Delegate call + 4. Static call + 5. sol_interface + 2. Sending ETH + 3. Factory deploy + 4. Function modifiers + 5. Inheritance (temporary) + 6. Constructors (coming soon) diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/reference/data-types/compound-types.mdx new file mode 100644 index 0000000000..33466eddca --- /dev/null +++ b/docs/stylus/reference/data-types/compound-types.mdx @@ -0,0 +1,17 @@ +--- +title: 'Stylus compound types' +description: 'Stylus Rust SDK compound types' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +2. Compound types + 1. Tuple + 2. Struct + 3. Array + 4. Vector + 5. Bytes + 6. FixedBytes diff --git a/docs/stylus/reference/data-types/conversions-between-types.mdx b/docs/stylus/reference/data-types/conversions-between-types.mdx new file mode 100644 index 0000000000..f44e822ec2 --- /dev/null +++ b/docs/stylus/reference/data-types/conversions-between-types.mdx @@ -0,0 +1,11 @@ +--- +title: 'Conversions Between Types' +description: 'Conversions Between Types' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/reference/data-types/primitives.mdx new file mode 100644 index 0000000000..ac1440578c --- /dev/null +++ b/docs/stylus/reference/data-types/primitives.mdx @@ -0,0 +1,15 @@ +--- +title: 'Stylus primitives' +description: 'Stylus Rust SDK primitives' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +1. Boolean +2. Integers +3. Address (include AddressVM traits from types module) 4. String + 1. Literals + 2. Hex diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx new file mode 100644 index 0000000000..8f49eab97c --- /dev/null +++ b/docs/stylus/reference/data-types/storage.mdx @@ -0,0 +1,20 @@ +--- +title: 'Stylus Rust SDK storage' +description: 'Stylus Rust SDK storage' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +3. Storage + 1. Bool + 2. Uint + 3. Address + 4. Struct + 5. Array + 6. Map + 7. String + 8. Bytes + 9. FixedBytes diff --git a/docs/stylus/reference/global-variables-and-functions.mdx b/docs/stylus/reference/global-variables-and-functions.mdx new file mode 100644 index 0000000000..dd71e050db --- /dev/null +++ b/docs/stylus/reference/global-variables-and-functions.mdx @@ -0,0 +1,18 @@ +--- +title: 'Global variables and functions' +description: 'Global variables and functions' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +5. Global variables and functions + 1. block + 2. contract + 3. crypto + 4. evm + 5. msg + 6. tx + 7. debug diff --git a/sidebars.js b/sidebars.js index c59cdb9834..96cc50b096 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1215,6 +1215,43 @@ const sidebars = { id: 'stylus/reference/project-structure', label: 'Structure of a Contract', }, + { + type: 'category', + label: 'Data types', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/reference/data-types/primitives', + label: 'Primitives', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/compound-types', + label: 'Compound types', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/storage', + label: 'Storage', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/conversions-between-types', + label: 'Conversions Between Types', + }, + ], + }, + { + type: 'doc', + id: 'stylus/reference/global-variables-and-functions', + label: 'Global variables and functions', + }, + { + type: 'doc', + id: 'stylus/reference/contracts', + label: 'Contracts', + }, { type: 'doc', id: 'stylus/how-tos/using-inheritance', From 0e121cdead24a02adfbdf1468b664dd10d718390 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 18 Nov 2025 11:14:31 -0800 Subject: [PATCH 009/162] tone adjustments and simplification --- docs/stylus/gentle-introduction.mdx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index b6f1695509..1ec4540453 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -14,18 +14,18 @@ import ImageZoom from '@site/src/components/ImageZoom'; ### In a nutshell: - Stylus lets you write smart contracts in programming languages that compile to WASM, such as **Rust, C, C++, and many others**, allowing you to tap into their ecosystem of libraries and tools. Rich language and tooling support already exist for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). -- Solidity contracts and Stylus contracts are **fully interoperable**. In Solidity, you can call a Rust program and vice versa, thanks to a second, coequal WASM virtual machine. -- Stylus contracts offer significantly **faster execution and lower gas fees** for memory and compute-intensive operations, thanks to the superior efficiency of WASM programs. +- Solidity contracts and Stylus contracts are **fully interoperable**. In Solidity, you can call a Rust program and vice versa. +- Stylus contracts offer **faster execution and lower gas fees** for memory and compute-intensive operations, they also enable complex computation Solidity doesn't support. ### What's Stylus? -Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. We call this paradigm **MultiVM** since **everything is entirely additive.** +Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. We call this paradigm MultiVM. -This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a modern binary format popularized by its use in major web standards, browsers, and companies to speed up computation. WASM is built to be fast, portable, and human-readable. It has sandboxed execution environments for security and simplicity. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fully functioning fraud proofs. +This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a modern binary format popularized by its use in major web standards, browsers, and companies to speed up computation. WASM is built to be fast, portable, and human-readable. It has sandboxed execution environments for security and simplicity. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fully functioning fraud proofs. -With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile into WASM, some compilers are more suitable for smart contract development than others, like Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and Javascript, are more complex for Stylus to support, although not impossible. Compared to Solidity, WASM programs are much more efficient for memory-intensive applications. There are many reasons for this, including the decades of compiler development for Rust and C. WASM also has a faster runtime than the EVM, resulting in faster execution. Third-party contributions in the form of libraries for new and existing languages are welcomed! +With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile into WASM, some compilers are more suitable for smart contract development than others, like Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and Javascript, are more complex for Stylus to support, although not impossible. Compared to Solidity, WASM programs are more efficient for memory-intensive applications. There are many reasons for this, including the decades of compiler development for Rust and C. WASM also has a faster runtime than the EVM, resulting in faster execution. Third-party contributions in the form of libraries for new and existing languages are welcomed! ### Use Cases @@ -40,9 +40,8 @@ While many developers will be drawn to new use cases, rebuilding existing applic - **High-Performance Onchain Logic**: Support memory and compute-intensive applications like onchain games and generative art either by writing all of the application in Stylus or enhance performance of existing Solidity contracts by optimizing specific parts. -- **Endless Possibilities**: Enable innovative use cases such as generative art, compute-heavy - AI models, onchain games, and projects utilizing advanced cryptography, unlocking the full potential - of resource-intensive applications onchain. +- **Innovations**: generative art, compute-heavy + AI models, onchain games, advanced cryptography. ### Getting Started From 42c22bb25522c8e302570894febfe0e47b710311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 19 Nov 2025 19:37:44 -0800 Subject: [PATCH 010/162] add template files --- docs/stylus/advanced/hostio-exports.mdx | 11 +++++++++++ .../advanced/minimal-entrypoint-contracts.mdx | 11 +++++++++++ .../recommended-libraries.mdx} | 0 docs/stylus/advanced/solidity-differences.mdx | 11 +++++++++++ docs/stylus/concepts/activation.mdx | 11 +++++++++++ docs/stylus/concepts/caching-strategy.mdx | 11 +++++++++++ docs/stylus/concepts/evm-differences.mdx | 15 +++++++++++++++ docs/stylus/concepts/webassembly.mdx | 11 +++++++++++ docs/stylus/how-tos/check-and-deploy.mdx | 11 +++++++++++ .../how-tos/deploying-non-rust-wasm-contracts.mdx | 13 +++++++++++++ docs/stylus/how-tos/exporting-abi.mdx | 11 +++++++++++ .../how-tos/optimizing-wasm-binary-size.mdx | 13 +++++++++++++ 12 files changed, 129 insertions(+) create mode 100644 docs/stylus/advanced/hostio-exports.mdx create mode 100644 docs/stylus/advanced/minimal-entrypoint-contracts.mdx rename docs/stylus/{recommended-libraries.md => advanced/recommended-libraries.mdx} (100%) create mode 100644 docs/stylus/advanced/solidity-differences.mdx create mode 100644 docs/stylus/concepts/activation.mdx create mode 100644 docs/stylus/concepts/caching-strategy.mdx create mode 100644 docs/stylus/concepts/evm-differences.mdx create mode 100644 docs/stylus/concepts/webassembly.mdx create mode 100644 docs/stylus/how-tos/check-and-deploy.mdx create mode 100644 docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx create mode 100644 docs/stylus/how-tos/exporting-abi.mdx create mode 100644 docs/stylus/how-tos/optimizing-wasm-binary-size.mdx diff --git a/docs/stylus/advanced/hostio-exports.mdx b/docs/stylus/advanced/hostio-exports.mdx new file mode 100644 index 0000000000..8dc22dfa6b --- /dev/null +++ b/docs/stylus/advanced/hostio-exports.mdx @@ -0,0 +1,11 @@ +--- +title: 'Hostio exports' +description: 'Hostio exports' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how to use hostio exports with Stylus. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx new file mode 100644 index 0000000000..211fa3acc5 --- /dev/null +++ b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx @@ -0,0 +1,11 @@ +--- +title: 'Minimal entrypoint contracts' +description: 'Minimal entrypoint contracts' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how to build a minimal entrypoint contract. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/recommended-libraries.md b/docs/stylus/advanced/recommended-libraries.mdx similarity index 100% rename from docs/stylus/recommended-libraries.md rename to docs/stylus/advanced/recommended-libraries.mdx diff --git a/docs/stylus/advanced/solidity-differences.mdx b/docs/stylus/advanced/solidity-differences.mdx new file mode 100644 index 0000000000..1acd8509c9 --- /dev/null +++ b/docs/stylus/advanced/solidity-differences.mdx @@ -0,0 +1,11 @@ +--- +title: 'Differences between Solidity and Stylus' +description: 'Solidity and Stylus differences' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to compare Stylus with Solidity. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx new file mode 100644 index 0000000000..14376d2def --- /dev/null +++ b/docs/stylus/concepts/activation.mdx @@ -0,0 +1,11 @@ +--- +title: 'Activation' +description: 'Activation' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: . +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/concepts/caching-strategy.mdx b/docs/stylus/concepts/caching-strategy.mdx new file mode 100644 index 0000000000..3bed5bb6fd --- /dev/null +++ b/docs/stylus/concepts/caching-strategy.mdx @@ -0,0 +1,11 @@ +--- +title: 'Caching strategy' +description: 'Caching strategy' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: . +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/concepts/evm-differences.mdx b/docs/stylus/concepts/evm-differences.mdx new file mode 100644 index 0000000000..720af77c48 --- /dev/null +++ b/docs/stylus/concepts/evm-differences.mdx @@ -0,0 +1,15 @@ +--- +title: 'evm-differences' +description: 'EVM-differences' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how Stylus works with evm-differences. +displayed_sidebar: buildAppsSidebar +--- + +- Size limits +- Ink and gas +- Memory and compute + +TBD diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx new file mode 100644 index 0000000000..a67c6a44c5 --- /dev/null +++ b/docs/stylus/concepts/webassembly.mdx @@ -0,0 +1,11 @@ +--- +title: 'WebAssembly' +description: 'WebAssembly' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how Stylus works with WebAssembly. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx new file mode 100644 index 0000000000..be3fe47b9f --- /dev/null +++ b/docs/stylus/how-tos/check-and-deploy.mdx @@ -0,0 +1,11 @@ +--- +title: 'Check and deploy' +description: 'Check and deploy Stylus contracts' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how to check and deploy Stylus contracts. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx new file mode 100644 index 0000000000..42ff37236b --- /dev/null +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -0,0 +1,13 @@ +--- +id: Deploying non-Rust WASM contracts +title: 'Deploying non-Rust WASM contracts' +description: 'Deploying non-Rust WASM contracts' +author: chrisco +sme: chrisco +target_audience: 'Developers who need to deploy non-Rust WASM contracts' +content_type: how-to +sidebar_position: 2 +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/how-tos/exporting-abi.mdx b/docs/stylus/how-tos/exporting-abi.mdx new file mode 100644 index 0000000000..579319a42e --- /dev/null +++ b/docs/stylus/how-tos/exporting-abi.mdx @@ -0,0 +1,11 @@ +--- +title: 'Exporting ABIs' +description: 'Exporting ABIs' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how to check and deploy Stylus contracts. +displayed_sidebar: buildAppsSidebar +--- + +TBD diff --git a/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx b/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx new file mode 100644 index 0000000000..d8c3c0fab5 --- /dev/null +++ b/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx @@ -0,0 +1,13 @@ +--- +id: Optimizing WASM binary size +title: 'How to optimizing WASM binary size' +description: 'How-to optimize WASM binary size' +author: chrisco +sme: chrisco +target_audience: 'Developers who need to reduce their Stylus binary size' +content_type: how-to +sidebar_position: 2 +displayed_sidebar: buildAppsSidebar +--- + +TBD From b02bc5bb553c5e16d07d5c348dda402acdc6ec80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 11:04:28 -0800 Subject: [PATCH 011/162] add redirect to new recommended libraries location --- vercel.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vercel.json b/vercel.json index baa2930216..7ebb9a0d98 100644 --- a/vercel.json +++ b/vercel.json @@ -426,6 +426,11 @@ "destination": "/(docs/run-arbitrum-node/run-feed-relay/?)", "permanent": false }, + { + "source": "/(docs/stylus/recommended-libraries/?)", + "destination": "/(docs/stylus/advanced/recommended-libraries/?)", + "permanent": false + }, { "source": "/(docs/tx_lifecycle/?)", "destination": "/how-arbitrum-works/deep-dives/transaction-lifecycle", From d62a2050f428ae0bfc96bb227110afb24359a451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 11:19:56 -0800 Subject: [PATCH 012/162] add new articles in sidebars > WIP --- sidebars.js | 241 +++++++++++++++++++++++++--------------------------- 1 file changed, 118 insertions(+), 123 deletions(-) diff --git a/sidebars.js b/sidebars.js index 96cc50b096..193cc4b735 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1195,11 +1195,6 @@ const sidebars = { id: 'stylus/gentle-introduction', label: 'A gentle introduction', }, - { - type: 'doc', - id: 'stylus/quickstart', - label: 'Quickstart', - }, { type: 'category', label: 'Rust SDK', @@ -1252,141 +1247,141 @@ const sidebars = { id: 'stylus/reference/contracts', label: 'Contracts', }, - { - type: 'doc', - id: 'stylus/how-tos/using-inheritance', - label: 'Composition and trait-based routing model', - }, - { - type: 'doc', - id: 'stylus/reference/rust-sdk-guide', - label: 'Advanced features', - }, - { - type: 'doc', - id: 'stylus/recommended-libraries', - label: 'Recommended Rust Crates', - }, - ], - }, - { - type: 'category', - label: 'Rust CLI', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/using-cli', - label: 'Overview', - }, - { - type: 'doc', - id: 'stylus/how-tos/debugging-tx', - label: 'Debug transactions', - }, { type: 'doc', id: 'stylus/how-tos/testing-contracts', - label: 'Testing contracts', + label: 'Writing Tests', }, { - type: 'doc', - id: 'stylus/how-tos/verifying-contracts', - label: 'Verify contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/caching-contracts', - label: 'Cache contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/verifying-contracts-arbiscan', - label: 'Verify on Arbiscan', - }, - { - type: 'doc', - id: 'stylus/how-tos/optimizing-binaries', - label: 'Optimize WASM binaries', - }, - ], - }, - { - type: 'html', - value: - 'Run a local dev nodeโ†‘', - }, - { - type: 'category', - label: 'Concepts', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/concepts/how-it-works', - label: 'Architecture overview', - }, - { - type: 'doc', - id: 'stylus/concepts/gas-metering', - label: 'Gas metering', - }, - ], - }, - { - type: 'category', - label: 'Examples', - collapsed: true, - items: [ - { - type: 'link', - label: 'Awesome Stylus', - href: 'https://github.com/OffchainLabs/awesome-stylus', + type: 'category', + label: 'Advanced', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/advanced/solidity-differences', + label: 'Solidity differences', + }, + { + type: 'doc', + id: 'stylus/advanced/recommended-libraries', + label: 'Recommended packages', + }, + { + type: 'doc', + id: 'stylus/advanced/minimal-entrypoint-contracts', + label: 'Minimal entrypoint contracts', + }, + { + type: 'doc', + id: 'stylus/advanced/hostio-exports', + label: 'Hostio exports', + }, + ], }, - ], - }, - { - type: 'category', - label: 'Reference', - collapsed: true, - items: [ { type: 'doc', - id: 'stylus/reference/opcode-hostio-pricing', - label: 'Gas & Ink Pricing', + id: 'stylus/troubleshooting-building-stylus', + label: 'Troubleshooting', }, { - type: 'link', - label: 'Stylus by Example', - href: 'https://stylus-by-example.org/', - }, - { - type: 'link', - label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/cargo-stylus', + type: 'category', + label: 'Using the CLI', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-wasm-binary-size', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], }, { - type: 'link', - label: 'Rust SDK Crate', - href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + type: 'category', + label: 'WM Concepts', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/concepts/webassembly', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/concepts/evm-differences', + label: 'EVM differences', + }, + { + type: 'doc', + id: 'stylus/concepts/activation', + label: 'Activation', + }, + { + type: 'doc', + id: 'stylus/how-tos/caching-contracts', + label: 'Caching Strategy', + }, + { + type: 'doc', + id: 'stylus/how-tos/caching-contracts', + label: 'Caching Strategy', + }, + ], }, { - type: 'link', - label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus', + type: 'category', + label: 'Reference', + collapsed: true, + items: [ + { + type: 'link', + label: 'Stylus by Example', + href: 'https://stylus-by-example.org/', + }, + { + type: 'link', + label: 'Cargo Stylus CLI GitHub', + href: 'https://github.com/OffchainLabs/cargo-stylus', + }, + { + type: 'link', + label: 'Rust SDK Crate', + href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + }, + { + type: 'link', + label: 'Source Code Repository', + href: 'https://github.com/OffchainLabs/stylus', + }, + ], }, ], }, - { - type: 'doc', - id: 'stylus/how-tos/adding-support-for-new-languages', - label: 'Using other languages', - }, - { - type: 'doc', - id: 'stylus/troubleshooting-building-stylus', - label: 'Troubleshooting', - }, ], }, { From 42b23d56a0a02df50e3f5d70cd7ffa05382c6708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 18:04:47 -0800 Subject: [PATCH 013/162] remove unneeded how-to guide on optimizing WASM binary size --- docs/stylus/how-tos/optimizing-wasm-binary-size.mdx | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 docs/stylus/how-tos/optimizing-wasm-binary-size.mdx diff --git a/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx b/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx deleted file mode 100644 index d8c3c0fab5..0000000000 --- a/docs/stylus/how-tos/optimizing-wasm-binary-size.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -id: Optimizing WASM binary size -title: 'How to optimizing WASM binary size' -description: 'How-to optimize WASM binary size' -author: chrisco -sme: chrisco -target_audience: 'Developers who need to reduce their Stylus binary size' -content_type: how-to -sidebar_position: 2 -displayed_sidebar: buildAppsSidebar ---- - -TBD From fe4ff4ffaa24ba15ec27b32ec807ba7d5eaa5d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 18:05:15 -0800 Subject: [PATCH 014/162] update sidebars.js --- sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sidebars.js b/sidebars.js index 193cc4b735..6b79fb3ff8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1311,7 +1311,7 @@ const sidebars = { }, { type: 'doc', - id: 'stylus/how-tos/optimizing-wasm-binary-size', + id: 'stylus/how-tos/optimizing-binaries', label: 'Optimizing WASM binary size', }, { From 21fc192075a973e7b3fc2b90340eceba2dc91e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 18:19:29 -0800 Subject: [PATCH 015/162] fix frontmatter typo in deploying-non-rust-wasm-contracts --- docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx index 42ff37236b..97bd94cd1a 100644 --- a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -1,5 +1,5 @@ --- -id: Deploying non-Rust WASM contracts +id: deploying-non-rust-wasm-contracts title: 'Deploying non-Rust WASM contracts' description: 'Deploying non-Rust WASM contracts' author: chrisco From 382792361a259a5a18e75219ff9768abf79fab13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Nov 2025 18:29:42 -0800 Subject: [PATCH 016/162] fix recommended libraries broken links --- docs/stylus/how-tos/optimizing-binaries.mdx | 2 +- docs/stylus/reference/project-structure.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stylus/how-tos/optimizing-binaries.mdx b/docs/stylus/how-tos/optimizing-binaries.mdx index d88274f8ad..9924b3f5b6 100644 --- a/docs/stylus/how-tos/optimizing-binaries.mdx +++ b/docs/stylus/how-tos/optimizing-binaries.mdx @@ -46,7 +46,7 @@ Additional WASM-specific tooling exists to shrink binaries. Due to being third p [twiggy](https://github.com/rustwasm/twiggy) is a code size profiler for WASM, it can help you estimate the impact of each added component on your binaries' size. -Our team has also curated a [list of recommended libraries](/stylus/recommended-libraries) that are helpful to Stylus development and optimally sized. +Our team has also curated a [list of recommended libraries](/stylus/advanced/recommended-libraries) that are helpful to Stylus development and optimally sized. ### Frequently asked questions diff --git a/docs/stylus/reference/project-structure.mdx b/docs/stylus/reference/project-structure.mdx index c37969b3d7..1d978c2c51 100644 --- a/docs/stylus/reference/project-structure.mdx +++ b/docs/stylus/reference/project-structure.mdx @@ -159,7 +159,7 @@ Use imported types in your contract: let price = dec!(72.00); ``` -Note, not all Rust crates are compatible with Stylus since they need to be compiled to WASM and used in a blockchain context, which is more limited than a desktop application. For instance, the `rand` crate is not usable, as there is no onchain randomness available to smart contracts. In addition, contracts cannot access functions that use networking or filesystem access features. There is also a need to be mindful of the size of the crates you import, since the default contract size limit is 24KB (compressed). Crates that do not use the standard library (`no_std` crates) tend to work best. See [Using public Rust crates](https://docs.arbitrum.io/stylus/recommended-libraries#using-public-rust-crates) for more important details on using public Rust crates as well as a curated list of crates that tend to work well for smart contract development. +Note, not all Rust crates are compatible with Stylus since they need to be compiled to WASM and used in a blockchain context, which is more limited than a desktop application. For instance, the `rand` crate is not usable, as there is no onchain randomness available to smart contracts. In addition, contracts cannot access functions that use networking or filesystem access features. There is also a need to be mindful of the size of the crates you import, since the default contract size limit is 24KB (compressed). Crates that do not use the standard library (`no_std` crates) tend to work best. See [Using public Rust crates](https://docs.arbitrum.io/stylus/advanced/recommended-libraries#using-public-rust-crates) for more important details on using public Rust crates as well as a curated list of crates that tend to work well for smart contract development. ## Events From cdb1f6f7cc89cb4ac88a20ffa888fc2af17a80c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 12:37:23 -0800 Subject: [PATCH 017/162] Document Stylus Rust primitives with comprehensive examples Add detailed documentation for all Stylus SDK primitive types including: - Boolean (bool) with usage examples and Solidity mappings - Unsigned integers (u8-u128, U256, Uint) - Signed integers (i8-i128, I256, Signed) - Address type with constants and validation examples - String type with literal and formatting examples - Bytes types (dynamic Bytes and fixed FixedBytes) - Hex literal usage examples - Complete type mapping tables for all primitives - Best practices for each primitive type - Type conversion examples Each section includes: - Practical code examples - Solidity type mappings - Storage size information - ABI signature details - Common usage patterns --- .../reference/data-types/primitives.mdx | 561 +++++++++++++++++- 1 file changed, 556 insertions(+), 5 deletions(-) diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/reference/data-types/primitives.mdx index ac1440578c..28e0d78357 100644 --- a/docs/stylus/reference/data-types/primitives.mdx +++ b/docs/stylus/reference/data-types/primitives.mdx @@ -8,8 +8,559 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -1. Boolean -2. Integers -3. Address (include AddressVM traits from types module) 4. String - 1. Literals - 2. Hex +# Primitives + +The Stylus SDK provides full support for Rust primitive types with automatic ABI encoding/decoding and Solidity type mappings. These primitives can be used in contract method signatures, storage, and as function parameters. + +## Boolean (`bool`) + +Booleans in Rust map directly to Solidity's `bool` type. + +### Usage in Contract Methods + +```rust +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + pub fn is_valid(&self) -> bool { + true + } + + pub fn toggle(&mut self, flag: bool) { + // Use the boolean value + if flag { + // Do something + } + } +} +``` + +### Solidity Mapping + +- **Rust type**: `bool` +- **Solidity type**: `bool` +- **Storage size**: 1 byte +- **ABI signature**: `"bool"` + +## Integers + +The Stylus SDK supports both signed and unsigned integers with various bit sizes. All integer types from Rust's standard library and alloy-primitives are supported. + +### Unsigned Integers + +#### Standard Rust Unsigned Integers + +```rust +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // u8: 8-bit unsigned integer + pub fn get_byte(&self) -> u8 { + 255 + } + + // u16: 16-bit unsigned integer + pub fn get_short(&self) -> u16 { + 65535 + } + + // u32: 32-bit unsigned integer + pub fn get_int(&self) -> u32 { + 4294967295 + } + + // u64: 64-bit unsigned integer + pub fn get_long(&self) -> u64 { + 18446744073709551615 + } + + // u128: 128-bit unsigned integer + pub fn get_u128(&self) -> u128 { + 340282366920938463463374607431768211455 + } +} +``` + +#### Alloy Unsigned Integers + +For larger integers and full compatibility with Solidity's uint types, use `alloy_primitives::Uint`: + +```rust +use alloy_primitives::{U256, Uint}; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // U256: 256-bit unsigned integer (most common in Solidity) + pub fn get_balance(&self) -> U256 { + U256::from(1000000) + } + + // Any bit size from 8 to 256 (in multiples of 8) + pub fn get_u160(&self) -> Uint<160, 3> { + Uint::<160, 3>::from(999) + } + + pub fn get_u96(&self) -> Uint<96, 2> { + Uint::<96, 2>::from(123456) + } +} +``` + +### Signed Integers + +#### Standard Rust Signed Integers + +```rust +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // i8: 8-bit signed integer + pub fn get_signed_byte(&self) -> i8 { + -128 + } + + // i16: 16-bit signed integer + pub fn get_signed_short(&self) -> i16 { + -32768 + } + + // i32: 32-bit signed integer + pub fn get_signed_int(&self) -> i32 { + -2147483648 + } + + // i64: 64-bit signed integer + pub fn get_signed_long(&self) -> i64 { + -9223372036854775808 + } + + // i128: 128-bit signed integer + pub fn get_signed_i128(&self) -> i128 { + -170141183460469231731687303715884105728 + } +} +``` + +#### Alloy Signed Integers + +```rust +use alloy_primitives::{Signed, I256}; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // I256: 256-bit signed integer + pub fn get_signed_balance(&self) -> I256 { + I256::try_from(-1000).unwrap() + } + + // Any bit size from 8 to 256 (in multiples of 8) + pub fn get_i160(&self) -> Signed<160, 3> { + Signed::<160, 3>::try_from(-999).unwrap() + } +} +``` + +### Integer Type Mappings + +| Rust Type | Solidity Type | Bit Size | ABI Signature | +| ------------------------- | ------------- | -------- | ------------- | +| `u8` | `uint8` | 8 bits | `"uint8"` | +| `u16` | `uint16` | 16 bits | `"uint16"` | +| `u32` | `uint32` | 32 bits | `"uint32"` | +| `u64` | `uint64` | 64 bits | `"uint64"` | +| `u128` | `uint128` | 128 bits | `"uint128"` | +| `Uint<160, 3>` | `uint160` | 160 bits | `"uint160"` | +| `U256` / `Uint<256, 4>` | `uint256` | 256 bits | `"uint256"` | +| `i8` | `int8` | 8 bits | `"int8"` | +| `i16` | `int16` | 16 bits | `"int16"` | +| `i32` | `int32` | 32 bits | `"int32"` | +| `i64` | `int64` | 64 bits | `"int64"` | +| `i128` | `int128` | 128 bits | `"int128"` | +| `Signed<160, 3>` | `int160` | 160 bits | `"int160"` | +| `I256` / `Signed<256, 4>` | `int256` | 256 bits | `"int256"` | + +**Note**: All Solidity uint/int types from `uint8`/`int8` to `uint256`/`int256` (in 8-bit increments) are supported through `Uint` and `Signed`. + +## Address + +Ethereum addresses are represented by the `Address` type from `alloy_primitives`. + +### Basic Usage + +```rust +use alloy_primitives::Address; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + pub fn get_owner(&self) -> Address { + Address::ZERO + } + + pub fn is_owner(&self, account: Address) -> bool { + account == self.vm().msg_sender() + } + + pub fn transfer_ownership(&mut self, new_owner: Address) { + // Address validation and logic + if new_owner == Address::ZERO { + // Handle error + } + } +} +``` + +### Address Constants + +```rust +use alloy_primitives::Address; + +// Zero address (0x0000000000000000000000000000000000000000) +let zero = Address::ZERO; + +// Parse from string +let addr = Address::parse_checksummed("0x1234567890123456789012345678901234567890", None).unwrap(); + +// Create from bytes +let bytes: [u8; 20] = [0; 20]; +let addr = Address::from(bytes); +``` + +### Solidity Mapping + +- **Rust type**: `Address` (from `alloy_primitives`) +- **Solidity type**: `address` +- **Storage size**: 20 bytes (160 bits) +- **ABI signature**: `"address"` + +## String + +Rust `String` types map to Solidity `string` type. + +### String Literals + +```rust +use stylus_sdk::prelude::*; +use alloc::string::String; + +#[public] +impl MyContract { + pub fn get_name(&self) -> String { + String::from("MyToken") + } + + pub fn greet(&self, name: String) -> String { + format!("Hello, {}!", name) + } +} +``` + +### Solidity Mapping + +- **Rust type**: `String` (from `alloc::string`) +- **Solidity type**: `string` +- **Storage**: Dynamic (heap-allocated) +- **ABI signature**: `"string"` +- **ABI export**: + - As argument: `"string calldata"` + - As return: `"string memory"` + +**Note**: Strings in Solidity are UTF-8 encoded byte arrays. When using strings in Stylus: + +- Use `alloc::string::String` for owned strings +- Strings are dynamically sized and stored in memory/calldata +- For storage, use `StorageString` (see [Storage Types](./storage.mdx)) + +## Bytes + +The SDK provides two types for working with byte data: + +### 1. Dynamic Bytes (`Bytes`) + +For variable-length byte arrays (Solidity `bytes`): + +```rust +use alloy_primitives::Bytes; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + pub fn get_data(&self) -> Bytes { + Bytes::from(vec![1, 2, 3, 4]) + } + + pub fn process_data(&mut self, data: Bytes) -> usize { + data.len() + } +} +``` + +### 2. Fixed Bytes (`FixedBytes`) + +For fixed-length byte arrays (Solidity `bytesN`): + +```rust +use alloy_primitives::FixedBytes; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // bytes32 (common for hashes) + pub fn get_hash(&self) -> FixedBytes<32> { + FixedBytes::<32>::ZERO + } + + // bytes2 + pub fn get_signature(&self) -> FixedBytes<2> { + FixedBytes::new([0x12, 0x34]) + } + + // Any size from 1 to 32 + pub fn get_bytes8(&self) -> FixedBytes<8> { + FixedBytes::<8>::from([1, 2, 3, 4, 5, 6, 7, 8]) + } +} +``` + +### Common FixedBytes Aliases + +```rust +use alloy_primitives::{B256, B160, B128}; + +// B256 is FixedBytes<32> (bytes32) +let hash: B256 = B256::ZERO; + +// B160 is FixedBytes<20> (bytes20) +let data: B160 = B160::ZERO; + +// B128 is FixedBytes<16> (bytes16) +let value: B128 = B128::ZERO; +``` + +### Bytes Type Mappings + +| Rust Type | Solidity Type | Description | +| ------------------------- | ------------- | -------------------------------- | +| `Bytes` | `bytes` | Dynamic byte array | +| `Vec` | `uint8[]` | Array of bytes (NOT `bytes`!) | +| `FixedBytes` | `bytesN` | Fixed-size byte array (N = 1-32) | +| `B256` / `FixedBytes<32>` | `bytes32` | 32-byte array (hashes) | +| `B160` / `FixedBytes<20>` | `bytes20` | 20-byte array | +| `B128` / `FixedBytes<16>` | `bytes16` | 16-byte array | + +**Important Distinction**: + +- `Vec` maps to Solidity `uint8[]` (array of unsigned integers) +- `Bytes` maps to Solidity `bytes` (dynamic byte array) +- For Solidity `bytes`, always use `alloy_primitives::Bytes` + +### Bytes ABI Encoding + +```rust +// Bytes type +// ABI signature: "bytes" +// As argument: "bytes calldata" +// As return: "bytes memory" + +// FixedBytes type +// ABI signature: "bytesN" where N is 1-32 +// Example: FixedBytes<32> -> "bytes32" +``` + +## Hex String Literals + +When working with hex data, you can use hex literals: + +```rust +use alloy_primitives::{hex, Address, FixedBytes, Bytes}; + +// Hex bytes +let data = hex!("deadbeef"); + +// Address from hex +let addr = Address::from(hex!("1234567890123456789012345678901234567890")); + +// FixedBytes from hex +let hash = FixedBytes::<32>::from(hex!( + "0000000000000000000000000000000000000000000000000000000000000000" +)); + +// Dynamic Bytes from hex +let bytes = Bytes::from(hex!("aabbccdd")); +``` + +## Complete Example + +Here's a comprehensive example showing all primitive types: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::string::String; +use alloy_primitives::{Address, Bytes, FixedBytes, U256}; +use stylus_sdk::prelude::*; + +sol_storage! { + #[entrypoint] + pub struct PrimitiveExample { + bool initialized; + uint256 count; + address owner; + } +} + +#[public] +impl PrimitiveExample { + // Boolean + pub fn is_initialized(&self) -> bool { + self.initialized.get() + } + + // Unsigned integers (native Rust) + pub fn get_u8(&self) -> u8 { + 255 + } + + pub fn get_u256(&self) -> U256 { + self.count.get() + } + + // Signed integers + pub fn get_signed(&self) -> i32 { + -42 + } + + // Address + pub fn get_owner(&self) -> Address { + self.owner.get() + } + + pub fn set_owner(&mut self, new_owner: Address) { + self.owner.set(new_owner); + } + + // String + pub fn get_name(&self) -> String { + String::from("PrimitiveExample") + } + + // Dynamic bytes + pub fn get_data(&self) -> Bytes { + Bytes::from(vec![1, 2, 3, 4]) + } + + // Fixed bytes + pub fn get_hash(&self) -> FixedBytes<32> { + FixedBytes::<32>::ZERO + } + + // Multiple parameters + pub fn complex_function( + &mut self, + flag: bool, + amount: U256, + recipient: Address, + data: Bytes + ) -> bool { + // Function logic + true + } +} +``` + +## Best Practices + +1. **Use U256 for token amounts**: Solidity commonly uses `uint256` for token balances and amounts. + + ```rust + use alloy_primitives::U256; + + pub fn transfer(&mut self, amount: U256) { + // amount is uint256 in Solidity + } + ``` + +2. **Use Address for account addresses**: Always use `alloy_primitives::Address` for Ethereum addresses. + + ```rust + use alloy_primitives::Address; + + pub fn get_balance(&self, account: Address) -> U256 { + // Query balance + } + ``` + +3. **Use Bytes for dynamic byte data**: For Solidity `bytes`, use `alloy_primitives::Bytes`, not `Vec`. + + ```rust + use alloy_primitives::Bytes; + + pub fn process(&self, data: Bytes) { + // data maps to Solidity bytes + } + ``` + +4. **Use FixedBytes for hashes and signatures**: For fixed-size byte data like hashes. + + ```rust + use alloy_primitives::FixedBytes; + + pub fn verify(&self, hash: FixedBytes<32>) -> bool { + // hash maps to Solidity bytes32 + true + } + ``` + +5. **Check for zero addresses**: Always validate addresses before use. + + ```rust + use alloy_primitives::Address; + + pub fn set_admin(&mut self, admin: Address) { + if admin == Address::ZERO { + // Handle error + } + } + ``` + +## Type Conversion + +### Between Integer Types + +```rust +use alloy_primitives::U256; + +// Native to U256 +let amount: u64 = 1000; +let big_amount = U256::from(amount); + +// U256 to native (with bounds checking) +let big_value = U256::from(1000); +let small_value: u64 = big_value.to::(); +``` + +### Address Conversions + +```rust +use alloy_primitives::Address; + +// From bytes +let bytes: [u8; 20] = [0; 20]; +let addr = Address::from(bytes); + +// To bytes +let addr = Address::ZERO; +let bytes: [u8; 20] = addr.into(); +``` + +## See Also + +- [Compound Types](./compound-types.mdx) - Arrays, tuples, structs +- [Storage Types](./storage.mdx) - Persistent storage for primitives +- [Type Conversions](./conversions-between-types.mdx) - Converting between types From 928ac21470331649537f323893b32e62ec6cfeb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 12:45:01 -0800 Subject: [PATCH 018/162] add slop primitive data type documentation --- docs/stylus/reference/data-types/primitives.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/reference/data-types/primitives.mdx index 28e0d78357..ee5ce71227 100644 --- a/docs/stylus/reference/data-types/primitives.mdx +++ b/docs/stylus/reference/data-types/primitives.mdx @@ -8,8 +8,6 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -# Primitives - The Stylus SDK provides full support for Rust primitive types with automatic ABI encoding/decoding and Solidity type mappings. These primitives can be used in contract method signatures, storage, and as function parameters. ## Boolean (`bool`) From 1a47f7d59dc47a20292e2452e9b3ec2381da5157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 12:50:18 -0800 Subject: [PATCH 019/162] Document Stylus Rust compound types with comprehensive examples Add detailed documentation for all Stylus SDK compound types including: - Tuples with destructuring and pattern matching examples - Structs using sol! macro with AbiType derivation - Nested structs for complex data structures - Fixed-size arrays with iteration and operations - Vectors (dynamic arrays) with filter, map, and fold operations - Bytes types (dynamic Bytes and fixed FixedBytes) - Complete type mapping tables for all compound types - Best practices for each compound type - Type conversion helpers and iterator patterns - Common patterns (batch operations, pagination) Each section includes: - Practical code examples from SDK examples - Solidity type mappings - ABI signature details - Memory and gas efficiency considerations - Complete working examples with nested structures - Iterator and functional programming patterns --- .../reference/data-types/compound-types.mdx | 846 +++++++++++++++++- 1 file changed, 838 insertions(+), 8 deletions(-) diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/reference/data-types/compound-types.mdx index 33466eddca..d418445953 100644 --- a/docs/stylus/reference/data-types/compound-types.mdx +++ b/docs/stylus/reference/data-types/compound-types.mdx @@ -3,15 +3,845 @@ title: 'Stylus compound types' description: 'Stylus Rust SDK compound types' author: chrisco sme: chrisco -sidebar_position: 1 +sidebar_position: 2 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. displayed_sidebar: buildAppsSidebar --- -2. Compound types - 1. Tuple - 2. Struct - 3. Array - 4. Vector - 5. Bytes - 6. FixedBytes +# Compound Types + +Compound types allow you to group multiple values together in Stylus contracts. The SDK provides full support for tuples, structs, arrays, and vectors with automatic ABI encoding/decoding and Solidity type mappings. + +## Tuples + +Tuples group multiple values of different types together. They map directly to Solidity tuples. + +### Basic Tuples + +```rust +use alloy_primitives::{Address, U256, Bytes}; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Return multiple values as a tuple + pub fn get_data(&self) -> (U256, Address, bool) { + (U256::from(100), Address::ZERO, true) + } + + // Accept tuple as parameter + pub fn process_tuple(&mut self, data: (U256, U256, U256)) -> U256 { + let (a, b, c) = data; + a + b + c + } + + // Nested tuples + pub fn nested(&self) -> ((U256, U256), bool) { + ((U256::from(1), U256::from(2)), true) + } +} +``` + +### Tuple Destructuring + +```rust +use alloy_primitives::U256; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + pub fn calculate(&self) -> (U256, U256) { + let values = (U256::from(100), U256::from(200)); + + // Destructure the tuple + let (first, second) = values; + + // Return new tuple + (first * U256::from(2), second * U256::from(2)) + } + + // Pattern matching with tuples + pub fn match_tuple(&self, data: (bool, U256)) -> U256 { + match data { + (true, value) => value * U256::from(2), + (false, value) => value, + } + } +} +``` + +### Tuple Type Mappings + +| Rust Type | Solidity Type | ABI Signature | +| ---------------------- | ---------------------------- | ---------------------------- | +| `(U256,)` | `(uint256)` | `"(uint256)"` | +| `(U256, Address)` | `(uint256, address)` | `"(uint256,address)"` | +| `(bool, U256, Bytes)` | `(bool, uint256, bytes)` | `"(bool,uint256,bytes)"` | +| `((U256, U256), bool)` | `((uint256, uint256), bool)` | `"((uint256,uint256),bool)"` | + +**Tuple Limitations**: + +- Tuples support up to 24 elements +- Tuples are always returned as `memory` in Solidity +- Empty tuple `()` represents no return value + +## Structs + +Structs define custom data types with named fields. Use the `sol!` macro to define Solidity-compatible structs. + +### Defining Structs with `sol!` + +```rust +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct User { + address account; + uint256 balance; + string name; + } + + #[derive(Debug, AbiType)] + struct Token { + string name; + string symbol; + uint8 decimals; + } +} + +#[public] +impl MyContract { + pub fn get_user(&self) -> User { + User { + account: Address::ZERO, + balance: U256::from(1000), + name: "Alice".to_string(), + } + } + + pub fn process_user(&mut self, user: User) -> U256 { + // Access struct fields + user.balance + } + + pub fn get_token_info(&self) -> Token { + Token { + name: "MyToken".to_string(), + symbol: "MTK".to_string(), + decimals: 18, + } + } +} +``` + +### Nested Structs + +Structs can contain other structs, enabling complex data structures: + +```rust +use alloy_primitives::Address; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct Dog { + string name; + string breed; + } + + #[derive(Debug, AbiType)] + struct User { + address account; + string name; + Dog[] dogs; + } +} + +#[public] +impl MyContract { + pub fn create_user(&self) -> User { + let dogs = vec![ + Dog { + name: "Rex".to_string(), + breed: "Labrador".to_string(), + }, + Dog { + name: "Max".to_string(), + breed: "Beagle".to_string(), + }, + ]; + + User { + account: Address::ZERO, + name: "Alice".to_string(), + dogs, + } + } + + pub fn get_dog_count(&self, user: User) -> u256 { + user.dogs.len() as u256 + } +} +``` + +### Struct Best Practices + +1. **Always use `#[derive(AbiType)]`** for structs that will be used in contract interfaces: + + ```rust + sol! { + #[derive(Debug, AbiType)] + struct MyData { + uint256 value; + address owner; + } + } + ``` + +2. **Add `Debug` derive** for easier debugging: + + ```rust + sol! { + #[derive(Debug, AbiType)] + struct Config { + bool enabled; + uint256 timeout; + } + } + ``` + +3. **Use descriptive field names** that match Solidity conventions: + ```rust + sol! { + #[derive(Debug, AbiType)] + struct VestingSchedule { + address beneficiary; + uint256 startTime; + uint256 cliffDuration; + uint256 totalAmount; + } + } + ``` + +## Arrays + +Arrays are fixed-size collections of elements. Stylus supports both Rust arrays and Solidity-style arrays. + +### Fixed-Size Arrays + +```rust +use alloy_primitives::U256; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Return a fixed-size array + pub fn get_numbers(&self) -> [U256; 5] { + [ + U256::from(1), + U256::from(2), + U256::from(3), + U256::from(4), + U256::from(5), + ] + } + + // Accept fixed-size array as parameter + pub fn sum_array(&self, numbers: [U256; 5]) -> U256 { + numbers.iter().fold(U256::ZERO, |acc, &x| acc + x) + } + + // Nested arrays + pub fn matrix(&self) -> [[u32; 2]; 3] { + [[1, 2], [3, 4], [5, 6]] + } +} +``` + +### Array Operations + +```rust +use alloy_primitives::{Address, U256}; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Iterate over array + pub fn process_addresses(&self, addresses: [Address; 10]) -> U256 { + let mut count = U256::ZERO; + for addr in addresses.iter() { + if *addr != Address::ZERO { + count += U256::from(1); + } + } + count + } + + // Array of booleans + pub fn check_flags(&self, flags: [bool; 8]) -> bool { + flags.iter().all(|&f| f) + } +} +``` + +### Array Type Mappings + +| Rust Type | Solidity Type | Description | +| --------------------- | -------------- | ------------------------- | +| `[U256; 5]` | `uint256[5]` | 5-element uint256 array | +| `[bool; 10]` | `bool[10]` | 10-element bool array | +| `[Address; 3]` | `address[3]` | 3-element address array | +| `[[u32; 2]; 4]` | `uint32[2][4]` | Nested array (4x2 matrix) | +| `[FixedBytes<32>; 2]` | `bytes32[2]` | 2-element bytes32 array | + +## Vectors + +Vectors are dynamic arrays that can grow or shrink at runtime. They map to Solidity dynamic arrays. + +### Basic Vector Usage + +```rust +use alloy_primitives::{Address, U256, Bytes}; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Return a vector + pub fn get_numbers(&self) -> Vec { + vec![U256::from(1), U256::from(2), U256::from(3)] + } + + // Accept vector as parameter + pub fn sum_vec(&self, numbers: Vec) -> U256 { + numbers.iter().fold(U256::ZERO, |acc, x| acc + *x) + } + + // Vector of addresses + pub fn get_addresses(&self) -> Vec
{ + vec![Address::ZERO, Address::ZERO] + } + + // Vector of bytes + pub fn get_data_list(&self) -> Vec { + vec![ + Bytes::from(vec![1, 2, 3]), + Bytes::from(vec![4, 5, 6]), + ] + } +} +``` + +### Vector Operations + +```rust +use alloy_primitives::U256; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Filter vector + pub fn filter_even(&self, numbers: Vec) -> Vec { + numbers + .into_iter() + .filter(|n| n.byte(0) % 2 == 0) + .collect() + } + + // Map over vector + pub fn double_values(&self, numbers: Vec) -> Vec { + numbers + .into_iter() + .map(|n| n * U256::from(2)) + .collect() + } + + // Find in vector + pub fn contains_value(&self, numbers: Vec, target: U256) -> bool { + numbers.contains(&target) + } + + // Get vector length + pub fn get_length(&self, items: Vec) -> U256 { + U256::from(items.len()) + } +} +``` + +### Vectors of Structs + +```rust +use alloy_primitives::Address; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct Transaction { + address from; + address to; + uint256 amount; + } +} + +#[public] +impl MyContract { + pub fn get_transactions(&self) -> Vec { + vec![ + Transaction { + from: Address::ZERO, + to: Address::ZERO, + amount: U256::from(100), + }, + Transaction { + from: Address::ZERO, + to: Address::ZERO, + amount: U256::from(200), + }, + ] + } + + pub fn total_amount(&self, txs: Vec) -> U256 { + txs.iter() + .fold(U256::ZERO, |acc, tx| acc + tx.amount) + } +} +``` + +### Vector Type Mappings + +| Rust Type | Solidity Type | ABI Signature | Storage | +| --------------- | ------------- | --------------------- | ------- | +| `Vec` | `uint256[]` | `"uint256[] memory"` | Dynamic | +| `Vec
` | `address[]` | `"address[] memory"` | Dynamic | +| `Vec` | `bool[]` | `"bool[] memory"` | Dynamic | +| `Vec` | `bytes[]` | `"bytes[] memory"` | Dynamic | +| `Vec` | `MyStruct[]` | `"MyStruct[] memory"` | Dynamic | + +**Important Notes**: + +- Vectors are **always returned as `memory`** in Solidity, never as `calldata` +- `Vec` maps to `uint8[]`, not `bytes` (use `Bytes` for Solidity `bytes`) +- Vectors have dynamic size and consume more gas than fixed arrays + +## Bytes Types + +The SDK provides `Bytes` for dynamic byte arrays and `FixedBytes` for fixed-size byte arrays. + +### Dynamic Bytes (`Bytes`) + +```rust +use alloy_primitives::Bytes; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // Return dynamic bytes + pub fn get_data(&self) -> Bytes { + Bytes::from(vec![1, 2, 3, 4, 5]) + } + + // Process bytes + pub fn get_length(&self, data: Bytes) -> usize { + data.len() + } + + // Concatenate bytes + pub fn concat(&self, a: Bytes, b: Bytes) -> Bytes { + let mut result = a.to_vec(); + result.extend_from_slice(&b); + Bytes::from(result) + } +} +``` + +### Fixed Bytes (`FixedBytes`) + +```rust +use alloy_primitives::FixedBytes; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + // bytes32 (common for hashes) + pub fn get_hash(&self) -> FixedBytes<32> { + FixedBytes::<32>::ZERO + } + + // bytes4 (common for selectors) + pub fn get_selector(&self) -> FixedBytes<4> { + FixedBytes::from([0x12, 0x34, 0x56, 0x78]) + } + + // bytes16 + pub fn get_uuid(&self) -> FixedBytes<16> { + FixedBytes::<16>::from([ + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + ]) + } +} +``` + +## Complete Examples + +### Example 1: Complex Data Structures + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::string::String; +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct Token { + string name; + string symbol; + uint8 decimals; + uint256 totalSupply; + } + + #[derive(Debug, AbiType)] + struct Balance { + address owner; + uint256 amount; + } +} + +sol_storage! { + #[entrypoint] + pub struct CompoundExample { + uint256 counter; + } +} + +#[public] +impl CompoundExample { + // Return tuple + pub fn get_info(&self) -> (String, U256, bool) { + ("Example".to_string(), U256::from(42), true) + } + + // Return struct + pub fn get_token(&self) -> Token { + Token { + name: "MyToken".to_string(), + symbol: "MTK".to_string(), + decimals: 18, + totalSupply: U256::from(1000000), + } + } + + // Return vector of structs + pub fn get_balances(&self) -> Vec { + vec![ + Balance { + owner: Address::ZERO, + amount: U256::from(100), + }, + Balance { + owner: Address::ZERO, + amount: U256::from(200), + }, + ] + } + + // Accept array + pub fn process_array(&self, data: [U256; 5]) -> U256 { + data.iter().sum() + } + + // Accept vector and struct + pub fn batch_transfer(&mut self, recipients: Vec) -> U256 { + recipients.iter().map(|b| b.amount).sum() + } +} +``` + +### Example 2: Nested Data Structures + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::string::String; +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct Dog { + string name; + string breed; + } + + #[derive(Debug, AbiType)] + struct User { + address account; + string name; + Dog[] dogs; + } +} + +sol_storage! { + #[entrypoint] + pub struct NestedExample {} +} + +#[public] +impl NestedExample { + pub fn create_user(&self) -> User { + User { + account: Address::ZERO, + name: "Alice".to_string(), + dogs: vec![ + Dog { + name: "Rex".to_string(), + breed: "Labrador".to_string(), + }, + Dog { + name: "Max".to_string(), + breed: "Beagle".to_string(), + }, + ], + } + } + + pub fn get_dog_names(&self, user: User) -> Vec { + user.dogs.into_iter().map(|dog| dog.name).collect() + } + + pub fn count_dogs(&self, users: Vec) -> U256 { + let total: usize = users.iter().map(|u| u.dogs.len()).sum(); + U256::from(total) + } +} +``` + +## Best Practices + +### 1. Choose the Right Type + +```rust +// Use tuples for simple groupings +pub fn get_basics(&self) -> (U256, Address, bool) { /* ... */ } + +// Use structs for complex data with named fields +sol! { + #[derive(Debug, AbiType)] + struct UserProfile { + address account; + string name; + uint256 balance; + bool active; + } +} + +// Use arrays for fixed-size collections +pub fn get_top_five(&self) -> [U256; 5] { /* ... */ } + +// Use vectors for dynamic collections +pub fn get_all_users(&self) -> Vec
{ /* ... */ } +``` + +### 2. Memory Efficiency + +```rust +use alloy_primitives::U256; + +// Prefer fixed arrays when size is known +pub fn fixed_data(&self) -> [U256; 10] { + // More gas-efficient + [U256::ZERO; 10] +} + +// Use vectors only when size varies +pub fn dynamic_data(&self, count: usize) -> Vec { + vec![U256::ZERO; count] +} +``` + +### 3. Struct Naming + +```rust +use alloy_sol_types::sol; + +sol! { + // Good: Clear, descriptive names + #[derive(Debug, AbiType)] + struct TokenMetadata { + string name; + string symbol; + uint8 decimals; + } + + // Avoid: Ambiguous names + #[derive(Debug, AbiType)] + struct Data { + uint256 x; + uint256 y; + } +} +``` + +### 4. Vector vs Array + +```rust +use alloy_primitives::{Address, U256}; + +// Use fixed arrays for known sizes +pub fn get_admins(&self) -> [Address; 3] { + // Three admin addresses + [Address::ZERO; 3] +} + +// Use vectors for variable sizes +pub fn get_users(&self) -> Vec
{ + // Unknown number of users + vec![] +} +``` + +### 5. Nested Structures + +```rust +use alloy_sol_types::sol; + +sol! { + // Good: Reasonable nesting depth + #[derive(Debug, AbiType)] + struct User { + address account; + Profile profile; + } + + #[derive(Debug, AbiType)] + struct Profile { + string name; + uint256 age; + } + + // Avoid: Excessive nesting (gas inefficient) + #[derive(Debug, AbiType)] + struct DeepNesting { + Level1 l1; + } + + #[derive(Debug, AbiType)] + struct Level1 { + Level2 l2; + } + + #[derive(Debug, AbiType)] + struct Level2 { + Level3 l3; + } + + #[derive(Debug, AbiType)] + struct Level3 { + uint256 value; + } +} +``` + +## Type Conversion and Helpers + +### Converting Between Types + +```rust +use alloy_primitives::{U256, Bytes}; + +// Vec to Bytes +let vec: Vec = vec![1, 2, 3]; +let bytes = Bytes::from(vec); + +// Bytes to Vec +let bytes = Bytes::from(vec![1, 2, 3]); +let vec: Vec = bytes.to_vec(); + +// Array to Vec +let arr: [U256; 3] = [U256::from(1), U256::from(2), U256::from(3)]; +let vec: Vec = arr.to_vec(); + +// Vec to array (if size matches) +let vec = vec![U256::from(1), U256::from(2), U256::from(3)]; +let arr: [U256; 3] = vec.try_into().unwrap(); +``` + +### Working with Iterators + +```rust +use alloy_primitives::U256; + +// Map over vector +let numbers = vec![U256::from(1), U256::from(2), U256::from(3)]; +let doubled: Vec = numbers.iter().map(|n| n * U256::from(2)).collect(); + +// Filter vector +let evens: Vec = numbers.into_iter().filter(|n| n.byte(0) % 2 == 0).collect(); + +// Fold/reduce +let sum = numbers.iter().fold(U256::ZERO, |acc, n| acc + n); +``` + +## Common Patterns + +### Batch Operations + +```rust +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + #[derive(Debug, AbiType)] + struct Transfer { + address to; + uint256 amount; + } +} + +#[public] +impl MyContract { + pub fn batch_transfer(&mut self, transfers: Vec) -> U256 { + let mut total = U256::ZERO; + for transfer in transfers { + // Process each transfer + total += transfer.amount; + } + total + } +} +``` + +### Pagination + +```rust +use alloy_primitives::U256; +use stylus_sdk::prelude::*; + +#[public] +impl MyContract { + pub fn get_page(&self, items: Vec, page: usize, size: usize) -> Vec { + let start = page * size; + let end = start + size; + items.get(start..end.min(items.len())) + .unwrap_or(&[]) + .to_vec() + } +} +``` + +## See Also + +- [Primitives](./primitives.mdx) - Basic types (bool, integers, address, strings) +- [Storage Types](./storage.mdx) - Persistent storage for compound types +- [Type Conversions](./conversions-between-types.mdx) - Converting between types From 69b669f8e94d25f4730998eeca9aed434bc2c368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 13:11:37 -0800 Subject: [PATCH 020/162] add slop compound types article --- docs/stylus/reference/data-types/compound-types.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/reference/data-types/compound-types.mdx index d418445953..4de7cedb30 100644 --- a/docs/stylus/reference/data-types/compound-types.mdx +++ b/docs/stylus/reference/data-types/compound-types.mdx @@ -8,8 +8,6 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -# Compound Types - Compound types allow you to group multiple values together in Stylus contracts. The SDK provides full support for tuples, structs, arrays, and vectors with automatic ABI encoding/decoding and Solidity type mappings. ## Tuples From a34e1dc8256b16335ee5e440df671f42371b3145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 13:16:42 -0800 Subject: [PATCH 021/162] Document Stylus Rust storage types with comprehensive examples Add detailed documentation for all Stylus SDK storage types including: - Storage overview and EVM State Trie interoperability - Storage primitives (StorageBool, StorageUint, StorageAddress, FixedBytes) - Integer update operations (wrapping and checked) - Storage collections (StorageVec, StorageArray, StorageMap) - StorageString and StorageBytes for dynamic data - Storage structs with nested structures - Complete type mapping tables - Storage patterns (initialization, counter, access control, registry) - Best practices for storage operations - Storage slots and layout explanation - Complete working token example Each section includes: - Practical code examples from SDK examples - Method signatures and usage patterns - Solidity equivalents and mappings - Gas optimization guidance - Common design patterns - Best practices for efficient storage use --- docs/stylus/reference/data-types/storage.mdx | 1103 +++++++++++++++++- 1 file changed, 1091 insertions(+), 12 deletions(-) diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 8f49eab97c..da71a86abb 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -1,20 +1,1099 @@ --- title: 'Stylus Rust SDK storage' -description: 'Stylus Rust SDK storage' +description: 'Stylus Rust SDK storage types' author: chrisco sme: chrisco -sidebar_position: 1 +sidebar_position: 3 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. displayed_sidebar: buildAppsSidebar --- -3. Storage - 1. Bool - 2. Uint - 3. Address - 4. Struct - 5. Array - 6. Map - 7. String - 8. Bytes - 9. FixedBytes +# Storage + +Persistent storage in Stylus contracts provides access to the EVM State Trie, the same key-value storage used by Solidity contracts. The SDK provides type-safe storage access through dedicated storage types that prevent aliasing errors at compile time using Rust's borrow checker. + +## Overview + +Stylus contracts share the same persistent storage as Solidity contracts: + +- Both Stylus and Solidity access the **same EVM State Trie** +- Storage is **fully interoperable** between Stylus and Solidity contracts +- Stylus provides **compile-time safety** through Rust's type system +- Storage operations are **cached** for gas efficiency + +### Storage Declaration + +Use the `sol_storage!` macro to define contract storage with Solidity-compatible layout: + +```rust +use stylus_sdk::prelude::*; + +sol_storage! { + #[entrypoint] + pub struct MyContract { + uint256 count; + address owner; + bool initialized; + } +} +``` + +Alternatively, use the `#[storage]` attribute for Rust-style declarations: + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::storage::*; + +#[storage] +#[entrypoint] +pub struct MyContract { + count: StorageU256, + owner: StorageAddress, + initialized: StorageBool, +} +``` + +## Storage Primitives + +Storage primitives are persistent versions of basic types. + +### Boolean Storage (`StorageBool`) + +Store boolean values in persistent storage: + +```rust +use stylus_sdk::prelude::*; + +sol_storage! { + #[entrypoint] + pub struct Contract { + bool is_initialized; + bool is_paused; + } +} + +#[public] +impl Contract { + pub fn initialize(&mut self) { + self.is_initialized.set(true); + } + + pub fn is_initialized(&self) -> bool { + self.is_initialized.get() + } + + pub fn toggle_pause(&mut self) { + let current = self.is_paused.get(); + self.is_paused.set(!current); + } +} +``` + +### Integer Storage + +Store unsigned and signed integers with various bit sizes: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +sol_storage! { + #[entrypoint] + pub struct Counter { + uint256 count; + uint64 timestamp; + int256 balance; + } +} + +#[public] +impl Counter { + // Unsigned integer operations + pub fn increment(&mut self) { + let current = self.count.get(); + self.count.set(current + U256::from(1)); + } + + pub fn add(&mut self, value: U256) { + let current = self.count.get(); + self.count.set(current + value); + } + + pub fn get_count(&self) -> U256 { + self.count.get() + } + + // Timestamp storage + pub fn set_timestamp(&mut self, ts: u64) { + self.timestamp.set(ts); + } +} +``` + +#### Available Storage Integer Types + +| Storage Type | Primitive Type | Bit Size | Solidity Type | +| ------------- | -------------- | -------- | ------------- | +| `StorageU8` | `U8` | 8 bits | `uint8` | +| `StorageU16` | `U16` | 16 bits | `uint16` | +| `StorageU32` | `U32` | 32 bits | `uint32` | +| `StorageU64` | `U64` | 64 bits | `uint64` | +| `StorageU128` | `U128` | 128 bits | `uint128` | +| `StorageU256` | `U256` | 256 bits | `uint256` | +| `StorageI8` | `I8` | 8 bits | `int8` | +| `StorageI16` | `I16` | 16 bits | `int16` | +| `StorageI32` | `I32` | 32 bits | `int32` | +| `StorageI64` | `I64` | 64 bits | `int64` | +| `StorageI128` | `I128` | 128 bits | `int128` | +| `StorageI256` | `I256` | 256 bits | `int256` | + +#### Integer Update Operations + +`StorageUint` types provide convenient update methods: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +sol_storage! { + #[entrypoint] + pub struct Contract { + uint256 balance; + } +} + +#[public] +impl Contract { + // Wrapping operations (overflow wraps around) + pub fn add_wrapping(&mut self, value: U256) -> U256 { + self.balance.update_wrap_add(value) + } + + pub fn sub_wrapping(&mut self, value: U256) -> U256 { + self.balance.update_wrap_sub(value) + } + + pub fn mul_wrapping(&mut self, value: U256) -> U256 { + self.balance.update_wrap_mul(value) + } + + // Checked operations (return None on overflow) + pub fn add_checked(&mut self, value: U256) -> Option { + self.balance.update_check_add(value) + } + + pub fn sub_checked(&mut self, value: U256) -> Option { + self.balance.update_check_sub(value) + } +} +``` + +### Address Storage (`StorageAddress`) + +Store Ethereum addresses: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::Address; + +sol_storage! { + #[entrypoint] + pub struct Ownership { + address owner; + address pending_owner; + } +} + +#[public] +impl Ownership { + pub fn get_owner(&self) -> Address { + self.owner.get() + } + + pub fn transfer_ownership(&mut self, new_owner: Address) { + // Validate address + if new_owner == Address::ZERO { + // Handle error + return; + } + + let current_owner = self.owner.get(); + if self.vm().msg_sender() != current_owner { + // Not authorized + return; + } + + self.pending_owner.set(new_owner); + } + + pub fn accept_ownership(&mut self) { + let caller = self.vm().msg_sender(); + if caller != self.pending_owner.get() { + return; + } + + self.owner.set(caller); + self.pending_owner.set(Address::ZERO); + } +} +``` + +### Fixed Bytes Storage + +Store fixed-size byte arrays: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::FixedBytes; + +sol_storage! { + #[entrypoint] + pub struct Hashes { + bytes32 merkle_root; + bytes32 commitment; + bytes4 selector; + } +} + +#[public] +impl Hashes { + pub fn set_merkle_root(&mut self, root: FixedBytes<32>) { + self.merkle_root.set(root); + } + + pub fn get_merkle_root(&self) -> FixedBytes<32> { + self.merkle_root.get() + } + + pub fn verify_hash(&self, proof: FixedBytes<32>) -> bool { + self.merkle_root.get() == proof + } +} +``` + +#### Available Fixed Bytes Storage Types + +| Storage Type | Bytes | Bits | Solidity Type | +| ------------- | ----- | -------- | ------------- | +| `StorageB8` | 1 | 8 bits | `bytes1` | +| `StorageB16` | 2 | 16 bits | `bytes2` | +| `StorageB32` | 4 | 32 bits | `bytes4` | +| `StorageB64` | 8 | 64 bits | `bytes8` | +| `StorageB128` | 16 | 128 bits | `bytes16` | +| `StorageB160` | 20 | 160 bits | `bytes20` | +| `StorageB224` | 28 | 224 bits | `bytes28` | +| `StorageB256` | 32 | 256 bits | `bytes32` | + +## Storage Collections + +Storage collections provide persistent arrays, vectors, and maps. + +### StorageVec (Dynamic Array) + +Dynamic arrays that can grow and shrink: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +sol_storage! { + #[entrypoint] + pub struct TokenList { + address[] holders; + uint256[] balances; + } +} + +#[public] +impl TokenList { + // Add element + pub fn add_holder(&mut self, holder: Address) { + self.holders.push(holder); + } + + // Get element + pub fn get_holder(&self, index: U256) -> Address { + self.holders.get(index).unwrap() + } + + // Get length + pub fn holder_count(&self) -> U256 { + U256::from(self.holders.len()) + } + + // Set element + pub fn set_balance(&mut self, index: U256, balance: U256) { + self.balances.setter(index).unwrap().set(balance); + } + + // Iterate over elements + pub fn total_balance(&self) -> U256 { + let mut total = U256::ZERO; + for i in 0..self.balances.len() { + total += self.balances.get(U256::from(i)).unwrap(); + } + total + } + + // Remove element (erase to zero) + pub fn remove_holder(&mut self, index: U256) { + self.holders.setter(index).unwrap().erase(); + } + + // Clear all elements + pub fn clear_holders(&mut self) { + self.holders.erase(); + } +} +``` + +#### StorageVec Methods + +```rust +// Length operations +fn len(&self) -> usize +fn is_empty(&self) -> bool + +// Access operations +fn get(&self, index: impl TryInto) -> Option +fn getter(&self, index: impl TryInto) -> Option> +fn setter(&mut self, index: impl TryInto) -> Option> + +// Mutation operations +fn push(&mut self, value: T) +fn grow(&mut self) -> StorageGuardMut<'_, T> // Add new element and return mutable reference +fn erase(&mut self) // Clear all elements +``` + +### StorageArray (Fixed Array) + +Fixed-size arrays with compile-time known length: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +sol_storage! { + #[entrypoint] + pub struct FixedData { + uint256[10] values; + address[5] admins; + } +} + +#[public] +impl FixedData { + // Get element + pub fn get_value(&self, index: U256) -> U256 { + self.values.get(index).unwrap() + } + + // Set element + pub fn set_value(&mut self, index: U256, value: U256) { + self.values.setter(index).unwrap().set(value); + } + + // Get array length (compile-time constant) + pub fn array_size(&self) -> U256 { + U256::from(self.values.len()) + } + + // Iterate over array + pub fn sum_values(&self) -> U256 { + let mut sum = U256::ZERO; + for i in 0..self.values.len() { + sum += self.values.get(U256::from(i)).unwrap(); + } + sum + } +} +``` + +### StorageMap (Mapping) + +Key-value storage, equivalent to Solidity `mapping`: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +sol_storage! { + #[entrypoint] + pub struct Token { + mapping(address => uint256) balances; + mapping(address => mapping(address => uint256)) allowances; + } +} + +#[public] +impl Token { + // Get value (returns zero if not set) + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } + + // Set value + pub fn set_balance(&mut self, account: Address, amount: U256) { + self.balances.setter(account).set(amount); + } + + // Insert value (same as set) + pub fn mint(&mut self, account: Address, amount: U256) { + let current = self.balances.get(account); + self.balances.insert(account, current + amount); + } + + // Delete value (reset to zero) + pub fn burn(&mut self, account: Address, amount: U256) { + let current = self.balances.get(account); + if current >= amount { + self.balances.setter(account).set(current - amount); + } + } + + // Nested mapping + pub fn allowance(&self, owner: Address, spender: Address) -> U256 { + self.allowances.get(owner).get(spender) + } + + pub fn approve(&mut self, spender: Address, amount: U256) { + let owner = self.vm().msg_sender(); + self.allowances + .setter(owner) + .setter(spender) + .set(amount); + } +} +``` + +#### StorageMap Methods + +```rust +// Read operations +fn get(&self, key: K) -> V // Returns zero-value if not present +fn getter(&self, key: K) -> StorageGuard<'_, V> + +// Write operations +fn setter(&mut self, key: K) -> StorageGuardMut<'_, V> +fn insert(&mut self, key: K, value: V) +fn replace(&mut self, key: K, value: V) -> V // Returns old value +fn take(&mut self, key: K) -> V // Returns value and deletes +fn delete(&mut self, key: K) // Erases entry +``` + +#### Supported Map Key Types + +Any type implementing `StorageKey` can be used as a map key: + +- `Address` +- `U256`, `U160`, and other `Uint` types +- `FixedBytes` +- `Signed` types +- `bool` + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256, FixedBytes}; + +sol_storage! { + #[entrypoint] + pub struct MultiMap { + mapping(address => uint256) by_address; + mapping(uint256 => address) by_id; + mapping(bytes32 => bool) by_hash; + mapping(bool => uint256) by_flag; + } +} +``` + +### StorageString and StorageBytes + +Dynamic string and bytes storage: + +```rust +use stylus_sdk::prelude::*; +use alloc::string::String; + +sol_storage! { + #[entrypoint] + pub struct Metadata { + string name; + string symbol; + bytes data; + } +} + +#[public] +impl Metadata { + // String operations + pub fn get_name(&self) -> String { + self.name.get_string() + } + + pub fn set_name(&mut self, name: String) { + self.name.set_str(name); + } + + pub fn name_length(&self) -> usize { + self.name.len() + } + + pub fn clear_name(&mut self) { + self.name.erase(); + } + + // Bytes operations + pub fn get_data(&self) -> Vec { + self.data.get_bytes() + } + + pub fn set_data(&mut self, data: Vec) { + self.data.set_bytes(data); + } + + pub fn data_length(&self) -> usize { + self.data.len() + } +} +``` + +## Storage Structs + +Define custom storage types with nested structures: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +// Storage struct definition +#[storage] +pub struct UserInfo { + balance: StorageU256, + is_active: StorageBool, + timestamp: StorageU64, +} + +sol_storage! { + #[entrypoint] + pub struct UserRegistry { + mapping(address => UserInfo) users; + uint256 total_users; + } +} + +#[public] +impl UserRegistry { + pub fn register_user(&mut self, user: Address) { + let mut user_info = self.users.setter(user); + user_info.balance.set(U256::ZERO); + user_info.is_active.set(true); + user_info.timestamp.set(self.vm().block_timestamp()); + + let count = self.total_users.get(); + self.total_users.set(count + U256::from(1)); + } + + pub fn get_balance(&self, user: Address) -> U256 { + self.users.get(user).balance.get() + } + + pub fn update_balance(&mut self, user: Address, amount: U256) { + self.users.setter(user).balance.set(amount); + } + + pub fn is_active(&self, user: Address) -> bool { + self.users.get(user).is_active.get() + } +} +``` + +### Nested Storage Structs + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::Address; + +#[storage] +pub struct Dog { + name: StorageString, + breed: StorageString, +} + +#[storage] +pub struct User { + name: StorageString, + dogs: StorageVec, +} + +sol_storage! { + #[entrypoint] + pub struct Registry { + mapping(address => User) users; + } +} + +#[public] +impl Registry { + pub fn add_dog(&mut self, owner: Address, name: String, breed: String) { + let mut user = self.users.setter(owner); + let mut dog = user.dogs.grow(); + dog.name.set_str(name); + dog.breed.set_str(breed); + } + + pub fn get_dog_count(&self, owner: Address) -> usize { + self.users.get(owner).dogs.len() + } + + pub fn get_dog_name(&self, owner: Address, index: usize) -> String { + self.users + .get(owner) + .dogs + .get(index) + .unwrap() + .name + .get_string() + } +} +``` + +## Storage Patterns + +### Initialization Pattern + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +sol_storage! { + #[entrypoint] + pub struct Contract { + bool initialized; + address owner; + uint256 value; + } +} + +#[public] +impl Contract { + #[constructor] + pub fn constructor(&mut self, initial_value: U256) { + self.owner.set(self.vm().msg_sender()); + self.value.set(initial_value); + self.initialized.set(true); + } + + fn only_initialized(&self) { + if !self.initialized.get() { + // Revert: not initialized + } + } + + pub fn get_value(&self) -> U256 { + self.only_initialized(); + self.value.get() + } +} +``` + +### Counter Pattern + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +sol_storage! { + #[entrypoint] + pub struct Counter { + uint256 count; + mapping(address => uint256) user_counts; + } +} + +#[public] +impl Counter { + pub fn increment(&mut self) { + let current = self.count.get(); + self.count.set(current + U256::from(1)); + } + + pub fn increment_by(&mut self, amount: U256) { + let current = self.count.get(); + self.count.set(current + amount); + } + + pub fn increment_user(&mut self) { + let user = self.vm().msg_sender(); + let current = self.user_counts.get(user); + self.user_counts.insert(user, current + U256::from(1)); + } + + pub fn get_count(&self) -> U256 { + self.count.get() + } + + pub fn get_user_count(&self, user: Address) -> U256 { + self.user_counts.get(user) + } +} +``` + +### Access Control Pattern + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::Address; + +sol_storage! { + #[entrypoint] + pub struct AccessControl { + address owner; + mapping(address => bool) admins; + mapping(address => bool) users; + } +} + +#[public] +impl AccessControl { + #[constructor] + pub fn constructor(&mut self) { + let sender = self.vm().msg_sender(); + self.owner.set(sender); + self.admins.insert(sender, true); + } + + fn only_owner(&self) { + if self.vm().msg_sender() != self.owner.get() { + // Revert: not owner + } + } + + fn only_admin(&self) { + let sender = self.vm().msg_sender(); + if !self.admins.get(sender) { + // Revert: not admin + } + } + + pub fn add_admin(&mut self, admin: Address) { + self.only_owner(); + self.admins.insert(admin, true); + } + + pub fn remove_admin(&mut self, admin: Address) { + self.only_owner(); + self.admins.delete(admin); + } + + pub fn add_user(&mut self, user: Address) { + self.only_admin(); + self.users.insert(user, true); + } + + pub fn is_admin(&self, account: Address) -> bool { + self.admins.get(account) + } + + pub fn is_user(&self, account: Address) -> bool { + self.users.get(account) + } +} +``` + +### Registry Pattern + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +#[storage] +pub struct Record { + owner: StorageAddress, + created_at: StorageU64, + updated_at: StorageU64, + active: StorageBool, +} + +sol_storage! { + #[entrypoint] + pub struct Registry { + mapping(bytes32 => Record) records; + mapping(address => bytes32[]) user_records; + uint256 total_records; + } +} + +#[public] +impl Registry { + pub fn create_record(&mut self, id: FixedBytes<32>) { + let now = self.vm().block_timestamp(); + let owner = self.vm().msg_sender(); + + let mut record = self.records.setter(id); + record.owner.set(owner); + record.created_at.set(now); + record.updated_at.set(now); + record.active.set(true); + + // Add to user's record list + self.user_records.setter(owner).push(id); + + // Increment total + let total = self.total_records.get(); + self.total_records.set(total + U256::from(1)); + } + + pub fn get_record_owner(&self, id: FixedBytes<32>) -> Address { + self.records.get(id).owner.get() + } + + pub fn is_active(&self, id: FixedBytes<32>) -> bool { + self.records.get(id).active.get() + } + + pub fn deactivate(&mut self, id: FixedBytes<32>) { + let owner = self.records.get(id).owner.get(); + if owner != self.vm().msg_sender() { + // Not authorized + return; + } + + self.records.setter(id).active.set(false); + } +} +``` + +## Best Practices + +### 1. Use Appropriate Storage Types + +```rust +// Good: Use StorageU256 for counters +sol_storage! { + pub struct Counter { + uint256 count; + } +} + +// Good: Use StorageMap for lookups +sol_storage! { + pub struct Balances { + mapping(address => uint256) balances; + } +} + +// Good: Use StorageVec for dynamic lists +sol_storage! { + pub struct Users { + address[] user_list; + } +} +``` + +### 2. Minimize Storage Operations + +```rust +// Bad: Multiple storage reads +pub fn bad_example(&self) -> U256 { + let a = self.value.get(); + let b = self.value.get(); // Unnecessary read + a + b +} + +// Good: Single storage read +pub fn good_example(&self) -> U256 { + let value = self.value.get(); + value + value +} +``` + +### 3. Use Batch Operations + +```rust +// Good: Batch updates in a single transaction +pub fn update_multiple(&mut self, values: Vec) { + for (i, value) in values.iter().enumerate() { + self.data.setter(U256::from(i)).unwrap().set(*value); + } +} +``` + +### 4. Check Before Delete + +```rust +// Good: Verify before deletion +pub fn remove_user(&mut self, user: Address) { + if self.users.get(user) { + self.users.delete(user); + // Update related storage + } +} +``` + +### 5. Use Erase for Gas Refunds + +```rust +// Good: Clear storage for gas refunds +pub fn clear_data(&mut self) { + self.data.erase(); // Refunds gas +} +``` + +## Storage Slots and Layout + +Stylus uses the same storage layout as Solidity: + +- Each storage slot is **32 bytes** (256 bits) +- Variables are **packed** when possible to save space +- Arrays and mappings use **computed slots** via hashing + +```rust +sol_storage! { + pub struct Packed { + uint128 a; // Slot 0 (first 16 bytes) + uint128 b; // Slot 0 (last 16 bytes) + uint256 c; // Slot 1 (full 32 bytes) + bool d; // Slot 2 (1 byte) + address e; // Slot 2 (20 bytes, packed with d) + } +} +``` + +### Custom Storage Slots + +You can specify custom storage slots for specific use cases: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +#[storage] +#[entrypoint] +pub struct CustomSlots { + // Default slot allocation + value: StorageU256, + + // Custom slot (advanced usage) + // Note: Requires manual slot management +} +``` + +## Complete Example + +Here's a comprehensive example demonstrating various storage types: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::string::String; +use alloy_primitives::{Address, FixedBytes, U256}; +use stylus_sdk::prelude::*; + +#[storage] +pub struct TokenMetadata { + name: StorageString, + symbol: StorageString, + decimals: StorageU8, +} + +sol_storage! { + #[entrypoint] + pub struct Token { + // Primitives + uint256 total_supply; + bool paused; + address owner; + + // Collections + mapping(address => uint256) balances; + mapping(address => mapping(address => uint256)) allowances; + address[] holders; + + // Nested struct + TokenMetadata metadata; + } +} + +#[public] +impl Token { + #[constructor] + pub fn constructor(&mut self, name: String, symbol: String) { + self.owner.set(self.vm().msg_sender()); + self.metadata.name.set_str(name); + self.metadata.symbol.set_str(symbol); + self.metadata.decimals.set(18); + self.paused.set(false); + } + + pub fn total_supply(&self) -> U256 { + self.total_supply.get() + } + + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } + + pub fn transfer(&mut self, to: Address, amount: U256) -> bool { + if self.paused.get() { + return false; + } + + let from = self.vm().msg_sender(); + let from_balance = self.balances.get(from); + + if from_balance < amount { + return false; + } + + self.balances.insert(from, from_balance - amount); + + let to_balance = self.balances.get(to); + self.balances.insert(to, to_balance + amount); + + true + } + + pub fn approve(&mut self, spender: Address, amount: U256) -> bool { + let owner = self.vm().msg_sender(); + self.allowances.setter(owner).insert(spender, amount); + true + } + + pub fn allowance(&self, owner: Address, spender: Address) -> U256 { + self.allowances.get(owner).get(spender) + } + + pub fn pause(&mut self) { + if self.vm().msg_sender() != self.owner.get() { + return; + } + self.paused.set(true); + } + + pub fn unpause(&mut self) { + if self.vm().msg_sender() != self.owner.get() { + return; + } + self.paused.set(false); + } + + pub fn name(&self) -> String { + self.metadata.name.get_string() + } + + pub fn symbol(&self) -> String { + self.metadata.symbol.get_string() + } + + pub fn decimals(&self) -> u8 { + self.metadata.decimals.get() + } +} +``` + +## See Also + +- [Primitives](./primitives.mdx) - Basic types used in storage +- [Compound Types](./compound-types.mdx) - Complex types in storage +- [Type Conversions](./conversions-between-types.mdx) - Converting between types From 29555c6e29a3445e3645b5dc6f4d8aa0675ac0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 13:22:26 -0800 Subject: [PATCH 022/162] fix slop storage article --- docs/stylus/reference/data-types/storage.mdx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index da71a86abb..82461b39fa 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -8,18 +8,16 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -# Storage - Persistent storage in Stylus contracts provides access to the EVM State Trie, the same key-value storage used by Solidity contracts. The SDK provides type-safe storage access through dedicated storage types that prevent aliasing errors at compile time using Rust's borrow checker. ## Overview Stylus contracts share the same persistent storage as Solidity contracts: -- Both Stylus and Solidity access the **same EVM State Trie** -- Storage is **fully interoperable** between Stylus and Solidity contracts -- Stylus provides **compile-time safety** through Rust's type system -- Storage operations are **cached** for gas efficiency +- Both Stylus and Solidity access the same EVM State Trie +- Storage is fully interoperable between Stylus and Solidity contracts +- Stylus provides compile-time safety through Rust's type system +- Storage operations are cached for gas efficiency ### Storage Declaration From 43251884e6037867a1fc55bb34b8b9e2289e9296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 13:31:02 -0800 Subject: [PATCH 023/162] Document Stylus Rust contracts Add comprehensive documentation for Stylus contracts covering: - Contract basics and minimal contract structure - Storage definition with sol_storage! and #[storage] - #[entrypoint] macro and TopLevelStorage trait - #[public] macro for exposing methods - State mutability inference (view, write, pure) - Constructor with #[constructor] attribute - Method attributes: #[payable], #[receive], #[fallback], #[selector] - Trait-based contract composition with #[implements] - Accessing VM context via self.vm() - Events definition and emission with sol! macro - External contract calls with sol_interface! - Call configurations (view, mutating, payable, gas) - Low-level calls (call, static_call, RawCall) - Error handling with SolidityError - Complete ERC-20 example demonstrating all features - Best practices for state mutability, validation, errors, events, access control, gas optimization, CEI pattern, and type-safe interfaces All code examples are based on actual SDK implementation from stylus-sdk-rs repository. --- docs/stylus/reference/contracts.mdx | 1122 ++++++++++++++++++++++++++- 1 file changed, 1107 insertions(+), 15 deletions(-) diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx index 771b25cea6..9348a417e1 100644 --- a/docs/stylus/reference/contracts.mdx +++ b/docs/stylus/reference/contracts.mdx @@ -1,22 +1,1114 @@ --- -title: 'Contracts' -description: 'Contracts' +title: 'Stylus contracts' +description: 'Stylus Rust SDK contracts, methods, and lifecycle' author: chrisco sme: chrisco -sidebar_position: 1 +sidebar_position: 2 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. displayed_sidebar: buildAppsSidebar --- -6. Contracts - 1. Calling other contracts - 1. Call - 2. Raw call - 3. Delegate call - 4. Static call - 5. sol_interface - 2. Sending ETH - 3. Factory deploy - 4. Function modifiers - 5. Inheritance (temporary) - 6. Constructors (coming soon) +The Stylus SDK provides a complete framework for writing smart contracts in Rust that are fully compatible with Solidity contracts on Arbitrum chains. Contracts written with Stylus compile to WebAssembly and share the same EVM state trie as Solidity contracts, enabling seamless interoperability. + +## Contract Basics + +A Stylus contract consists of three main components: + +1. **Storage Definition**: Defines the contract's persistent state +2. **Entrypoint**: Marks the main contract struct that handles incoming calls +3. **Public Methods**: Functions exposed to external callers via the `#[public]` macro + +### Minimal Contract + +Here's the simplest possible Stylus contract: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use stylus_sdk::prelude::*; + +#[storage] +#[entrypoint] +pub struct HelloWorld; + +#[public] +impl HelloWorld { + fn user_main(_input: Vec) -> ArbResult { + Ok(Vec::new()) + } +} +``` + +This contract: + +- Uses `#[storage]` to define the contract struct (empty in this case) +- Uses `#[entrypoint]` to mark it as the contract's entry point +- Uses `#[public]` to expose the `user_main` function +- Returns `ArbResult`, which is `Result, Vec>` + +## Storage Definition + +Stylus contracts use the `sol_storage!` macro or `#[storage]` attribute to define persistent storage that maps directly to Solidity storage slots. + +### Using `sol_storage!` (Solidity-style) + +The `sol_storage!` macro lets you define storage using Solidity syntax: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +sol_storage! { + #[entrypoint] + pub struct Counter { + uint256 count; + address owner; + mapping(address => uint256) balances; + } +} +``` + +This creates a contract with: + +- A `count` field of type `StorageU256` +- An `owner` field of type `StorageAddress` +- A `balances` mapping from `Address` to `StorageU256` + +### Using `#[storage]` (Rust-style) + +Alternatively, use the `#[storage]` attribute with explicit storage types: + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::storage::{StorageU256, StorageAddress, StorageMap}; +use alloy_primitives::{Address, U256}; + +#[storage] +#[entrypoint] +pub struct Counter { + count: StorageU256, + owner: StorageAddress, + balances: StorageMap, +} +``` + +Both approaches produce identical storage layouts and are fully interoperable with Solidity contracts using the same storage structure. + +## The `#[entrypoint]` Macro + +The `#[entrypoint]` macro marks a struct as the contract's main entry point. It automatically implements the `TopLevelStorage` trait, which enables: + +- Routing incoming calls to public methods +- Managing contract storage +- Handling reentrancy protection (unless the `reentrant` feature is enabled) + +**Key requirements:** + +- Exactly one struct per contract must have `#[entrypoint]` +- The struct must also have `#[storage]` or be defined in `sol_storage!` +- The entrypoint struct represents the contract's root storage + +**Example:** + +```rust +sol_storage! { + #[entrypoint] + pub struct MyContract { + uint256 value; + } +} +``` + +The `#[entrypoint]` macro generates: + +1. An implementation of `TopLevelStorage` for the struct +2. A `user_entrypoint` function that Stylus calls when the contract receives a transaction +3. Method routing logic to dispatch calls to `#[public]` methods + +## Public Methods with `#[public]` + +The `#[public]` macro exposes Rust methods as external contract functions callable from Solidity, other Stylus contracts, or external callers. + +### Basic Public Methods + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::U256; + +sol_storage! { + #[entrypoint] + pub struct Calculator { + uint256 result; + } +} + +#[public] +impl Calculator { + // View function (read-only) + pub fn get_result(&self) -> U256 { + self.result.get() + } + + // Write function (mutates state) + pub fn set_result(&mut self, value: U256) { + self.result.set(value); + } + + // Pure function (no state access) + pub fn add(a: U256, b: U256) -> U256 { + a + b + } +} +``` + +### State Mutability + +The SDK automatically infers state mutability from the method signature: + +| Signature | Mutability | Solidity Equivalent | Description | +| ----------- | ---------- | ------------------- | --------------------- | +| `&self` | `view` | `view` | Read contract state | +| `&mut self` | Write | (default) | Modify contract state | +| Neither | `pure` | `pure` | No state access | + +**Examples:** + +```rust +#[public] +impl MyContract { + // View: can read state, cannot modify + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } + + // Write: can read and modify state + pub fn transfer(&mut self, to: Address, amount: U256) { + let sender = self.vm().msg_sender(); + let balance = self.balances.get(sender); + self.balances.setter(sender).set(balance - amount); + self.balances.setter(to).set(self.balances.get(to) + amount); + } + + // Pure: no state access at all + pub fn calculate_fee(amount: U256) -> U256 { + amount * U256::from(3) / U256::from(100) + } +} +``` + +## Constructor + +The `#[constructor]` attribute marks a function that runs once during contract deployment. + +### Basic Constructor + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +sol_storage! { + #[entrypoint] + pub struct Token { + address owner; + uint256 total_supply; + } +} + +#[public] +impl Token { + #[constructor] + pub fn constructor(&mut self, initial_supply: U256) { + let deployer = self.vm().msg_sender(); + self.owner.set(deployer); + self.total_supply.set(initial_supply); + } + + pub fn owner(&self) -> Address { + self.owner.get() + } +} +``` + +### Constructor Features + +**Payable Constructor:** + +```rust +#[public] +impl Token { + #[constructor] + #[payable] + pub fn constructor(&mut self, initial_supply: U256) { + // Contract can receive ETH during deployment + let received = self.vm().msg_value(); + self.owner.set(self.vm().msg_sender()); + self.total_supply.set(initial_supply); + } +} +``` + +**Important Notes:** + +- The constructor name can be anything (doesn't have to be `constructor`) +- Only one constructor per contract +- Constructor runs exactly once when the contract is deployed +- Use `tx_origin()` instead of `msg_sender()` when deploying via a factory contract + +## Method Attributes + +### `#[payable]` + +Marks a function as able to receive ETH: + +```rust +#[public] +impl PaymentProcessor { + #[payable] + pub fn deposit(&mut self) -> U256 { + let sender = self.vm().msg_sender(); + let amount = self.vm().msg_value(); + + let current = self.balances.get(sender); + self.balances.setter(sender).set(current + amount); + + amount + } + + // Non-payable function will revert if ETH is sent + pub fn withdraw(&mut self, amount: U256) { + // Will revert if msg.value > 0 + let sender = self.vm().msg_sender(); + let balance = self.balances.get(sender); + self.balances.setter(sender).set(balance - amount); + } +} +``` + +**Important:** Without `#[payable]`, sending ETH to a function causes a revert. + +### `#[receive]` + +Handles plain ETH transfers without calldata (equivalent to Solidity's `receive()` function): + +```rust +use alloy_sol_types::sol; + +sol! { + event EtherReceived(address indexed sender, uint256 amount); +} + +#[public] +impl Wallet { + #[receive] + #[payable] + pub fn receive(&mut self) -> Result<(), Vec> { + let sender = self.vm().msg_sender(); + let amount = self.vm().msg_value(); + + let balance = self.balances.get(sender); + self.balances.setter(sender).set(balance + amount); + + self.vm().log(EtherReceived { sender, amount }); + Ok(()) + } +} +``` + +**Notes:** + +- Must be combined with `#[payable]` +- Called when the contract receives ETH without calldata +- Only one `#[receive]` function per contract +- Must have signature: `fn name(&mut self) -> Result<(), Vec>` + +### `#[fallback]` + +Handles calls to non-existent functions or as a fallback for ETH transfers: + +```rust +use alloy_sol_types::sol; + +sol! { + event FallbackCalled(address indexed sender, bytes4 selector, uint256 value); +} + +#[public] +impl Contract { + #[fallback] + #[payable] + pub fn fallback(&mut self, calldata: &[u8]) -> ArbResult { + let sender = self.vm().msg_sender(); + let value = self.vm().msg_value(); + + // Extract function selector if present + let selector = if calldata.len() >= 4 { + [calldata[0], calldata[1], calldata[2], calldata[3]] + } else { + [0; 4] + }; + + self.vm().log(FallbackCalled { + sender, + selector: selector.into(), + value, + }); + + Ok(vec![]) + } +} +``` + +**Fallback is called when:** + +1. A function call doesn't match any existing function signature +2. Plain ETH transfer when no `#[receive]` function exists +3. The contract receives calldata but no function matches + +**Notes:** + +- Must have signature: `fn name(&mut self, calldata: &[u8]) -> ArbResult` +- Can optionally include `#[payable]` to accept ETH +- Only one `#[fallback]` function per contract + +### `#[selector]` + +Customizes the Solidity function selector: + +```rust +#[public] +impl Token { + // Use a custom name in the ABI + #[selector(name = "balanceOf")] + pub fn get_balance(&self, account: Address) -> U256 { + self.balances.get(account) + } + + // Explicitly set the 4-byte selector + #[selector(bytes = "0x70a08231")] + pub fn balance_of_custom(&self, account: Address) -> U256 { + self.balances.get(account) + } +} +``` + +This is useful for: + +- Matching existing Solidity interfaces exactly +- Avoiding naming conflicts +- Implementing multiple methods with the same name but different selectors + +## Contract Composition and Inheritance + +Stylus supports two patterns for code reuse: trait-based composition (new, preferred) and struct inheritance (legacy). + +### Trait-Based Composition (Preferred) + +Define reusable functionality as traits and implement them on your contract: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +// Define interface traits +#[public] +trait IOwnable { + fn owner(&self) -> Address; + fn transfer_ownership(&mut self, new_owner: Address) -> bool; +} + +#[public] +trait IErc20 { + fn name(&self) -> String; + fn symbol(&self) -> String; + fn balance_of(&self, account: Address) -> U256; + fn transfer(&mut self, to: Address, value: U256) -> bool; +} + +// Define storage components +#[storage] +struct Ownable { + owner: StorageAddress, +} + +#[storage] +struct Erc20 { + balances: StorageMap, +} + +// Compose into main contract +#[storage] +#[entrypoint] +struct MyToken { + ownable: Ownable, + erc20: Erc20, +} + +// Declare which interfaces this contract implements +#[public] +#[implements(IOwnable, IErc20)] +impl MyToken {} + +// Implement each trait +#[public] +impl IOwnable for MyToken { + fn owner(&self) -> Address { + self.ownable.owner.get() + } + + fn transfer_ownership(&mut self, new_owner: Address) -> bool { + let caller = self.vm().msg_sender(); + if caller != self.ownable.owner.get() { + return false; + } + self.ownable.owner.set(new_owner); + true + } +} + +#[public] +impl IErc20 for MyToken { + fn name(&self) -> String { + "MyToken".into() + } + + fn symbol(&self) -> String { + "MTK".into() + } + + fn balance_of(&self, account: Address) -> U256 { + self.erc20.balances.get(account) + } + + fn transfer(&mut self, to: Address, value: U256) -> bool { + let from = self.vm().msg_sender(); + let from_balance = self.erc20.balances.get(from); + if from_balance < value { + return false; + } + self.erc20.balances.setter(from).set(from_balance - value); + let to_balance = self.erc20.balances.get(to); + self.erc20.balances.setter(to).set(to_balance + value); + true + } +} +``` + +**Benefits:** + +- Clear separation of concerns +- Explicit interface declarations +- Type-safe composition +- Easy to test components independently +- Compatible with Solidity interface standards + +### Accessing VM Context + +All public methods can access blockchain context via `self.vm()`: + +```rust +#[public] +impl MyContract { + pub fn get_caller_info(&self) -> (Address, U256, U256) { + let vm = self.vm(); + ( + vm.msg_sender(), // Caller's address + vm.msg_value(), // ETH sent with call + vm.block_number(), // Current block number + ) + } +} +``` + +See the [Global Variables and Functions](./global-variables-and-functions.mdx) documentation for a complete list of available VM methods. + +## Events + +Events allow contracts to log data to the blockchain, enabling off-chain monitoring and indexing. + +### Defining Events + +Use the `sol!` macro to define events with Solidity-compatible signatures: + +```rust +use alloy_sol_types::sol; +use alloy_primitives::{Address, U256}; + +sol! { + // Up to 3 parameters can be indexed + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + event DataUpdated(string indexed key, bytes data); +} +``` + +**Indexed parameters:** + +- Allow filtering events by that parameter +- Limited to 3 indexed parameters per event +- Indexed parameters are stored in log topics, not data + +### Emitting Events + +Use `self.vm().log()` to emit events: + +```rust +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, value: U256) -> bool { + let from = self.vm().msg_sender(); + + // Transfer logic... + let from_balance = self.balances.get(from); + if from_balance < value { + return false; + } + self.balances.setter(from).set(from_balance - value); + self.balances.setter(to).set(self.balances.get(to) + value); + + // Emit event + self.vm().log(Transfer { from, to, value }); + + true + } +} +``` + +### Raw Log Emission + +For advanced use cases, emit raw logs directly: + +```rust +use alloy_primitives::FixedBytes; + +#[public] +impl Contract { + pub fn emit_raw_log(&self) { + let user = Address::from([0x22; 20]); + let balance = U256::from(1000); + + // Topics (up to 4, must be FixedBytes<32>) + let topics = &[user.into_word()]; + + // Data (arbitrary bytes) + let mut data: Vec = vec![]; + data.extend_from_slice(&balance.to_be_bytes::<32>()); + + self.vm().raw_log(topics, &data).unwrap(); + } +} +``` + +## External Contract Calls + +Stylus contracts can call other contracts (Solidity or Stylus) using typed interfaces or raw calls. + +### Defining Contract Interfaces + +Use `sol_interface!` to define interfaces for external contracts: + +```rust +use stylus_sdk::prelude::*; + +sol_interface! { + interface IToken { + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + } + + interface IOracle { + function getPrice() external view returns (uint256); + } +} +``` + +### Calling External Contracts + +#### View Calls (Read-Only) + +```rust +use stylus_sdk::call::Call; + +#[public] +impl MyContract { + pub fn get_token_balance(&self, token: IToken, account: Address) -> U256 { + // Call::new() for view calls (no state mutation) + let config = Call::new(); + token.balance_of(self.vm(), config, account).unwrap() + } +} +``` + +#### Mutating Calls + +```rust +#[public] +impl MyContract { + pub fn transfer_tokens(&mut self, token: IToken, to: Address, amount: U256) -> bool { + // Call::new_mutating(self) for state-changing calls + let config = Call::new_mutating(self); + token.transfer(self.vm(), config, to, amount).unwrap() + } +} +``` + +#### Payable Calls + +```rust +#[public] +impl MyContract { + #[payable] + pub fn forward_payment(&mut self, recipient: IPaymentProcessor) -> Result<(), Vec> { + // Forward received ETH to another contract + let value = self.vm().msg_value(); + let config = Call::new_payable(self, value); + + recipient.process_payment(self.vm(), config)?; + Ok(()) + } +} +``` + +#### Configuring Gas + +```rust +#[public] +impl MyContract { + pub fn call_with_limited_gas(&mut self, token: IToken, to: Address) -> bool { + let config = Call::new_mutating(self) + .gas(self.vm().evm_gas_left() / 2); // Use half remaining gas + + token.transfer(self.vm(), config, to, U256::from(100)).unwrap() + } +} +``` + +### Low-Level Calls + +For maximum flexibility, use raw calls: + +```rust +use stylus_sdk::call::{call, static_call, RawCall}; + +#[public] +impl MyContract { + // Low-level call (state-changing) + pub fn execute_call(&mut self, target: Address, calldata: Vec) -> Result, Vec> { + let config = Call::new_mutating(self) + .gas(self.vm().evm_gas_left()); + + call(self.vm(), config, target, &calldata) + } + + // Static call (read-only) + pub fn execute_static_call(&self, target: Address, calldata: Vec) -> Result, Vec> { + static_call(self.vm(), Call::new(), target, &calldata) + } + + // Unsafe raw call with advanced options + pub fn execute_raw_call(&mut self, target: Address, calldata: Vec) -> Result, Vec> { + unsafe { + RawCall::new_delegate(self.vm()) + .gas(2100) + .limit_return_data(0, 32) + .flush_storage_cache() + .call(target, &calldata) + } + } +} +``` + +**Call Types:** + +- `call()`: State-changing call to another contract +- `static_call()`: Read-only call (equivalent to Solidity `staticcall`) +- `RawCall`: Low-level unsafe calls with fine-grained control + +## Error Handling + +Stylus contracts can define and return custom errors using Solidity-compatible error types. + +### Defining Errors + +```rust +use alloy_sol_types::sol; + +sol! { + error Unauthorized(); + error InsufficientBalance(address from, uint256 have, uint256 want); + error InvalidAddress(address addr); +} + +#[derive(SolidityError)] +pub enum TokenError { + Unauthorized(Unauthorized), + InsufficientBalance(InsufficientBalance), + InvalidAddress(InvalidAddress), +} +``` + +### Using Errors in Methods + +```rust +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, amount: U256) -> Result { + let from = self.vm().msg_sender(); + + if to == Address::ZERO { + return Err(TokenError::InvalidAddress(InvalidAddress { addr: to })); + } + + let balance = self.balances.get(from); + if balance < amount { + return Err(TokenError::InsufficientBalance(InsufficientBalance { + from, + have: balance, + want: amount, + })); + } + + self.balances.setter(from).set(balance - amount); + self.balances.setter(to).set(self.balances.get(to) + amount); + + Ok(true) + } +} +``` + +**Error handling notes:** + +- Errors automatically encode as Solidity-compatible error data +- Use `Result` where `E` implements `SolidityError` +- Error data includes the error signature and parameters +- Compatible with Solidity `try/catch` blocks + +## Complete Example + +Here's a complete ERC-20-style token contract demonstrating all major features: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +// Define events +sol! { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +// Define errors +sol! { + error InsufficientBalance(address from, uint256 have, uint256 want); + error InsufficientAllowance(address owner, address spender, uint256 have, uint256 want); + error Unauthorized(); +} + +#[derive(SolidityError)] +pub enum TokenError { + InsufficientBalance(InsufficientBalance), + InsufficientAllowance(InsufficientAllowance), + Unauthorized(Unauthorized), +} + +// Define storage +sol_storage! { + #[entrypoint] + pub struct SimpleToken { + mapping(address => uint256) balances; + mapping(address => mapping(address => uint256)) allowances; + uint256 total_supply; + address owner; + } +} + +#[public] +impl SimpleToken { + // Constructor + #[constructor] + pub fn constructor(&mut self, initial_supply: U256) { + let deployer = self.vm().msg_sender(); + self.owner.set(deployer); + self.balances.setter(deployer).set(initial_supply); + self.total_supply.set(initial_supply); + + self.vm().log(Transfer { + from: Address::ZERO, + to: deployer, + value: initial_supply, + }); + } + + // View functions + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } + + pub fn allowance(&self, owner: Address, spender: Address) -> U256 { + self.allowances.getter(owner).get(spender) + } + + pub fn total_supply(&self) -> U256 { + self.total_supply.get() + } + + pub fn owner(&self) -> Address { + self.owner.get() + } + + // Write functions + pub fn transfer(&mut self, to: Address, value: U256) -> Result { + let from = self.vm().msg_sender(); + self._transfer(from, to, value)?; + Ok(true) + } + + pub fn approve(&mut self, spender: Address, value: U256) -> bool { + let owner = self.vm().msg_sender(); + self.allowances.setter(owner).setter(spender).set(value); + + self.vm().log(Approval { owner, spender, value }); + true + } + + pub fn transfer_from( + &mut self, + from: Address, + to: Address, + value: U256 + ) -> Result { + let spender = self.vm().msg_sender(); + + // Check allowance + let current_allowance = self.allowances.getter(from).get(spender); + if current_allowance < value { + return Err(TokenError::InsufficientAllowance(InsufficientAllowance { + owner: from, + spender, + have: current_allowance, + want: value, + })); + } + + // Update allowance + self.allowances.setter(from).setter(spender).set(current_allowance - value); + + // Transfer + self._transfer(from, to, value)?; + Ok(true) + } + + // Owner-only functions + pub fn mint(&mut self, to: Address, value: U256) -> Result<(), TokenError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(TokenError::Unauthorized(Unauthorized {})); + } + + self.balances.setter(to).set(self.balances.get(to) + value); + self.total_supply.set(self.total_supply.get() + value); + + self.vm().log(Transfer { + from: Address::ZERO, + to, + value, + }); + + Ok(()) + } + + // Internal helper function + fn _transfer(&mut self, from: Address, to: Address, value: U256) -> Result<(), TokenError> { + let from_balance = self.balances.get(from); + if from_balance < value { + return Err(TokenError::InsufficientBalance(InsufficientBalance { + from, + have: from_balance, + want: value, + })); + } + + self.balances.setter(from).set(from_balance - value); + self.balances.setter(to).set(self.balances.get(to) + value); + + self.vm().log(Transfer { from, to, value }); + Ok(()) + } +} +``` + +## Best Practices + +### 1. Use Appropriate State Mutability + +```rust +// Good: Read-only functions use &self +pub fn get_balance(&self, account: Address) -> U256 { + self.balances.get(account) +} + +// Good: State-changing functions use &mut self +pub fn set_balance(&mut self, account: Address, balance: U256) { + self.balances.setter(account).set(balance); +} +``` + +### 2. Validate Inputs Early + +```rust +pub fn transfer(&mut self, to: Address, amount: U256) -> Result { + // Validate inputs first + if to == Address::ZERO { + return Err(TokenError::InvalidAddress(InvalidAddress { addr: to })); + } + + if amount == U256::ZERO { + return Ok(true); // Nothing to transfer + } + + // Then proceed with logic + let from = self.vm().msg_sender(); + // ... +} +``` + +### 3. Use Custom Errors + +```rust +// Good: Descriptive custom errors +pub fn withdraw(&mut self, amount: U256) -> Result<(), VaultError> { + let balance = self.balances.get(self.vm().msg_sender()); + if balance < amount { + return Err(VaultError::InsufficientBalance(InsufficientBalance { + have: balance, + want: amount, + })); + } + // ... +} + +// Avoid: Generic Vec errors +pub fn withdraw(&mut self, amount: U256) -> Result<(), Vec> { + // Less informative +} +``` + +### 4. Emit Events for State Changes + +```rust +pub fn update_value(&mut self, new_value: U256) { + let old_value = self.value.get(); + self.value.set(new_value); + + // Always emit events for important state changes + self.vm().log(ValueUpdated { + old_value, + new_value, + }); +} +``` + +### 5. Access Control Patterns + +```rust +// Good: Clear access control checks +pub fn admin_function(&mut self) -> Result<(), TokenError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(TokenError::Unauthorized(Unauthorized {})); + } + // Admin logic... + Ok(()) +} + +// Consider: Reusable modifier-like helper +impl Token { + fn only_owner(&self) -> Result<(), TokenError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(TokenError::Unauthorized(Unauthorized {})); + } + Ok(()) + } + + pub fn admin_function(&mut self) -> Result<(), TokenError> { + self.only_owner()?; + // Admin logic... + Ok(()) + } +} +``` + +### 6. Gas-Efficient Storage Access + +```rust +// Good: Read once, use multiple times +pub fn complex_calculation(&self, account: Address) -> U256 { + let balance = self.balances.get(account); // Read once + let result = balance * U256::from(2) + balance / U256::from(10); + result +} + +// Avoid: Multiple reads of same storage slot +pub fn inefficient_calculation(&self, account: Address) -> U256 { + self.balances.get(account) * U256::from(2) + self.balances.get(account) / U256::from(10) +} +``` + +### 7. Check Effects Interactions Pattern + +```rust +// Good: Check-Effects-Interactions pattern +pub fn withdraw(&mut self, amount: U256) -> Result<(), VaultError> { + let caller = self.vm().msg_sender(); + + // Checks + let balance = self.balances.get(caller); + if balance < amount { + return Err(VaultError::InsufficientBalance(InsufficientBalance { + have: balance, + want: amount, + })); + } + + // Effects (update state BEFORE external calls) + self.balances.setter(caller).set(balance - amount); + + // Interactions (external calls last) + // self.transfer_eth(caller, amount)?; + + Ok(()) +} +``` + +### 8. Use Type-Safe Interfaces for External Calls + +```rust +// Good: Use sol_interface! for type safety +sol_interface! { + interface IToken { + function transfer(address to, uint256 amount) external returns (bool); + } +} + +pub fn call_token(&mut self, token: IToken, to: Address, amount: U256) -> bool { + let config = Call::new_mutating(self); + token.transfer(self.vm(), config, to, amount).unwrap() +} + +// Avoid: Raw calls unless necessary +pub fn raw_call(&mut self, token: Address, to: Address, amount: U256) -> Vec { + // Less type-safe, more error-prone + let config = Call::new_mutating(self); + let calldata = /* manually construct */; + call(self.vm(), config, token, &calldata).unwrap() +} +``` + +## See Also + +- [Primitives](./data-types/primitives.mdx) - Basic data types +- [Compound Types](./data-types/compound-types.mdx) - Arrays, structs, tuples +- [Storage Types](./data-types/storage.mdx) - Persistent storage +- [Global Variables and Functions](./global-variables-and-functions.mdx) - VM context methods From c3627884b6fba8532546701df25abe196189c2a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 14:08:31 -0800 Subject: [PATCH 024/162] touch up on slop contracts article --- docs/stylus/reference/contracts.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx index 9348a417e1..3a3bc982f1 100644 --- a/docs/stylus/reference/contracts.mdx +++ b/docs/stylus/reference/contracts.mdx @@ -8,7 +8,7 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -The Stylus SDK provides a complete framework for writing smart contracts in Rust that are fully compatible with Solidity contracts on Arbitrum chains. Contracts written with Stylus compile to WebAssembly and share the same EVM state trie as Solidity contracts, enabling seamless interoperability. +Stylus smart contracts are fully compatible with Solidity contracts on Arbitrum chains. They compile to WebAssembly and share the same EVM state trie as Solidity contracts, enabling seamless interoperability. ## Contract Basics From 83995ab61c8e9e4824ff423a1f3dc5dbca592a73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 14:12:39 -0800 Subject: [PATCH 025/162] Document Stylus Rust global variables and functions Add comprehensive documentation for global variables and functions accessible via self.vm() in Stylus contracts: - Message context: msg_sender(), msg_value(), msg_reentrant() - Transaction context: tx_origin(), tx_gas_price(), tx_ink_price() - Block context: block_number(), block_timestamp(), block_basefee(), block_coinbase(), block_gas_limit() - Chain context: chain_id() - Account information: contract_address(), balance(), code(), code_size(), code_hash() - Gas and metering: evm_gas_left(), evm_ink_left(), ink_to_gas(), gas_to_ink() - Cryptographic functions: crypto::keccak(), native_keccak256() - Event logging: log(), raw_log() - Storage operations: storage_load_bytes32(), flush_cache() - Memory management: pay_for_memory_grow() Each section includes: - Method signatures - Solidity equivalents - Practical code examples - Important notes and caveats - Arbitrum-specific behavior details Complete example contract demonstrating usage of all major VM methods, plus a summary table of all available methods. All code examples based on actual SDK implementation from stylus-sdk-rs repository. --- .../global-variables-and-functions.mdx | 896 +++++++++++++++++- 1 file changed, 886 insertions(+), 10 deletions(-) diff --git a/docs/stylus/reference/global-variables-and-functions.mdx b/docs/stylus/reference/global-variables-and-functions.mdx index dd71e050db..4b45b9e45a 100644 --- a/docs/stylus/reference/global-variables-and-functions.mdx +++ b/docs/stylus/reference/global-variables-and-functions.mdx @@ -1,18 +1,894 @@ --- title: 'Global variables and functions' -description: 'Global variables and functions' +description: 'Stylus Rust SDK global variables and functions for blockchain context access' author: chrisco sme: chrisco -sidebar_position: 1 +sidebar_position: 3 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. displayed_sidebar: buildAppsSidebar --- -5. Global variables and functions - 1. block - 2. contract - 3. crypto - 4. evm - 5. msg - 6. tx - 7. debug +Stylus contracts access blockchain context and utilities through the VM (Virtual Machine) interface via `self.vm()`. This provides access to message context, block information, transaction details, account data, cryptographic functions, and gas metering. + +## Accessing the VM + +All public contract methods have access to the VM context through `self.vm()`: + +```rust +use stylus_sdk::prelude::*; +use alloy_primitives::{Address, U256}; + +#[public] +impl MyContract { + pub fn get_context_info(&self) -> (Address, U256, u64) { + let vm = self.vm(); + ( + vm.msg_sender(), // Caller's address + vm.msg_value(), // ETH sent with call + vm.block_number(), // Current block number + ) + } +} +``` + +The VM provides methods organized into several categories: + +## Message Context (`msg`) + +Methods for accessing information about the current call. + +### `msg_sender()` + +Gets the address of the account that called the program. + +```rust +pub fn msg_sender(&self) -> Address +``` + +**Equivalent to**: Solidity's `msg.sender` + +**Example:** + +```rust +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, amount: U256) -> bool { + let from = self.vm().msg_sender(); + // Transfer from the caller to recipient + self._transfer(from, to, amount) + } +} +``` + +**Important Notes:** + +- For normal L2-to-L2 transactions, behaves like EVM's `CALLER` opcode +- For L1-to-L2 retryable ticket transactions, the top-level sender's address will be [aliased](https://developer.arbitrum.io/arbos/l1-to-l2-messaging#address-aliasing) +- In delegate calls, returns the original caller (not the delegating contract) + +### `msg_value()` + +Gets the ETH value in wei sent to the program. + +```rust +pub fn msg_value(&self) -> U256 +``` + +**Equivalent to**: Solidity's `msg.value` + +**Example:** + +```rust +#[public] +impl PaymentContract { + #[payable] + pub fn deposit(&mut self) -> U256 { + let amount = self.vm().msg_value(); + let sender = self.vm().msg_sender(); + + let balance = self.balances.get(sender); + self.balances.setter(sender).set(balance + amount); + + amount + } +} +``` + +**Note:** Only functions marked with `#[payable]` can receive ETH. Non-payable functions will revert if `msg_value() > 0`. + +### `msg_reentrant()` + +Checks whether the current call is reentrant. + +```rust +pub fn msg_reentrant(&self) -> bool +``` + +**Example:** + +```rust +#[public] +impl Vault { + pub fn withdraw(&mut self, amount: U256) { + if self.vm().msg_reentrant() { + // Handle reentrancy + panic!("Reentrant call detected"); + } + // Withdrawal logic... + } +} +``` + +**Note:** By default, Stylus contracts prevent reentrancy unless the `reentrant` feature is enabled. + +## Transaction Context (`tx`) + +Methods for accessing information about the current transaction. + +### `tx_origin()` + +Gets the top-level sender of the transaction. + +```rust +pub fn tx_origin(&self) -> Address +``` + +**Equivalent to**: Solidity's `tx.origin` + +**Example:** + +```rust +#[public] +impl Factory { + #[constructor] + pub fn constructor(&mut self) { + // Use tx_origin when deploying via a factory + let deployer = self.vm().tx_origin(); + self.owner.set(deployer); + } +} +``` + +**Important:** Returns the original EOA (Externally Owned Account) that initiated the transaction, even through multiple contract calls. + +### `tx_gas_price()` + +Gets the gas price in wei per gas, which on Arbitrum chains equals the basefee. + +```rust +pub fn tx_gas_price(&self) -> U256 +``` + +**Equivalent to**: Solidity's `tx.gasprice` + +**Example:** + +```rust +#[public] +impl Analytics { + pub fn record_gas_price(&mut self) { + let price = self.vm().tx_gas_price(); + self.gas_prices.push(price); + } +} +``` + +### `tx_ink_price()` + +Gets the price of ink in EVM gas basis points. + +```rust +pub fn tx_ink_price(&self) -> u32 +``` + +**Description:** Stylus uses "ink" as its unit of computation. This method returns the conversion rate from ink to gas. See [Ink and Gas](https://docs.arbitrum.io/stylus/concepts/gas-metering) for more information. + +**Example:** + +```rust +#[public] +impl Contract { + pub fn get_ink_price(&self) -> u32 { + self.vm().tx_ink_price() + } +} +``` + +## Block Context (`block`) + +Methods for accessing information about the current block. + +### `block_number()` + +Gets a bounded estimate of the L1 block number at which the Sequencer sequenced the transaction. + +```rust +pub fn block_number(&self) -> u64 +``` + +**Equivalent to**: Solidity's `block.number` + +**Example:** + +```rust +#[public] +impl TimeLock { + pub fn lock_until(&mut self, blocks: u64) { + let unlock_block = self.vm().block_number() + blocks; + self.unlock_block.set(U256::from(unlock_block)); + } + + pub fn can_unlock(&self) -> bool { + let current = self.vm().block_number(); + let unlock = self.unlock_block.get().try_into().unwrap_or(u64::MAX); + current >= unlock + } +} +``` + +**Note:** See [Block Numbers and Time](https://developer.arbitrum.io/time) for more information on how this value is determined on Arbitrum. + +### `block_timestamp()` + +Gets a bounded estimate of the Unix timestamp at which the Sequencer sequenced the transaction. + +```rust +pub fn block_timestamp(&self) -> u64 +``` + +**Equivalent to**: Solidity's `block.timestamp` + +**Example:** + +```rust +#[public] +impl Auction { + pub fn place_bid(&mut self, amount: U256) { + let now = self.vm().block_timestamp(); + let deadline = self.deadline.get().try_into().unwrap_or(0); + + if now > deadline { + panic!("Auction ended"); + } + + // Process bid... + } +} +``` + +**Note:** See [Block Numbers and Time](https://developer.arbitrum.io/time) for more information on how this value is determined on Arbitrum. + +### `block_basefee()` + +Gets the basefee of the current block. + +```rust +pub fn block_basefee(&self) -> U256 +``` + +**Equivalent to**: Solidity's `block.basefee` + +**Example:** + +```rust +#[public] +impl FeeTracker { + pub fn current_basefee(&self) -> U256 { + self.vm().block_basefee() + } +} +``` + +### `block_coinbase()` + +Gets the coinbase of the current block. + +```rust +pub fn block_coinbase(&self) -> Address +``` + +**Equivalent to**: Solidity's `block.coinbase` + +**Important:** On Arbitrum chains, this is the L1 batch poster's address, which differs from Ethereum where the validator determines the coinbase. + +**Example:** + +```rust +#[public] +impl Contract { + pub fn get_batch_poster(&self) -> Address { + self.vm().block_coinbase() + } +} +``` + +### `block_gas_limit()` + +Gets the gas limit of the current block. + +```rust +pub fn block_gas_limit(&self) -> u64 +``` + +**Equivalent to**: Solidity's `block.gaslimit` + +**Example:** + +```rust +#[public] +impl Contract { + pub fn check_gas_limit(&self) -> bool { + let limit = self.vm().block_gas_limit(); + limit > 30_000_000 + } +} +``` + +## Chain Context + +Methods for accessing chain-specific information. + +### `chain_id()` + +Gets the unique chain identifier of the Arbitrum chain. + +```rust +pub fn chain_id(&self) -> u64 +``` + +**Equivalent to**: Solidity's `block.chainid` + +**Example:** + +```rust +#[public] +impl MultiChain { + pub fn verify_chain(&self, expected_chain: u64) -> bool { + self.vm().chain_id() == expected_chain + } +} +``` + +**Common Arbitrum Chain IDs:** + +- Arbitrum One: 42161 +- Arbitrum Nova: 42170 +- Arbitrum Sepolia (testnet): 421614 + +## Account Information + +Methods for querying account details. + +### `contract_address()` + +Gets the address of the current program. + +```rust +pub fn contract_address(&self) -> Address +``` + +**Equivalent to**: Solidity's `address(this)` + +**Example:** + +```rust +#[public] +impl Contract { + pub fn this_address(&self) -> Address { + self.vm().contract_address() + } + + pub fn this_balance(&self) -> U256 { + let addr = self.vm().contract_address(); + self.vm().balance(addr) + } +} +``` + +### `balance(address)` + +Gets the ETH balance in wei of the account at the given address. + +```rust +pub fn balance(&self, account: Address) -> U256 +``` + +**Equivalent to**: Solidity's `address.balance` + +**Example:** + +```rust +#[public] +impl BalanceChecker { + pub fn get_balance(&self, account: Address) -> U256 { + self.vm().balance(account) + } + + pub fn has_sufficient_balance(&self, account: Address, required: U256) -> bool { + self.vm().balance(account) >= required + } +} +``` + +### `code(address)` + +Gets the code from the account at the given address. + +```rust +pub fn code(&self, account: Address) -> Vec +``` + +**Equivalent to**: Solidity's `address.code` (similar to `EXTCODECOPY` opcode) + +**Example:** + +```rust +#[public] +impl Contract { + pub fn is_contract(&self, account: Address) -> bool { + self.vm().code(account).len() > 0 + } +} +``` + +### `code_size(address)` + +Gets the size of the code in bytes at the given address. + +```rust +pub fn code_size(&self, account: Address) -> usize +``` + +**Equivalent to**: Solidity's `EXTCODESIZE` opcode + +**Example:** + +```rust +#[public] +impl Contract { + pub fn get_code_size(&self, account: Address) -> usize { + self.vm().code_size(account) + } +} +``` + +### `code_hash(address)` + +Gets the code hash of the account at the given address. + +```rust +pub fn code_hash(&self, account: Address) -> B256 +``` + +**Equivalent to**: Solidity's `EXTCODEHASH` opcode + +**Example:** + +```rust +#[public] +impl Contract { + pub fn verify_code(&self, account: Address, expected_hash: B256) -> bool { + self.vm().code_hash(account) == expected_hash + } +} +``` + +**Note:** The code hash of an account without code will be the empty hash: `keccak("") = c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`. + +## Gas and Metering + +Methods for accessing gas and ink metering information. + +### `evm_gas_left()` + +Gets the amount of gas left after paying for the cost of this hostio. + +```rust +pub fn evm_gas_left(&self) -> u64 +``` + +**Equivalent to**: Solidity's `gasleft()` + +**Example:** + +```rust +use stylus_sdk::call::Call; + +#[public] +impl Contract { + pub fn complex_operation(&mut self, target: ITarget) { + let gas_before = self.vm().evm_gas_left(); + + // Use half the remaining gas for external call + let config = Call::new_mutating(self) + .gas(gas_before / 2); + + target.do_work(self.vm(), config); + } +} +``` + +### `evm_ink_left()` + +Gets the amount of ink remaining after paying for the cost of this hostio. + +```rust +pub fn evm_ink_left(&self) -> u64 +``` + +**Description:** Returns remaining computation units in "ink". See [Ink and Gas](https://docs.arbitrum.io/stylus/concepts/gas-metering) for more information on Stylus's compute pricing. + +**Example:** + +```rust +#[public] +impl Contract { + pub fn check_ink(&self) -> u64 { + self.vm().evm_ink_left() + } +} +``` + +### `ink_to_gas(ink)` + +Computes the units of gas per a specified amount of ink. + +```rust +pub fn ink_to_gas(&self, ink: u64) -> u64 +``` + +**Example:** + +```rust +#[public] +impl Contract { + pub fn convert_ink_to_gas(&self, ink: u64) -> u64 { + self.vm().ink_to_gas(ink) + } +} +``` + +### `gas_to_ink(gas)` + +Computes the units of ink per a specified amount of gas. + +```rust +pub fn gas_to_ink(&self, gas: u64) -> u64 +``` + +**Example:** + +```rust +#[public] +impl Contract { + pub fn convert_gas_to_ink(&self, gas: u64) -> u64 { + self.vm().gas_to_ink(gas) + } +} +``` + +## Cryptographic Functions + +The SDK provides cryptographic utilities through the `crypto` module and VM methods. + +### `keccak()` + +Efficiently computes the keccak256 hash of the given preimage. + +```rust +use stylus_sdk::crypto; + +pub fn keccak>(bytes: T) -> B256 +``` + +**Equivalent to**: Solidity's `keccak256()` + +**Example:** + +```rust +use stylus_sdk::crypto; +use alloy_primitives::{Address, FixedBytes, U256}; + +#[public] +impl Contract { + pub fn hash_data(&self, data: Vec) -> FixedBytes<32> { + crypto::keccak(data) + } + + pub fn verify_hash(&self, data: Vec, expected: FixedBytes<32>) -> bool { + crypto::keccak(data) == expected + } + + // Hash multiple values together + pub fn hash_packed(&self, addr: Address, amount: U256) -> FixedBytes<32> { + let packed = [ + addr.as_ref(), + &amount.to_be_bytes_vec(), + ].concat(); + crypto::keccak(packed) + } +} +``` + +### `native_keccak256()` + +VM method for computing keccak256 hash (alternative to `crypto::keccak`). + +```rust +pub fn native_keccak256(&self, input: &[u8]) -> B256 +``` + +**Example:** + +```rust +#[public] +impl Contract { + pub fn hash_via_vm(&self, data: Vec) -> B256 { + self.vm().native_keccak256(&data) + } +} +``` + +**Note:** `crypto::keccak()` is the recommended approach as it's more ergonomic. + +## Event Logging + +Methods for emitting events to the blockchain. + +### `log(event)` + +Emits a typed Solidity event. + +```rust +pub fn log(&self, event: T) +``` + +**Example:** + +```rust +use alloy_sol_types::sol; + +sol! { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, value: U256) -> bool { + let from = self.vm().msg_sender(); + + // Transfer logic... + self._transfer(from, to, value); + + // Emit event + self.vm().log(Transfer { from, to, value }); + + true + } +} +``` + +### `raw_log(topics, data)` + +Emits a raw log with custom topics and data. + +```rust +pub fn raw_log(&self, topics: &[B256], data: &[u8]) -> Result<(), &'static str> +``` + +**Example:** + +```rust +use alloy_primitives::{B256, FixedBytes}; + +#[public] +impl Contract { + pub fn emit_custom_log(&self) { + let topic = B256::from([1u8; 32]); + let topics = &[topic]; + let data = b"custom data"; + + self.vm().raw_log(topics, data).unwrap(); + } +} +``` + +**Note:** Maximum of 4 topics allowed. The first topic is typically the event signature hash. + +## Storage Operations + +Methods for interacting with contract storage. + +### `storage_load_bytes32(key)` + +Reads a 32-byte value from permanent storage. + +```rust +pub fn storage_load_bytes32(&self, key: U256) -> B256 +``` + +**Equivalent to**: Solidity's `SLOAD` opcode + +**Note:** Storage is cached for efficiency. Use the SDK's storage types instead of direct storage access. + +### `flush_cache(clear)` + +Persists dirty values in the storage cache to the EVM state trie. + +```rust +pub fn flush_cache(&self, clear: bool) +``` + +**Parameters:** + +- `clear`: If `true`, drops the cache entirely after flushing + +**Note:** Typically handled automatically by the SDK. Manual cache flushing is rarely needed. + +## Memory Management + +### `pay_for_memory_grow(pages)` + +Pays for memory growth in WASM pages. + +```rust +pub fn pay_for_memory_grow(&self, pages: u16) +``` + +**Note:** The `#[entrypoint]` macro handles this automatically. Manual calls are not recommended and will unproductively consume gas. + +## Complete Example + +Here's a comprehensive example using various global variables and functions: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloy_primitives::{Address, U256, FixedBytes}; +use alloy_sol_types::sol; +use stylus_sdk::{crypto, prelude::*}; + +sol! { + event Action( + address indexed caller, + uint256 value, + uint256 timestamp, + bytes32 data_hash + ); +} + +sol_storage! { + #[entrypoint] + pub struct ContextExample { + mapping(address => uint256) balances; + uint256 total_deposits; + uint256 creation_block; + address owner; + } +} + +#[public] +impl ContextExample { + #[constructor] + pub fn constructor(&mut self) { + // Use tx_origin for factory deployments + self.owner.set(self.vm().tx_origin()); + self.creation_block.set(U256::from(self.vm().block_number())); + } + + #[payable] + pub fn deposit(&mut self, data: Vec) { + // Message context + let caller = self.vm().msg_sender(); + let amount = self.vm().msg_value(); + + // Block context + let timestamp = self.vm().block_timestamp(); + let block_num = self.vm().block_number(); + + // Require minimum value + if amount < U256::from(1000) { + panic!("Insufficient deposit"); + } + + // Update balances + let balance = self.balances.get(caller); + self.balances.setter(caller).set(balance + amount); + self.total_deposits.set(self.total_deposits.get() + amount); + + // Hash the data + let data_hash = crypto::keccak(&data); + + // Emit event + self.vm().log(Action { + caller, + value: amount, + timestamp: U256::from(timestamp), + data_hash, + }); + } + + pub fn get_contract_info(&self) -> (Address, U256, u64, u64) { + ( + self.vm().contract_address(), // Contract's address + self.vm().balance(self.vm().contract_address()), // Contract's balance + self.vm().chain_id(), // Chain ID + self.vm().block_number(), // Current block + ) + } + + pub fn verify_signature(&self, message: Vec, expected_hash: FixedBytes<32>) -> bool { + let hash = crypto::keccak(message); + hash == expected_hash + } + + pub fn is_owner(&self, account: Address) -> bool { + account == self.owner.get() + } + + pub fn time_since_creation(&self) -> u64 { + let current_block = self.vm().block_number(); + let creation_block: u64 = self.creation_block.get().try_into().unwrap_or(0); + current_block.saturating_sub(creation_block) + } +} +``` + +## Summary of Available Methods + +### Message Context + +- `msg_sender()` โ†’ `Address` - Caller's address +- `msg_value()` โ†’ `U256` - ETH sent with call +- `msg_reentrant()` โ†’ `bool` - Is reentrant call + +### Transaction Context + +- `tx_origin()` โ†’ `Address` - Original transaction sender +- `tx_gas_price()` โ†’ `U256` - Gas price +- `tx_ink_price()` โ†’ `u32` - Ink price + +### Block Context + +- `block_number()` โ†’ `u64` - Block number +- `block_timestamp()` โ†’ `u64` - Block timestamp +- `block_basefee()` โ†’ `U256` - Base fee +- `block_coinbase()` โ†’ `Address` - Batch poster +- `block_gas_limit()` โ†’ `u64` - Gas limit + +### Chain Context + +- `chain_id()` โ†’ `u64` - Chain identifier + +### Account Information + +- `contract_address()` โ†’ `Address` - This contract's address +- `balance(Address)` โ†’ `U256` - Account balance +- `code(Address)` โ†’ `Vec` - Account code +- `code_size(Address)` โ†’ `usize` - Code size +- `code_hash(Address)` โ†’ `B256` - Code hash + +### Gas and Metering + +- `evm_gas_left()` โ†’ `u64` - Remaining gas +- `evm_ink_left()` โ†’ `u64` - Remaining ink +- `ink_to_gas(u64)` โ†’ `u64` - Convert ink to gas +- `gas_to_ink(u64)` โ†’ `u64` - Convert gas to ink + +### Cryptographic Functions + +- `crypto::keccak(bytes)` โ†’ `B256` - Keccak256 hash +- `native_keccak256(&[u8])` โ†’ `B256` - Keccak256 via VM + +### Event Logging + +- `log(event)` - Emit typed event +- `raw_log(&[B256], &[u8])` - Emit raw log + +## See Also + +- [Contracts](./contracts.mdx) - Contract structure and methods +- [Primitives](./data-types/primitives.mdx) - Basic data types +- [Storage Types](./data-types/storage.mdx) - Persistent storage From 36ae71af98ab15f3f020a22ab18364da40e46380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 14:48:06 -0800 Subject: [PATCH 026/162] Document Stylus Rust minimal entrypoint contracts Add comprehensive documentation for minimal entrypoint contracts covering: - ArbResult type and its usage in contract methods - user_entrypoint function structure and generated code - Router trait implementation and routing logic - TopLevelStorage trait and safety requirements - Step-by-step guide to building contracts without macros - Function selector computation and implementation - Complete working minimal contract example - Comparison with high-level macro approach - Advanced use cases and debugging tips Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../advanced/minimal-entrypoint-contracts.mdx | 639 +++++++++++++++++- 1 file changed, 636 insertions(+), 3 deletions(-) diff --git a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx index 211fa3acc5..e291439ec7 100644 --- a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx +++ b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx @@ -1,11 +1,644 @@ --- title: 'Minimal entrypoint contracts' -description: 'Minimal entrypoint contracts' +description: 'Understanding low-level Stylus contract entrypoints and the Router trait' author: chrisco sme: chrisco sidebar_position: 1 -target_audience: Developers who need to understand how to build a minimal entrypoint contract. +target_audience: Developers who need to understand how to build a minimal entrypoint contract without high-level macros. displayed_sidebar: buildAppsSidebar --- -TBD +This guide explains the low-level mechanics of Stylus contract entrypoints, helping you understand what happens behind the `#[entrypoint]` and `#[public]` macros. This knowledge is useful for advanced use cases, debugging, and building custom contract frameworks. + +## Overview + +A Stylus contract at its core consists of: + +1. **`user_entrypoint` function**: The WASM export that Stylus calls +2. **Router implementation**: Routes function selectors to method implementations +3. **TopLevelStorage trait**: Marks the contract's root storage type +4. **ArbResult type**: Represents success/failure with encoded return data + +## Understanding `ArbResult` + +`ArbResult` is the fundamental return type for Stylus contract methods: + +```rust +pub type ArbResult = Result, Vec>; +``` + +- `Ok(Vec)` - Success with ABI-encoded return data +- `Err(Vec)` - Revert with ABI-encoded error data + +**Example:** + +```rust +use stylus_sdk::ArbResult; + +// Success with no return data +fn no_return() -> ArbResult { + Ok(Vec::new()) +} + +// Success with encoded data +fn return_value() -> ArbResult { + let value: u32 = 42; + Ok(value.to_le_bytes().to_vec()) +} + +// Revert with error data +fn revert_with_error() -> ArbResult { + Err(b"InsufficientBalance".to_vec()) +} +``` + +## The `user_entrypoint` Function + +The `user_entrypoint` function is the WASM export that Stylus calls when a transaction invokes the contract. The `#[entrypoint]` macro generates this function automatically. + +### Generated Structure + +When you use `#[entrypoint]`, the macro generates: + +```rust +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + let host = stylus_sdk::host::VM { + host: stylus_sdk::host::WasmVM{} + }; + + // Reentrancy check (unless reentrant feature enabled) + if host.msg_reentrant() { + return 1; // revert + } + + // Ensure pay_for_memory_grow is referenced + // (costs 8700 ink, less than 1 gas) + host.pay_for_memory_grow(0); + + // Read calldata + let input = host.read_args(len); + + // Call the router + let (data, status) = match router_entrypoint::(input, host.clone()) { + Ok(data) => (data, 0), // Success + Err(data) => (data, 1), // Revert + }; + + // Persist storage changes + host.flush_cache(false); + + // Write return data + host.write_result(&data); + + status +} +``` + +### Key Points + +- **Signature**: `extern "C" fn user_entrypoint(len: usize) -> usize` +- **Input**: `len` is the length of calldata to read +- **Output**: `0` for success, `1` for revert +- **Side effects**: Reads calldata, writes return data, flushes storage cache + +## The `Router` Trait + +The `Router` trait defines how function calls are dispatched to method implementations. + +### Trait Definition + +```rust +pub trait Router +where + S: TopLevelStorage + BorrowMut + ValueDenier, + I: ?Sized, +{ + type Storage; + + /// Route a function call by selector + fn route(storage: &mut S, selector: u32, input: &[u8]) -> Option; + + /// Handle receive (plain ETH transfers, no calldata) + fn receive(storage: &mut S) -> Option>>; + + /// Handle fallback (unknown selectors or no receive) + fn fallback(storage: &mut S, calldata: &[u8]) -> Option; + + /// Handle constructor + fn constructor(storage: &mut S, calldata: &[u8]) -> Option; +} +``` + +### Routing Logic + +The `router_entrypoint` function implements the routing logic: + +```rust +pub fn router_entrypoint(input: Vec, host: VM) -> ArbResult +where + R: Router, + S: StorageType + TopLevelStorage + BorrowMut + ValueDenier, +{ + let mut storage = unsafe { S::new(U256::ZERO, 0, host) }; + + // No calldata - try receive, then fallback + if input.is_empty() { + if let Some(res) = R::receive(&mut storage) { + return res.map(|_| Vec::new()); + } + if let Some(res) = R::fallback(&mut storage, &[]) { + return res; + } + return Err(Vec::new()); // No receive or fallback + } + + // Extract selector (first 4 bytes) + if input.len() >= 4 { + let selector = u32::from_be_bytes(input[..4].try_into().unwrap()); + + // Check for constructor + if selector == CONSTRUCTOR_SELECTOR { + if let Some(res) = R::constructor(&mut storage, &input[4..]) { + return res; + } + } + // Try to route to a method + else if let Some(res) = R::route(&mut storage, selector, &input[4..]) { + return res; + } + } + + // Try fallback + if let Some(res) = R::fallback(&mut storage, &input) { + return res; + } + + Err(Vec::new()) // Unknown selector and no fallback +} +``` + +## The `TopLevelStorage` Trait + +The `TopLevelStorage` trait marks types that represent the contract's root storage. + +### Trait Definition + +```rust +pub unsafe trait TopLevelStorage {} +``` + +### Purpose + +- Prevents storage aliasing during reentrancy +- Lifetime tracks all EVM state changes during contract invocation +- Must hold a reference when making external calls +- Automatically implemented by `#[entrypoint]` + +### Safety + +The trait is `unsafe` because: + +- Type must truly be top-level to prevent storage aliasing +- Incorrectly implementing this trait can lead to undefined behavior + +## Building a Minimal Contract + +Here's a minimal contract without using the high-level macros: + +### Step 1: Define Storage + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::vec::Vec; +use stylus_sdk::{ + abi::{Router, ArbResult}, + storage::StorageType, + host::VM, + alloy_primitives::U256, +}; + +// Mark as top-level storage (normally done by #[entrypoint]) +pub struct MyContract; + +unsafe impl stylus_core::storage::TopLevelStorage for MyContract {} + +impl StorageType for MyContract { + type Wraps<'a> = &'a Self where Self: 'a; + type WrapsMut<'a> = &'a mut Self where Self: 'a; + + unsafe fn new(_slot: U256, _offset: u8, _host: VM) -> Self { + MyContract + } + + fn load<'s>(self) -> Self::Wraps<'s> { + &self + } + + fn load_mut<'s>(self) -> Self::WrapsMut<'s> { + &mut self + } +} +``` + +### Step 2: Implement Router + +```rust +impl Router for MyContract { + type Storage = MyContract; + + fn route(_storage: &mut MyContract, selector: u32, _input: &[u8]) -> Option { + // Simple example: one method with selector 0x12345678 + match selector { + 0x12345678 => Some(Ok(Vec::new())), + _ => None, // Unknown selector + } + } + + fn receive(_storage: &mut MyContract) -> Option>> { + None // No receive function + } + + fn fallback(_storage: &mut MyContract, _calldata: &[u8]) -> Option { + None // No fallback function + } + + fn constructor(_storage: &mut MyContract, _calldata: &[u8]) -> Option { + None // No constructor + } +} +``` + +### Step 3: Define Entrypoint + +```rust +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + let host = VM { host: stylus_sdk::host::WasmVM{} }; + + // Reentrancy check + if host.msg_reentrant() { + return 1; + } + + // Reference pay_for_memory_grow + host.pay_for_memory_grow(0); + + // Read input + let input = host.read_args(len); + + // Route the call + let (data, status) = match stylus_sdk::abi::router_entrypoint::(input, host.clone()) { + Ok(data) => (data, 0), + Err(data) => (data, 1), + }; + + // Flush storage + host.flush_cache(false); + + // Write result + host.write_result(&data); + + status +} +``` + +## Function Selectors + +Function selectors are 4-byte identifiers computed from the function signature. + +### Computing Selectors + +```rust +use stylus_sdk::function_selector; + +// Manual computation +const MY_FUNCTION: [u8; 4] = function_selector!("myFunction"); + +// With parameters +const TRANSFER: [u8; 4] = function_selector!("transfer", Address, U256); + +// Constructor selector +const CONSTRUCTOR_SELECTOR: u32 = + u32::from_be_bytes(function_selector!("constructor")); +``` + +### Using in Router + +```rust +impl Router for MyContract { + type Storage = MyContract; + + fn route(_storage: &mut MyContract, selector: u32, input: &[u8]) -> Option { + const GET_VALUE: u32 = u32::from_be_bytes(function_selector!("getValue")); + const SET_VALUE: u32 = u32::from_be_bytes(function_selector!("setValue", U256)); + + match selector { + GET_VALUE => { + // Return encoded U256 value + let value = U256::from(42); + Some(Ok(value.to_be_bytes::<32>().to_vec())) + } + SET_VALUE => { + // Decode input and set value + if input.len() >= 32 { + // Process set_value logic + Some(Ok(Vec::new())) + } else { + Some(Err(Vec::new())) + } + } + _ => None, + } + } + + fn receive(_storage: &mut MyContract) -> Option>> { + None + } + + fn fallback(_storage: &mut MyContract, _calldata: &[u8]) -> Option { + None + } + + fn constructor(_storage: &mut MyContract, _calldata: &[u8]) -> Option { + None + } +} +``` + +## Implementing Special Functions + +### Receive Function + +Handles plain ETH transfers (no calldata): + +```rust +fn receive(storage: &mut MyContract) -> Option>> { + // Access msg_value via storage.vm().msg_value() + // Must return Ok(()) for success + Some(Ok(())) +} +``` + +### Fallback Function + +Handles unknown selectors or when no receive is defined: + +```rust +fn fallback(storage: &mut MyContract, calldata: &[u8]) -> Option { + // Can access full calldata + // Return Some to handle, None to revert + Some(Ok(Vec::new())) +} +``` + +### Constructor + +Called once during deployment with `CONSTRUCTOR_SELECTOR`: + +```rust +fn constructor(storage: &mut MyContract, calldata: &[u8]) -> Option { + // Initialize contract state + // calldata contains constructor parameters + Some(Ok(Vec::new())) +} +``` + +## Complete Minimal Example + +Here's a complete working minimal contract: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloc::vec::Vec; +use core::borrow::BorrowMut; +use stylus_sdk::{ + abi::Router, + alloy_primitives::U256, + host::VM, + storage::StorageType, + ArbResult, + function_selector, +}; +use stylus_core::{storage::TopLevelStorage, ValueDenier}; + +// Contract storage +pub struct MinimalContract; + +// Mark as top-level storage +unsafe impl TopLevelStorage for MinimalContract {} + +// Implement StorageType +impl StorageType for MinimalContract { + type Wraps<'a> = &'a Self where Self: 'a; + type WrapsMut<'a> = &'a mut Self where Self: 'a; + + unsafe fn new(_slot: U256, _offset: u8, _host: VM) -> Self { + MinimalContract + } + + fn load<'s>(self) -> Self::Wraps<'s> { + &self + } + + fn load_mut<'s>(self) -> Self::WrapsMut<'s> { + &mut self + } +} + +// Implement ValueDenier (for non-payable check) +impl ValueDenier for MinimalContract { + fn deny_value(&self, _method_name: &str) -> Result<(), Vec> { + Ok(()) // Allow all for simplicity + } +} + +// Implement BorrowMut +impl BorrowMut for MinimalContract { + fn borrow_mut(&mut self) -> &mut MinimalContract { + self + } +} + +// Implement Router +impl Router for MinimalContract { + type Storage = MinimalContract; + + fn route(_storage: &mut MinimalContract, selector: u32, _input: &[u8]) -> Option { + const HELLO: u32 = u32::from_be_bytes(function_selector!("hello")); + + match selector { + HELLO => Some(Ok(Vec::new())), + _ => None, + } + } + + fn receive(_storage: &mut MinimalContract) -> Option>> { + None + } + + fn fallback(_storage: &mut MinimalContract, _calldata: &[u8]) -> Option { + Some(Ok(Vec::new())) // Accept all unknown calls + } + + fn constructor(_storage: &mut MinimalContract, _calldata: &[u8]) -> Option { + Some(Ok(Vec::new())) + } +} + +// Define user_entrypoint +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + let host = VM { host: stylus_sdk::host::WasmVM{} }; + + if host.msg_reentrant() { + return 1; + } + + host.pay_for_memory_grow(0); + + let input = host.read_args(len); + let (data, status) = match stylus_sdk::abi::router_entrypoint::(input, host.clone()) { + Ok(data) => (data, 0), + Err(data) => (data, 1), + }; + + host.flush_cache(false); + host.write_result(&data); + status +} +``` + +## Why Use High-Level Macros? + +While minimal contracts are educational, the `#[entrypoint]` and `#[public]` macros provide: + +1. **Automatic selector generation** from method names +2. **Type-safe parameter encoding/decoding** using Alloy types +3. **Solidity ABI export** for interoperability +4. **Storage trait implementations** with caching +5. **Error handling** with `Result` types +6. **Payable checks** for ETH-receiving functions +7. **Reentrancy protection** by default + +**Recommended approach:** + +```rust +// Use macros for production contracts +#[storage] +#[entrypoint] +pub struct MyContract { + value: StorageU256, +} + +#[public] +impl MyContract { + pub fn get_value(&self) -> U256 { + self.value.get() + } + + pub fn set_value(&mut self, value: U256) { + self.value.set(value); + } +} +``` + +This generates all the low-level code automatically while providing a clean, type-safe interface. + +## Advanced Use Cases + +### Custom Routing Logic + +Implement custom routing for multi-contract systems: + +```rust +impl Router for MultiContract { + type Storage = MultiContract; + + fn route(storage: &mut MultiContract, selector: u32, input: &[u8]) -> Option { + // Route to different modules based on selector range + match selector { + 0x00000000..=0x0fffffff => ModuleA::route(storage, selector, input), + 0x10000000..=0x1fffffff => ModuleB::route(storage, selector, input), + _ => None, + } + } + + // ... other methods +} +``` + +### Custom Entrypoint Logic + +Add custom logic before/after routing: + +```rust +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + let host = VM { host: stylus_sdk::host::WasmVM{} }; + + // Custom pre-processing + let start_gas = host.evm_gas_left(); + + // Standard entrypoint logic + if host.msg_reentrant() { + return 1; + } + + host.pay_for_memory_grow(0); + let input = host.read_args(len); + + let (data, status) = match stylus_sdk::abi::router_entrypoint::(input, host.clone()) { + Ok(data) => (data, 0), + Err(data) => (data, 1), + }; + + // Custom post-processing + let gas_used = start_gas - host.evm_gas_left(); + // Log or handle gas usage + + host.flush_cache(false); + host.write_result(&data); + status +} +``` + +## Debugging Tips + +### Enable Debug Mode + +```rust +#[cfg(feature = "debug")] +use stylus_sdk::console; + +fn route(storage: &mut MyContract, selector: u32, input: &[u8]) -> Option { + #[cfg(feature = "debug")] + console!("Selector: {:08x}", selector); + + // Routing logic... +} +``` + +### Check Selector Computation + +```rust +#[test] +fn test_selectors() { + use stylus_sdk::function_selector; + + let hello = u32::from_be_bytes(function_selector!("hello")); + assert_eq!(hello, 0x19ff1d21); + + // Compare with Solidity: bytes4(keccak256("hello()")) +} +``` + +## See Also + +- [Contracts](../reference/contracts.mdx) - High-level contract development +- [Global Variables](../reference/global-variables-and-functions.mdx) - VM context methods +- [Storage Types](../reference/data-types/storage.mdx) - Persistent storage From 5c118b0e8a3b212e887365e3672bc610ada8349d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 18:06:21 -0800 Subject: [PATCH 027/162] Document Stylus Rust contract activation Add comprehensive documentation for Stylus contract activation covering: - Two-step deployment and activation process - WASM compilation and processing pipeline - Deployment bytecode structure and EVM initcode - Activation fee calculation and configuration - ArbWasm precompile interface and functions - cargo-stylus CLI commands and workflows - Constructor support and arguments - Contract lifecycle and expiration management - Code reuse optimization via codehash - Multi-contract deployment patterns - Programmatic deployment examples - Troubleshooting common activation errors - Best practices for production deployment Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- docs/stylus/concepts/activation.mdx | 783 +++++++++++++++++++++++++++- 1 file changed, 780 insertions(+), 3 deletions(-) diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index 14376d2def..dce723a561 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -1,11 +1,788 @@ --- title: 'Activation' -description: 'Activation' +description: 'Understanding Stylus contract deployment and activation' author: chrisco sme: chrisco sidebar_position: 1 -target_audience: . +target_audience: Developers deploying Stylus contracts to Arbitrum chains. displayed_sidebar: buildAppsSidebar --- -TBD +Stylus contracts undergo a two-step process to become executable on Arbitrum chains: **deployment** and **activation**. This guide explains both steps, the distinction between them, and how to manage the activation process. + +## Overview + +Unlike traditional EVM contracts that become immediately executable after deployment, Stylus contracts require an additional activation step: + +1. **Deployment**: Stores the compressed WASM bytecode on-chain at a contract address +2. **Activation**: Converts the bytecode into an executable Stylus program by registering it with the ArbWasm precompile + +**Why two steps?** + +- **Gas optimization**: Activation involves one-time processing and caching that would be expensive to repeat on every call +- **Code reuse**: Multiple contracts can share the same activated codehash, reducing activation costs +- **Version management**: Allows the chain to track which Stylus protocol version a contract targets + +## Deployment vs Activation + +| Aspect | Deployment | Activation | +| --------------------- | ------------------------------ | ------------------------------ | +| **Purpose** | Store compressed WASM on-chain | Register program with ArbWasm | +| **Transaction count** | 1 transaction | 1 transaction (separate) | +| **Cost type** | Standard EVM deployment gas | Data fee (WASM-specific cost) | +| **When required** | Always - stores the code | Always - makes code executable | +| **Reversible** | No | No (but can expire) | +| **Who can call** | Anyone with funds | Anyone (after deployment) | +| **Can be skipped** | No | No (unless already activated) | + +### Contract States + +A Stylus contract can be in one of these states: + +```rust +pub enum ContractStatus { + /// Contract already exists on-chain and is activated + Active { code: Vec }, + + /// Contract is deployed but not yet activated + /// Ready to activate with the given data fee + Ready { code: Vec, fee: U256 }, +} +``` + +## The Activation Process + +### Step 1: Build and Process WASM + +Before deployment, your Rust contract is compiled and processed: + +```bash +cargo stylus check +``` + +This performs: + +1. **Compile Rust to WASM**: Using `wasm32-unknown-unknown` target +2. **Process WASM binary**: + - Remove dangling references + - Add project hash metadata + - Strip unnecessary custom sections +3. **Brotli compression**: Maximum compression (level 11) +4. **Add EOF prefix**: `EFF00000` (identifies Stylus programs) +5. **Size validation**: Compressed code must be โ‰ค 24KB + +**WASM Processing Pipeline**: + +``` +Raw WASM Binary + โ†“ +Remove dangling references + โ†“ +Add project_hash metadata + โ†“ +Strip user custom sections + โ†“ +Brotli compress (level 11) + โ†“ +Add EOF prefix (EFF00000) + โ†“ +Final compressed code (โ‰ค 24KB) +``` + +### Step 2: Deploy the Contract + +Deployment creates a transaction that stores your processed WASM on-chain: + +```bash +cargo stylus deploy \ + --private-key-path=key.txt \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +**What happens during deployment:** + +1. **Generate deployment bytecode**: Create EVM initcode with embedded compressed WASM +2. **Estimate gas**: Calculate deployment transaction gas cost +3. **Send deployment transaction**: To Stylus deployer contract +4. **Extract contract address**: From transaction receipt + +**Deployment Bytecode Structure**: + +``` +EVM Initcode Prelude (43 bytes): +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ 0x7f PUSH32 โ”‚ Push code length +โ”‚ 0x80 DUP1 โ”‚ Duplicate length +โ”‚ 0x60 PUSH1 โ”‚ Push prelude length +โ”‚ 0x60 PUSH1 0x00 โ”‚ Push 0 +โ”‚ 0x39 CODECOPY โ”‚ Copy code to memory +โ”‚ 0x60 PUSH1 0x00 โ”‚ Push 0 +โ”‚ 0xf3 RETURN โ”‚ Return code +โ”‚ 0x00 โ”‚ Stylus version +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ†“ + +``` + +### Step 3: Calculate Activation Fee + +Before activating, the data fee must be calculated: + +```rust +// Simulated via state overrides (no transaction sent) +let data_fee = calculate_activation_fee(contract_address); + +// Apply bump percentage for safety (default: 20%) +let final_fee = data_fee * (1 + bump_percent / 100); +``` + +**Data fee calculation**: + +- Uses state override simulation to estimate fee +- No actual transaction sent during estimation +- Configurable bump percentage protects against variance (default: 20%) +- Fee is paid in ETH when activating + +### Step 4: Activate the Contract + +Activation registers your contract with the ArbWasm precompile: + +```bash +# Automatic activation (default) +cargo stylus deploy --private-key-path=key.txt + +# Or manual activation +cargo stylus activate \ + --address=0x1234... \ + --private-key-path=key.txt +``` + +**What happens during activation:** + +1. **Call ArbWasm precompile**: At address `0x0000000000000000000000000000000000000071` +2. **Send activation transaction**: + ```solidity + ArbWasm.activateProgram{value: dataFee}(contractAddress) + ``` +3. **ArbWasm processes the code**: + - Validates WASM format + - Checks against protocol version + - Stores activation metadata + - Emits `ProgramActivated` event +4. **Returns activation info**: + ```solidity + returns (uint16 version, uint256 actualDataFee) + ``` + +## Using cargo-stylus + +The `cargo-stylus` CLI tool simplifies the deployment and activation workflow. + +### Basic Deployment (Automatic Activation) + +By default, `cargo stylus deploy` handles both steps: + +```bash +cargo stylus deploy \ + --private-key-path=wallet.txt \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +**Output**: + +``` +Building contract... +Compressing WASM... +Deploying contract to 0x1234567890abcdef... +Deployment transaction: 0xabcd... +Contract deployed at: 0x1234567890abcdef +Activating contract... +Activation transaction: 0xef12... +Contract activated successfully! +``` + +### Deploy Without Activation + +To deploy but skip activation: + +```bash +cargo stylus deploy \ + --private-key-path=wallet.txt \ + --no-activate +``` + +This is useful when: + +- You want to inspect the contract before activating +- Someone else will handle activation +- You're testing deployment workflows + +### Manual Activation + +Activate a previously deployed contract: + +```bash +cargo stylus activate \ + --address=0x1234567890abcdef \ + --private-key-path=wallet.txt \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +### Check Contract Status + +Before deploying, check if a contract with the same code is already activated: + +```bash +cargo stylus check \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +**Possible outcomes**: + +1. **Code already activated**: You can reuse the existing deployment +2. **Ready to activate**: Shows estimated data fee +3. **Validation errors**: Displays issues that must be fixed + +## Deployment with Constructors + +If your contract has a constructor, provide arguments during deployment: + +```rust +#[public] +impl MyContract { + #[constructor] + pub fn constructor(&mut self, initial_value: U256, owner: Address) { + self.value.set(initial_value); + self.owner.set(owner); + } +} +``` + +**Deploy with constructor arguments**: + +```bash +cargo stylus deploy \ + --private-key-path=wallet.txt \ + --constructor-args 42 0x1234567890abcdef1234567890abcdef12345678 +``` + +**With payable constructor**: + +```rust +#[constructor] +#[payable] +pub fn constructor(&mut self) { + let value = self.vm().msg_value(); + self.initial_balance.set(value); +} +``` + +```bash +cargo stylus deploy \ + --private-key-path=wallet.txt \ + --constructor-value=1000000000000000000 # 1 ETH in wei +``` + +## The ArbWasm Precompile + +Activation is handled by the ArbWasm precompile at address `0x0000000000000000000000000000000000000071`. + +### Key Functions + +#### activateProgram + +Activates a deployed Stylus contract: + +```solidity +function activateProgram( + address program +) external payable returns (uint16 version, uint256 dataFee); +``` + +**Parameters**: + +- `program`: Contract address containing WASM bytecode + +**Payment**: + +- Must send `value` equal to the calculated data fee (in wei) + +**Returns**: + +- `version`: Stylus protocol version the program was activated against +- `dataFee`: Actual fee paid for activation + +**Example (via cast)**: + +```bash +cast send 0x0000000000000000000000000000000000000071 \ + "activateProgram(address)" \ + 0x1234567890abcdef \ + --value 100000000000000000 \ + --private-key=$PRIVATE_KEY +``` + +#### codehashVersion + +Check if a codehash is activated and get its version: + +```solidity +function codehashVersion(bytes32 codehash) external view returns (uint16 version); +``` + +**Reverts if**: + +- Code is not activated +- Program needs upgrade +- Program has expired + +#### programTimeLeft + +Get remaining time before a program expires: + +```solidity +function programTimeLeft(address program) external view returns (uint64 timeLeft); +``` + +Returns seconds until expiration (default: ~1 year from activation). + +#### codehashKeepalive + +Extend a program's expiration time: + +```solidity +function codehashKeepalive(bytes32 codehash) external payable returns (uint64 expirySeconds); +``` + +Resets the expiration timer, preventing program deactivation. + +### ArbWasm Errors + +Activation can fail with these errors: + +```solidity +error ProgramNotWasm(); +// The deployed bytecode is not valid WASM + +error ProgramNotActivated(); +// Contract exists but hasn't been activated + +error ProgramNeedsUpgrade(uint16 version, uint16 stylusVersion); +// Program version incompatible with current Stylus version + +error ProgramExpired(uint64 ageInSeconds); +// Program has expired and must be reactivated + +error ProgramInsufficientValue(uint256 have, uint256 want); +// Sent data fee is less than required +``` + +## Gas and Fee Optimization + +### Estimating Costs + +Get cost estimates before deploying: + +```bash +# Estimate deployment gas +cargo stylus deploy --estimate-gas + +# Check activation fee +cargo stylus check # Shows estimated data fee +``` + +### Fee Bump Configuration + +Protect against fee variance with configurable bump percentage: + +```bash +# Default: 20% bump +cargo stylus deploy --private-key-path=wallet.txt + +# Custom bump percentage +# (Note: Use programmatically via stylus-tools library) +``` + +**In code** (using stylus-tools): + +```rust +use stylus_tools::core::activation::ActivationConfig; + +let config = ActivationConfig { + data_fee_bump_percent: 25, // 25% safety margin +}; +``` + +### Code Reuse Optimization + +If your contract's codehash matches an already-activated contract: + +```bash +cargo stylus check +``` + +**Output if already activated**: + +``` +Checking contract... +โœ“ Contract with this codehash is already activated! +Version: 1 +No activation needed - you can deploy without activating. +``` + +You can deploy the contract normally, and it will automatically use the existing activation. + +### Contract Caching + +After activation, contracts can be cached for cheaper calls: + +```solidity +// ArbWasmCache precompile (0x0000000000000000000000000000000000000072) +function cacheProgram(address program) external payable returns (uint256); +``` + +**Benefits**: + +- Reduces gas costs for subsequent contract calls +- One-time caching fee +- Shared across all contracts with same codehash + +## Advanced Activation Patterns + +### Multi-Contract Deployment + +When deploying multiple instances of the same contract: + +```bash +# First deployment: full deploy + activate +cargo stylus deploy --private-key-path=wallet.txt +# Contract 1: 0xaaaa... (activated) + +# Subsequent deployments: deploy only (reuses activation) +cargo stylus deploy --private-key-path=wallet.txt --no-activate +# Contract 2: 0xbbbb... (uses existing activation) + +cargo stylus deploy --private-key-path=wallet.txt --no-activate +# Contract 3: 0xcccc... (uses existing activation) +``` + +All three contracts share the same codehash and activation, saving on data fees. + +### Programmatic Deployment + +Using the stylus-tools library directly: + +```rust +use stylus_tools::core::{ + deployment::{deploy, DeploymentConfig}, + activation::{activate_contract, ActivationConfig, data_fee}, + check::{check_contract, ContractStatus}, +}; +use alloy::providers::{Provider, WalletProvider}; + +async fn deploy_and_activate( + provider: &impl Provider + WalletProvider, +) -> Result> { + let contract = /* build contract */; + + // Step 1: Check if already activated + let config = CheckConfig::default(); + match check_contract(&contract, None, &config, provider).await? { + ContractStatus::Active { .. } => { + println!("Already activated!"); + // Deploy without activation + } + ContractStatus::Ready { code, fee } => { + println!("Ready to activate. Data fee: {}", fee); + // Continue with deployment + activation + } + } + + // Step 2: Deploy + let deploy_config = DeploymentConfig { + no_activate: false, + ..Default::default() + }; + + deploy(&contract, &deploy_config, provider).await?; + + // Contract address returned from deployment + Ok(contract_address) +} +``` + +### Custom Deployer Contracts + +Use a custom deployer contract instead of the default: + +```bash +cargo stylus deploy \ + --private-key-path=wallet.txt \ + --deployer-address=0x... \ + --deployer-salt=0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +This is useful for: + +- CREATE2 deterministic addresses +- Custom deployment logic +- Factory patterns + +## Contract Lifecycle + +### Activation Lifecycle + +``` +Deployed โ†’ Activated โ†’ [Active] โ†’ [Keepalive] โ†’ [Expired] + โ†‘ โ†“ + โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + (Periodic keepalive) +``` + +### Expiration and Keepalive + +Programs automatically expire after ~1 year (configurable by chain): + +```solidity +// Check time remaining +uint64 timeLeft = ArbWasm.programTimeLeft(contractAddress); + +// Extend expiration +ArbWasm.codehashKeepalive{value: keepaliveFee}(codehash); +``` + +**Why expiration?** + +- Prevents abandoned contracts from consuming ArbOS resources +- Encourages active maintenance +- Allows protocol upgrades + +**Keepalive strategy**: + +- Monitor `programTimeLeft()` periodically +- Call `codehashKeepalive()` before expiration +- Automated scripts can handle this + +### Reactivation After Expiry + +If a program expires: + +```bash +# Reactivate the existing deployment +cargo stylus activate --address=0x... +``` + +The contract code remains on-chain; only the activation state was cleared. + +## Troubleshooting + +### Common Activation Errors + +#### "Program not activated" + +**Cause**: Trying to call a deployed but not activated contract + +**Solution**: + +```bash +cargo stylus activate --address=0x... +``` + +#### "Insufficient value" + +**Cause**: Data fee sent is less than required + +**Solution**: + +- Check current data fee: `cargo stylus check` +- Increase fee bump percentage +- Ensure sufficient ETH balance + +#### "Program not WASM" + +**Cause**: Deployed bytecode is not valid Stylus WASM + +**Solution**: + +- Verify you deployed the correct contract +- Rebuild and redeploy: `cargo stylus deploy` + +#### "Program needs upgrade" + +**Cause**: Contract was activated against an old Stylus version + +**Solution**: + +- Recompile with latest SDK +- Redeploy and reactivate + +#### "Program expired" + +**Cause**: Contract hasn't been kept alive and expired + +**Solution**: + +```bash +# Reactivate the contract +cargo stylus activate --address=0x... +``` + +### Debugging Activation + +Enable verbose output: + +```bash +# Check detailed status +cargo stylus check --verbose + +# Deploy with verbose logging +RUST_LOG=debug cargo stylus deploy --private-key-path=wallet.txt +``` + +### Verifying Activation Status + +Check if a contract is activated: + +```bash +# Via cargo-stylus +cargo stylus check --address=0x... + +# Via cast (calling ArbWasm) +cast call 0x0000000000000000000000000000000000000071 \ + "codehashVersion(bytes32)" \ + $(cast keccak $(cast code 0x...)) +``` + +## Best Practices + +### 1. Always Check Before Deploying + +```bash +cargo stylus check +``` + +This prevents deploying duplicate code and wasting gas. + +### 2. Use Automatic Activation + +Unless you have specific reasons to split deployment and activation, use the default behavior: + +```bash +cargo stylus deploy # Deploys AND activates +``` + +### 3. Test on Testnet First + +Deploy to Arbitrum Sepolia before mainnet: + +```bash +cargo stylus deploy \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" \ + --private-key-path=testnet-key.txt +``` + +### 4. Monitor Contract Expiration + +Set up monitoring for production contracts: + +```solidity +uint64 timeLeft = ArbWasm.programTimeLeft(contractAddress); +if (timeLeft < 30 days) { + // Send alert or trigger keepalive +} +``` + +### 5. Document Activation Details + +Track activation information: + +- Contract address +- Activation transaction hash +- Stylus version +- Data fee paid +- Activation timestamp + +### 6. Keep SDK Updated + +Use the latest Stylus SDK version: + +```toml +[dependencies] +stylus-sdk = "0.10.0-beta.1" +``` + +Older versions may become incompatible with chain upgrades. + +### 7. Handle Constructor Arguments Carefully + +Type-check constructor arguments: + +```bash +# Incorrect (will fail) +cargo stylus deploy --constructor-args "hello" 123 + +# Correct (matches constructor signature) +cargo stylus deploy --constructor-args 0x1234... 42 +``` + +## Complete Example + +Here's a full deployment workflow: + +```bash +# 1. Create new Stylus project +cargo stylus new my-token +cd my-token + +# 2. Build and verify locally +cargo build --release --target wasm32-unknown-unknown +cargo stylus check + +# 3. Test on Arbitrum Sepolia +export SEPOLIA_ENDPOINT="https://sepolia-rollup.arbitrum.io/rpc" +export PRIVATE_KEY_PATH="./sepolia-key.txt" + +cargo stylus deploy \ + --endpoint=$SEPOLIA_ENDPOINT \ + --private-key-path=$PRIVATE_KEY_PATH \ + --constructor-args "MyToken" "MTK" 18 + +# 4. Verify deployment +cargo stylus check \ + --endpoint=$SEPOLIA_ENDPOINT \ + --address=0x... # Address from step 3 + +# 5. Deploy to mainnet +export MAINNET_ENDPOINT="https://arb1.arbitrum.io/rpc" +export MAINNET_KEY_PATH="./mainnet-key.txt" + +cargo stylus deploy \ + --endpoint=$MAINNET_ENDPOINT \ + --private-key-path=$MAINNET_KEY_PATH \ + --constructor-args "MyToken" "MTK" 18 + +# 6. Cache the contract (optional, for gas optimization) +cast send 0x0000000000000000000000000000000000000072 \ + "cacheProgram(address)" \ + 0x... # Your contract address \ + --value 10000000000000000 \ + --rpc-url=$MAINNET_ENDPOINT \ + --private-key=$MAINNET_PRIVATE_KEY +``` + +## Summary + +- **Two-step process**: Deployment stores code, activation makes it executable +- **cargo-stylus handles both**: Use `deploy` for automatic activation +- **Data fee required**: Activation costs ETH (separate from deployment gas) +- **Code reuse**: Identical contracts share activation, saving costs +- **Expiration**: Programs expire after ~1 year without keepalive +- **ArbWasm precompile**: All activation goes through address `0x71` +- **Check first**: Use `cargo stylus check` to avoid duplicate activations + +## See Also + +- [Contracts](../reference/contracts.mdx) - Writing Stylus contracts +- [Global Variables and Functions](../reference/global-variables-and-functions.mdx) - VM interface methods +- [cargo-stylus CLI Reference](../reference/cargo-stylus-reference.mdx) - Complete CLI documentation +- [ArbWasm Precompile](../reference/precompiles.mdx#arbwasm) - Detailed precompile reference From 8b2a6e602316a6248f90f8309d854deae3844fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 21 Nov 2025 18:13:54 -0800 Subject: [PATCH 028/162] fix boilerplate links --- docs/stylus/concepts/activation.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index dce723a561..f8b0762318 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -784,5 +784,5 @@ cast send 0x0000000000000000000000000000000000000072 \ - [Contracts](../reference/contracts.mdx) - Writing Stylus contracts - [Global Variables and Functions](../reference/global-variables-and-functions.mdx) - VM interface methods -- [cargo-stylus CLI Reference](../reference/cargo-stylus-reference.mdx) - Complete CLI documentation -- [ArbWasm Precompile](../reference/precompiles.mdx#arbwasm) - Detailed precompile reference + + From 213940aa90803a9c9a6c8285907b56d60947a7ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 10:54:00 -0800 Subject: [PATCH 029/162] Add custom NavbarItem component for sidebar control Create a wrapper around Docusaurus's default NavbarItem that intercepts clicks on navbar items with a sidebarExpand property and adds URL parameters to control which sidebar categories should be expanded/collapsed. --- src/theme/NavbarItem/index.js | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/theme/NavbarItem/index.js diff --git a/src/theme/NavbarItem/index.js b/src/theme/NavbarItem/index.js new file mode 100644 index 0000000000..1de9d28b39 --- /dev/null +++ b/src/theme/NavbarItem/index.js @@ -0,0 +1,36 @@ +import React from 'react'; +import OriginalNavbarItem from '@theme-original/NavbarItem'; +import { useHistory } from '@docusaurus/router'; + +export default function NavbarItem(props) { + const history = useHistory(); + + // Check if this navbar item should control sidebar state + if (props.sidebarExpand) { + const enhancedProps = { + ...props, + onClick: (e) => { + // Call original onClick if it exists + if (props.onClick) { + props.onClick(e); + } + + // Don't add our custom behavior if the event was prevented + if (e.defaultPrevented) { + return; + } + + // Add sidebar expansion parameter to URL + e.preventDefault(); + const url = new URL(props.to, window.location.origin); + url.searchParams.set('sidebar_expand', props.sidebarExpand); + history.push(url.pathname + url.search); + }, + }; + + return ; + } + + // For all other navbar items, use default behavior + return ; +} From a2f228b3919d9215defacec45d8e8eee43d37136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 10:54:09 -0800 Subject: [PATCH 030/162] Add custom DocSidebar component for auto-collapse/expand Create a wrapper around Docusaurus's default DocSidebar that reads URL parameters and programmatically expands/collapses the "Build apps with Solidity" and "Build apps with Stylus" sidebar categories based on which navbar item was clicked. --- src/theme/DocSidebar/index.js | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/theme/DocSidebar/index.js diff --git a/src/theme/DocSidebar/index.js b/src/theme/DocSidebar/index.js new file mode 100644 index 0000000000..66e50c4b84 --- /dev/null +++ b/src/theme/DocSidebar/index.js @@ -0,0 +1,71 @@ +import React, { useEffect } from 'react'; +import OriginalDocSidebar from '@theme-original/DocSidebar'; +import { useLocation } from '@docusaurus/router'; + +export default function DocSidebar(props) { + const location = useLocation(); + + useEffect(() => { + // Check if there's a sidebar_expand parameter in the URL + const params = new URLSearchParams(location.search); + const expandTarget = params.get('sidebar_expand'); + + if (expandTarget) { + // Use a small delay to ensure sidebar has rendered + const timeoutId = setTimeout(() => { + // Find the sidebar category elements by their text content + const categories = document.querySelectorAll('.theme-doc-sidebar-item-category'); + + let solidityCategory = null; + let stylusCategory = null; + + categories.forEach((category) => { + const label = category.querySelector('.menu__link--sublist'); + if (label) { + const text = label.textContent.trim(); + if (text === 'Build apps with Solidity') { + solidityCategory = category; + } else if (text === 'Build apps with Stylus') { + stylusCategory = category; + } + } + }); + + if (expandTarget === 'stylus' && stylusCategory) { + // Expand Stylus, collapse Solidity + const stylusButton = stylusCategory.querySelector('button.menu__link--sublist'); + const solidityButton = solidityCategory?.querySelector('button.menu__link--sublist'); + + if (stylusButton && stylusButton.getAttribute('aria-expanded') === 'false') { + stylusButton.click(); + } + if (solidityButton && solidityButton.getAttribute('aria-expanded') === 'true') { + solidityButton.click(); + } + } else if (expandTarget === 'solidity' && solidityCategory) { + // Expand Solidity, collapse Stylus + const solidityButton = solidityCategory.querySelector('button.menu__link--sublist'); + const stylusButton = stylusCategory?.querySelector('button.menu__link--sublist'); + + if (solidityButton && solidityButton.getAttribute('aria-expanded') === 'false') { + solidityButton.click(); + } + if (stylusButton && stylusButton.getAttribute('aria-expanded') === 'true') { + stylusButton.click(); + } + } + + // Clean up URL by removing the parameter after processing + if (window.history.replaceState) { + const cleanUrl = new URL(window.location); + cleanUrl.searchParams.delete('sidebar_expand'); + window.history.replaceState({}, '', cleanUrl.pathname + cleanUrl.search); + } + }, 150); + + return () => clearTimeout(timeoutId); + } + }, [location]); + + return ; +} From b189ef18a8b20f4fa27be034de298022d1d1880a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 10:54:15 -0800 Subject: [PATCH 031/162] Add sidebarExpand metadata to Build apps navbar items Add sidebarExpand property to "Build with Solidity" and "Build with Stylus" navbar dropdown items to enable automatic sidebar category expansion when these items are clicked. --- docusaurus.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docusaurus.config.js b/docusaurus.config.js index 6b1d87da85..91d2f84770 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -241,10 +241,12 @@ const config = { { label: 'Build with Solidity', to: '/build-decentralized-apps/quickstart-solidity-remix', + sidebarExpand: 'solidity', }, { label: 'Build with Stylus', to: '/stylus/quickstart', + sidebarExpand: 'stylus', }, ], }, From 3f553153cdda5d9662221e10e1c14715d78ec646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:01:12 -0800 Subject: [PATCH 032/162] Revert "Add sidebarExpand metadata to Build apps navbar items" This reverts commit b189ef18a8b20f4fa27be034de298022d1d1880a. --- docusaurus.config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index 91d2f84770..6b1d87da85 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -241,12 +241,10 @@ const config = { { label: 'Build with Solidity', to: '/build-decentralized-apps/quickstart-solidity-remix', - sidebarExpand: 'solidity', }, { label: 'Build with Stylus', to: '/stylus/quickstart', - sidebarExpand: 'stylus', }, ], }, From 1dc9af29d4f0e1ff6d3f6ea40d232bfc5b66a3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:01:16 -0800 Subject: [PATCH 033/162] Revert "Add custom DocSidebar component for auto-collapse/expand" This reverts commit a2f228b3919d9215defacec45d8e8eee43d37136. --- src/theme/DocSidebar/index.js | 71 ----------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 src/theme/DocSidebar/index.js diff --git a/src/theme/DocSidebar/index.js b/src/theme/DocSidebar/index.js deleted file mode 100644 index 66e50c4b84..0000000000 --- a/src/theme/DocSidebar/index.js +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useEffect } from 'react'; -import OriginalDocSidebar from '@theme-original/DocSidebar'; -import { useLocation } from '@docusaurus/router'; - -export default function DocSidebar(props) { - const location = useLocation(); - - useEffect(() => { - // Check if there's a sidebar_expand parameter in the URL - const params = new URLSearchParams(location.search); - const expandTarget = params.get('sidebar_expand'); - - if (expandTarget) { - // Use a small delay to ensure sidebar has rendered - const timeoutId = setTimeout(() => { - // Find the sidebar category elements by their text content - const categories = document.querySelectorAll('.theme-doc-sidebar-item-category'); - - let solidityCategory = null; - let stylusCategory = null; - - categories.forEach((category) => { - const label = category.querySelector('.menu__link--sublist'); - if (label) { - const text = label.textContent.trim(); - if (text === 'Build apps with Solidity') { - solidityCategory = category; - } else if (text === 'Build apps with Stylus') { - stylusCategory = category; - } - } - }); - - if (expandTarget === 'stylus' && stylusCategory) { - // Expand Stylus, collapse Solidity - const stylusButton = stylusCategory.querySelector('button.menu__link--sublist'); - const solidityButton = solidityCategory?.querySelector('button.menu__link--sublist'); - - if (stylusButton && stylusButton.getAttribute('aria-expanded') === 'false') { - stylusButton.click(); - } - if (solidityButton && solidityButton.getAttribute('aria-expanded') === 'true') { - solidityButton.click(); - } - } else if (expandTarget === 'solidity' && solidityCategory) { - // Expand Solidity, collapse Stylus - const solidityButton = solidityCategory.querySelector('button.menu__link--sublist'); - const stylusButton = stylusCategory?.querySelector('button.menu__link--sublist'); - - if (solidityButton && solidityButton.getAttribute('aria-expanded') === 'false') { - solidityButton.click(); - } - if (stylusButton && stylusButton.getAttribute('aria-expanded') === 'true') { - stylusButton.click(); - } - } - - // Clean up URL by removing the parameter after processing - if (window.history.replaceState) { - const cleanUrl = new URL(window.location); - cleanUrl.searchParams.delete('sidebar_expand'); - window.history.replaceState({}, '', cleanUrl.pathname + cleanUrl.search); - } - }, 150); - - return () => clearTimeout(timeoutId); - } - }, [location]); - - return ; -} From 728b52dde954fa395f2dbab871e2ea2c593910b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:01:23 -0800 Subject: [PATCH 034/162] Revert "Add custom NavbarItem component for sidebar control" This reverts commit 213940aa90803a9c9a6c8285907b56d60947a7ee. --- src/theme/NavbarItem/index.js | 36 ----------------------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/theme/NavbarItem/index.js diff --git a/src/theme/NavbarItem/index.js b/src/theme/NavbarItem/index.js deleted file mode 100644 index 1de9d28b39..0000000000 --- a/src/theme/NavbarItem/index.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import OriginalNavbarItem from '@theme-original/NavbarItem'; -import { useHistory } from '@docusaurus/router'; - -export default function NavbarItem(props) { - const history = useHistory(); - - // Check if this navbar item should control sidebar state - if (props.sidebarExpand) { - const enhancedProps = { - ...props, - onClick: (e) => { - // Call original onClick if it exists - if (props.onClick) { - props.onClick(e); - } - - // Don't add our custom behavior if the event was prevented - if (e.defaultPrevented) { - return; - } - - // Add sidebar expansion parameter to URL - e.preventDefault(); - const url = new URL(props.to, window.location.origin); - url.searchParams.set('sidebar_expand', props.sidebarExpand); - history.push(url.pathname + url.search); - }, - }; - - return ; - } - - // For all other navbar items, use default behavior - return ; -} From cc388be0e49b16e1db66afff363cb1adea358d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:08:12 -0800 Subject: [PATCH 035/162] Swizzle DocSidebarItem/Category for sidebar state control Create a wrapper around Docusaurus's Category component that intercepts URL parameters and modifies the collapsed property based on which navbar item was clicked. This approach works with React's state management instead of fighting against it with DOM manipulation. --- src/theme/DocSidebarItem/Category/index.tsx | 47 +++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/theme/DocSidebarItem/Category/index.tsx diff --git a/src/theme/DocSidebarItem/Category/index.tsx b/src/theme/DocSidebarItem/Category/index.tsx new file mode 100644 index 0000000000..62b8e87272 --- /dev/null +++ b/src/theme/DocSidebarItem/Category/index.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import Category from '@theme-original/DocSidebarItem/Category'; +import type CategoryType from '@theme/DocSidebarItem/Category'; +import type { WrapperProps } from '@docusaurus/types'; +import { useLocation } from '@docusaurus/router'; + +type Props = WrapperProps; + +export default function CategoryWrapper(props: Props): JSX.Element { + const location = useLocation(); + const { item, level } = props; + + // Only process root-level categories (level 0) + if (level === 0 && item.type === 'category') { + const params = new URLSearchParams(location.search); + const expandTarget = params.get('sidebar_expand'); + + if (expandTarget) { + // Determine if this category should be expanded based on URL param + const shouldExpand = + (expandTarget === 'stylus' && item.label === 'Build apps with Stylus') || + (expandTarget === 'solidity' && item.label === 'Build apps with Solidity'); + + // Override the item's collapsed property + if (shouldExpand && item.collapsible) { + const modifiedItem = { + ...item, + collapsed: false, // Force this category to be expanded + }; + + return ; + } + + // For other categories at this level, force them to collapse if we're expanding a specific one + if (item.collapsible && !shouldExpand) { + const modifiedItem = { + ...item, + collapsed: true, // Force other categories to collapse + }; + + return ; + } + } + } + + return ; +} From 98518675c5ea5146cd3398cdcacc90488cb561c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:08:24 -0800 Subject: [PATCH 036/162] Add custom NavbarItem component for URL parameter injection Create a wrapper around Docusaurus's NavbarItem that intercepts clicks on navbar items with sidebarExpand property and adds URL parameters to signal which sidebar category should be expanded. --- src/theme/NavbarItem/index.tsx | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/theme/NavbarItem/index.tsx diff --git a/src/theme/NavbarItem/index.tsx b/src/theme/NavbarItem/index.tsx new file mode 100644 index 0000000000..e94d80657b --- /dev/null +++ b/src/theme/NavbarItem/index.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import OriginalNavbarItem from '@theme-original/NavbarItem'; +import { useHistory } from '@docusaurus/router'; +import type { Props } from '@theme/NavbarItem'; + +export default function NavbarItem(props: Props): JSX.Element { + const history = useHistory(); + + // Check if this navbar item should control sidebar state + if ('sidebarExpand' in props && props.sidebarExpand) { + const enhancedProps = { + ...props, + onClick: (e: React.MouseEvent) => { + // Call original onClick if it exists + if (props.onClick) { + props.onClick(e); + } + + // Don't add our custom behavior if the event was prevented + if (e.defaultPrevented) { + return; + } + + // Add sidebar expansion parameter to URL + if ('to' in props && props.to) { + e.preventDefault(); + const url = new URL(props.to as string, window.location.origin); + url.searchParams.set('sidebar_expand', props.sidebarExpand as string); + history.push(url.pathname + url.search); + } + }, + }; + + return ; + } + + // For all other navbar items, use default behavior + return ; +} From 0771198fe9471a1ca75025d2aaefbbf707e70993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:08:35 -0800 Subject: [PATCH 037/162] Add sidebarExpand metadata to Build apps navbar items Configure navbar dropdown items with sidebarExpand property to enable automatic sidebar category expansion when clicked. --- docusaurus.config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docusaurus.config.js b/docusaurus.config.js index 6b1d87da85..91d2f84770 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -241,10 +241,12 @@ const config = { { label: 'Build with Solidity', to: '/build-decentralized-apps/quickstart-solidity-remix', + sidebarExpand: 'solidity', }, { label: 'Build with Stylus', to: '/stylus/quickstart', + sidebarExpand: 'stylus', }, ], }, From a1a644c38de993b655476ba7b349ff05e151c3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:09:03 -0800 Subject: [PATCH 038/162] Revert "Add sidebarExpand metadata to Build apps navbar items" This reverts commit 0771198fe9471a1ca75025d2aaefbbf707e70993. --- docusaurus.config.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index 91d2f84770..6b1d87da85 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -241,12 +241,10 @@ const config = { { label: 'Build with Solidity', to: '/build-decentralized-apps/quickstart-solidity-remix', - sidebarExpand: 'solidity', }, { label: 'Build with Stylus', to: '/stylus/quickstart', - sidebarExpand: 'stylus', }, ], }, From 10e749961c3b0c863c3879022e99a9c3f858157c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:09:06 -0800 Subject: [PATCH 039/162] Revert "Add custom NavbarItem component for URL parameter injection" This reverts commit 98518675c5ea5146cd3398cdcacc90488cb561c7. --- src/theme/NavbarItem/index.tsx | 39 ---------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 src/theme/NavbarItem/index.tsx diff --git a/src/theme/NavbarItem/index.tsx b/src/theme/NavbarItem/index.tsx deleted file mode 100644 index e94d80657b..0000000000 --- a/src/theme/NavbarItem/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import OriginalNavbarItem from '@theme-original/NavbarItem'; -import { useHistory } from '@docusaurus/router'; -import type { Props } from '@theme/NavbarItem'; - -export default function NavbarItem(props: Props): JSX.Element { - const history = useHistory(); - - // Check if this navbar item should control sidebar state - if ('sidebarExpand' in props && props.sidebarExpand) { - const enhancedProps = { - ...props, - onClick: (e: React.MouseEvent) => { - // Call original onClick if it exists - if (props.onClick) { - props.onClick(e); - } - - // Don't add our custom behavior if the event was prevented - if (e.defaultPrevented) { - return; - } - - // Add sidebar expansion parameter to URL - if ('to' in props && props.to) { - e.preventDefault(); - const url = new URL(props.to as string, window.location.origin); - url.searchParams.set('sidebar_expand', props.sidebarExpand as string); - history.push(url.pathname + url.search); - } - }, - }; - - return ; - } - - // For all other navbar items, use default behavior - return ; -} From 93854627da86eb259596dd88dd9b36094b57d865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:09:11 -0800 Subject: [PATCH 040/162] Revert "Swizzle DocSidebarItem/Category for sidebar state control" This reverts commit cc388be0e49b16e1db66afff363cb1adea358d6e. --- src/theme/DocSidebarItem/Category/index.tsx | 47 --------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/theme/DocSidebarItem/Category/index.tsx diff --git a/src/theme/DocSidebarItem/Category/index.tsx b/src/theme/DocSidebarItem/Category/index.tsx deleted file mode 100644 index 62b8e87272..0000000000 --- a/src/theme/DocSidebarItem/Category/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import Category from '@theme-original/DocSidebarItem/Category'; -import type CategoryType from '@theme/DocSidebarItem/Category'; -import type { WrapperProps } from '@docusaurus/types'; -import { useLocation } from '@docusaurus/router'; - -type Props = WrapperProps; - -export default function CategoryWrapper(props: Props): JSX.Element { - const location = useLocation(); - const { item, level } = props; - - // Only process root-level categories (level 0) - if (level === 0 && item.type === 'category') { - const params = new URLSearchParams(location.search); - const expandTarget = params.get('sidebar_expand'); - - if (expandTarget) { - // Determine if this category should be expanded based on URL param - const shouldExpand = - (expandTarget === 'stylus' && item.label === 'Build apps with Stylus') || - (expandTarget === 'solidity' && item.label === 'Build apps with Solidity'); - - // Override the item's collapsed property - if (shouldExpand && item.collapsible) { - const modifiedItem = { - ...item, - collapsed: false, // Force this category to be expanded - }; - - return ; - } - - // For other categories at this level, force them to collapse if we're expanding a specific one - if (item.collapsible && !shouldExpand) { - const modifiedItem = { - ...item, - collapsed: true, // Force other categories to collapse - }; - - return ; - } - } - } - - return ; -} From 135e32a19a674c2be92fa3523d1b29566447ff95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:21:06 -0800 Subject: [PATCH 041/162] Document Stylus type conversions Add comprehensive documentation for converting between Rust types, Alloy primitives, and Solidity types in Stylus smart contracts. Covers: - Type relationship mappings between Rust and Solidity - Numeric type conversions (integers, U256, I256) - Address conversions and the address! macro - Byte type conversions (fixed and dynamic) - String conversions - Collection conversions (Vec, arrays) - ABI encoding/decoding with examples - Packed encoding for hashing - Error type conversions with Into trait - Storage type conversions - Best practices for safe conversions --- .../data-types/conversions-between-types.mdx | 372 +++++++++++++++++- 1 file changed, 369 insertions(+), 3 deletions(-) diff --git a/docs/stylus/reference/data-types/conversions-between-types.mdx b/docs/stylus/reference/data-types/conversions-between-types.mdx index f44e822ec2..4e8478dfc9 100644 --- a/docs/stylus/reference/data-types/conversions-between-types.mdx +++ b/docs/stylus/reference/data-types/conversions-between-types.mdx @@ -1,6 +1,6 @@ --- -title: 'Conversions Between Types' -description: 'Conversions Between Types' +title: 'Conversions between types' +description: 'Learn how to convert between Rust types, Alloy primitives, and Solidity types in Stylus smart contracts' author: chrisco sme: chrisco sidebar_position: 1 @@ -8,4 +8,370 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart displayed_sidebar: buildAppsSidebar --- -TBD +Stylus smart contracts often need to convert between different type representations: Rust native types, Alloy primitives, and Solidity types. The Stylus SDK provides comprehensive conversion mechanisms through the `AbiType` trait and various standard Rust conversion traits. + +## Understanding type relationships + +The Stylus SDK establishes a bidirectional relationship between Rust and Solidity types: + +- **Alloy provides**: Solidity types โ†’ Rust types mapping via `SolType` +- **Stylus SDK provides**: Rust types โ†’ Solidity types mapping via `AbiType` + +Together, these create a complete two-way type system for interoperability. + +### Key type mappings + +| Rust/Alloy type | Solidity type | Notes | +| --------------------------------- | ------------------------- | ---------------------------------------------- | +| `bool` | `bool` | Native boolean | +| `u8`, `u16`, `u32`, `u64`, `u128` | `uint8` through `uint128` | Native unsigned integers | +| `i8`, `i16`, `i32`, `i64`, `i128` | `int8` through `int128` | Native signed integers | +| `Uint` | `uintBITS` | Arbitrary-sized unsigned integers (8-256 bits) | +| `Signed` | `intBITS` | Arbitrary-sized signed integers (8-256 bits) | +| `U256` | `uint256` | 256-bit unsigned integer (most common) | +| `Address` | `address` | 20-byte Ethereum address | +| `FixedBytes` | `bytesN` | Fixed-size byte array | +| `Bytes` | `bytes` | Dynamic byte array | +| `String` | `string` | Dynamic UTF-8 string | +| `Vec` | `T[]` | Dynamic array | +| `[T; N]` | `T[N]` | Fixed-size array | +| `(T1, T2, ...)` | `(T1, T2, ...)` | Tuple types | + +**Important**: The SDK treats `Vec` as Solidity `uint8[]`. For Solidity `bytes`, use `alloy_primitives::Bytes`. + +## Converting numeric types + +### Creating integers from literals + +```rust +use stylus_sdk::alloy_primitives::{U256, I256, U8, I8}; + +// From integer literals +let small: U8 = U8::from(1); +let large: U256 = U256::from(255); + +// For signed integers +let positive: I8 = I8::unchecked_from(127); +let negative: I8 = I8::unchecked_from(-1); +let signed_large: I256 = I256::unchecked_from(0xff_u64); +``` + +### Parsing from strings + +```rust +use stylus_sdk::alloy_primitives::I256; + +// Parse decimal strings +let a = I256::try_from(20003000).unwrap(); +let b = "100".parse::().unwrap(); + +// Parse hexadecimal strings +let c = "-0x138f".parse::().unwrap(); + +// Underscores are ignored for readability +let d = "1_000_000".parse::().unwrap(); + +// Arithmetic works as expected +let result = a * b + c - d; +``` + +### Integer constants + +```rust +use stylus_sdk::alloy_primitives::I256; + +let max = I256::MAX; // Maximum value +let min = I256::MIN; // Minimum value +let zero = I256::ZERO; // Zero +let minus_one = I256::MINUS_ONE; // -1 +``` + +### Converting between integer sizes + +```rust +use stylus_sdk::alloy_primitives::{Uint, Signed, U256}; + +// Between Alloy integer types (same bit-width) +let uint_value = Uint::<128, 2>::from(999); +let u128_value: u128 = uint_value.try_into() + .map_err(|_| "conversion error") + .unwrap(); + +// Between different bit-widths +let small = Uint::<8, 1>::from(100); +let large = U256::from(small); +``` + +The SDK uses the `ConvertInt` trait internally to enable conversions between Alloy's `Uint` types and Rust native integer types like `u8`, `u16`, `u32`, `u64`, and `u128`. + +## Converting addresses + +### Creating addresses + +```rust +use stylus_sdk::alloy_primitives::{Address, address}; + +// From a 20-byte array +let addr1 = Address::from([0x11; 20]); + +// Using the address! macro with checksummed string +let addr2 = address!("d8da6bf26964af9d7eed9e03e53415d37aa96045"); + +// From a byte slice +let bytes: [u8; 20] = [0xd8, 0xda, 0x6b, 0xf2, /* ... */]; +let addr3 = Address::from(bytes); +``` + +### Converting addresses to bytes + +```rust +use stylus_sdk::alloy_primitives::Address; + +let addr = address!("d8da6bf26964af9d7eed9e03e53415d37aa96045"); + +// Get reference to underlying bytes +let bytes_ref: &[u8] = addr.as_ref(); + +// Use in byte concatenation +let data = [addr.as_ref(), other_data].concat(); +``` + +## Converting byte types + +### Fixed-size bytes + +```rust +use stylus_sdk::alloy_primitives::FixedBytes; + +// Create from array +let fixed = FixedBytes::<32>::new([0u8; 32]); + +// Create from slice +let slice: &[u8] = &[1, 2, 3, 4]; +let fixed = FixedBytes::<4>::from_slice(slice); + +// Convert to slice +let bytes_ref: &[u8] = fixed.as_ref(); +``` + +### Dynamic bytes + +```rust +use stylus_sdk::abi::Bytes; + +// Create from Vec +let bytes = Bytes::from(vec![1, 2, 3, 4]); + +// Create empty +let empty = Bytes::new(); + +// Get reference to underlying data +let data: &[u8] = bytes.as_ref(); + +// Convert to Vec +let vec: Vec = bytes.to_vec(); +``` + +### Byte array conversions + +```rust +use stylus_sdk::alloy_primitives::U256; + +// Convert U256 to big-endian bytes +let value = U256::from(12345); +let bytes_vec: Vec = value.to_be_bytes_vec(); +let bytes_array: [u8; 32] = value.to_be_bytes(); + +// Convert from big-endian bytes +let from_slice = U256::try_from_be_slice(&bytes_vec).unwrap(); +``` + +## Converting strings + +```rust +use alloc::string::{String, ToString}; + +// String conversions +let rust_string = "hello".to_string(); +let bytes = rust_string.as_bytes(); + +// For Solidity string parameters in functions +// the String type is automatically handled by AbiType +pub fn process_string(&self, text: String) -> String { + text +} +``` + +## Converting collections + +### Dynamic arrays (Vec) + +```rust +use stylus_sdk::alloy_primitives::U256; +use alloc::vec::Vec; + +// Vec is used directly as Solidity dynamic arrays +let numbers: Vec = vec![ + U256::from(1), + U256::from(2), + U256::from(3), +]; + +// For Vec, note this maps to uint8[], not bytes +let uint8_array: Vec = vec![1, 2, 3]; +``` + +### Fixed-size arrays + +```rust +use stylus_sdk::alloy_primitives::U256; + +// Fixed arrays map directly to Solidity fixed arrays +let fixed: [U256; 3] = [ + U256::from(1), + U256::from(2), + U256::from(3), +]; + +// Nested arrays +let nested: [[u32; 2]; 4] = [[1, 2], [3, 4], [5, 6], [7, 8]]; +``` + +## ABI encoding and decoding + +### Encoding types + +```rust +use stylus_sdk::abi::{encode, encode_params}; +use stylus_sdk::alloy_primitives::{Address, U256}; +use alloy_sol_types::{sol_data::*, SolType}; + +// Encode a single value +let value = U256::from(100); +let encoded = encode(&value); + +// Encode tuple of parameters +type TransferParams = (Address, Uint<256>); +let params = (address, amount); +let encoded = TransferParams::abi_encode_params(¶ms); +``` + +### Decoding types + +```rust +use stylus_sdk::abi::decode_params; +use stylus_sdk::alloy_primitives::{Address, U256}; +use alloy_sol_types::{sol_data::*, SolType}; + +// Define the expected type structure +type TransferParams = (Address, Uint<256>); + +// Decode from bytes +let decoded: (Address, U256) = TransferParams::abi_decode_params(&encoded_data) + .map_err(|_| "decode error")?; +``` + +### Packed encoding + +Packed encoding is useful for hashing and signature verification: + +```rust +use stylus_sdk::alloy_primitives::{Address, U256}; +use alloy_sol_types::{sol_data::*, SolType}; + +// Method 1: Using SolType::abi_encode_packed +type DataTypes = (Address, Uint<256>, String, Bytes, Uint<256>); +let data = (target, value, func, bytes, timestamp); +let packed = DataTypes::abi_encode_packed(&data); + +// Method 2: Manual concatenation +let packed_manual = [ + target.as_ref(), + &value.to_be_bytes_vec(), + func.as_bytes(), + bytes.as_ref(), + ×tamp.to_be_bytes_vec(), +].concat(); +``` + +## Error type conversions + +Stylus error types can be converted using the `Into` trait: + +```rust +use stylus_sdk::prelude::*; + +sol! { + error InvalidParam(); + error NotFound(); +} + +#[derive(SolidityError)] +pub enum MyError { + InvalidParam(InvalidParam), + NotFound(NotFound), +} + +pub fn check_value(&self, value: U256) -> Result<(), MyError> { + if value == U256::ZERO { + return Err(InvalidParam {}.into()); + } + Ok(()) +} +``` + +## Storage type conversions + +Storage types require special handling for persistence: + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::U256; + +#[storage] +pub struct Counter { + count: StorageU256, +} + +#[public] +impl Counter { + // Get value from storage + pub fn get_count(&self) -> U256 { + self.count.get() + } + + // Set value in storage + pub fn set_count(&mut self, value: U256) { + self.count.set(value); + } + + // Increment using arithmetic + pub fn increment(&mut self) { + let current = self.count.get(); + self.count.set(current + U256::from(1)); + } +} +``` + +## Best practices + +1. **Use try_from for fallible conversions**: When converting between types where overflow is possible, use `try_from` instead of panicking conversions. + +2. **Prefer native types when appropriate**: Use Rust's native `bool`, `u8`-`u128`, and `i8`-`i128` types when they match your needs exactly. They're more efficient and ergonomic. + +3. **Be explicit about byte types**: Remember that `Vec` maps to `uint8[]`, not `bytes`. Use `Bytes` from `stylus_sdk::abi` for Solidity `bytes` type. + +4. **Use the address! macro**: For hardcoded addresses, use the `address!` macro which performs compile-time validation and checksumming. + +5. **Handle conversion errors**: Always handle potential errors from `try_from`, `try_into`, and `parse` operations rather than using unwrap in production code. + +6. **Consider packed encoding for hashing**: When preparing data for hashing or signature verification, packed encoding produces more compact representations. + +## Reference + +For complete implementation details, see: + +- `/stylus-sdk/src/abi/mod.rs` - AbiType trait and encoding functions +- `/stylus-sdk/src/abi/ints.rs` - Integer type conversions +- `/stylus-sdk/src/abi/impls.rs` - Implementations for standard types +- `/stylus-sdk/src/storage/traits.rs` - Storage type conversion traits From 67778cdcdd853e3a259d3ae81cf6ee220e01b843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:25:49 -0800 Subject: [PATCH 042/162] Document Solidity and Stylus differences Add comprehensive documentation comparing Solidity and Stylus smart contract development. Covers: - Language and syntax differences - Contract structure and attributes - Function visibility and state mutability (view, pure, payable) - Constructors with #[constructor] attribute - Modifiers replaced by regular Rust functions - Fallback and receive functions with #[receive] and #[fallback] - Events using sol! macro and vm().log() - Error handling with Result types and SolidityError - Inheritance using traits and composition - Storage types and access patterns - Constants and immutables - Type system mappings (integers, arrays, mappings) - Global variables (msg.sender, block.timestamp, etc.) - External calls using RawCall - Contract deployment - Assembly alternatives - Features unique to Stylus (type safety, performance) - Memory and gas efficiency - Development workflow (compilation, testing, deployment) - Interoperability between Solidity and Stylus - Best practices for transitioning from Solidity Based on stylus-sdk-rs examples including constructor, fallback_receive, events, errors, and inheritance patterns. --- docs/stylus/advanced/solidity-differences.mdx | 735 +++++++++++++++++- 1 file changed, 733 insertions(+), 2 deletions(-) diff --git a/docs/stylus/advanced/solidity-differences.mdx b/docs/stylus/advanced/solidity-differences.mdx index 1acd8509c9..456ef0503f 100644 --- a/docs/stylus/advanced/solidity-differences.mdx +++ b/docs/stylus/advanced/solidity-differences.mdx @@ -1,6 +1,6 @@ --- title: 'Differences between Solidity and Stylus' -description: 'Solidity and Stylus differences' +description: 'Learn the key differences between writing smart contracts in Solidity versus Stylus Rust' author: chrisco sme: chrisco sidebar_position: 1 @@ -8,4 +8,735 @@ target_audience: Developers who need to compare Stylus with Solidity. displayed_sidebar: buildAppsSidebar --- -TBD +Stylus introduces a new paradigm for writing smart contracts on Arbitrum using Rust and other WebAssembly-compatible languages. While Stylus contracts maintain full interoperability with Solidity contracts, there are important differences in how you structure and write code. This guide helps Solidity developers understand these differences. + +## Language and syntax + +### Contract structure + +**Solidity:** + +```solidity +contract MyContract { + uint256 private value; + address public owner; + + constructor(uint256 initialValue) { + value = initialValue; + owner = msg.sender; + } + + function setValue(uint256 newValue) public { + value = newValue; + } +} +``` + +**Stylus (Rust):** + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::{Address, U256}; + +#[storage] +#[entrypoint] +pub struct MyContract { + value: StorageU256, + owner: StorageAddress, +} + +#[public] +impl MyContract { + #[constructor] + pub fn constructor(&mut self, initial_value: U256) { + self.value.set(initial_value); + self.owner.set(self.vm().msg_sender()); + } + + pub fn set_value(&mut self, new_value: U256) { + self.value.set(new_value); + } +} +``` + +### Key structural differences + +1. **Attributes over keywords**: Stylus uses Rust attributes (`#[storage]`, `#[entrypoint]`, `#[public]`) instead of Solidity keywords +2. **Explicit storage types**: Storage variables use special types like `StorageU256`, `StorageAddress` +3. **Getter/setter pattern**: Storage access requires explicit `.get()` and `.set()` calls +4. **Module system**: Rust uses `mod` and `use` for imports instead of `import` + +## Function visibility and state mutability + +### Visibility + +**Solidity:** + +```solidity +function publicFunc() public {} +function externalFunc() external {} +function internalFunc() internal {} +function privateFunc() private {} +``` + +**Stylus:** + +```rust +#[public] +impl MyContract { + // Public external functions + pub fn public_func(&self) {} + + // Internal functions (not in #[public] block) + fn internal_func(&self) {} + + // Private functions + fn private_func(&self) {} +} +``` + +In Stylus: + +- Functions in `#[public]` blocks are externally callable +- Regular `pub fn` outside `#[public]` blocks are internal +- Non-pub functions are private to the module + +### State mutability + +**Solidity:** + +```solidity +function viewFunc() public view returns (uint256) {} +function pureFunc() public pure returns (uint256) {} +function payableFunc() public payable {} +``` + +**Stylus:** + +```rust +#[public] +impl MyContract { + // View function (immutable reference) + pub fn view_func(&self) -> U256 { + self.value.get() + } + + // Pure function (no self reference) + pub fn pure_func(a: U256, b: U256) -> U256 { + a + b + } + + // Payable function + #[payable] + pub fn payable_func(&mut self) { + // Can receive Ether + } + + // Write function (mutable reference) + pub fn write_func(&mut self) { + self.value.set(U256::from(42)); + } +} +``` + +State mutability in Stylus is determined by: + +- `&self` โ†’ View (read-only) +- `&mut self` โ†’ Write (can modify storage) +- No `self` โ†’ Pure (no storage access) +- `#[payable]` โ†’ Can receive Ether + +## Constructors + +**Solidity:** + +```solidity +constructor(uint256 initialValue) { + value = initialValue; +} +``` + +**Stylus:** + +```rust +#[public] +impl MyContract { + #[constructor] + pub fn constructor(&mut self, initial_value: U256) { + self.value.set(initial_value); + } +} +``` + +Key differences: + +- Use `#[constructor]` attribute +- Constructor name is always `constructor` +- Can be marked `#[payable]` if needed +- Called only once during deployment +- Each contract struct can have only one constructor + +## Modifiers + +Solidity modifiers don't exist in Stylus. Instead, use regular Rust patterns. + +**Solidity:** + +```solidity +modifier onlyOwner() { + require(msg.sender == owner, "Not owner"); + _; +} + +function sensitiveFunction() public onlyOwner { + // Function logic +} +``` + +**Stylus:** + +```rust +impl MyContract { + fn only_owner(&self) -> Result<(), Vec> { + if self.owner.get() != self.vm().msg_sender() { + return Err(b"Not owner".to_vec()); + } + Ok(()) + } +} + +#[public] +impl MyContract { + pub fn sensitive_function(&mut self) -> Result<(), Vec> { + self.only_owner()?; + // Function logic + Ok(()) + } +} +``` + +Or using custom errors: + +```rust +sol! { + error Unauthorized(); +} + +#[derive(SolidityError)] +pub enum MyErrors { + Unauthorized(Unauthorized), +} + +impl MyContract { + fn only_owner(&self) -> Result<(), MyErrors> { + if self.owner.get() != self.vm().msg_sender() { + return Err(MyErrors::Unauthorized(Unauthorized {})); + } + Ok(()) + } +} +``` + +## Fallback and receive functions + +**Solidity:** + +```solidity +receive() external payable { + // Handle plain Ether transfers +} + +fallback() external payable { + // Handle unmatched calls +} +``` + +**Stylus:** + +```rust +#[public] +impl MyContract { + #[receive] + #[payable] + pub fn receive(&mut self) -> Result<(), Vec> { + // Handle plain Ether transfers + Ok(()) + } + + #[fallback] + #[payable] + pub fn fallback(&mut self, calldata: &[u8]) -> ArbResult { + // Handle unmatched calls + Ok(Vec::new()) + } +} +``` + +Key differences: + +- Use `#[receive]` and `#[fallback]` attributes +- Receive function takes no parameters +- Fallback function receives calldata as a parameter +- Both return `Result` types + +## Events + +**Solidity:** + +```solidity +event Transfer(address indexed from, address indexed to, uint256 value); + +function transfer() public { + emit Transfer(msg.sender, recipient, amount); +} +``` + +**Stylus:** + +```rust +sol! { + event Transfer(address indexed from, address indexed to, uint256 value); +} + +#[public] +impl MyContract { + pub fn transfer(&mut self, recipient: Address, amount: U256) { + self.vm().log(Transfer { + from: self.vm().msg_sender(), + to: recipient, + value: amount, + }); + } +} +``` + +Key differences: + +- Define events in `sol!` macro +- Emit using `self.vm().log()` +- Up to 3 parameters can be indexed +- Can also use `raw_log()` for custom logging + +## Error handling + +**Solidity:** + +```solidity +error InsufficientBalance(uint256 requested, uint256 available); + +function withdraw(uint256 amount) public { + if (balance < amount) { + revert InsufficientBalance(amount, balance); + } +} +``` + +**Stylus:** + +```rust +sol! { + error InsufficientBalance(uint256 requested, uint256 available); +} + +#[derive(SolidityError)] +pub enum MyErrors { + InsufficientBalance(InsufficientBalance), +} + +#[public] +impl MyContract { + pub fn withdraw(&mut self, amount: U256) -> Result<(), MyErrors> { + let balance = self.balance.get(); + if balance < amount { + return Err(MyErrors::InsufficientBalance(InsufficientBalance { + requested: amount, + available: balance, + })); + } + Ok(()) + } +} +``` + +Key differences: + +- Define errors in `sol!` macro +- Create error enum with `#[derive(SolidityError)]` +- Return `Result` +- Use Rust's `?` operator for error propagation + +## Inheritance + +**Solidity:** + +```solidity +contract Base { + function baseFoo() public virtual {} +} + +contract Derived is Base { + function baseFoo() public override {} +} +``` + +**Stylus:** + +```rust +#[public] +trait IBase { + fn base_foo(&self); +} + +#[storage] +struct Base {} + +#[public] +impl IBase for Base { + fn base_foo(&self) { + // Implementation + } +} + +#[storage] +#[entrypoint] +struct Derived { + base: Base, +} + +#[public] +#[implements(IBase)] +impl Derived {} + +#[public] +impl IBase for Derived { + fn base_foo(&self) { + // Override implementation + } +} +``` + +Key differences: + +- Use Rust traits for interfaces +- Composition through storage fields +- Use `#[implements()]` to expose inherited interfaces +- No `virtual` or `override` keywords + +## Storage + +### Storage slots + +**Solidity:** + +```solidity +uint256 public value; +mapping(address => uint256) public balances; +uint256[] public items; +``` + +**Stylus:** + +```rust +#[storage] +pub struct MyContract { + value: StorageU256, + balances: StorageMap, + items: StorageVec, +} +``` + +### Storage access + +**Solidity:** + +```solidity +value = 42; +uint256 x = value; +balances[user] = 100; +``` + +**Stylus:** + +```rust +self.value.set(U256::from(42)); +let x = self.value.get(); +self.balances.setter(user).set(U256::from(100)); +``` + +Key differences: + +- Explicit storage types (`Storage*`) +- Must use `.get()` and `.set()` +- Maps use `.setter()` for write access +- Storage layout is compatible with Solidity + +## Constants and immutables + +**Solidity:** + +```solidity +uint256 public constant MAX_SUPPLY = 1000000; +address public immutable OWNER; + +constructor() { + OWNER = msg.sender; +} +``` + +**Stylus:** + +```rust +const MAX_SUPPLY: u64 = 1000000; + +#[storage] +#[entrypoint] +pub struct MyContract { + owner: StorageAddress, // Set in constructor +} + +#[public] +impl MyContract { + #[constructor] + pub fn constructor(&mut self) { + self.owner.set(self.vm().msg_sender()); + } +} +``` + +Key differences: + +- Use Rust `const` for constants +- No direct equivalent to `immutable` (use storage set once in constructor) +- Constants can be defined outside structs + +## Type system + +### Integer types + +| Solidity | Stylus (Rust) | Notes | +| -------------------- | ---------------------- | ------------------------------------- | +| `uint8` to `uint256` | `u8` to `u128`, `U256` | Native Rust types or Alloy primitives | +| `int8` to `int256` | `i8` to `i128`, `I256` | Signed integers | +| `address` | `Address` | 20-byte addresses | +| `bytes` | `Bytes` | Dynamic bytes | +| `bytesN` | `FixedBytes` | Fixed-size bytes | +| `string` | `String` | UTF-8 strings | + +### Arrays and mappings + +| Solidity | Stylus (Rust) | Notes | +| ----------------------------- | ------------------------------------------------------------ | -------------- | +| `uint256[]` | `Vec` (memory)
`StorageVec` (storage) | Dynamic arrays | +| `uint256[5]` | `[U256; 5]` | Fixed arrays | +| `mapping(address => uint256)` | `StorageMap` | Key-value maps | + +## Global variables and functions + +### Block and transaction properties + +| Solidity | Stylus (Rust) | +| ----------------- | ----------------------------- | +| `msg.sender` | `self.vm().msg_sender()` | +| `msg.value` | `self.vm().msg_value()` | +| `msg.data` | Access through calldata | +| `tx.origin` | `self.vm().tx_origin()` | +| `tx.gasprice` | `self.vm().tx_gas_price()` | +| `block.number` | `self.vm().block_number()` | +| `block.timestamp` | `self.vm().block_timestamp()` | +| `block.basefee` | `self.vm().block_basefee()` | +| `block.coinbase` | `self.vm().block_coinbase()` | + +### Cryptographic functions + +| Solidity | Stylus (Rust) | +| ----------------- | ---------------------------------- | +| `keccak256(data)` | `self.vm().native_keccak256(data)` | +| `sha256(data)` | Use external crate | +| `ecrecover(...)` | Use `crypto::recover()` | + +## External calls + +**Solidity:** + +```solidity +(bool success, bytes memory data) = address.call{value: amount}(data); +``` + +**Stylus:** + +```rust +use stylus_sdk::call::RawCall; + +let result = unsafe { + RawCall::new(self.vm()) + .value(amount) + .call(address, &data) +}; +``` + +Key differences: + +- Use `RawCall` for raw calls +- Calls are `unsafe` in Rust +- Use type-safe interfaces when possible via `sol_interface!` + +## Contract deployment + +**Solidity:** + +```solidity +new MyContract{value: amount}(arg1, arg2); +``` + +**Stylus:** + +```rust +use stylus_sdk::deploy::RawDeploy; + +let contract_address = unsafe { + RawDeploy::new(self.vm()) + .value(amount) + .deploy(&bytecode, salt)? +}; +``` + +## Assembly + +**Solidity:** + +```solidity +assembly { + let x := mload(0x40) + sstore(0, x) +} +``` + +**Stylus:** + +Stylus does not support inline assembly. Instead: + +- Use hostio functions for low-level operations +- Use Rust's `unsafe` blocks when necessary +- Direct memory manipulation through safe Rust APIs + +## Features not in Stylus + +1. **No inline assembly**: Use hostio or safe Rust instead +2. **No `selfdestruct`**: Deprecated in Ethereum, not available in Stylus +3. **No `delegatecall` from storage**: Available but requires careful use +4. **No modifier syntax**: Use regular functions +5. **No multiple inheritance complexity**: Use trait-based composition + +## Features unique to Stylus + +1. **Rust's type system**: Strong compile-time guarantees +2. **Zero-cost abstractions**: No overhead for safe code patterns +3. **Cargo ecosystem**: Access to thousands of Rust crates +4. **Memory safety**: Rust's borrow checker prevents common bugs +5. **Better performance**: Wasm execution can be more efficient +6. **Testing framework**: Use Rust's built-in testing with `TestVM` + +## Memory and gas costs + +### Memory management + +- **Solidity**: Automatic memory management with gas costs for allocation +- **Stylus**: Manual control with Rust's ownership system, more efficient memory usage + +### Gas efficiency + +Stylus programs typically use less gas than equivalent Solidity: + +- More efficient Wasm execution +- Better compiler optimizations +- Fine-grained control over allocations + +## Development workflow + +### Compilation + +**Solidity:** + +```shell +solc --bin --abi MyContract.sol +``` + +**Stylus:** + +```shell +cargo stylus build +``` + +### Testing + +**Solidity:** + +```javascript +// Hardhat or Foundry tests +``` + +**Stylus:** + +```rust +#[cfg(test)] +mod tests { + use super::*; + use stylus_sdk::testing::*; + + #[test] + fn test_function() { + let vm = TestVM::default(); + let mut contract = MyContract::from(&vm); + // Test logic + } +} +``` + +### Deployment + +Both use similar deployment processes but Stylus requires an activation step for new programs. + +## Interoperability + +Stylus and Solidity contracts can fully interact: + +- Stylus can call Solidity contracts +- Solidity can call Stylus contracts +- Same ABI encoding/decoding +- Share storage layout compatibility + +Example calling Solidity from Stylus: + +```rust +sol_interface! { + interface IToken { + function transfer(address to, uint256 amount) external returns (bool); + } +} + +#[public] +impl MyContract { + pub fn call_token(&self, token: Address, recipient: Address, amount: U256) -> Result> { + let token_contract = IToken::new(token); + let result = token_contract.transfer(self.vm(), recipient, amount)?; + Ok(result) + } +} +``` + +## Best practices for transitioning + +1. **Think in Rust patterns**: Don't translate Solidity directly, use idiomatic Rust +2. **Leverage the type system**: Use Rust's types to prevent bugs at compile time +3. **Use composition over inheritance**: Prefer traits and composition +4. **Handle errors explicitly**: Use `Result` types and the `?` operator +5. **Write tests in Rust**: Take advantage of `TestVM` for unit testing +6. **Read existing examples**: Study the stylus-sdk-rs examples directory +7. **Start small**: Convert simple contracts first to learn the patterns + +## Resources + +- [Stylus SDK Documentation](https://docs.arbitrum.io/stylus/reference/stylus-sdk) +- [stylus-sdk-rs Repository](https://github.com/OffchainLabs/stylus-sdk-rs) +- [Example Contracts](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/examples) +- [Rust Book](https://doc.rust-lang.org/book/) for learning Rust From 4367240c57c0977b0ec12659c47feb6430332b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:29:09 -0800 Subject: [PATCH 043/162] Document Stylus hostio exports Add comprehensive documentation for hostio (Host I/O) exports in Stylus smart contracts. Covers: - Overview of hostio as low-level VM runtime functions - How hostio works as WebAssembly imports - Complete function reference organized by category: - Account operations (balance, code, codehash) - Storage operations (load, cache, flush) with caching benefits - Block information (basefee, number, timestamp, etc.) - Transaction context (msg_sender, msg_value, tx_origin, etc.) - Contract calls (call, delegate_call, static_call) with 63/64 rule - Contract deployment (create1, create2) with WASM support - Events and logging (emit_log) with topic limits - Gas and ink metering (evm_gas_left, evm_ink_left) - Cryptography (native_keccak256) - Calldata operations (read_args, read_return_data, write_result) - Debug console functions (log_txt, log_i32, etc.) - Safety considerations for unsafe operations - Higher-level SDK wrappers for safe usage - Feature flags (export-abi, stylus-test, debug) - Performance considerations (storage caching, ink vs gas) - Common patterns (check-effects-interactions, event logging) - Testing with TestVM - Best practices for safe hostio usage Based on stylus-sdk-rs hostio.rs, debug.rs, call/raw.rs, and crypto.rs implementations with EVM opcode equivalents. --- docs/stylus/advanced/hostio-exports.mdx | 871 +++++++++++++++++++++++- 1 file changed, 869 insertions(+), 2 deletions(-) diff --git a/docs/stylus/advanced/hostio-exports.mdx b/docs/stylus/advanced/hostio-exports.mdx index 8dc22dfa6b..85849bc4dc 100644 --- a/docs/stylus/advanced/hostio-exports.mdx +++ b/docs/stylus/advanced/hostio-exports.mdx @@ -1,6 +1,6 @@ --- title: 'Hostio exports' -description: 'Hostio exports' +description: 'Learn about low-level hostio functions for direct VM access in Stylus smart contracts' author: chrisco sme: chrisco sidebar_position: 1 @@ -8,4 +8,871 @@ target_audience: Developers who need to understand how to use hostio exports wit displayed_sidebar: buildAppsSidebar --- -TBD +Hostio (Host I/O) exports are low-level functions that provide direct access to the Stylus VM runtime. These functions are WebAssembly imports that allow Stylus programs to interact with the blockchain environment, similar to how EVM opcodes work in Solidity. + +## Overview + +Hostio functions are the foundational layer that powers all Stylus smart contract operations. While most developers will use the higher-level SDK abstractions, understanding hostio functions is valuable for: + +- Performance optimization through direct VM access +- Implementing custom low-level operations +- Understanding gas costs and execution flow +- Debugging and troubleshooting contract behavior + +:::info +Most developers should use the high-level SDK wrappers instead of calling hostio functions directly. The SDK provides safe, ergonomic interfaces that handle memory management and error checking automatically. +::: + +## How hostio works + +Hostio functions are WebAssembly imports defined in the `vm_hooks` module. When a Stylus program is compiled to WASM, these functions are linked at runtime by the Arbitrum VM: + +```rust +#[link(wasm_import_module = "vm_hooks")] +extern "C" { + pub fn msg_sender(sender: *mut u8); + pub fn block_number() -> u64; + // ... more functions +} +``` + +During execution, calls to these functions are intercepted by the Stylus VM, which implements the actual functionality using the underlying ArbOS infrastructure. + +## Function categories + +Hostio functions are organized into several categories based on their purpose. + +### Account operations + +Query information about accounts on the blockchain. + +#### `account_balance` + +Gets the ETH balance of an account in wei. Equivalent to EVM's `BALANCE` opcode. + +```rust +pub fn account_balance(address: *const u8, dest: *mut u8); +``` + +**Parameters:** + +- `address`: Pointer to 20-byte address +- `dest`: Pointer to write 32-byte balance value + +**Usage:** + +```rust +use stylus_sdk::alloy_primitives::{Address, U256}; + +unsafe { + let addr = Address::from([0x11; 20]); + let mut balance_bytes = [0u8; 32]; + hostio::account_balance(addr.as_ptr(), balance_bytes.as_mut_ptr()); + let balance = U256::from_be_bytes(balance_bytes); +} +``` + +#### `account_code` + +Gets a subset of code from an account. Equivalent to EVM's `EXTCODECOPY` opcode. + +```rust +pub fn account_code( + address: *const u8, + offset: usize, + size: usize, + dest: *mut u8 +) -> usize; +``` + +**Returns:** Number of bytes actually written + +#### `account_code_size` + +Gets the size of code at an address. Equivalent to EVM's `EXTCODESIZE` opcode. + +```rust +pub fn account_code_size(address: *const u8) -> usize; +``` + +#### `account_codehash` + +Gets the code hash of an account. Equivalent to EVM's `EXTCODEHASH` opcode. + +```rust +pub fn account_codehash(address: *const u8, dest: *mut u8); +``` + +:::note +Empty accounts return the keccak256 hash of empty bytes: `c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470` +::: + +### Storage operations + +Interact with persistent contract storage. + +#### `storage_load_bytes32` + +Reads a 32-byte value from storage. Equivalent to EVM's `SLOAD` opcode. + +```rust +pub fn storage_load_bytes32(key: *const u8, dest: *mut u8); +``` + +**Parameters:** + +- `key`: Pointer to 32-byte storage key +- `dest`: Pointer to write 32-byte value + +#### `storage_cache_bytes32` + +Writes a 32-byte value to the storage cache. Equivalent to EVM's `SSTORE` opcode. + +```rust +pub fn storage_cache_bytes32(key: *const u8, value: *const u8); +``` + +:::warning +Values are cached and must be persisted using `storage_flush_cache` before they're permanently written to storage. +::: + +#### `storage_flush_cache` + +Persists cached storage values to the EVM state trie. Equivalent to multiple `SSTORE` operations. + +```rust +pub fn storage_flush_cache(clear: bool); +``` + +**Parameters:** + +- `clear`: Whether to drop the cache entirely after flushing + +**Storage caching benefits:** + +The Stylus VM implements storage caching for improved performance: + +- Repeated reads of the same key cost less gas +- Writes are batched for efficiency +- Cache is automatically managed by the SDK + +### Block information + +Access information about the current block. + +#### `block_basefee` + +Gets the basefee of the current block. Equivalent to EVM's `BASEFEE` opcode. + +```rust +pub fn block_basefee(basefee: *mut u8); +``` + +#### `block_chainid` + +Gets the chain identifier. Equivalent to EVM's `CHAINID` opcode. + +```rust +pub fn chainid() -> u64; +``` + +#### `block_coinbase` + +Gets the coinbase (block producer address). On Arbitrum, this is the L1 batch poster's address. + +```rust +pub fn block_coinbase(coinbase: *mut u8); +``` + +#### `block_gas_limit` + +Gets the gas limit of the current block. Equivalent to EVM's `GASLIMIT` opcode. + +```rust +pub fn block_gas_limit() -> u64; +``` + +#### `block_number` + +Gets a bounded estimate of the L1 block number when the transaction was sequenced. + +```rust +pub fn block_number() -> u64; +``` + +:::info +See [Arbitrum block numbers and time](https://developer.arbitrum.io/time) for more information on how block numbers work on Arbitrum chains. +::: + +#### `block_timestamp` + +Gets a bounded estimate of the Unix timestamp when the transaction was sequenced. + +```rust +pub fn block_timestamp() -> u64; +``` + +### Transaction and message context + +Access information about the current transaction and call context. + +#### `msg_sender` + +Gets the address of the caller. Equivalent to EVM's `CALLER` opcode. + +```rust +pub fn msg_sender(sender: *mut u8); +``` + +**Parameters:** + +- `sender`: Pointer to write 20-byte address + +:::note +For L1-to-L2 retryable ticket transactions, addresses are aliased. See [address aliasing documentation](https://developer.arbitrum.io/arbos/l1-to-l2-messaging#address-aliasing). +::: + +#### `msg_value` + +Gets the ETH value sent with the call in wei. Equivalent to EVM's `CALLVALUE` opcode. + +```rust +pub fn msg_value(value: *mut u8); +``` + +#### `msg_reentrant` + +Checks if the current call is reentrant. + +```rust +pub fn msg_reentrant() -> bool; +``` + +#### `tx_gas_price` + +Gets the gas price in wei per gas. On Arbitrum, this equals the basefee. Equivalent to EVM's `GASPRICE` opcode. + +```rust +pub fn tx_gas_price(gas_price: *mut u8); +``` + +#### `tx_origin` + +Gets the top-level sender of the transaction. Equivalent to EVM's `ORIGIN` opcode. + +```rust +pub fn tx_origin(origin: *mut u8); +``` + +#### `tx_ink_price` + +Gets the price of ink in EVM gas basis points. See [Ink and Gas](https://docs.arbitrum.io/stylus/concepts/gas-metering) for more information. + +```rust +pub fn tx_ink_price() -> u32; +``` + +### Contract calls + +Make calls to other contracts. + +#### `call_contract` + +Calls another contract with optional value and gas limit. Equivalent to EVM's `CALL` opcode. + +```rust +pub fn call_contract( + contract: *const u8, + calldata: *const u8, + calldata_len: usize, + value: *const u8, + gas: u64, + return_data_len: *mut usize +) -> u8; +``` + +**Parameters:** + +- `contract`: Pointer to 20-byte contract address +- `calldata`: Pointer to calldata bytes +- `calldata_len`: Length of calldata +- `value`: Pointer to 32-byte value in wei (use 0 for no value) +- `gas`: Gas to supply (use `u64::MAX` for all available gas) +- `return_data_len`: Pointer to store length of return data + +**Returns:** `0` on success, non-zero on failure + +**Gas rules:** + +- Follows the 63/64 rule (at most 63/64 of available gas is forwarded) +- Includes callvalue stipend when value is sent + +**Usage:** + +```rust +use stylus_sdk::call::RawCall; + +unsafe { + let result = RawCall::new(self.vm()) + .gas(100_000) + .value(U256::from(1_000_000)) + .call(contract_address, &calldata)?; +} +``` + +#### `delegate_call_contract` + +Delegate calls another contract. Equivalent to EVM's `DELEGATECALL` opcode. + +```rust +pub fn delegate_call_contract( + contract: *const u8, + calldata: *const u8, + calldata_len: usize, + gas: u64, + return_data_len: *mut usize +) -> u8; +``` + +:::warning +Delegate calls execute code in the context of the current contract. Be extremely careful when delegate calling to untrusted contracts as they have full access to your storage. +::: + +#### `static_call_contract` + +Static calls another contract (read-only). Equivalent to EVM's `STATICCALL` opcode. + +```rust +pub fn static_call_contract( + contract: *const u8, + calldata: *const u8, + calldata_len: usize, + gas: u64, + return_data_len: *mut usize +) -> u8; +``` + +### Contract deployment + +Deploy new contracts. + +#### `create1` + +Deploys a contract using CREATE. Equivalent to EVM's `CREATE` opcode. + +```rust +pub fn create1( + code: *const u8, + code_len: usize, + endowment: *const u8, + contract: *mut u8, + revert_data_len: *mut usize +); +``` + +**Parameters:** + +- `code`: Pointer to initialization code (EVM bytecode) +- `code_len`: Length of initialization code +- `endowment`: Pointer to 32-byte value to send +- `contract`: Pointer to write deployed contract address (20 bytes) +- `revert_data_len`: Pointer to store revert data length on failure + +**Deployment rules:** + +- Init code must be EVM bytecode +- Deployed code can be Stylus (WASM) if it starts with `0xEFF000` header +- Address is determined by sender and nonce +- On failure, address will be zero + +#### `create2` + +Deploys a contract using CREATE2. Equivalent to EVM's `CREATE2` opcode. + +```rust +pub fn create2( + code: *const u8, + code_len: usize, + endowment: *const u8, + salt: *const u8, + contract: *mut u8, + revert_data_len: *mut usize +); +``` + +**Parameters:** + +- `salt`: Pointer to 32-byte salt value + +**Address calculation:** + +- Address is deterministic based on sender, salt, and init code hash +- Allows for pre-computed addresses + +### Events and logging + +Emit events to the blockchain. + +#### `emit_log` + +Emits an EVM log with topics and data. Equivalent to EVM's `LOG0`-`LOG4` opcodes. + +```rust +pub fn emit_log(data: *const u8, len: usize, topics: usize); +``` + +**Parameters:** + +- `data`: Pointer to event data (first bytes should be 32-byte aligned topics) +- `len`: Total length of data including topics +- `topics`: Number of topics (0-4) + +:::warning +Requesting more than 4 topics will cause a revert. +::: + +**Higher-level usage:** + +```rust +sol! { + event Transfer(address indexed from, address indexed to, uint256 value); +} + +// Emit using the SDK +self.vm().log(Transfer { + from: sender, + to: recipient, + value: amount, +}); +``` + +### Gas and ink metering + +Monitor execution costs. + +#### `evm_gas_left` + +Gets the amount of gas remaining. Equivalent to EVM's `GAS` opcode. + +```rust +pub fn evm_gas_left() -> u64; +``` + +#### `evm_ink_left` + +Gets the amount of ink remaining. Stylus-specific metering unit. + +```rust +pub fn evm_ink_left() -> u64; +``` + +:::info +Ink is Stylus's compute pricing unit. See [Ink and Gas](https://docs.arbitrum.io/stylus/concepts/gas-metering) for conversion between ink and gas. +::: + +#### `pay_for_memory_grow` + +Pays for WASM memory growth. Automatically called when allocating new pages. + +```rust +pub fn pay_for_memory_grow(pages: u16); +``` + +:::note +The `entrypoint!` macro handles importing this hostio. Manual calls will unproductively consume gas. +::: + +### Cryptography + +Cryptographic operations. + +#### `native_keccak256` + +Efficiently computes keccak256 hash. Equivalent to EVM's `SHA3` opcode. + +```rust +pub fn native_keccak256(bytes: *const u8, len: usize, output: *mut u8); +``` + +**Parameters:** + +- `bytes`: Pointer to input data +- `len`: Length of input data +- `output`: Pointer to write 32-byte hash + +**Higher-level usage:** + +```rust +use stylus_sdk::crypto::keccak; + +let hash = keccak(b"hello world"); +``` + +### Calldata operations + +Read and write calldata and return data. + +#### `read_args` + +Reads the program calldata. Equivalent to EVM's `CALLDATACOPY` opcode. + +```rust +pub fn read_args(dest: *mut u8); +``` + +:::note +This reads the entirety of the call's calldata. +::: + +#### `read_return_data` + +Copies bytes from the last call or deployment return result. Equivalent to EVM's `RETURNDATACOPY` opcode. + +```rust +pub fn read_return_data(dest: *mut u8, offset: usize, size: usize) -> usize; +``` + +**Parameters:** + +- `dest`: Destination buffer +- `offset`: Offset in return data to start copying from +- `size`: Number of bytes to copy + +**Returns:** Number of bytes actually written + +**Behavior:** + +- Does not revert if out of bounds +- Copies overlapping portion only + +#### `return_data_size` + +Gets the length of the last return result. Equivalent to EVM's `RETURNDATASIZE` opcode. + +```rust +pub fn return_data_size() -> usize; +``` + +#### `write_result` + +Writes the final return data for the current call. + +```rust +pub fn write_result(data: *const u8, len: usize); +``` + +**Behavior:** + +- Does not cause program to exit +- If not called, return data will be empty +- Program exits naturally when entrypoint returns + +#### `contract_address` + +Gets the address of the current program. Equivalent to EVM's `ADDRESS` opcode. + +```rust +pub fn contract_address(address: *mut u8); +``` + +### Debug and console + +Debug-only functions for development. + +#### `log_txt` + +Prints UTF-8 text to console. Only available in debug mode. + +```rust +pub fn log_txt(text: *const u8, len: usize); +``` + +#### `log_i32` / `log_i64` + +Prints integers to console. Only available in debug mode. + +```rust +pub fn log_i32(value: i32); +pub fn log_i64(value: i64); +``` + +#### `log_f32` / `log_f64` + +Prints floating-point numbers to console. Only available in debug mode with floating point enabled. + +```rust +pub fn log_f32(value: f32); +pub fn log_f64(value: f64); +``` + +**Higher-level usage:** + +```rust +use stylus_sdk::console; + +console!("Value: {}", value); // Prints in debug mode, no-op in production +``` + +## Safety considerations + +All hostio functions are marked `unsafe` because they: + +1. **Operate on raw pointers**: Require correct memory management +2. **Lack bounds checking**: Can cause undefined behavior if pointers are invalid +3. **Have side effects**: Can modify contract state or make external calls +4. **May revert**: Some operations can cause the transaction to revert + +### Safe usage patterns + +**Always validate inputs:** + +```rust +// Bad: unchecked pointer usage +unsafe { + hostio::msg_sender(ptr); // ptr might be invalid +} + +// Good: use safe wrappers +let sender = self.vm().msg_sender(); +``` + +**Use SDK wrappers:** + +```rust +// Bad: direct hostio call +unsafe { + let mut balance = [0u8; 32]; + hostio::account_balance(addr.as_ptr(), balance.as_mut_ptr()); +} + +// Good: use SDK wrapper +use stylus_sdk::evm; +let balance = evm::balance(addr); +``` + +**Handle return values:** + +```rust +// Check return status from calls +let status = unsafe { + hostio::call_contract( + contract.as_ptr(), + calldata.as_ptr(), + calldata.len(), + value.as_ptr(), + gas, + &mut return_len, + ) +}; + +if status != 0 { + // Handle call failure +} +``` + +## Higher-level wrappers + +The Stylus SDK provides safe, ergonomic wrappers around hostio functions: + +### Storage operations + +```rust +// Instead of direct hostio: +unsafe { + hostio::storage_load_bytes32(key.as_ptr(), dest.as_mut_ptr()); +} + +// Use storage types: +use stylus_sdk::storage::StorageU256; + +#[storage] +pub struct Contract { + value: StorageU256, +} + +let value = self.value.get(); // Safe, ergonomic +``` + +### Contract calls + +```rust +// Instead of direct hostio: +unsafe { + hostio::call_contract(/* many parameters */); +} + +// Use RawCall or typed interfaces: +use stylus_sdk::call::RawCall; + +let result = unsafe { + RawCall::new(self.vm()) + .gas(100_000) + .call(contract, &calldata)? +}; +``` + +### VM context + +```rust +// Instead of direct hostio: +unsafe { + let mut sender = [0u8; 20]; + hostio::msg_sender(sender.as_mut_ptr()); +} + +// Use VM accessor: +let sender = self.vm().msg_sender(); +let value = self.vm().msg_value(); +let timestamp = self.vm().block_timestamp(); +``` + +## Feature flags + +Hostio behavior changes based on feature flags: + +### `export-abi` + +When enabled, hostio functions are stubbed and return `unimplemented!()`. Used for ABI generation. + +### `stylus-test` + +When enabled, hostio functions panic with an error message. Use `TestVM` for testing instead. + +### `debug` + +When enabled, console logging functions become available. In production, console functions are no-ops. + +## Performance considerations + +### Direct hostio vs SDK wrappers + +- **Direct hostio**: Slightly lower overhead, requires manual memory management +- **SDK wrappers**: Minimal overhead (often zero-cost abstractions), much safer + +**Recommendation:** Use SDK wrappers unless profiling shows a specific performance bottleneck. + +### Storage caching + +The Stylus VM automatically caches storage operations: + +```rust +// First read: full SLOAD cost +let value1 = storage.value.get(); + +// Subsequent reads: reduced cost from cache +let value2 = storage.value.get(); + +// Writes are cached until flush +storage.value.set(new_value); // Cached + +// Cache is flushed automatically at call boundaries +``` + +### Gas vs ink + +Stylus uses "ink" for fine-grained gas metering: + +- **Ink**: WASM execution cost in Stylus-specific units +- **Gas**: Standard EVM gas units +- Conversion happens automatically + +Most developers don't need to think about ink vs gas distinction. + +## Common patterns + +### Check-effects-interactions pattern + +```rust +#[public] +impl MyContract { + pub fn transfer(&mut self, to: Address, amount: U256) -> Result<(), Vec> { + // Checks + let sender = self.vm().msg_sender(); + let balance = self.balances.get(sender); + if balance < amount { + return Err(b"Insufficient balance".to_vec()); + } + + // Effects + self.balances.setter(sender).set(balance - amount); + self.balances.setter(to).set(self.balances.get(to) + amount); + + // Interactions (if any) + Ok(()) + } +} +``` + +### Efficient event logging + +```rust +sol! { + event DataUpdated(bytes32 indexed key, uint256 value); +} + +// SDK handles hostio::emit_log internally +self.vm().log(DataUpdated { + key: key_hash, + value: new_value, +}); +``` + +### Gas-limited external calls + +```rust +use stylus_sdk::call::RawCall; + +// Limit gas to prevent griefing +let result = unsafe { + RawCall::new(self.vm()) + .gas(50_000) // Fixed gas limit + .call(untrusted_contract, &calldata) +}; + +match result { + Ok(data) => { /* process return data */ }, + Err(_) => { /* handle failure gracefully */ }, +} +``` + +## Testing with hostio + +Hostio functions are not available in the test environment. Use `TestVM` instead: + +```rust +#[cfg(test)] +mod tests { + use super::*; + use stylus_sdk::testing::*; + + #[test] + fn test_function() { + let vm = TestVM::default(); + let mut contract = MyContract::from(&vm); + + // VM functions work in tests + let sender = vm.msg_sender(); // Works + + // Direct hostio would panic + // unsafe { hostio::msg_sender(...) } // Would panic + } +} +``` + +## Resources + +- [Stylus VM specification](https://github.com/OffchainLabs/stylus) +- [EVM opcodes reference](https://www.evm.codes/) +- [Arbitrum block numbers and time](https://developer.arbitrum.io/time) +- [Ink and gas metering](https://docs.arbitrum.io/stylus/concepts/gas-metering) +- [stylus-sdk-rs source](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/stylus-sdk/src/hostio.rs) + +## Best practices + +1. **Use SDK wrappers**: Prefer high-level abstractions over direct hostio calls +2. **Validate inputs**: Always check pointers and sizes before unsafe operations +3. **Handle errors**: Check return values from call operations +4. **Test thoroughly**: Use `TestVM` for comprehensive testing +5. **Profile first**: Only optimize to direct hostio if profiling shows it's necessary +6. **Document unsafe code**: Always document why `unsafe` is necessary +7. **Minimize unsafe blocks**: Keep `unsafe` blocks as small as possible From 8c3adb1e04bc8119d0884c82b87072a43929e8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:29:50 -0800 Subject: [PATCH 044/162] fix duplicate entry in sidebars.js --- sidebars.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sidebars.js b/sidebars.js index 898a9d6b10..c859168371 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1346,11 +1346,6 @@ const sidebars = { id: 'stylus/how-tos/caching-contracts', label: 'Caching Strategy', }, - { - type: 'doc', - id: 'stylus/how-tos/caching-contracts', - label: 'Caching Strategy', - }, ], }, { From d9e5a0db5bdfb9e6e097ab82dc1c2a54da74927e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:38:44 -0800 Subject: [PATCH 045/162] Document EVM and WASM VM differences in Stylus Add comprehensive documentation comparing EVM and Nitro WASM VM. Covers: - Execution model differences (stack-based vs register-based) - Memory model (32-byte chunks vs 64KB pages) - Gas metering with ink system and conversion formula - Instruction sets (EVM opcodes vs WASM instructions) - Size limits (24KB for both with optimization notes) - Storage model compatibility and caching benefits - Performance characteristics (10-100x cheaper compute) - Call semantics and interoperability examples - Contract lifecycle (deployment, activation, execution) - Developer experience comparison - Feature compatibility matrix - State sharing across VMs - Gas economics and cost structures - Best practices for each environment - Hybrid approach strategies - Migration considerations from Solidity to Stylus - Future developments for both platforms Includes practical examples of: - Memory growth with pay_for_memory_grow - Storage caching in Stylus - Cross-VM contract calls - Hybrid contract architectures Based on stylus-sdk-rs implementation including hostio.rs, entrypoint.rs, host.rs, and SDK examples showing WASM execution patterns compared to traditional EVM operations. --- docs/stylus/concepts/evm-differences.mdx | 637 ++++++++++++++++++++++- 1 file changed, 630 insertions(+), 7 deletions(-) diff --git a/docs/stylus/concepts/evm-differences.mdx b/docs/stylus/concepts/evm-differences.mdx index 720af77c48..37535cf2e5 100644 --- a/docs/stylus/concepts/evm-differences.mdx +++ b/docs/stylus/concepts/evm-differences.mdx @@ -1,15 +1,638 @@ --- -title: 'evm-differences' -description: 'EVM-differences' +title: 'EVM and WASM VM differences' +description: 'Understand the key differences between the traditional EVM and Nitro WASM VM for Stylus contracts' author: chrisco sme: chrisco sidebar_position: 1 -target_audience: Developers who need to understand how Stylus works with evm-differences. +target_audience: Developers who need to understand how Stylus works with EVM differences. displayed_sidebar: buildAppsSidebar --- -- Size limits -- Ink and gas -- Memory and compute +Arbitrum Nitro supports two execution environments: the traditional Ethereum Virtual Machine (EVM) for Solidity contracts and a WebAssembly (WASM) VM for Stylus contracts. While both environments are fully interoperable and share the same state, they differ significantly in their execution models, performance characteristics, and developer experience. -TBD +## Execution model + +### EVM: Stack-based architecture + +The EVM uses a stack-based execution model: + +- **Operations**: Work with values on a stack (PUSH, POP, ADD, etc.) +- **Opcodes**: 256 predefined opcodes with fixed gas costs +- **Memory**: Linear, byte-addressable memory that grows dynamically +- **Storage**: 256-bit word-based key-value store +- **Call depth**: Limited to 1024 levels + +**Example EVM execution:** + +``` +PUSH1 0x02 // Push 2 onto stack +PUSH1 0x03 // Push 3 onto stack +ADD // Pop 2 values, push sum (5) +``` + +### WASM: Register-based architecture + +The Stylus WASM VM uses a register-based execution model: + +- **Operations**: Work with virtual registers and local variables +- **Instructions**: Thousands of WASM instructions with fine-grained metering +- **Memory**: Linear memory with explicit grow operations +- **Storage**: Same 256-bit storage as EVM (shared state) +- **Call depth**: Same 1024 limit for compatibility + +**Example WASM execution:** + +```wasm +(local.get 0) ;; Read from local variable 0 +(local.get 1) ;; Read from local variable 1 +(i32.add) ;; Add and store result +(local.set 2) ;; Store in local variable 2 +``` + +## Memory model + +### EVM memory + +- **Dynamic expansion**: Memory grows in 32-byte chunks +- **Gas cost**: Quadratic growth (memory expansion gets expensive) +- **Access pattern**: Byte-level addressing +- **Limit**: Practical limit around 15 MB due to gas costs + +### WASM memory + +- **Page-based**: Memory grows in 64 KB pages (WASM standard) +- **Gas cost**: Linear cost per page through `pay_for_memory_grow` +- **Access pattern**: Direct memory load/store instructions +- **Limit**: Can grow much larger efficiently + +**Memory growth in Stylus:** + +```rust +// The entrypoint macro automatically handles pay_for_memory_grow +#[entrypoint] +pub struct MyContract { + // Large data structures are more practical in WASM + data: StorageVec, +} + +// Nitro automatically inserts pay_for_memory_grow calls +// when allocating new pages +let large_vector = vec![0u8; 100_000]; // Efficient in WASM +``` + +:::note +The Stylus SDK's `entrypoint!` macro includes a no-op call to `pay_for_memory_grow` to ensure the function is referenced. Nitro then automatically inserts actual calls when memory allocation occurs. +::: + +## Gas metering: Ink and gas + +### EVM gas metering + +- **Unit**: Gas (standard Ethereum unit) +- **Granularity**: Per opcode (e.g., ADD = 3 gas, SSTORE = 20,000 gas) +- **Measurement**: Coarse-grained +- **Refunds**: Available for storage deletions + +### Stylus ink metering + +Stylus introduces "ink" as a fine-grained metering unit: + +- **Unit**: Ink (Stylus-specific, converted to gas) +- **Granularity**: Per WASM instruction (more fine-grained) +- **Measurement**: Precise tracking of WASM execution costs +- **Conversion**: Ink โ†’ Gas conversion happens automatically + +**Ink to gas conversion:** + +```rust +// Check remaining ink +let ink_left = evm_ink_left(); + +// Check remaining gas +let gas_left = evm_gas_left(); + +// Get ink price (in gas basis points) +let ink_price = tx_ink_price(); + +// Conversion formula: +// gas = ink * ink_price / 10000 +``` + +**Why ink?** + +1. **Precision**: WASM instructions have varying costs that don't map cleanly to EVM gas +2. **Efficiency**: Fine-grained metering allows for more accurate pricing +3. **Performance**: Enables cheaper execution for compute-heavy operations +4. **Flexibility**: Ink prices can be adjusted without changing contract code + +**Gas cost comparison:** + +| Operation | EVM Gas | Stylus Gas | Improvement | +| ------------------- | --------- | ---------- | --------------- | +| Basic arithmetic | 3-5 | ~1-2 | 2-3x cheaper | +| Memory operations | Variable | Efficient | 10-100x cheaper | +| Complex computation | Expensive | Cheap | 10-100x cheaper | +| Storage operations | Same | Same | Equal | +| External calls | Same | Same | Equal | + +## Instruction sets + +### EVM opcodes + +- **Count**: ~140 opcodes +- **Categories**: Arithmetic, logic, storage, flow control, system +- **Size**: 1 byte per opcode +- **Examples**: + - `ADD`, `MUL`, `SUB`, `DIV` (arithmetic) + - `SLOAD`, `SSTORE` (storage) + - `CALL`, `DELEGATECALL` (calls) + - `SHA3` (hashing) + +### WASM instructions + +- **Count**: Hundreds of instructions +- **Categories**: Numeric, memory, control flow, function calls +- **Size**: Variable encoding (1-5 bytes) +- **Examples**: + - `i32.add`, `i64.mul`, `f64.div` (numeric) + - `memory.grow`, `memory.size` (memory) + - `call`, `call_indirect` (functions) + - Hostio imports (system operations) + +**WASM advantages:** + +- More expressive instruction set +- Better compiler optimization targets +- Efficient handling of complex data structures +- Native support for 32-bit and 64-bit operations + +## Size limits + +### EVM contracts + +- **Maximum size**: 24,576 bytes (24 KB) of deployed bytecode +- **Limit reason**: Block gas limit and deployment costs +- **Workaround**: Contract splitting, proxies + +### Stylus contracts + +- **Initial limit**: 24 KB (same as EVM for compatibility) +- **Compressed size**: Can be larger before compression +- **Future**: Limit may be increased as WASM tooling improves +- **Practical size**: Stylus programs are often smaller due to efficient compilation + +**Size optimization:** + +```rust +// Stylus contracts benefit from: +// 1. Rust's zero-cost abstractions +// 2. Dead code elimination by wasm-opt +// 3. Efficient WASM encoding + +#[no_std] // Opt out of standard library for smaller binaries +extern crate alloc; + +// Only the code actually used is included +use stylus_sdk::prelude::*; +``` + +## Storage model + +Both EVM and WASM contracts use the **same storage system**: + +- **Format**: 256-bit key-value store +- **Compatibility**: EVM and WASM contracts can share storage +- **Costs**: SLOAD and SSTORE costs are identical +- **Caching**: Stylus VM implements storage caching for efficiency + +### Storage caching in Stylus + +```rust +use stylus_sdk::prelude::*; + +#[storage] +pub struct Counter { + count: StorageU256, +} + +#[public] +impl Counter { + pub fn increment(&mut self) { + // First read: full SLOAD cost + let current = self.count.get(); + + // Write is cached + self.count.set(current + U256::from(1)); + + // Additional reads in same call are cheaper (cached) + let new_value = self.count.get(); + + // Cache is automatically flushed at call boundary + } +} +``` + +**Cache benefits:** + +1. **Reduced gas costs**: Repeated reads are cheaper +2. **Better performance**: Fewer state trie accesses +3. **Automatic management**: SDK handles cache flushing +4. **Compatibility**: Refund logic matches EVM exactly + +## Performance characteristics + +### Compute operations + +| Category | EVM | Stylus WASM | Winner | +| ------------------- | --------- | ----------- | ------------ | +| Integer arithmetic | Moderate | Fast | WASM (10x+) | +| Loops | Expensive | Cheap | WASM (100x+) | +| Memory copying | Expensive | Cheap | WASM (10x+) | +| Hashing (keccak256) | Native | Native | Equal | +| Cryptography | Limited | Efficient | WASM | +| String operations | Expensive | Cheap | WASM (100x+) | + +### Storage operations + +| Operation | EVM | Stylus WASM | Winner | +| --------------- | ---------- | ----------- | ------ | +| SLOAD | 2,100 gas | 2,100 gas | Equal | +| SSTORE (new) | 20,000 gas | 20,000 gas | Equal | +| SSTORE (update) | 5,000 gas | 5,000 gas | Equal | +| Storage refunds | Standard | Standard | Equal | +| Cached reads | No | Yes | WASM | + +### External interactions + +| Operation | EVM | Stylus WASM | Winner | +| -------------------- | ------------- | ------------- | ------ | +| Contract calls | ~700 gas base | ~700 gas base | Equal | +| Cross-language calls | N/A | Efficient | WASM | +| Event emission | Same cost | Same cost | Equal | +| Value transfers | Same cost | Same cost | Equal | + +## Call semantics + +### Interoperability + +Both environments support seamless interoperability: + +```rust +// Stylus calling Solidity +sol_interface! { + interface IERC20 { + function transfer(address to, uint256 amount) external returns (bool); + } +} + +#[public] +impl MyContract { + pub fn call_evm_contract(&self, token: Address) -> Result> { + let erc20 = IERC20::new(token); + let result = erc20.transfer(self.vm(), recipient, amount)?; + Ok(result) + } +} +``` + +```solidity +// Solidity calling Stylus +interface IStylusContract { + function computeHash(bytes calldata data) external view returns (bytes32); +} + +contract EvmContract { + function useStylus(address stylusAddr, bytes calldata data) public view returns (bytes32) { + return IStylusContract(stylusAddr).computeHash(data); + } +} +``` + +### Call costs + +- **Same call overhead**: Both directions have similar base costs +- **ABI encoding**: Identical for both +- **Gas forwarding**: Follows 63/64 rule in both cases +- **Return data**: Handled consistently + +## Contract lifecycle + +### Deployment + +**EVM contracts:** + +1. Submit init code (constructor bytecode) +2. EVM executes init code +3. Returns runtime bytecode +4. Bytecode stored onchain + +**Stylus contracts:** + +1. Compile Rust โ†’ WASM +2. Submit WASM code +3. **Activation step**: One-time compilation to native code +4. Activated programs cached for efficiency +5. WASM code stored onchain + +**Activation benefits:** + +```shell +# Deploy and activate a Stylus program +cargo stylus deploy --private-key $PRIVATE_KEY + +# Activation happens once +# Subsequent calls use cached native code +``` + +- **One-time cost**: Pay activation gas once +- **Future savings**: All executions use optimized native code +- **Upgradeability**: Re-activation needed for upgrades + +### Execution flow + +**EVM contracts:** + +``` +Transaction โ†’ EVM โ†’ Opcode interpretation โ†’ State changes +``` + +**Stylus contracts:** + +``` +Transaction โ†’ WASM VM โ†’ Native code execution โ†’ State changes + โ†“ + Hostio calls for state access +``` + +## Developer experience + +### EVM development + +**Languages**: Solidity, Vyper, Huff + +**Tools**: + +- Hardhat, Foundry for testing +- Remix for quick development +- Ethers.js/Web3.js for interaction + +**Debugging**: + +- Revert messages +- Events for tracing +- Stack traces limited + +### Stylus development + +**Languages**: Rust, C, C++ (any WASM-compatible language) + +**Tools**: + +- `cargo stylus` for deployment +- Standard Rust tooling (cargo, rustc) +- `TestVM` for unit testing +- Rust analyzer for IDE support + +**Debugging**: + +- Full Rust error messages +- Compile-time safety checks +- `console!` macro for debug builds +- Stack traces in development + +**Development comparison:** + +| Aspect | EVM | Stylus | Notes | +| --------------- | -------------- | ------------------- | ------------------------------------- | +| Type safety | Runtime | Compile-time | Rust catches errors before deployment | +| Memory safety | Manual | Automatic | Rust's borrow checker | +| Testing | External tools | Built-in Rust tests | `#[test]` functions work natively | +| Iteration speed | Slower | Faster | No need to redeploy for tests | +| Learning curve | Moderate | Steeper | Rust has more concepts | +| Maturity | Very mature | Growing | Solidity has more resources | + +## Feature compatibility + +### Supported features + +Both EVM and Stylus support: + +โœ… Contract calls and delegate calls +โœ… Value transfers +โœ… Event emission +โœ… Storage operations +โœ… Block and transaction properties +โœ… Cryptographic functions (keccak256) +โœ… Contract creation (CREATE, CREATE2) +โœ… Revert and error handling +โœ… Reentrancy guards + +### EVM-specific features not in WASM + +โŒ Inline assembly (use hostio or Rust instead) +โŒ `selfdestruct` (deprecated in Ethereum anyway) +โŒ Solidity modifiers (use Rust functions) +โŒ Multiple inheritance (use traits and composition) + +### Stylus-specific features not in EVM + +โœ… Access to Rust ecosystem (crates) +โœ… Efficient memory management +โœ… Zero-cost abstractions +โœ… Compile-time guarantees +โœ… Native testing support +โœ… Better optimization opportunities + +## State sharing + +EVM and WASM contracts share the same blockchain state: + +```rust +// Stylus contract can read EVM contract storage +#[storage] +pub struct Bridge { + evm_contract: StorageAddress, +} + +#[public] +impl Bridge { + pub fn read_evm_storage(&self, key: U256) -> U256 { + // Both VMs use the same storage layout + // Can read storage written by EVM contracts + storage_load_bytes32(key) + } +} +``` + +**Shared state:** + +- Account balances +- Contract storage +- Contract code +- Transaction history +- Block data + +## Gas economics + +### Cost structure + +**EVM contract execution:** + +``` +Total cost = Base transaction cost (21,000 gas) + + Input data cost (~16 gas/byte) + + Execution cost (opcode gas) + + Storage cost (SLOAD/SSTORE) +``` + +**Stylus contract execution:** + +``` +Total cost = Base transaction cost (21,000 gas) + + Input data cost (~16 gas/byte) + + Execution cost (ink โ†’ gas conversion) + + Storage cost (same as EVM) +``` + +### When to use each + +**Use EVM (Solidity) when:** + +- Quick prototyping needed +- Simple contracts with minimal computation +- Team expertise in Solidity +- Extensive storage operations (cost is equal) +- Maximum ecosystem compatibility + +**Use Stylus (Rust) when:** + +- Compute-intensive operations +- Complex algorithms or data structures +- Need for memory safety guarantees +- Existing Rust codebase to port +- Optimizing for gas efficiency +- Cryptographic operations +- String/byte manipulation + +## Best practices + +### For EVM contracts + +1. **Minimize storage operations**: Use memory when possible +2. **Optimize loops**: Keep iterations minimal +3. **Pack storage**: Use smaller types when possible +4. **Avoid complex math**: Basic operations only +5. **Use libraries**: Leverage audited code + +### For Stylus contracts + +1. **Leverage Rust's safety**: Let the compiler catch bugs +2. **Use iterators**: More efficient than manual loops +3. **Profile before optimizing**: Use cargo-stylus tools +4. **Test thoroughly**: Use Rust's built-in test framework +5. **Consider binary size**: Use `#[no_std]` if needed +6. **Batch operations**: Take advantage of cheap compute + +### Hybrid approach + +Many projects can benefit from both: + +```rust +// Compute-heavy logic in Stylus +#[public] +impl ComputeEngine { + pub fn complex_calculation(&self, data: Vec) -> Vec { + // Efficient loops and data processing + data.iter() + .map(|x| expensive_computation(*x)) + .collect() + } +} +``` + +```solidity +// Coordination and state management in Solidity +contract Coordinator { + IComputeEngine public engine; // Stylus contract + + function process(uint256[] calldata data) public { + uint256[] memory results = engine.complex_calculation(data); + // Store results, emit events, etc. + } +} +``` + +## Migration considerations + +### From Solidity to Stylus + +**What stays the same:** + +- Contract addresses +- Storage layout +- ABIs and interfaces +- Gas for storage operations +- Event signatures + +**What changes:** + +- Programming language (Solidity โ†’ Rust) +- Execution engine (EVM โ†’ WASM) +- Gas costs for compute (usually cheaper) +- Development workflow +- Testing approach + +**Migration strategy:** + +1. Start with compute-heavy functions +2. Maintain same ABI for compatibility +3. Test extensively with existing contracts +4. Monitor gas costs in production +5. Gradually migrate more functionality + +## Future developments + +### EVM evolution + +- EIP improvements +- New opcodes +- Gas repricing +- EOF (EVM Object Format) + +### Stylus evolution + +- Support for more languages +- SIMD instructions +- Floating point operations +- Larger contract size limits +- Further gas optimizations +- Enhanced debugging tools + +## Resources + +- [Stylus documentation](https://docs.arbitrum.io/stylus) +- [Ink and gas metering](https://docs.arbitrum.io/stylus/concepts/gas-metering) +- [WASM specification](https://webassembly.github.io/spec/) +- [EVM opcodes reference](https://www.evm.codes/) +- [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) + +## Summary + +The WASM VM in Arbitrum Nitro represents a significant evolution in smart contract execution: + +**Key advantages of WASM:** + +- 10-100x cheaper for compute operations +- More expressive programming languages +- Better memory management +- Compile-time safety guarantees +- Access to mature language ecosystems + +**Key advantages of EVM:** + +- Mature tooling and ecosystem +- Familiar to existing developers +- No activation cost +- Decades of collective knowledge + +Both execution environments coexist harmoniously on Arbitrum, allowing developers to choose the best tool for each use case while maintaining full interoperability. From ed4425a02c37621f1fa8843debc78d3398c3d584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:47:50 -0800 Subject: [PATCH 046/162] docs: add comprehensive WebAssembly guide for Nitro Add detailed documentation covering WASM basics in the context of Arbitrum Nitro and Stylus: - WASM fundamentals and why it's used in Nitro - Compilation target (wasm32-unknown-unknown) configuration - Binary structure (exports, imports, memory, custom sections) - Compression with brotli and 0xEFF000 prefix - Contract activation process and caching - Development workflow and best practices - Size limitations and optimization strategies - Memory model and supported WASM instructions --- docs/stylus/how-tos/webassembly.mdx | 402 ++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 docs/stylus/how-tos/webassembly.mdx diff --git a/docs/stylus/how-tos/webassembly.mdx b/docs/stylus/how-tos/webassembly.mdx new file mode 100644 index 0000000000..6e623a603b --- /dev/null +++ b/docs/stylus/how-tos/webassembly.mdx @@ -0,0 +1,402 @@ +--- +title: 'WebAssembly in Nitro' +description: 'Understanding WebAssembly compilation, deployment, and execution in Arbitrum Nitro' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how WebAssembly works in the context of Nitro and Stylus smart contracts. +displayed_sidebar: buildAppsSidebar +--- + +# WebAssembly in Nitro + +WebAssembly (WASM) is a binary instruction format that enables high-performance execution of programs in the Nitro virtual machine. This guide explains how WASM works in the context of Arbitrum Nitro and Stylus smart contract development. + +## What is WebAssembly? + +WebAssembly is a portable, size-efficient binary format designed for safe execution at near-native speeds. Key characteristics include: + +- **Binary format**: Compact representation that's faster to parse than text-based formats +- **Stack-based VM**: Simple execution model with operand stack +- **Sandboxed execution**: Memory-safe by design with explicit bounds checking +- **Language-agnostic**: Can be targeted by many programming languages (Rust, C, C++, etc.) + +## Why WebAssembly in Nitro? + +Nitro uses WebAssembly as its execution environment for several reasons: + +1. **Performance**: WASM compiles to native machine code for fast execution +2. **Security**: Sandboxed environment prevents unauthorized access +3. **Portability**: Same bytecode runs identically across all nodes +4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM +5. **Determinism**: Guaranteed identical execution across all validators + +## WASM Compilation Target + +Stylus contracts are compiled to the `wasm32-unknown-unknown` target, which means: + +- **32-bit addressing**: Uses 32-bit pointers and memory addresses +- **Unknown OS**: No operating system dependencies +- **Unknown environment**: Minimal runtime assumptions (no std by default) + +The `.cargo/config.toml` file in Stylus projects configures the WASM target: + +```toml +[target.wasm32-unknown-unknown] +rustflags = [ + "-C", "link-arg=-zstack-size=32768", # 32KB stack + "-C", "target-feature=-reference-types", # Disable reference types + "-C", "target-feature=+bulk-memory", # Enable bulk memory operations +] +``` + +### Compilation flags + +- **Stack size**: Limited to 32KB to ensure bounded memory usage +- **Bulk memory**: Enables efficient `memory.copy` and `memory.fill` operations +- **No reference types**: Keeps the WASM simpler and more compatible + +## WASM Binary Structure + +A Stylus WASM module consists of several sections: + +### Exports + +Every Stylus contract exports a `user_entrypoint` function: + +```rust +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + // Entry point for all contract calls + // len: size of calldata in bytes + // returns: size of output data in bytes +} +``` + +This function is automatically generated by the `#[entrypoint]` macro and serves as the single entry point for all contract interactions. + +### Imports + +WASM modules import low-level functions from the `vm_hooks` module: + +```rust +// Example hostio imports +extern "C" { + fn storage_load_bytes32(key: *const u8, dest: *mut u8); + fn storage_store_bytes32(key: *const u8, value: *const u8); + fn msg_sender(sender: *mut u8); + fn block_timestamp() -> u64; + // ... and many more +} +``` + +These imported functions (called "hostio" functions) provide access to blockchain state and functionality. + +### Memory + +WASM modules use linear memory, which is: + +- **Contiguous**: Single continuous address space starting at 0 +- **Growable**: Can expand at runtime (in 64KB pages) +- **Isolated**: Each contract has its own memory space + +Memory growth is explicitly metered: + +```rust +// Exported function that must exist +#[no_mangle] +pub extern "C" fn pay_for_memory_grow(pages: u16) { + // Called before memory.grow to charge for new pages + // Each page is 64KB +} +``` + +### Custom sections + +WASM supports custom sections for metadata: + +```rust +// Example: Add version information +#[link_section = ".custom.stylus-version"] +static VERSION: [u8; 5] = *b"0.1.0"; +``` + +Custom sections can store: + +- Contract version +- Source code hashes +- Compiler metadata +- ABI information + +## Compression and Deployment + +Before deployment, Stylus contracts undergo compression: + +### Brotli compression + +```rust +// From stylus-tools/src/utils/wasm.rs +pub fn brotli_compress(wasm: impl Read, compression_level: u32) -> io::Result> { + let mut compressed = Vec::new(); + let mut encoder = brotli::CompressorWriter::new(&mut compressed, 4096, compression_level, 22); + io::copy(&mut wasm, &mut encoder)?; + encoder.flush()?; + Ok(compressed) +} +``` + +Brotli compression typically reduces WASM size by 50-70%. + +### 0xEFF000 prefix + +Compressed WASM is prefixed with `0xEFF000` to identify it as a Stylus program: + +```rust +pub fn add_prefix(compressed_wasm: impl IntoIterator, prefix: &str) -> Vec { + let prefix_bytes = hex::decode(prefix.strip_prefix("0x").unwrap_or(prefix)).unwrap(); + prefix_bytes.into_iter().chain(compressed_wasm).collect() +} +``` + +This prefix allows the Nitro VM to distinguish Stylus contracts from EVM bytecode. + +## Contract Activation + +After deployment, contracts must be **activated** before execution: + +### Activation process + +1. **Initial deployment**: Contract code is stored on-chain (compressed) +2. **Activation call**: Special transaction invokes `activateProgram` +3. **Decompression**: Brotli-compressed WASM is decompressed +4. **Validation**: WASM is checked for: + - Valid structure + - Required exports (`user_entrypoint`) + - Allowed imports (only `vm_hooks`) + - Memory constraints +5. **Compilation**: WASM is compiled to native machine code +6. **Caching**: Compiled code is cached for future executions + +### One-time cost + +Activation incurs a one-time gas cost but provides benefits: + +- **Fast execution**: Native code runs 10-100x faster than interpreted +- **Persistent cache**: Compilation happens once, benefits all future calls +- **Optimizations**: Native compiler applies target-specific optimizations + +### Verification + +The activation process checks for the `pay_for_memory_grow` function to verify correct entrypoint setup: + +```rust +// From activation.rs +if !wasm::has_entrypoint(&wasm)? { + bail!("WASM is missing the entrypoint export"); +} +``` + +## Development Workflow + +### 1. Write Rust code + +```rust +use stylus_sdk::{alloy_primitives::U256, prelude::*}; + +#[entrypoint] +#[storage] +pub struct Counter { + count: StorageU256, +} + +#[public] +impl Counter { + pub fn increment(&mut self) { + let count = self.count.get() + U256::from(1); + self.count.set(count); + } +} +``` + +### 2. Compile to WASM + +```bash +cargo stylus build +``` + +This runs: + +```bash +cargo build \ + --lib \ + --locked \ + --release \ + --target wasm32-unknown-unknown \ + --target-dir target/wasm32-unknown-unknown/release +``` + +### 3. Optimize (optional) + +```bash +wasm-opt target/wasm32-unknown-unknown/release/my_contract.wasm \ + -O3 \ + --strip-debug \ + -o optimized.wasm +``` + +Optimization can reduce size by an additional 10-30%. + +### 4. Deploy and activate + +```bash +# Deploy compressed WASM +cargo stylus deploy --private-key=$PRIVATE_KEY + +# Activation happens automatically +``` + +## Size Limitations + +Nitro imposes limits on WASM contract size: + +| Limit | Value | Reason | +| --------------------- | ---------------------- | --------------------------------- | +| **Uncompressed size** | ~3-4 MB | Memory and processing constraints | +| **Compressed size** | 24 KB (initial) | Ethereum transaction size limit | +| **Compressed size** | 128 KB (with EIP-4844) | Larger blob transactions | + +To stay within limits: + +- Use `#[no_std]` to avoid standard library bloat +- Strip debug symbols with `--strip-debug` +- Enable aggressive optimization (`-O3`) +- Minimize dependencies +- Use compact data structures + +## Memory Model + +### Linear memory layout + +``` +0x00000000 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ Stack โ”‚ 32 KB fixed size +0x00008000 โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ Heap/Data โ”‚ Grows upward + โ”‚ โ”‚ + โ”‚ (Available) โ”‚ + โ”‚ โ”‚ +0xFFFFFFFF โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Memory operations + +```rust +// Bulk memory operations (enabled by target config) +unsafe { + // Fast memory copy + core::ptr::copy_nonoverlapping(src, dst, len); + + // Fast memory fill + core::ptr::write_bytes(ptr, value, len); +} +``` + +The `bulk-memory` feature flag enables efficient WASM instructions like `memory.copy` and `memory.fill`. + +## Advanced: WASM Instructions + +Stylus uses WASM MVP (Minimum Viable Product) instructions plus bulk-memory operations: + +### Arithmetic + +- `i32.add`, `i32.sub`, `i32.mul`, `i32.div_s`, `i32.div_u` +- `i64.add`, `i64.sub`, `i64.mul`, `i64.div_s`, `i64.div_u` + +### Memory access + +- `i32.load`, `i32.store` (32-bit load/store) +- `i64.load`, `i64.store` (64-bit load/store) +- `memory.grow` (expand memory) +- `memory.copy` (bulk copy, requires flag) +- `memory.fill` (bulk fill, requires flag) + +### Control flow + +- `call`, `call_indirect` (function calls) +- `if`, `else`, `block`, `loop` (structured control flow) +- `br`, `br_if` (branching) + +### Not supported + +- โŒ Floating point operations (f32, f64) +- โŒ SIMD operations +- โŒ Reference types +- โŒ Multiple memories +- โŒ Threads + +## Best Practices + +### 1. Minimize binary size + +```rust +// Use #[no_std] when possible +#![no_std] +extern crate alloc; + +// Avoid large dependencies +// Prefer: alloy-primitives +// Avoid: serde_json, regex (unless necessary) +``` + +### 2. Optimize memory usage + +```rust +// Stack allocate when possible +let small_buffer = [0u8; 32]; + +// Heap allocate only when necessary +let large_buffer = vec![0u8; 1024]; +``` + +### 3. Profile before optimizing + +```bash +# Check binary size +ls -lh target/wasm32-unknown-unknown/release/*.wasm + +# Analyze with twiggy +cargo install twiggy +twiggy top target/wasm32-unknown-unknown/release/my_contract.wasm +``` + +### 4. Test locally + +```bash +# Use cargo-stylus for local testing +cargo stylus check +cargo stylus export-abi +``` + +### 5. Validate before deployment + +```rust +// Ensure entrypoint exists +#[entrypoint] +#[storage] +pub struct MyContract { /* ... */ } + +// Verify required exports +#[no_mangle] +pub extern "C" fn pay_for_memory_grow(pages: u16) { + // Generated automatically by SDK +} +``` + +## Resources + +- [WebAssembly specification](https://webassembly.github.io/spec/) +- [Rust WASM target documentation](https://doc.rust-lang.org/rustc/platform-support/wasm32-unknown-unknown.html) +- [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) +- [Cargo Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus) +- [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) +- [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) From 9fd8ca77d66dfe7b28426c34a3399bfc2f6e71a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:48:26 -0800 Subject: [PATCH 047/162] remove wrongly named "check-and-deploy" stub article --- docs/stylus/how-tos/check-and-deploy.mdx | 11 ----------- sidebars.js | 4 ++-- 2 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 docs/stylus/how-tos/check-and-deploy.mdx diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx deleted file mode 100644 index be3fe47b9f..0000000000 --- a/docs/stylus/how-tos/check-and-deploy.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: 'Check and deploy' -description: 'Check and deploy Stylus contracts' -author: chrisco -sme: chrisco -sidebar_position: 1 -target_audience: Developers who need to understand how to check and deploy Stylus contracts. -displayed_sidebar: buildAppsSidebar ---- - -TBD diff --git a/sidebars.js b/sidebars.js index c859168371..67a16228b3 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1291,8 +1291,8 @@ const sidebars = { items: [ { type: 'doc', - id: 'stylus/how-tos/check-and-deploy', - label: 'Check and deploy', + id: 'stylus/how-tos/webassembly', + label: 'Webassembly', }, { type: 'doc', From 54281a3549e8e08de3aeb2ca3196f507ad9ea5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:51:45 -0800 Subject: [PATCH 048/162] remove duplicate webassembly reference in sidebars.js --- sidebars.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/sidebars.js b/sidebars.js index 67a16228b3..8b8e193c80 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1289,11 +1289,6 @@ const sidebars = { label: 'Using the CLI', collapsed: true, items: [ - { - type: 'doc', - id: 'stylus/how-tos/webassembly', - label: 'Webassembly', - }, { type: 'doc', id: 'stylus/how-tos/verifying-contracts', @@ -1329,7 +1324,7 @@ const sidebars = { { type: 'doc', id: 'stylus/concepts/webassembly', - label: 'Check and deploy', + label: 'Webassembly', }, { type: 'doc', From 5b08a9b7812ecd32ff853454e1e851b1f1b28b47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 11:54:27 -0800 Subject: [PATCH 049/162] remove duplicat webassembly stub duplicate --- docs/stylus/concepts/webassembly.mdx | 399 +++++++++++++++++++++++++- docs/stylus/how-tos/webassembly.mdx | 402 --------------------------- 2 files changed, 395 insertions(+), 406 deletions(-) delete mode 100644 docs/stylus/how-tos/webassembly.mdx diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index a67c6a44c5..6e623a603b 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -1,11 +1,402 @@ --- -title: 'WebAssembly' -description: 'WebAssembly' +title: 'WebAssembly in Nitro' +description: 'Understanding WebAssembly compilation, deployment, and execution in Arbitrum Nitro' author: chrisco sme: chrisco sidebar_position: 1 -target_audience: Developers who need to understand how Stylus works with WebAssembly. +target_audience: Developers who need to understand how WebAssembly works in the context of Nitro and Stylus smart contracts. displayed_sidebar: buildAppsSidebar --- -TBD +# WebAssembly in Nitro + +WebAssembly (WASM) is a binary instruction format that enables high-performance execution of programs in the Nitro virtual machine. This guide explains how WASM works in the context of Arbitrum Nitro and Stylus smart contract development. + +## What is WebAssembly? + +WebAssembly is a portable, size-efficient binary format designed for safe execution at near-native speeds. Key characteristics include: + +- **Binary format**: Compact representation that's faster to parse than text-based formats +- **Stack-based VM**: Simple execution model with operand stack +- **Sandboxed execution**: Memory-safe by design with explicit bounds checking +- **Language-agnostic**: Can be targeted by many programming languages (Rust, C, C++, etc.) + +## Why WebAssembly in Nitro? + +Nitro uses WebAssembly as its execution environment for several reasons: + +1. **Performance**: WASM compiles to native machine code for fast execution +2. **Security**: Sandboxed environment prevents unauthorized access +3. **Portability**: Same bytecode runs identically across all nodes +4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM +5. **Determinism**: Guaranteed identical execution across all validators + +## WASM Compilation Target + +Stylus contracts are compiled to the `wasm32-unknown-unknown` target, which means: + +- **32-bit addressing**: Uses 32-bit pointers and memory addresses +- **Unknown OS**: No operating system dependencies +- **Unknown environment**: Minimal runtime assumptions (no std by default) + +The `.cargo/config.toml` file in Stylus projects configures the WASM target: + +```toml +[target.wasm32-unknown-unknown] +rustflags = [ + "-C", "link-arg=-zstack-size=32768", # 32KB stack + "-C", "target-feature=-reference-types", # Disable reference types + "-C", "target-feature=+bulk-memory", # Enable bulk memory operations +] +``` + +### Compilation flags + +- **Stack size**: Limited to 32KB to ensure bounded memory usage +- **Bulk memory**: Enables efficient `memory.copy` and `memory.fill` operations +- **No reference types**: Keeps the WASM simpler and more compatible + +## WASM Binary Structure + +A Stylus WASM module consists of several sections: + +### Exports + +Every Stylus contract exports a `user_entrypoint` function: + +```rust +#[no_mangle] +pub extern "C" fn user_entrypoint(len: usize) -> usize { + // Entry point for all contract calls + // len: size of calldata in bytes + // returns: size of output data in bytes +} +``` + +This function is automatically generated by the `#[entrypoint]` macro and serves as the single entry point for all contract interactions. + +### Imports + +WASM modules import low-level functions from the `vm_hooks` module: + +```rust +// Example hostio imports +extern "C" { + fn storage_load_bytes32(key: *const u8, dest: *mut u8); + fn storage_store_bytes32(key: *const u8, value: *const u8); + fn msg_sender(sender: *mut u8); + fn block_timestamp() -> u64; + // ... and many more +} +``` + +These imported functions (called "hostio" functions) provide access to blockchain state and functionality. + +### Memory + +WASM modules use linear memory, which is: + +- **Contiguous**: Single continuous address space starting at 0 +- **Growable**: Can expand at runtime (in 64KB pages) +- **Isolated**: Each contract has its own memory space + +Memory growth is explicitly metered: + +```rust +// Exported function that must exist +#[no_mangle] +pub extern "C" fn pay_for_memory_grow(pages: u16) { + // Called before memory.grow to charge for new pages + // Each page is 64KB +} +``` + +### Custom sections + +WASM supports custom sections for metadata: + +```rust +// Example: Add version information +#[link_section = ".custom.stylus-version"] +static VERSION: [u8; 5] = *b"0.1.0"; +``` + +Custom sections can store: + +- Contract version +- Source code hashes +- Compiler metadata +- ABI information + +## Compression and Deployment + +Before deployment, Stylus contracts undergo compression: + +### Brotli compression + +```rust +// From stylus-tools/src/utils/wasm.rs +pub fn brotli_compress(wasm: impl Read, compression_level: u32) -> io::Result> { + let mut compressed = Vec::new(); + let mut encoder = brotli::CompressorWriter::new(&mut compressed, 4096, compression_level, 22); + io::copy(&mut wasm, &mut encoder)?; + encoder.flush()?; + Ok(compressed) +} +``` + +Brotli compression typically reduces WASM size by 50-70%. + +### 0xEFF000 prefix + +Compressed WASM is prefixed with `0xEFF000` to identify it as a Stylus program: + +```rust +pub fn add_prefix(compressed_wasm: impl IntoIterator, prefix: &str) -> Vec { + let prefix_bytes = hex::decode(prefix.strip_prefix("0x").unwrap_or(prefix)).unwrap(); + prefix_bytes.into_iter().chain(compressed_wasm).collect() +} +``` + +This prefix allows the Nitro VM to distinguish Stylus contracts from EVM bytecode. + +## Contract Activation + +After deployment, contracts must be **activated** before execution: + +### Activation process + +1. **Initial deployment**: Contract code is stored on-chain (compressed) +2. **Activation call**: Special transaction invokes `activateProgram` +3. **Decompression**: Brotli-compressed WASM is decompressed +4. **Validation**: WASM is checked for: + - Valid structure + - Required exports (`user_entrypoint`) + - Allowed imports (only `vm_hooks`) + - Memory constraints +5. **Compilation**: WASM is compiled to native machine code +6. **Caching**: Compiled code is cached for future executions + +### One-time cost + +Activation incurs a one-time gas cost but provides benefits: + +- **Fast execution**: Native code runs 10-100x faster than interpreted +- **Persistent cache**: Compilation happens once, benefits all future calls +- **Optimizations**: Native compiler applies target-specific optimizations + +### Verification + +The activation process checks for the `pay_for_memory_grow` function to verify correct entrypoint setup: + +```rust +// From activation.rs +if !wasm::has_entrypoint(&wasm)? { + bail!("WASM is missing the entrypoint export"); +} +``` + +## Development Workflow + +### 1. Write Rust code + +```rust +use stylus_sdk::{alloy_primitives::U256, prelude::*}; + +#[entrypoint] +#[storage] +pub struct Counter { + count: StorageU256, +} + +#[public] +impl Counter { + pub fn increment(&mut self) { + let count = self.count.get() + U256::from(1); + self.count.set(count); + } +} +``` + +### 2. Compile to WASM + +```bash +cargo stylus build +``` + +This runs: + +```bash +cargo build \ + --lib \ + --locked \ + --release \ + --target wasm32-unknown-unknown \ + --target-dir target/wasm32-unknown-unknown/release +``` + +### 3. Optimize (optional) + +```bash +wasm-opt target/wasm32-unknown-unknown/release/my_contract.wasm \ + -O3 \ + --strip-debug \ + -o optimized.wasm +``` + +Optimization can reduce size by an additional 10-30%. + +### 4. Deploy and activate + +```bash +# Deploy compressed WASM +cargo stylus deploy --private-key=$PRIVATE_KEY + +# Activation happens automatically +``` + +## Size Limitations + +Nitro imposes limits on WASM contract size: + +| Limit | Value | Reason | +| --------------------- | ---------------------- | --------------------------------- | +| **Uncompressed size** | ~3-4 MB | Memory and processing constraints | +| **Compressed size** | 24 KB (initial) | Ethereum transaction size limit | +| **Compressed size** | 128 KB (with EIP-4844) | Larger blob transactions | + +To stay within limits: + +- Use `#[no_std]` to avoid standard library bloat +- Strip debug symbols with `--strip-debug` +- Enable aggressive optimization (`-O3`) +- Minimize dependencies +- Use compact data structures + +## Memory Model + +### Linear memory layout + +``` +0x00000000 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” + โ”‚ Stack โ”‚ 32 KB fixed size +0x00008000 โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค + โ”‚ Heap/Data โ”‚ Grows upward + โ”‚ โ”‚ + โ”‚ (Available) โ”‚ + โ”‚ โ”‚ +0xFFFFFFFF โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ +``` + +### Memory operations + +```rust +// Bulk memory operations (enabled by target config) +unsafe { + // Fast memory copy + core::ptr::copy_nonoverlapping(src, dst, len); + + // Fast memory fill + core::ptr::write_bytes(ptr, value, len); +} +``` + +The `bulk-memory` feature flag enables efficient WASM instructions like `memory.copy` and `memory.fill`. + +## Advanced: WASM Instructions + +Stylus uses WASM MVP (Minimum Viable Product) instructions plus bulk-memory operations: + +### Arithmetic + +- `i32.add`, `i32.sub`, `i32.mul`, `i32.div_s`, `i32.div_u` +- `i64.add`, `i64.sub`, `i64.mul`, `i64.div_s`, `i64.div_u` + +### Memory access + +- `i32.load`, `i32.store` (32-bit load/store) +- `i64.load`, `i64.store` (64-bit load/store) +- `memory.grow` (expand memory) +- `memory.copy` (bulk copy, requires flag) +- `memory.fill` (bulk fill, requires flag) + +### Control flow + +- `call`, `call_indirect` (function calls) +- `if`, `else`, `block`, `loop` (structured control flow) +- `br`, `br_if` (branching) + +### Not supported + +- โŒ Floating point operations (f32, f64) +- โŒ SIMD operations +- โŒ Reference types +- โŒ Multiple memories +- โŒ Threads + +## Best Practices + +### 1. Minimize binary size + +```rust +// Use #[no_std] when possible +#![no_std] +extern crate alloc; + +// Avoid large dependencies +// Prefer: alloy-primitives +// Avoid: serde_json, regex (unless necessary) +``` + +### 2. Optimize memory usage + +```rust +// Stack allocate when possible +let small_buffer = [0u8; 32]; + +// Heap allocate only when necessary +let large_buffer = vec![0u8; 1024]; +``` + +### 3. Profile before optimizing + +```bash +# Check binary size +ls -lh target/wasm32-unknown-unknown/release/*.wasm + +# Analyze with twiggy +cargo install twiggy +twiggy top target/wasm32-unknown-unknown/release/my_contract.wasm +``` + +### 4. Test locally + +```bash +# Use cargo-stylus for local testing +cargo stylus check +cargo stylus export-abi +``` + +### 5. Validate before deployment + +```rust +// Ensure entrypoint exists +#[entrypoint] +#[storage] +pub struct MyContract { /* ... */ } + +// Verify required exports +#[no_mangle] +pub extern "C" fn pay_for_memory_grow(pages: u16) { + // Generated automatically by SDK +} +``` + +## Resources + +- [WebAssembly specification](https://webassembly.github.io/spec/) +- [Rust WASM target documentation](https://doc.rust-lang.org/rustc/platform-support/wasm32-unknown-unknown.html) +- [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) +- [Cargo Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus) +- [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) +- [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) diff --git a/docs/stylus/how-tos/webassembly.mdx b/docs/stylus/how-tos/webassembly.mdx deleted file mode 100644 index 6e623a603b..0000000000 --- a/docs/stylus/how-tos/webassembly.mdx +++ /dev/null @@ -1,402 +0,0 @@ ---- -title: 'WebAssembly in Nitro' -description: 'Understanding WebAssembly compilation, deployment, and execution in Arbitrum Nitro' -author: chrisco -sme: chrisco -sidebar_position: 1 -target_audience: Developers who need to understand how WebAssembly works in the context of Nitro and Stylus smart contracts. -displayed_sidebar: buildAppsSidebar ---- - -# WebAssembly in Nitro - -WebAssembly (WASM) is a binary instruction format that enables high-performance execution of programs in the Nitro virtual machine. This guide explains how WASM works in the context of Arbitrum Nitro and Stylus smart contract development. - -## What is WebAssembly? - -WebAssembly is a portable, size-efficient binary format designed for safe execution at near-native speeds. Key characteristics include: - -- **Binary format**: Compact representation that's faster to parse than text-based formats -- **Stack-based VM**: Simple execution model with operand stack -- **Sandboxed execution**: Memory-safe by design with explicit bounds checking -- **Language-agnostic**: Can be targeted by many programming languages (Rust, C, C++, etc.) - -## Why WebAssembly in Nitro? - -Nitro uses WebAssembly as its execution environment for several reasons: - -1. **Performance**: WASM compiles to native machine code for fast execution -2. **Security**: Sandboxed environment prevents unauthorized access -3. **Portability**: Same bytecode runs identically across all nodes -4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM -5. **Determinism**: Guaranteed identical execution across all validators - -## WASM Compilation Target - -Stylus contracts are compiled to the `wasm32-unknown-unknown` target, which means: - -- **32-bit addressing**: Uses 32-bit pointers and memory addresses -- **Unknown OS**: No operating system dependencies -- **Unknown environment**: Minimal runtime assumptions (no std by default) - -The `.cargo/config.toml` file in Stylus projects configures the WASM target: - -```toml -[target.wasm32-unknown-unknown] -rustflags = [ - "-C", "link-arg=-zstack-size=32768", # 32KB stack - "-C", "target-feature=-reference-types", # Disable reference types - "-C", "target-feature=+bulk-memory", # Enable bulk memory operations -] -``` - -### Compilation flags - -- **Stack size**: Limited to 32KB to ensure bounded memory usage -- **Bulk memory**: Enables efficient `memory.copy` and `memory.fill` operations -- **No reference types**: Keeps the WASM simpler and more compatible - -## WASM Binary Structure - -A Stylus WASM module consists of several sections: - -### Exports - -Every Stylus contract exports a `user_entrypoint` function: - -```rust -#[no_mangle] -pub extern "C" fn user_entrypoint(len: usize) -> usize { - // Entry point for all contract calls - // len: size of calldata in bytes - // returns: size of output data in bytes -} -``` - -This function is automatically generated by the `#[entrypoint]` macro and serves as the single entry point for all contract interactions. - -### Imports - -WASM modules import low-level functions from the `vm_hooks` module: - -```rust -// Example hostio imports -extern "C" { - fn storage_load_bytes32(key: *const u8, dest: *mut u8); - fn storage_store_bytes32(key: *const u8, value: *const u8); - fn msg_sender(sender: *mut u8); - fn block_timestamp() -> u64; - // ... and many more -} -``` - -These imported functions (called "hostio" functions) provide access to blockchain state and functionality. - -### Memory - -WASM modules use linear memory, which is: - -- **Contiguous**: Single continuous address space starting at 0 -- **Growable**: Can expand at runtime (in 64KB pages) -- **Isolated**: Each contract has its own memory space - -Memory growth is explicitly metered: - -```rust -// Exported function that must exist -#[no_mangle] -pub extern "C" fn pay_for_memory_grow(pages: u16) { - // Called before memory.grow to charge for new pages - // Each page is 64KB -} -``` - -### Custom sections - -WASM supports custom sections for metadata: - -```rust -// Example: Add version information -#[link_section = ".custom.stylus-version"] -static VERSION: [u8; 5] = *b"0.1.0"; -``` - -Custom sections can store: - -- Contract version -- Source code hashes -- Compiler metadata -- ABI information - -## Compression and Deployment - -Before deployment, Stylus contracts undergo compression: - -### Brotli compression - -```rust -// From stylus-tools/src/utils/wasm.rs -pub fn brotli_compress(wasm: impl Read, compression_level: u32) -> io::Result> { - let mut compressed = Vec::new(); - let mut encoder = brotli::CompressorWriter::new(&mut compressed, 4096, compression_level, 22); - io::copy(&mut wasm, &mut encoder)?; - encoder.flush()?; - Ok(compressed) -} -``` - -Brotli compression typically reduces WASM size by 50-70%. - -### 0xEFF000 prefix - -Compressed WASM is prefixed with `0xEFF000` to identify it as a Stylus program: - -```rust -pub fn add_prefix(compressed_wasm: impl IntoIterator, prefix: &str) -> Vec { - let prefix_bytes = hex::decode(prefix.strip_prefix("0x").unwrap_or(prefix)).unwrap(); - prefix_bytes.into_iter().chain(compressed_wasm).collect() -} -``` - -This prefix allows the Nitro VM to distinguish Stylus contracts from EVM bytecode. - -## Contract Activation - -After deployment, contracts must be **activated** before execution: - -### Activation process - -1. **Initial deployment**: Contract code is stored on-chain (compressed) -2. **Activation call**: Special transaction invokes `activateProgram` -3. **Decompression**: Brotli-compressed WASM is decompressed -4. **Validation**: WASM is checked for: - - Valid structure - - Required exports (`user_entrypoint`) - - Allowed imports (only `vm_hooks`) - - Memory constraints -5. **Compilation**: WASM is compiled to native machine code -6. **Caching**: Compiled code is cached for future executions - -### One-time cost - -Activation incurs a one-time gas cost but provides benefits: - -- **Fast execution**: Native code runs 10-100x faster than interpreted -- **Persistent cache**: Compilation happens once, benefits all future calls -- **Optimizations**: Native compiler applies target-specific optimizations - -### Verification - -The activation process checks for the `pay_for_memory_grow` function to verify correct entrypoint setup: - -```rust -// From activation.rs -if !wasm::has_entrypoint(&wasm)? { - bail!("WASM is missing the entrypoint export"); -} -``` - -## Development Workflow - -### 1. Write Rust code - -```rust -use stylus_sdk::{alloy_primitives::U256, prelude::*}; - -#[entrypoint] -#[storage] -pub struct Counter { - count: StorageU256, -} - -#[public] -impl Counter { - pub fn increment(&mut self) { - let count = self.count.get() + U256::from(1); - self.count.set(count); - } -} -``` - -### 2. Compile to WASM - -```bash -cargo stylus build -``` - -This runs: - -```bash -cargo build \ - --lib \ - --locked \ - --release \ - --target wasm32-unknown-unknown \ - --target-dir target/wasm32-unknown-unknown/release -``` - -### 3. Optimize (optional) - -```bash -wasm-opt target/wasm32-unknown-unknown/release/my_contract.wasm \ - -O3 \ - --strip-debug \ - -o optimized.wasm -``` - -Optimization can reduce size by an additional 10-30%. - -### 4. Deploy and activate - -```bash -# Deploy compressed WASM -cargo stylus deploy --private-key=$PRIVATE_KEY - -# Activation happens automatically -``` - -## Size Limitations - -Nitro imposes limits on WASM contract size: - -| Limit | Value | Reason | -| --------------------- | ---------------------- | --------------------------------- | -| **Uncompressed size** | ~3-4 MB | Memory and processing constraints | -| **Compressed size** | 24 KB (initial) | Ethereum transaction size limit | -| **Compressed size** | 128 KB (with EIP-4844) | Larger blob transactions | - -To stay within limits: - -- Use `#[no_std]` to avoid standard library bloat -- Strip debug symbols with `--strip-debug` -- Enable aggressive optimization (`-O3`) -- Minimize dependencies -- Use compact data structures - -## Memory Model - -### Linear memory layout - -``` -0x00000000 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” - โ”‚ Stack โ”‚ 32 KB fixed size -0x00008000 โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค - โ”‚ Heap/Data โ”‚ Grows upward - โ”‚ โ”‚ - โ”‚ (Available) โ”‚ - โ”‚ โ”‚ -0xFFFFFFFF โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ -``` - -### Memory operations - -```rust -// Bulk memory operations (enabled by target config) -unsafe { - // Fast memory copy - core::ptr::copy_nonoverlapping(src, dst, len); - - // Fast memory fill - core::ptr::write_bytes(ptr, value, len); -} -``` - -The `bulk-memory` feature flag enables efficient WASM instructions like `memory.copy` and `memory.fill`. - -## Advanced: WASM Instructions - -Stylus uses WASM MVP (Minimum Viable Product) instructions plus bulk-memory operations: - -### Arithmetic - -- `i32.add`, `i32.sub`, `i32.mul`, `i32.div_s`, `i32.div_u` -- `i64.add`, `i64.sub`, `i64.mul`, `i64.div_s`, `i64.div_u` - -### Memory access - -- `i32.load`, `i32.store` (32-bit load/store) -- `i64.load`, `i64.store` (64-bit load/store) -- `memory.grow` (expand memory) -- `memory.copy` (bulk copy, requires flag) -- `memory.fill` (bulk fill, requires flag) - -### Control flow - -- `call`, `call_indirect` (function calls) -- `if`, `else`, `block`, `loop` (structured control flow) -- `br`, `br_if` (branching) - -### Not supported - -- โŒ Floating point operations (f32, f64) -- โŒ SIMD operations -- โŒ Reference types -- โŒ Multiple memories -- โŒ Threads - -## Best Practices - -### 1. Minimize binary size - -```rust -// Use #[no_std] when possible -#![no_std] -extern crate alloc; - -// Avoid large dependencies -// Prefer: alloy-primitives -// Avoid: serde_json, regex (unless necessary) -``` - -### 2. Optimize memory usage - -```rust -// Stack allocate when possible -let small_buffer = [0u8; 32]; - -// Heap allocate only when necessary -let large_buffer = vec![0u8; 1024]; -``` - -### 3. Profile before optimizing - -```bash -# Check binary size -ls -lh target/wasm32-unknown-unknown/release/*.wasm - -# Analyze with twiggy -cargo install twiggy -twiggy top target/wasm32-unknown-unknown/release/my_contract.wasm -``` - -### 4. Test locally - -```bash -# Use cargo-stylus for local testing -cargo stylus check -cargo stylus export-abi -``` - -### 5. Validate before deployment - -```rust -// Ensure entrypoint exists -#[entrypoint] -#[storage] -pub struct MyContract { /* ... */ } - -// Verify required exports -#[no_mangle] -pub extern "C" fn pay_for_memory_grow(pages: u16) { - // Generated automatically by SDK -} -``` - -## Resources - -- [WebAssembly specification](https://webassembly.github.io/spec/) -- [Rust WASM target documentation](https://doc.rust-lang.org/rustc/platform-support/wasm32-unknown-unknown.html) -- [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) -- [Cargo Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus) -- [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) -- [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) From dfeefd8f5888d61c8f332aaf77e5303637f7e187 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 12:01:00 -0800 Subject: [PATCH 050/162] Create separate sidebars for Solidity and Stylus Add buildSoliditySidebar and buildStylusSidebar to provide focused navigation experiences. Each sidebar contains only its relevant content category, eliminating the need for collapse/expand behavior. --- sidebars.js | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) diff --git a/sidebars.js b/sidebars.js index 8b8e193c80..643adbba7f 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1391,6 +1391,445 @@ const sidebars = { }, ], + // Solidity-focused sidebar (only shows Solidity content) + buildSoliditySidebar: [ + { + type: 'category', + label: 'Build apps with Solidity', + collapsed: false, + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/quickstart-solidity-remix', + label: 'Quickstart', + }, + { + type: 'doc', + label: 'Estimate gas', + id: 'build-decentralized-apps/how-to-estimate-gas', + }, + { + type: 'doc', + label: 'Chains and testnets', + id: 'build-decentralized-apps/public-chains', + }, + { + type: 'doc', + label: 'Cross-chain messaging', + id: 'build-decentralized-apps/cross-chain-messaging', + }, + { + type: 'doc', + id: 'build-decentralized-apps/custom-gas-token-sdk', + label: 'Custom gas token SDK', + }, + { + type: 'category', + label: 'Arbitrum vs Ethereum', + items: [ + { + type: 'doc', + label: 'Comparison overview', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/comparison-overview', + }, + { + type: 'doc', + label: 'Block gas limit, numbers and time', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/block-numbers-and-time', + }, + { + type: 'doc', + label: 'RPC methods', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/rpc-methods', + }, + { + type: 'doc', + label: 'Solidity support', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/solidity-support', + }, + ], + }, + { + type: 'doc', + label: 'Oracles', + id: 'build-decentralized-apps/oracles/overview-oracles', + }, + { + type: 'category', + label: 'Precompiles', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/precompiles/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/precompiles/reference', + }, + ], + }, + { + type: 'category', + label: 'NodeInterface', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/nodeinterface/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/nodeinterface/reference', + }, + ], + }, + { + type: 'category', + label: 'Token bridging', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/token-bridging/overview', + }, + { + type: 'doc', + label: 'ETH bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-ether', + }, + { + type: 'doc', + label: 'ERC-20 token bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-erc20', + }, + { + type: 'category', + label: 'Bridge tokens programmatically', + items: [ + { + type: 'doc', + label: 'Get started', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/get-started', + }, + { + type: 'doc', + label: 'Use the standard gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-standard', + }, + { + type: 'doc', + label: 'Use the generic-custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-generic-custom', + }, + { + type: 'doc', + label: 'Use the custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-custom-gateway', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Reference', + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/reference/node-providers', + label: 'RPC endpoints and providers', + }, + { + type: 'doc', + label: 'Smart contract addresses', + id: 'build-decentralized-apps/reference/contract-addresses', + }, + { + type: 'doc', + label: 'Chain parameters', + id: 'build-decentralized-apps/reference/chain-params', + }, + { + type: 'doc', + label: 'Development frameworks', + id: 'build-decentralized-apps/reference/development-frameworks', + }, + { + type: 'doc', + label: 'Web3 libraries and tools', + id: 'build-decentralized-apps/reference/web3-libraries-tools', + }, + { + type: 'doc', + label: 'Monitoring tools and block explorers', + id: 'build-decentralized-apps/reference/monitoring-tools-block-explorers', + }, + { + type: 'doc', + label: 'Debugging tools', + id: 'build-decentralized-apps/reference/debugging-tools', + }, + + { + type: 'doc', + id: 'build-decentralized-apps/reference/mainnet-risks', + label: 'Mainnet risks', + }, + ], + }, + { + type: 'doc', + label: 'Troubleshooting', + id: 'for-devs/troubleshooting-building', + }, + { + type: 'category', + label: 'Arbitrum SDK', + items: sdkSidebar.sdkSidebar, + }, + { + type: 'link', + label: 'Tutorials', + href: 'https://github.com/OffchainLabs/arbitrum-tutorials', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Stylus-focused sidebar (only shows Stylus content) + buildStylusSidebar: [ + { + type: 'category', + label: 'Build apps with Stylus', + collapsed: false, + items: [ + { + type: 'doc', + id: 'stylus/gentle-introduction', + label: 'A gentle introduction', + }, + { + type: 'category', + label: 'Rust SDK', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/reference/overview', + label: 'Overview', + }, + { + type: 'doc', + id: 'stylus/reference/project-structure', + label: 'Structure of a Contract', + }, + { + type: 'category', + label: 'Data types', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/reference/data-types/primitives', + label: 'Primitives', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/compound-types', + label: 'Compound types', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/storage', + label: 'Storage', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/conversions-between-types', + label: 'Conversions Between Types', + }, + ], + }, + { + type: 'doc', + id: 'stylus/reference/global-variables-and-functions', + label: 'Global variables and functions', + }, + { + type: 'doc', + id: 'stylus/reference/contracts', + label: 'Contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/testing-contracts', + label: 'Writing Tests', + }, + { + type: 'category', + label: 'Advanced', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/advanced/solidity-differences', + label: 'Solidity differences', + }, + { + type: 'doc', + id: 'stylus/advanced/recommended-libraries', + label: 'Recommended packages', + }, + { + type: 'doc', + id: 'stylus/advanced/minimal-entrypoint-contracts', + label: 'Minimal entrypoint contracts', + }, + { + type: 'doc', + id: 'stylus/advanced/hostio-exports', + label: 'Hostio exports', + }, + ], + }, + { + type: 'doc', + id: 'stylus/troubleshooting-building-stylus', + label: 'Troubleshooting', + }, + { + type: 'category', + label: 'Using the CLI', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-binaries', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], + }, + { + type: 'category', + label: 'WM Concepts', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/concepts/webassembly', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/concepts/evm-differences', + label: 'EVM differences', + }, + { + type: 'doc', + id: 'stylus/concepts/activation', + label: 'Activation', + }, + { + type: 'doc', + id: 'stylus/how-tos/caching-contracts', + label: 'Caching Strategy', + }, + ], + }, + { + type: 'category', + label: 'Reference', + collapsed: true, + items: [ + { + type: 'link', + label: 'Stylus by Example', + href: 'https://stylus-by-example.org/', + }, + { + type: 'link', + label: 'Cargo Stylus CLI GitHub', + href: 'https://github.com/OffchainLabs/cargo-stylus', + }, + { + type: 'link', + label: 'Rust SDK Crate', + href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + }, + { + type: 'link', + label: 'Source Code Repository', + href: 'https://github.com/OffchainLabs/stylus', + }, + ], + }, + ], + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + // Notices sidebar noticeSidebar: [ { From c17347e8d12a701f46ebce1dec83e362a70a75a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 12:01:10 -0800 Subject: [PATCH 051/162] Update Solidity pages to use buildSoliditySidebar Change displayed_sidebar frontmatter from buildAppsSidebar to buildSoliditySidebar for all Solidity documentation pages. --- docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx | 2 +- docs/build-decentralized-apps/02-how-to-estimate-gas.mdx | 2 +- docs/build-decentralized-apps/03-public-chains.mdx | 2 +- docs/build-decentralized-apps/04-cross-chain-messaging.mdx | 2 +- .../arbitrum-vs-ethereum/01-comparison-overview.mdx | 2 +- .../arbitrum-vs-ethereum/02-block-numbers-and-time.mdx | 2 +- .../arbitrum-vs-ethereum/03-rpc-methods.mdx | 2 +- .../arbitrum-vs-ethereum/04-solidity-support.mdx | 2 +- docs/build-decentralized-apps/custom-gas-token-sdk.mdx | 2 +- docs/build-decentralized-apps/nodeinterface/01-overview.mdx | 2 +- docs/build-decentralized-apps/nodeinterface/02-reference.mdx | 2 +- docs/build-decentralized-apps/oracles/01-overview.mdx | 2 +- docs/build-decentralized-apps/precompiles/01-overview.mdx | 2 +- docs/build-decentralized-apps/precompiles/02-reference.mdx | 2 +- docs/build-decentralized-apps/reference/01-node-providers.mdx | 2 +- .../reference/02-contract-addresses.mdx | 2 +- docs/build-decentralized-apps/reference/03-chain-params.mdx | 2 +- .../reference/04-development-frameworks.mdx | 2 +- .../reference/05-web3-libraries-tools.mdx | 2 +- .../reference/06-monitoring-tools-block-explorers.mdx | 2 +- docs/build-decentralized-apps/reference/07-debugging-tools.mdx | 2 +- docs/build-decentralized-apps/reference/08-mainnet-risks.mdx | 2 +- docs/build-decentralized-apps/token-bridging/01-overview.mdx | 2 +- .../token-bridging/02-token-bridge-ether.mdx | 2 +- .../token-bridging/03-token-bridge-erc20.mdx | 2 +- .../bridge-tokens-programmatically/01-get-started.mdx | 2 +- .../02-how-to-bridge-tokens-standard.mdx | 2 +- .../03-how-to-bridge-tokens-generic-custom.mdx | 2 +- .../04-how-to-bridge-tokens-custom-gateway.mdx | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx b/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx index 2ea5737f97..d6558844ad 100644 --- a/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx +++ b/docs/build-decentralized-apps/01-quickstart-solidity-remix.mdx @@ -5,7 +5,7 @@ author: symbolpunk user_story: As a web2 developer, I want to onboard into Arbitrum by building and deploying my first smart contract, and knowing how to build a web widget interacting with it. content_type: quickstart slug: /build-decentralized-apps/quickstart-solidity-remix -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition/'; diff --git a/docs/build-decentralized-apps/02-how-to-estimate-gas.mdx b/docs/build-decentralized-apps/02-how-to-estimate-gas.mdx index eb7fb114f4..4d376b9c0b 100644 --- a/docs/build-decentralized-apps/02-how-to-estimate-gas.mdx +++ b/docs/build-decentralized-apps/02-how-to-estimate-gas.mdx @@ -3,7 +3,7 @@ title: 'How to estimate gas in Arbitrum' description: Learn how to estimate gas before submitting transactions. author: TucksonDev content_type: how-to -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- :::info Looking for Stylus guidance? diff --git a/docs/build-decentralized-apps/03-public-chains.mdx b/docs/build-decentralized-apps/03-public-chains.mdx index bbc0b796a6..66d941d7b9 100644 --- a/docs/build-decentralized-apps/03-public-chains.mdx +++ b/docs/build-decentralized-apps/03-public-chains.mdx @@ -3,7 +3,7 @@ title: 'Arbitrum chains overview' description: A high level description of the Arbitrum chains available user_story: As a developer, I want to understand the different Arbitrum chains and how they relate to each other. content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import { AddressExplorerLink as AEL } from '@site/src/components/AddressExplorerLink'; diff --git a/docs/build-decentralized-apps/04-cross-chain-messaging.mdx b/docs/build-decentralized-apps/04-cross-chain-messaging.mdx index f73d98e710..c581bb7732 100644 --- a/docs/build-decentralized-apps/04-cross-chain-messaging.mdx +++ b/docs/build-decentralized-apps/04-cross-chain-messaging.mdx @@ -3,7 +3,7 @@ title: 'Cross-chain messaging overview' description: Learn about cross-chain messaging in Arbitrum user_story: As a developer, I want to understand how cross-chain messaging works in Arbitrum. content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- The Arbitrum protocol and related tooling makes it easy for developers to build cross-chain applications; i.e., applications that involve sending messages from Ethereum to an Arbitrum chain, and/or from an Arbitrum chain to Ethereum. diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/01-comparison-overview.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/01-comparison-overview.mdx index 316fa8fdbc..595f405270 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/01-comparison-overview.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/01-comparison-overview.mdx @@ -6,7 +6,7 @@ author: jose-franco sme: jose-franco target_audience: developers who want to build on Arbitrum content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Arbitrum's design is to be as compatible and consistent with Ethereum as possible, from its high-level RPCs to its low-level bytecode and everything in between. Decentralized app developers with experience building on Ethereum will likely find that little to no new specific knowledge is required to build on Arbitrum. diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/02-block-numbers-and-time.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/02-block-numbers-and-time.mdx index a2b547e314..bc43a680e6 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/02-block-numbers-and-time.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/02-block-numbers-and-time.mdx @@ -6,7 +6,7 @@ author: dzgoldman, jose-franco sme: jose-franco target_audience: developers who want to build on Arbitrum content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- :::info block number vs `block.number` diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx index 3c6314fc56..91fdf6f8ed 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx @@ -5,7 +5,7 @@ description: This concept page provides information about the differences betwee target_audience: developers who want to build on Arbitrum author: dzgoldman content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Although the majority of RPC methods follow the same behavior as in Ethereum, some methods may produce a different result or add more information when used on an Arbitrum chain. This page covers the differences in response body fields you'll find when calling RPC methods on an Arbitrum chain vs on Ethereum. diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/04-solidity-support.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/04-solidity-support.mdx index b5842e3010..9ed06b6a16 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/04-solidity-support.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/04-solidity-support.mdx @@ -5,7 +5,7 @@ description: This concept page provides information about the differences betwee target_audience: developers who want to build on Arbitrum author: dzgoldman content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Arbitrum chains are Ethereum-compatible and, therefore, allow you to trustlessly deploy Solidity smart contracts, as well as contracts written in Vyper or any other language that compiles to EVM bytecode. However, when calling certain properties and functions on a Solidity smart contract, there are some differences between the result you'd obtain if that contract were on Ethereum and the result on Arbitrum. diff --git a/docs/build-decentralized-apps/custom-gas-token-sdk.mdx b/docs/build-decentralized-apps/custom-gas-token-sdk.mdx index f100dac3cc..77c8f2c3f6 100644 --- a/docs/build-decentralized-apps/custom-gas-token-sdk.mdx +++ b/docs/build-decentralized-apps/custom-gas-token-sdk.mdx @@ -5,7 +5,7 @@ author: Mehdi Salehi sme: Mehdi Salehi target_audience: 'Developers deploying and maintaining Arbitrum chains.' sidebar_position: 2 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Arbitrum SDK is a TypeScript library for client-side interactions with Arbitrum. It provides common helper functionality as well as access to the underlying smart contract interfaces. diff --git a/docs/build-decentralized-apps/nodeinterface/01-overview.mdx b/docs/build-decentralized-apps/nodeinterface/01-overview.mdx index fb39528454..b402199a1b 100644 --- a/docs/build-decentralized-apps/nodeinterface/01-overview.mdx +++ b/docs/build-decentralized-apps/nodeinterface/01-overview.mdx @@ -3,7 +3,7 @@ title: 'NodeInterface overview' description: A high level description of what the NodeInterface is and how it works user_story: As a developer, I want to understand what the NodeInterface is and how it works. content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- diff --git a/docs/build-decentralized-apps/nodeinterface/02-reference.mdx b/docs/build-decentralized-apps/nodeinterface/02-reference.mdx index 023bcc2db5..1be9333d80 100644 --- a/docs/build-decentralized-apps/nodeinterface/02-reference.mdx +++ b/docs/build-decentralized-apps/nodeinterface/02-reference.mdx @@ -3,7 +3,7 @@ title: 'NodeInterface reference' description: A reference page of the NodeInterface available on Arbitrum chains user_story: As a developer, I want to understand the specific methods available in the NodeInterface content_type: reference -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- The Arbitrum Nitro software includes a special `NodeInterface` contract available at address `0xc8` that is only accessible via RPCs (it's not actually deployed onchain, and thus can't be called by smart contracts). This reference page documents the specific calls available in the `NodeInterface`. For a more conceptual description of what it is and how it works, please refer to the [`NodeInterface` conceptual page](/build-decentralized-apps/nodeinterface/01-overview.mdx). diff --git a/docs/build-decentralized-apps/oracles/01-overview.mdx b/docs/build-decentralized-apps/oracles/01-overview.mdx index a4228fbe40..6f323431f6 100644 --- a/docs/build-decentralized-apps/oracles/01-overview.mdx +++ b/docs/build-decentralized-apps/oracles/01-overview.mdx @@ -5,7 +5,7 @@ description: A high level description of what oracles are user_story: As a developer, I want to understand what oracles are and how they work. content_type: concept sidebar_label: Oracles -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/build-decentralized-apps/precompiles/01-overview.mdx b/docs/build-decentralized-apps/precompiles/01-overview.mdx index 6b87a8c694..caad074ccd 100644 --- a/docs/build-decentralized-apps/precompiles/01-overview.mdx +++ b/docs/build-decentralized-apps/precompiles/01-overview.mdx @@ -3,7 +3,7 @@ title: 'Precompiles overview' description: A high level description of what precompiles are and how they work user_story: As a developer, I want to understand what precompiles are and how they work. content_type: concept -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Precompiles are predefined smart contracts that have special addresses and provide specific functionality which is executed not at the EVM bytecode level, but natively by the Arbitrum client itself. Precompiles are primarily used to introduce specific functions that would be computationally expensive if executed in EVM bytecode, and functions that facilitate the interaction between the parent chain and the child chain. By having them natively in the Arbitrum client, they can be optimized for performance. diff --git a/docs/build-decentralized-apps/precompiles/02-reference.mdx b/docs/build-decentralized-apps/precompiles/02-reference.mdx index 9a02c4fac4..d7ade097b3 100644 --- a/docs/build-decentralized-apps/precompiles/02-reference.mdx +++ b/docs/build-decentralized-apps/precompiles/02-reference.mdx @@ -3,7 +3,7 @@ title: 'Precompiles reference' description: A reference page of all precompiles available on Arbitrum chains user_story: As a developer, I want to understand the most useful precompiles available on Arbitrum chains and how to use them. content_type: reference -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- ArbOS provides child chain-specific precompiles with methods smart contracts can call the same way they can solidity functions. This reference page exhaustively documents the specific calls ArbOS makes available through precompiles. For a more conceptual description of what precompiles are and how they work, please refer to the [precompiles conceptual page](/build-decentralized-apps/precompiles/01-overview.mdx). diff --git a/docs/build-decentralized-apps/reference/01-node-providers.mdx b/docs/build-decentralized-apps/reference/01-node-providers.mdx index 1a6016b0cd..a3fd4af1d4 100644 --- a/docs/build-decentralized-apps/reference/01-node-providers.mdx +++ b/docs/build-decentralized-apps/reference/01-node-providers.mdx @@ -3,7 +3,7 @@ title: 'RPC endpoints and providers' description: Find available RPC endpoints and providers in the ecosystem reader_audience: developers who want to build on Arbitrum content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import ArbitrumRpcEndpoints from '../../partials/_reference-arbitrum-rpc-endpoints-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/02-contract-addresses.mdx b/docs/build-decentralized-apps/reference/02-contract-addresses.mdx index 01c4f451dd..5e91a09c55 100644 --- a/docs/build-decentralized-apps/reference/02-contract-addresses.mdx +++ b/docs/build-decentralized-apps/reference/02-contract-addresses.mdx @@ -6,7 +6,7 @@ author: anegg0 sme: anegg0 user_story: As a current or prospective Arbitrum user I need to know to what addresses Arbitrum contracts have been deployed. content_type: reference -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import ArbitrumContractAddresses from '../../partials/_reference-arbitrum-contract-addresses-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/03-chain-params.mdx b/docs/build-decentralized-apps/reference/03-chain-params.mdx index 221f35769a..fa5926041e 100644 --- a/docs/build-decentralized-apps/reference/03-chain-params.mdx +++ b/docs/build-decentralized-apps/reference/03-chain-params.mdx @@ -3,7 +3,7 @@ title: 'Chain parameters' description: Information about important system parameters for public Arbitrum chains user_story: As a developer, I want to understand the system parameters for the public Arbitrum chains. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- | Param | Description | Arbitrum One | Arbitrum Nova | Arb Sepolia | diff --git a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx index 8b7ac1eccb..f67a2ade1f 100644 --- a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx +++ b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx @@ -3,7 +3,7 @@ title: 'Development frameworks' description: An overview of popular development frameworks that exist in the Arbitrum ecosystem user_story: As a developer, I want to understand the popular development frameworks that exist in the Arbitrum ecosystem. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import KnowMoreToolsBox from '../../for-devs/partials/_know-more-tools-box-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/05-web3-libraries-tools.mdx b/docs/build-decentralized-apps/reference/05-web3-libraries-tools.mdx index 103f5582f1..3915f5f3db 100644 --- a/docs/build-decentralized-apps/reference/05-web3-libraries-tools.mdx +++ b/docs/build-decentralized-apps/reference/05-web3-libraries-tools.mdx @@ -3,7 +3,7 @@ title: 'Web3 libraries and tools' description: An overview of some popular Web3 libraries that help developers interact with the Ethereum and Arbitrum blockchains. user_story: As a developer, I want to understand what Web3 libraries and tools are available in the Ethereum and Arbitrum ecosystems. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import KnowMoreToolsBox from '../../for-devs/partials/_know-more-tools-box-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx b/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx index 2b59378770..23c3a82c61 100644 --- a/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx +++ b/docs/build-decentralized-apps/reference/06-monitoring-tools-block-explorers.mdx @@ -3,7 +3,7 @@ title: 'Monitoring tools and block explorers' description: An overview of popular monitoring tools and block explorers that exist in the Arbitrum ecosystem user_story: As a developer, I want to understand what monitoring tools and block explorers are available in the Arbitrum ecosystem. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import KnowMoreToolsBox from '../../for-devs/partials/_know-more-tools-box-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/07-debugging-tools.mdx b/docs/build-decentralized-apps/reference/07-debugging-tools.mdx index 22fe44b703..17a64fb0f5 100644 --- a/docs/build-decentralized-apps/reference/07-debugging-tools.mdx +++ b/docs/build-decentralized-apps/reference/07-debugging-tools.mdx @@ -3,7 +3,7 @@ title: 'Debugging tools' description: An overview of popular debugging tools that exist in the Arbitrum ecosystem user_story: As a developer, I want to understand what debugging tools are available in the Arbitrum ecosystem. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import KnowMoreToolsBox from '../../for-devs/partials/_know-more-tools-box-partial.mdx'; diff --git a/docs/build-decentralized-apps/reference/08-mainnet-risks.mdx b/docs/build-decentralized-apps/reference/08-mainnet-risks.mdx index 0431279295..219e3bae3f 100644 --- a/docs/build-decentralized-apps/reference/08-mainnet-risks.mdx +++ b/docs/build-decentralized-apps/reference/08-mainnet-risks.mdx @@ -2,7 +2,7 @@ title: 'Arbitrum: Understanding the risks' description: 'Understand the risks associated with cutting-edge software development' author: dzgoldman -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- # Arbitrum: Understanding the risks diff --git a/docs/build-decentralized-apps/token-bridging/01-overview.mdx b/docs/build-decentralized-apps/token-bridging/01-overview.mdx index 139e5b1ccd..0992179ad7 100644 --- a/docs/build-decentralized-apps/token-bridging/01-overview.mdx +++ b/docs/build-decentralized-apps/token-bridging/01-overview.mdx @@ -5,7 +5,7 @@ author: dzgoldman user_story: As a developer, I want to understand how the token bridge works and what options exist to bridge assets between layers. content_type: overview sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Token bridging is a fundamental aspect of any Layer 2 (child chain) protocol. Arbitrum uses its ability to pass messages between parent and child chains (see [Cross-chain messaging](/build-decentralized-apps/04-cross-chain-messaging.mdx)) to enable projects to move assets between Ethereum and an Arbitrum chain trustlessly, and vice versa. Any asset and asset type in principle can be bridged, including `ETH`, `ERC-20` tokens, and `ERC-721` tokens, among others. diff --git a/docs/build-decentralized-apps/token-bridging/02-token-bridge-ether.mdx b/docs/build-decentralized-apps/token-bridging/02-token-bridge-ether.mdx index d6f4803f34..7a99151a64 100644 --- a/docs/build-decentralized-apps/token-bridging/02-token-bridge-ether.mdx +++ b/docs/build-decentralized-apps/token-bridging/02-token-bridge-ether.mdx @@ -5,7 +5,7 @@ author: dzgoldman user_story: As a developer, I want to understand how bridging ether works on Arbitrum content_type: concept sidebar_position: 2 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx b/docs/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx index cbaa2cfe8a..99a1eaa60c 100644 --- a/docs/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx +++ b/docs/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx @@ -5,7 +5,7 @@ author: dzgoldman user_story: As a developer, I want to understand how ERC-20 token bridging works on Arbitrum, and the architecture of the token bridge. content_type: concept sidebar_position: 3 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx index 93ed153406..b35bd528c2 100644 --- a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx +++ b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx @@ -3,7 +3,7 @@ title: 'Get started with token bridging' description: Learn the different options available to bridge tokens programmatically user_story: As a developer, I want to understand how to bridge tokens between Ethereum and Arbitrum. content_type: overview -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- Token bridging is a fundamental aspect of any child chain protocol. It allows projects to quickly integrate with the Arbitrum ecosystem by leveraging their existing parent chain tokens. diff --git a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/02-how-to-bridge-tokens-standard.mdx b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/02-how-to-bridge-tokens-standard.mdx index 3412398745..7679ab82d1 100644 --- a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/02-how-to-bridge-tokens-standard.mdx +++ b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/02-how-to-bridge-tokens-standard.mdx @@ -3,7 +3,7 @@ title: "Bridge tokens via Arbitrum's standard `ERC-20` gateway" description: Learn how to programmatically bridge tokens between Ethereum and Arbitrum using Arbitrumโ€™s standard ER-C20 gateway user_story: As a developer, I want to understand how to bridge tokens between Ethereum and Arbitrum using the standard ER-C20 gateway. content_type: how-to -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- In this how-to, youโ€™ll learn how to bridge your own token between Ethereum (parent chain) and Arbitrum (child chain), using [Arbitrumโ€™s standard `ERC20` gateway](/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx#default-standard-bridging). For alternative ways of bridging tokens, donโ€™t forget to check out this [overview](/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx). diff --git a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/03-how-to-bridge-tokens-generic-custom.mdx b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/03-how-to-bridge-tokens-generic-custom.mdx index 81c8acd8f9..c1bf69c54a 100644 --- a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/03-how-to-bridge-tokens-generic-custom.mdx +++ b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/03-how-to-bridge-tokens-generic-custom.mdx @@ -3,7 +3,7 @@ title: 'Bridge tokens via Arbitrumโ€™s generic-custom gateway' description: Learn how to use the generic-custom gateway to bridge tokens programmatically user_story: As a developer, I want to understand how to bridge tokens between Ethereum and Arbitrum using the generic-custom gateway content_type: how-to -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- In this how-to, youโ€™ll learn how to bridge your own token between Ethereum (parent chain) and Arbitrum (child chain), using [Arbitrumโ€™s generic-custom gateway](/build-decentralized-apps/token-bridging/03-token-bridge-erc20.mdx#the-arbitrum-generic-custom-gateway). For alternative ways of bridging tokens, donโ€™t forget to check out this [overview](/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/01-get-started.mdx). diff --git a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/04-how-to-bridge-tokens-custom-gateway.mdx b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/04-how-to-bridge-tokens-custom-gateway.mdx index 29b7fbb608..3ad4a6ea84 100644 --- a/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/04-how-to-bridge-tokens-custom-gateway.mdx +++ b/docs/build-decentralized-apps/token-bridging/bridge-tokens-programmatically/04-how-to-bridge-tokens-custom-gateway.mdx @@ -3,7 +3,7 @@ title: 'How to bridge tokens via a custom gateway' description: Learn how to set up a custom gateway using Arbitrum's Token Bridge to bridge tokens programmatically reader_audience: developers who want to build on Ethereum/Arbitrum and bridge tokens between layers content_type: how-to -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildSoliditySidebar --- :::caution Do you really need a custom gateway? From d699ba0f23eb97e8a8e790bc93eb8bcdd4b5e768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 12:01:20 -0800 Subject: [PATCH 052/162] Update Stylus pages to use buildStylusSidebar Change displayed_sidebar frontmatter from buildAppsSidebar to buildStylusSidebar for all Stylus documentation pages. --- docs/stylus/advanced/hostio-exports.mdx | 2 +- docs/stylus/advanced/minimal-entrypoint-contracts.mdx | 2 +- docs/stylus/advanced/solidity-differences.mdx | 2 +- docs/stylus/concepts/activation.mdx | 2 +- docs/stylus/concepts/caching-strategy.mdx | 2 +- docs/stylus/concepts/evm-differences.mdx | 2 +- docs/stylus/concepts/gas-metering.mdx | 2 +- docs/stylus/concepts/webassembly.mdx | 5 ++--- docs/stylus/gentle-introduction.mdx | 2 +- .../how-tos/adding-support-for-new-languages.mdx | 2 +- docs/stylus/how-tos/caching-contracts.mdx | 2 +- docs/stylus/how-tos/check-and-deploy.mdx | 11 +++++++++++ docs/stylus/how-tos/debugging-tx.mdx | 2 +- .../how-tos/deploying-non-rust-wasm-contracts.mdx | 2 +- docs/stylus/how-tos/exporting-abi.mdx | 2 +- docs/stylus/how-tos/optimizing-binaries.mdx | 2 +- docs/stylus/how-tos/testing-contracts.mdx | 2 +- docs/stylus/how-tos/using-constructors.mdx | 2 +- docs/stylus/how-tos/using-inheritance.mdx | 2 +- docs/stylus/how-tos/verifying-contracts-arbiscan.mdx | 2 +- docs/stylus/how-tos/verifying-contracts.mdx | 2 +- docs/stylus/quickstart.mdx | 2 +- docs/stylus/reference/contracts.mdx | 2 +- docs/stylus/reference/data-types/compound-types.mdx | 2 +- .../data-types/conversions-between-types.mdx | 2 +- docs/stylus/reference/data-types/primitives.mdx | 2 +- docs/stylus/reference/data-types/storage.mdx | 2 +- .../reference/global-variables-and-functions.mdx | 2 +- docs/stylus/reference/project-structure.mdx | 2 +- docs/stylus/using-cli.mdx | 2 +- 30 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 docs/stylus/how-tos/check-and-deploy.mdx diff --git a/docs/stylus/advanced/hostio-exports.mdx b/docs/stylus/advanced/hostio-exports.mdx index 85849bc4dc..80210af745 100644 --- a/docs/stylus/advanced/hostio-exports.mdx +++ b/docs/stylus/advanced/hostio-exports.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers who need to understand how to use hostio exports with Stylus. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Hostio (Host I/O) exports are low-level functions that provide direct access to the Stylus VM runtime. These functions are WebAssembly imports that allow Stylus programs to interact with the blockchain environment, similar to how EVM opcodes work in Solidity. diff --git a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx index e291439ec7..d3d530ba7f 100644 --- a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx +++ b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers who need to understand how to build a minimal entrypoint contract without high-level macros. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- This guide explains the low-level mechanics of Stylus contract entrypoints, helping you understand what happens behind the `#[entrypoint]` and `#[public]` macros. This knowledge is useful for advanced use cases, debugging, and building custom contract frameworks. diff --git a/docs/stylus/advanced/solidity-differences.mdx b/docs/stylus/advanced/solidity-differences.mdx index 456ef0503f..984ab66bc4 100644 --- a/docs/stylus/advanced/solidity-differences.mdx +++ b/docs/stylus/advanced/solidity-differences.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers who need to compare Stylus with Solidity. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus introduces a new paradigm for writing smart contracts on Arbitrum using Rust and other WebAssembly-compatible languages. While Stylus contracts maintain full interoperability with Solidity contracts, there are important differences in how you structure and write code. This guide helps Solidity developers understand these differences. diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index f8b0762318..24c8edf9ed 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers deploying Stylus contracts to Arbitrum chains. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus contracts undergo a two-step process to become executable on Arbitrum chains: **deployment** and **activation**. This guide explains both steps, the distinction between them, and how to manage the activation process. diff --git a/docs/stylus/concepts/caching-strategy.mdx b/docs/stylus/concepts/caching-strategy.mdx index 3bed5bb6fd..5208761d74 100644 --- a/docs/stylus/concepts/caching-strategy.mdx +++ b/docs/stylus/concepts/caching-strategy.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: . -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- TBD diff --git a/docs/stylus/concepts/evm-differences.mdx b/docs/stylus/concepts/evm-differences.mdx index 37535cf2e5..e844c7a6ee 100644 --- a/docs/stylus/concepts/evm-differences.mdx +++ b/docs/stylus/concepts/evm-differences.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers who need to understand how Stylus works with EVM differences. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Arbitrum Nitro supports two execution environments: the traditional Ethereum Virtual Machine (EVM) for Solidity contracts and a WebAssembly (WASM) VM for Stylus contracts. While both environments are fully interoperable and share the same state, they differ significantly in their execution models, performance characteristics, and developer experience. diff --git a/docs/stylus/concepts/gas-metering.mdx b/docs/stylus/concepts/gas-metering.mdx index 9354556719..c10a902f0d 100644 --- a/docs/stylus/concepts/gas-metering.mdx +++ b/docs/stylus/concepts/gas-metering.mdx @@ -5,7 +5,7 @@ author: rachel-bousfield sme: rachel-bousfield target_audience: 'Developers deploying smart contracts using Stylus.' sidebar_position: 3 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- **Gas and ink** are the pricing primitives that are used to determine the cost of handling specific opcodes and host I/Os on Stylus. For an overview of specific opcode and host I/O costs, see [Gas and ink costs](/stylus/reference/opcode-hostio-pricing). diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 6e623a603b..bcea948e71 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -4,11 +4,10 @@ description: 'Understanding WebAssembly compilation, deployment, and execution i author: chrisco sme: chrisco sidebar_position: 1 -target_audience: Developers who need to understand how WebAssembly works in the context of Nitro and Stylus smart contracts. -displayed_sidebar: buildAppsSidebar +target_audience: Developers who need to understand how Stylus works with WebAssembly. +displayed_sidebar: buildStylusSidebar --- -# WebAssembly in Nitro WebAssembly (WASM) is a binary instruction format that enables high-performance execution of programs in the Nitro virtual machine. This guide explains how WASM works in the context of Arbitrum Nitro and Stylus smart contract development. diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 1ec4540453..f4e9b8b3d4 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -6,7 +6,7 @@ author: amarrazza sme: amarrazza target_audience: 'Developers who want to build on Arbitrum using popular programming languages, like Rust' sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/stylus/how-tos/adding-support-for-new-languages.mdx b/docs/stylus/how-tos/adding-support-for-new-languages.mdx index 3dd295f010..527e09fd95 100644 --- a/docs/stylus/how-tos/adding-support-for-new-languages.mdx +++ b/docs/stylus/how-tos/adding-support-for-new-languages.mdx @@ -6,7 +6,7 @@ sme: rauljordan target_audience: 'Developers deploying smart contracts using Stylus' content_type: how-to sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- [Arbitrum Stylus](../gentle-introduction.mdx) is a new technology developed for Arbitrum chains which gives smart contract developers superpowers. With Stylus, developers can write EVM-compatible smart contracts in many different programming languages, and reap massive performance gains. Stylus slashes fees, with performance gains ranging from 10-70x, and memory efficiency gains as high as 100-500x. diff --git a/docs/stylus/how-tos/caching-contracts.mdx b/docs/stylus/how-tos/caching-contracts.mdx index 92c3a75094..cd55d7d5c7 100644 --- a/docs/stylus/how-tos/caching-contracts.mdx +++ b/docs/stylus/how-tos/caching-contracts.mdx @@ -5,7 +5,7 @@ description: 'A conceptual overview of the Stylus caching strategy and CacheMana sme: mahsa-moosavi target_audience: 'Developers deploying smart contracts using Stylus.' sidebar_position: 3 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus is designed for fast computation and efficiency. However, diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx new file mode 100644 index 0000000000..07527ae53b --- /dev/null +++ b/docs/stylus/how-tos/check-and-deploy.mdx @@ -0,0 +1,11 @@ +--- +title: 'Check and deploy' +description: 'Check and deploy Stylus contracts' +author: chrisco +sme: chrisco +sidebar_position: 1 +target_audience: Developers who need to understand how to check and deploy Stylus contracts. +displayed_sidebar: buildStylusSidebar +--- + +TBD diff --git a/docs/stylus/how-tos/debugging-tx.mdx b/docs/stylus/how-tos/debugging-tx.mdx index c47cb69116..2cba8db919 100644 --- a/docs/stylus/how-tos/debugging-tx.mdx +++ b/docs/stylus/how-tos/debugging-tx.mdx @@ -7,7 +7,7 @@ sme: mahsamoosavi target_audience: 'Developers deploying smart contracts using Stylus' content_type: how-to sidebar_position: 2 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Debugging smart contracts can be challenging, especially when dealing with complex transactions. The `cargo-stylus` crate simplifies the debugging process by allowing developers to replay Stylus transactions. This tool leverages GDB to provide an interactive debugging experience, enabling developers to set breakpoints, inspect state changes, and trace the execution flow step-by-step. This capability is crucial for identifying and resolving issues, ensuring that smart contracts function correctly and efficiently. diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx index 97bd94cd1a..52c5e34f60 100644 --- a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -7,7 +7,7 @@ sme: chrisco target_audience: 'Developers who need to deploy non-Rust WASM contracts' content_type: how-to sidebar_position: 2 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- TBD diff --git a/docs/stylus/how-tos/exporting-abi.mdx b/docs/stylus/how-tos/exporting-abi.mdx index 579319a42e..d50d82fe94 100644 --- a/docs/stylus/how-tos/exporting-abi.mdx +++ b/docs/stylus/how-tos/exporting-abi.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers who need to understand how to check and deploy Stylus contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- TBD diff --git a/docs/stylus/how-tos/optimizing-binaries.mdx b/docs/stylus/how-tos/optimizing-binaries.mdx index 9924b3f5b6..c8de5e1323 100644 --- a/docs/stylus/how-tos/optimizing-binaries.mdx +++ b/docs/stylus/how-tos/optimizing-binaries.mdx @@ -6,7 +6,7 @@ sme: rauljordan target_audience: 'Developers deploying smart contracts using Stylus' content_type: how-to sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- To be deployed onchain, the size of your **uncompressed WebAssembly (WASM) file** must not exceed 128Kb, while the **compressed binary** must not exceed 24KB. Stylus conforms with the same contract size limit as the EVM to remain fully interoperable with all smart contracts on Arbitrum chains. diff --git a/docs/stylus/how-tos/testing-contracts.mdx b/docs/stylus/how-tos/testing-contracts.mdx index dd61568bb5..c960961ba2 100644 --- a/docs/stylus/how-tos/testing-contracts.mdx +++ b/docs/stylus/how-tos/testing-contracts.mdx @@ -5,7 +5,7 @@ description: 'A comprehensive guide to writing and running tests for Stylus smar sme: anegg0 target_audience: 'Developers writing smart contracts using Stylus.' sidebar_position: 3 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import CustomDetails from '@site/src/components/CustomDetails'; diff --git a/docs/stylus/how-tos/using-constructors.mdx b/docs/stylus/how-tos/using-constructors.mdx index c50a713bd4..8f58324d2c 100644 --- a/docs/stylus/how-tos/using-constructors.mdx +++ b/docs/stylus/how-tos/using-constructors.mdx @@ -7,7 +7,7 @@ sme: 'anegg0' user_story: 'As a Rust developer, I want to understand how to implement and use constructors in Stylus smart contracts' content_type: 'how-to' sidebar_position: 3 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import CustomDetails from '@site/src/components/CustomDetails'; diff --git a/docs/stylus/how-tos/using-inheritance.mdx b/docs/stylus/how-tos/using-inheritance.mdx index 155ff8813f..a413e427d1 100644 --- a/docs/stylus/how-tos/using-inheritance.mdx +++ b/docs/stylus/how-tos/using-inheritance.mdx @@ -5,7 +5,7 @@ author: anegg0 sme: mahsamoosavi content_type: how-to sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import CustomDetails from '@site/src/components/CustomDetails'; diff --git a/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx b/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx index 358f20ba2c..54a6420c9b 100644 --- a/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx +++ b/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx @@ -6,7 +6,7 @@ sme: mahsamoosavi target_audience: 'Developers deploying smart contracts using Stylus' content_type: how-to sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/stylus/how-tos/verifying-contracts.mdx b/docs/stylus/how-tos/verifying-contracts.mdx index 819ec19f4b..e19d19e036 100644 --- a/docs/stylus/how-tos/verifying-contracts.mdx +++ b/docs/stylus/how-tos/verifying-contracts.mdx @@ -8,7 +8,7 @@ target_audience: 'Developers learning how to use Stylus' sidebar_position: 2 user_story: 'As a current or prospective Stylus user, I want to learn how to make sure my Stylus contracts deployment are reproducible by anyone running the same environment.' content_type: how-to -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- :::caution diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index a3b28c3042..7651067793 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -6,7 +6,7 @@ author: chrisco512, anegg0 sme: chrisco512, anegg0 sidebar_position: 2 target_audience: Developers writing Stylus contracts in Rust using Stylus -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import ImageZoom from '@site/src/components/ImageZoom'; diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx index 3a3bc982f1..0b23a35abb 100644 --- a/docs/stylus/reference/contracts.mdx +++ b/docs/stylus/reference/contracts.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 2 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus smart contracts are fully compatible with Solidity contracts on Arbitrum chains. They compile to WebAssembly and share the same EVM state trie as Solidity contracts, enabling seamless interoperability. diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/reference/data-types/compound-types.mdx index 4de7cedb30..00b7e89b2b 100644 --- a/docs/stylus/reference/data-types/compound-types.mdx +++ b/docs/stylus/reference/data-types/compound-types.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 2 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Compound types allow you to group multiple values together in Stylus contracts. The SDK provides full support for tuples, structs, arrays, and vectors with automatic ABI encoding/decoding and Solidity type mappings. diff --git a/docs/stylus/reference/data-types/conversions-between-types.mdx b/docs/stylus/reference/data-types/conversions-between-types.mdx index 4e8478dfc9..e2f77358e8 100644 --- a/docs/stylus/reference/data-types/conversions-between-types.mdx +++ b/docs/stylus/reference/data-types/conversions-between-types.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus smart contracts often need to convert between different type representations: Rust native types, Alloy primitives, and Solidity types. The Stylus SDK provides comprehensive conversion mechanisms through the `AbiType` trait and various standard Rust conversion traits. diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/reference/data-types/primitives.mdx index ee5ce71227..d46d8c6f1b 100644 --- a/docs/stylus/reference/data-types/primitives.mdx +++ b/docs/stylus/reference/data-types/primitives.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- The Stylus SDK provides full support for Rust primitive types with automatic ABI encoding/decoding and Solidity type mappings. These primitives can be used in contract method signatures, storage, and as function parameters. diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 82461b39fa..8f353542fe 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 3 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Persistent storage in Stylus contracts provides access to the EVM State Trie, the same key-value storage used by Solidity contracts. The SDK provides type-safe storage access through dedicated storage types that prevent aliasing errors at compile time using Rust's borrow checker. diff --git a/docs/stylus/reference/global-variables-and-functions.mdx b/docs/stylus/reference/global-variables-and-functions.mdx index 4b45b9e45a..8d0bafbb19 100644 --- a/docs/stylus/reference/global-variables-and-functions.mdx +++ b/docs/stylus/reference/global-variables-and-functions.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 3 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Stylus contracts access blockchain context and utilities through the VM (Virtual Machine) interface via `self.vm()`. This provides access to message context, block information, transaction details, account data, cryptographic functions, and gas metering. diff --git a/docs/stylus/reference/project-structure.mdx b/docs/stylus/reference/project-structure.mdx index 1d978c2c51..e6f6cd19c8 100644 --- a/docs/stylus/reference/project-structure.mdx +++ b/docs/stylus/reference/project-structure.mdx @@ -5,7 +5,7 @@ author: chrisco sme: chrisco sidebar_position: 1 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- Contracts in Rust are similar to contracts in Solidity. Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Errors, Struct Types, and Enum Types. In addition, Rust contracts can import third-party packages from [crates.io](https://crates.io) as dependencies and use them for advanced functionality. diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index 9fa36931e9..da6b73b4fa 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -6,7 +6,7 @@ author: 'anegg0' sme: 'anegg0' sidebar_position: 2 target_audience: Developers writing Stylus contracts in Rust using Stylus -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. From 5e512b6439ecea0288beb0b014727c7db9737097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 13:51:43 -0800 Subject: [PATCH 053/162] re-clean up old webassembly content + sidebar --- sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sidebars.js b/sidebars.js index 643adbba7f..8898bd368b 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1763,7 +1763,7 @@ const sidebars = { { type: 'doc', id: 'stylus/concepts/webassembly', - label: 'Check and deploy', + label: 'webassembly', }, { type: 'doc', From 9130f99ccdb5c5beb78dbcb1b5c66f2fda846a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 14:16:14 -0800 Subject: [PATCH 054/162] docs: add comprehensive check and deploy guide for Stylus Add detailed documentation for validating and deploying Stylus contracts: - Prerequisites and setup requirements - Two-step deployment process (deploy + activate) - cargo stylus check command with validation details - cargo stylus deploy command with all options - Activation process and data fee calculation - Development and production workflows - Best practices for secure deployment - Comprehensive troubleshooting section - Non-Rust WASM deployment support - Command reference and examples --- docs/stylus/how-tos/check-and-deploy.mdx | 772 ++++++++++++++++++++++- 1 file changed, 771 insertions(+), 1 deletion(-) diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx index 07527ae53b..ea35051def 100644 --- a/docs/stylus/how-tos/check-and-deploy.mdx +++ b/docs/stylus/how-tos/check-and-deploy.mdx @@ -8,4 +8,774 @@ target_audience: Developers who need to understand how to check and deploy Stylu displayed_sidebar: buildStylusSidebar --- -TBD +# Check and Deploy Stylus Contracts + +This guide explains how to validate and deploy Stylus smart contracts using the `cargo stylus` CLI tool. The process involves two main steps: checking that your contract is valid, and deploying it to an Arbitrum chain. + +## Prerequisites + +Before checking or deploying contracts, ensure you have: + +1. **Rust toolchain** installed (see [rustup.rs](https://rustup.rs)) +2. **WebAssembly target** added: + ```shell + rustup target add wasm32-unknown-unknown + ``` +3. **cargo-stylus CLI** installed: + ```shell + cargo install cargo-stylus + ``` +4. **RPC endpoint** for the target chain (see [testnet information](https://docs.arbitrum.io/stylus/reference/testnet-information)) +5. **Funded account** with ETH for gas and activation fees + +## Overview: The Two-Step Process + +Deploying a Stylus contract involves two distinct steps: + +1. **Deployment**: Upload the compressed WASM bytecode to the chain, assigning it an address +2. **Activation**: Trigger onchain compilation to native code and cache it for fast execution + +The `cargo stylus check` command validates your contract before deployment, and `cargo stylus deploy` handles both steps automatically. + +## Checking Contracts + +The `cargo stylus check` command validates that your contract can be deployed and activated without actually sending a transaction. + +### What check does + +1. **Compiles** your Rust code to WASM with `wasm32-unknown-unknown` target +2. **Compresses** the WASM using brotli compression +3. **Validates** the WASM structure: + - Required exports (`user_entrypoint`) + - Allowed imports (only `vm_hooks`) + - Memory constraints + - Size limits (24KB compressed) +4. **Simulates activation** using `eth_call` to verify onchain compatibility +5. **Estimates data fee** required for activation + +### Basic usage + +```shell +# Check the current project against Arbitrum Sepolia (default) +cargo stylus check +``` + +### Common options + +```shell +# Check against a specific network +cargo stylus check \ + --endpoint="https://arb1.arbitrum.io/rpc" + +# Check a specific WASM file +cargo stylus check \ + --wasm-file=./target/wasm32-unknown-unknown/release/my_contract.wasm + +# Check with a specific contract address +cargo stylus check \ + --contract-address=0x1234567890123456789012345678901234567890 +``` + +### Success output + +When your contract passes validation: + +```shell +Finished release [optimized] target(s) in 1.88s +Reading WASM file at target/wasm32-unknown-unknown/release/my_contract.wasm +Compressed WASM size: 3 KB +Contract succeeded Stylus onchain activation checks with Stylus version: 1 +wasm data fee: 0.0001 ETH (originally 0.00008 ETH with 20% bump) +``` + +### Failure output + +If validation fails, you'll see detailed error information: + +```shell +Reading WASM file at target/wasm32-unknown-unknown/release/bad_contract.wasm +Compressed WASM size: 55 B +Stylus checks failed: contract predeployment check failed + +Caused by: + binary exports reserved symbol stylus_ink_left + +Location: + prover/src/binary.rs:493:9 +``` + +Common validation errors include: + +- **Missing entrypoint**: Contract lacks `#[entrypoint]` attribute +- **Invalid exports**: Contract exports reserved symbols +- **Size limit exceeded**: Compressed WASM exceeds 24KB +- **Invalid imports**: Contract imports functions outside `vm_hooks` +- **Memory violations**: Incorrect memory handling or growth + +## Deploying Contracts + +The `cargo stylus deploy` command compiles, deploys, and activates your contract in a single operation. + +### What deploy does + +1. **Compiles and checks** the contract (same as `cargo stylus check`) +2. **Deploys bytecode**: Sends transaction to upload compressed WASM to the chain +3. **Activates contract**: Calls `activateProgram` precompile to compile to native code +4. **Verifies success**: Confirms both transactions completed successfully + +### Basic deployment + +```shell +# Deploy to Arbitrum Sepolia (default testnet) +cargo stylus deploy \ + --private-key-path=./key.txt +``` + +### Deployment with gas estimation + +Before deploying, estimate the gas required: + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt \ + --estimate-gas +``` + +Output: + +```shell +Compressed WASM size: 3 KB +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Estimated gas: 12756792 +wasm data fee: 0.0001 ETH +``` + +### Full deployment + +Once estimation looks correct, deploy for real: + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt +``` + +Output shows both transactions: + +```shell +Compressed WASM size: 3 KB +Deploying contract to address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Estimated gas: 12756792 +Submitting tx... +Confirmed tx 0x42db...7311, gas used 11657164 + +Activating contract at address 0x457b1ba688e9854bdbed2f473f7510c476a3da09 +Estimated gas: 14251759 +Submitting tx... +Confirmed tx 0x0bdb...3307, gas used 14204908 +``` + +### Deployment options + +#### Network selection + +```shell +# Deploy to Arbitrum One (mainnet) +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt + +# Deploy to Arbitrum Sepolia (testnet) +cargo stylus deploy \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" \ + --private-key-path=./key.txt +``` + +#### Private key management + +```shell +# From file (recommended) +cargo stylus deploy \ + --private-key-path=./key.txt + +# From environment (WARNING: exposes key to shell history) +cargo stylus deploy \ + --private-key=$PRIVATE_KEY + +# From keystore file +cargo stylus deploy \ + --keystore-path=./keystore.json \ + --keystore-password-path=./password.txt +``` + +#### Gas price control + +```shell +# Set custom gas price (in gwei) +cargo stylus deploy \ + --private-key-path=./key.txt \ + --max-fee-per-gas-gwei=0.05 +``` + +#### Deploy without activation + +For advanced use cases, deploy bytecode without immediate activation: + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt \ + --no-activate +``` + +Later, activate separately: + +```shell +cargo stylus activate \ + --address=0x457b1ba688e9854bdbed2f473f7510c476a3da09 \ + --private-key-path=./key.txt +``` + +#### Constructor arguments + +Deploy contracts with constructor arguments: + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt \ + --constructor-args "Hello" "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb" 42 +``` + +Send ETH to payable constructor: + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt \ + --constructor-value=0.1 \ + --constructor-args "InitialValue" +``` + +#### Reproducible builds + +For contract verification, use Docker-based reproducible builds: + +```shell +# Default: uses Docker for reproducibility +cargo stylus deploy \ + --private-key-path=./key.txt + +# Specify cargo-stylus version +cargo stylus deploy \ + --private-key-path=./key.txt \ + --cargo-stylus-version=0.5.0 +``` + +Skip Docker for local development (non-reproducible): + +```shell +cargo stylus deploy \ + --private-key-path=./key.txt \ + --no-verify +``` + +## Understanding Activation + +Activation is the process of compiling WASM to native machine code onchain. + +### Why activation is required + +- **Performance**: Native code executes 10-100x faster than interpreted WASM +- **Validation**: Ensures WASM is well-formed and follows all constraints +- **Caching**: Compiled code is cached for all future contract calls + +### Activation process + +1. **Decompress**: Brotli-compressed WASM is decompressed +2. **Validate**: WASM structure is checked for correctness +3. **Compile**: WASM is compiled to native machine code +4. **Cache**: Compiled code is stored in the activation cache +5. **Charge fee**: Data fee based on WASM size is charged + +### Data fee calculation + +The data fee depends on the size of your WASM: + +```rust +// From activation.rs +pub async fn data_fee( + code: impl Into, + address: Address, + config: &ActivationConfig, + provider: &impl Provider, +) -> Result { + let result = arbwasm + .activateProgram(address) + .call() + .await?; + + let data_fee = result.dataFee; + let bump = config.data_fee_bump_percent; // Default 20% + let adjusted = bump_data_fee(data_fee, bump); + + Ok(adjusted) +} +``` + +By default, the fee is bumped by 20% to account for gas price fluctuations. + +### Activation errors + +Common activation failures: + +#### Missing entrypoint + +``` +Error: Contract could not be activated as it is missing an entrypoint. +Please ensure that your contract has an #[entrypoint] defined on your main struct +``` + +**Solution**: Add `#[entrypoint]` to your main storage struct: + +```rust +#[entrypoint] +#[storage] +pub struct MyContract { + // ... +} +``` + +#### Insufficient funds + +``` +Error: not enough funds in account 0x... to pay for data fee +balance 0.0001 ETH < 0.0005 ETH +``` + +**Solution**: Fund your account with more ETH. Get testnet ETH from faucets: + +- [Arbitrum Sepolia faucet](https://faucet.quicknode.com/arbitrum/sepolia) + +#### Invalid WASM + +``` +Error: contract activation failed: failed to parse contract +Caused by: binary exports reserved symbol stylus_ink_left +``` + +**Solution**: Ensure you're using the latest `stylus-sdk` version and following SDK conventions. + +## Deployment Workflows + +### Development workflow + +For rapid iteration during development: + +```shell +# 1. Check frequently during development +cargo stylus check + +# 2. Deploy to testnet with no-verify for speed +cargo stylus deploy \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" \ + --private-key-path=./key.txt \ + --no-verify + +# 3. Test the deployed contract +# (use your testing framework) + +# 4. Iterate and redeploy as needed +``` + +### Production workflow + +For production deployments: + +```shell +# 1. Final check against mainnet +cargo stylus check \ + --endpoint="https://arb1.arbitrum.io/rpc" + +# 2. Estimate costs +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt \ + --estimate-gas + +# 3. Deploy with reproducible build (for verification) +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt \ + --cargo-stylus-version=0.5.0 + +# 4. Verify the deployed contract +cargo stylus verify \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --deployment-tx=0x... +``` + +### Multi-contract deployment + +Deploy multiple contracts from a workspace: + +```shell +# Check all contracts in workspace +cargo stylus check + +# Deploy specific contract +cargo stylus deploy \ + --contract=my-token \ + --private-key-path=./key.txt + +# Deploy all contracts (must have no-arg constructors) +cargo stylus deploy \ + --private-key-path=./key.txt +``` + +## Checking Existing Deployments + +### Check if contract is activated + +```rust +// From check.rs +let codehash = processed.codehash(); +if Contract::exists(codehash, &provider).await? { + return Ok(ContractStatus::Active { + code: processed.code, + }); +} +``` + +Use `cargo stylus check` with `--contract-address` to verify an existing deployment: + +```shell +cargo stylus check \ + --contract-address=0x457b1ba688e9854bdbed2f473f7510c476a3da09 +``` + +### Re-activation + +If a contract is already deployed but not activated, activate it: + +```shell +cargo stylus activate \ + --address=0x457b1ba688e9854bdbed2f473f7510c476a3da09 \ + --private-key-path=./key.txt +``` + +## Best Practices + +### 1. Always check before deploying + +```shell +# โœ… Good: Check first +cargo stylus check +cargo stylus deploy --private-key-path=./key.txt + +# โŒ Bad: Deploy without checking +cargo stylus deploy --private-key-path=./key.txt +``` + +### 2. Use gas estimation + +```shell +# โœ… Good: Estimate first +cargo stylus deploy --private-key-path=./key.txt --estimate-gas +# Review the output, then deploy for real +cargo stylus deploy --private-key-path=./key.txt + +# โŒ Bad: Deploy without estimation +cargo stylus deploy --private-key-path=./key.txt +``` + +### 3. Secure private key handling + +```shell +# โœ… Good: Use key file +echo $PRIVATE_KEY > /tmp/key.txt +chmod 600 /tmp/key.txt +cargo stylus deploy --private-key-path=/tmp/key.txt +rm /tmp/key.txt + +# โš ๏ธ Risky: Expose key in command line +cargo stylus deploy --private-key=$PRIVATE_KEY +``` + +### 4. Test on testnet first + +```shell +# โœ… Good: Test on Sepolia first +cargo stylus deploy \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" \ + --private-key-path=./key.txt + +# After testing succeeds, deploy to mainnet +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt + +# โŒ Bad: Deploy directly to mainnet +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt +``` + +### 5. Use reproducible builds for verification + +```shell +# โœ… Good: Reproducible build for mainnet +cargo stylus deploy \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --private-key-path=./key.txt \ + --cargo-stylus-version=0.5.0 + +# Then verify on Arbiscan +cargo stylus verify \ + --endpoint="https://arb1.arbitrum.io/rpc" \ + --deployment-tx=0x... + +# โš ๏ธ OK for development: Skip Docker +cargo stylus deploy \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" \ + --private-key-path=./key.txt \ + --no-verify +``` + +### 6. Monitor contract size + +```shell +# Check compressed size +cargo stylus check + +# If size is close to 24KB limit: +# - Use #[no_std] +# - Remove unused dependencies +# - Enable aggressive optimizations +# - Strip debug symbols +``` + +### 7. Verify data fee is reasonable + +```shell +# Check data fee before deploying +cargo stylus deploy --private-key-path=./key.txt --estimate-gas + +# Output shows: +# wasm data fee: 0.0001 ETH (originally 0.00008 ETH with 20% bump) + +# If fee seems high: +# - Optimize WASM size +# - Check network congestion +# - Verify contract correctness +``` + +## Troubleshooting + +### Size limit errors + +**Error**: Compressed WASM exceeds 24KB + +**Solutions**: + +1. Use `#[no_std]` to eliminate standard library: + + ```rust + #![no_std] + extern crate alloc; + ``` + +2. Remove unused dependencies from `Cargo.toml`: + + ```toml + [dependencies] + stylus-sdk = "0.5" + # Remove unnecessary crates + ``` + +3. Enable size optimizations in `Cargo.toml`: + + ```toml + [profile.release] + opt-level = "z" + lto = true + strip = true + ``` + +4. Use `wasm-opt` for additional optimization: + ```shell + wasm-opt -Oz -o optimized.wasm input.wasm + cargo stylus deploy --wasm-file=optimized.wasm --private-key-path=./key.txt + ``` + +### Activation failures + +**Error**: Transaction reverted during activation + +**Solutions**: + +1. Verify entrypoint exists: + + ```rust + #[entrypoint] + #[storage] + pub struct MyContract { /* ... */ } + ``` + +2. Check WASM validity: + + ```shell + cargo stylus check --wasm-file=./target/wasm32-unknown-unknown/release/my_contract.wasm + ``` + +3. Ensure sufficient funds: + + ```shell + # Check balance + cast balance $YOUR_ADDRESS --rpc-url $RPC_URL + + # Get testnet ETH if needed + # Visit faucet.quicknode.com/arbitrum/sepolia + ``` + +### RPC errors + +**Error**: Connection timeout or RPC error + +**Solutions**: + +1. Verify endpoint URL: + + ```shell + curl -X POST $RPC_URL \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' + ``` + +2. Try alternative endpoints: + + ```shell + # Arbitrum One + --endpoint="https://arb1.arbitrum.io/rpc" + --endpoint="https://arbitrum-one.publicnode.com" + + # Arbitrum Sepolia + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" + --endpoint="https://arbitrum-sepolia.blockpi.network/v1/rpc/public" + ``` + +3. Check network status: + - [Arbitrum Status](https://arbiscan.io/) + - [Chainlist](https://chainlist.org/) + +### Build errors + +**Error**: Compilation fails + +**Solutions**: + +1. Update dependencies: + + ```shell + cargo update + ``` + +2. Clear build cache: + + ```shell + cargo clean + ``` + +3. Verify Rust toolchain: + + ```shell + rustup update + rustup target add wasm32-unknown-unknown + ``` + +4. Check SDK version compatibility: + ```toml + [dependencies] + stylus-sdk = "0.5" # Use latest stable version + ``` + +## Non-Rust WASM Deployment + +Deploy WASM from any language (C, C++, etc.): + +```shell +# Deploy raw WASM file +cargo stylus deploy \ + --wasm-file=./my_contract.wasm \ + --private-key-path=./key.txt + +# Deploy WebAssembly Text (WAT) file +cargo stylus deploy \ + --wasm-file=./my_contract.wat \ + --private-key-path=./key.txt +``` + +Example WAT file structure: + +```wasm +(module + (memory 0 0) + (export "memory" (memory 0)) + (func (export "user_entrypoint") (param $args_len i32) (result i32) + (i32.const 0) + )) +``` + +## Command Reference + +### cargo stylus check + +**Syntax**: + +```shell +cargo stylus check [OPTIONS] +``` + +**Common options**: + +- `--endpoint=`: RPC endpoint (default: Arbitrum Sepolia) +- `--wasm-file=`: Check specific WASM file +- `--contract-address=
`: Target contract address + +### cargo stylus deploy + +**Syntax**: + +```shell +cargo stylus deploy [OPTIONS] +``` + +**Common options**: + +- `--endpoint=`: RPC endpoint +- `--private-key-path=`: Private key file +- `--estimate-gas`: Only estimate gas +- `--no-activate`: Deploy without activation +- `--no-verify`: Skip Docker reproducible build +- `--constructor-args `: Constructor arguments +- `--constructor-value=`: ETH sent to constructor +- `--max-fee-per-gas-gwei=`: Custom gas price + +### cargo stylus activate + +**Syntax**: + +```shell +cargo stylus activate --address=
[OPTIONS] +``` + +**Options**: + +- `--address=
`: Deployed contract address (required) +- `--private-key-path=`: Private key file +- `--estimate-gas`: Only estimate gas + +## Resources + +- [Stylus quickstart guide](https://docs.arbitrum.io/stylus/stylus-quickstart) +- [Cargo Stylus repository](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) +- [Testnet information](https://docs.arbitrum.io/stylus/reference/testnet-information) +- [Contract verification guide](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts) +- [Optimizing WASM size](https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md) +- [Valid WASM requirements](https://github.com/OffchainLabs/cargo-stylus/blob/main/VALID_WASM.md) From 670e60c0a4a79b33f25d6f5a8571c0404b08c671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 14:22:52 -0800 Subject: [PATCH 055/162] docs: add comprehensive ABI export guide for Stylus Add detailed documentation for exporting Solidity ABIs from Stylus contracts: - Overview of ABI generation process - Basic usage of cargo stylus export-abi - Solidity interface and JSON format output - Writing ABI-compatible contracts with #[public] macro - Function visibility mapping (view, pure, payable) - Type mapping between Rust and Solidity - Custom errors and events - Trait implementation and interface inheritance - Constructor signature export - Front-end integration (ethers.js, viem, wagmi) - Solidity contract integration - Export configuration options - Best practices for ABI management - Troubleshooting common issues - Multi-contract workspace support --- docs/stylus/how-tos/exporting-abi.mdx | 995 +++++++++++++++++++++++++- 1 file changed, 991 insertions(+), 4 deletions(-) diff --git a/docs/stylus/how-tos/exporting-abi.mdx b/docs/stylus/how-tos/exporting-abi.mdx index d50d82fe94..6696f81d9d 100644 --- a/docs/stylus/how-tos/exporting-abi.mdx +++ b/docs/stylus/how-tos/exporting-abi.mdx @@ -1,11 +1,998 @@ --- title: 'Exporting ABIs' -description: 'Exporting ABIs' +description: 'Exporting Solidity ABIs from Stylus contracts' author: chrisco sme: chrisco -sidebar_position: 1 -target_audience: Developers who need to understand how to check and deploy Stylus contracts. +sidebar_position: 2 +target_audience: Developers who need to understand how to export ABIs from Stylus contracts for integration with front-end applications and other tools. displayed_sidebar: buildStylusSidebar --- -TBD +# Exporting Solidity ABIs + +Stylus contracts written in Rust can automatically generate Solidity Application Binary Interfaces (ABIs) that enable seamless interoperability with existing Ethereum tools, front-end libraries, and other smart contracts. + +## What is an ABI? + +An Application Binary Interface (ABI) defines how to interact with a smart contract: + +- **Function signatures**: Names, parameters, and return types +- **Events**: Event definitions and indexed parameters +- **Errors**: Custom error types and parameters +- **Constructor**: Initialization parameters + +ABIs enable: + +- Front-end libraries (ethers.js, web3.js, viem) to interact with contracts +- Solidity contracts to call Rust contracts +- Block explorers to decode transactions +- Development tools to provide type-safe interfaces + +## Overview: ABI Generation + +Stylus contracts generate ABIs through: + +1. **`#[public]` macro**: Annotates public functions +2. **`export-abi` feature**: Enables ABI generation code +3. **`cargo stylus export-abi`**: CLI command to generate output +4. **Solidity interface**: Generated Solidity interface file +5. **JSON format**: Optional JSON ABI for tool integration + +The process is automaticโ€”just annotate your functions with `#[public]` and run the export command. + +## Basic Usage + +### Export Solidity interface + +Generate a Solidity interface for your contract: + +```shell +cargo stylus export-abi +``` + +Output: + +```solidity +/** + * This file was automatically generated by Stylus and represents a Rust program. + * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs). + */ + +// SPDX-License-Identifier: MIT-OR-APACHE-2.0 +pragma solidity ^0.8.23; + +interface IMyContract { + function getValue() external view returns (uint256); + + function setValue(uint256 new_value) external; + + error Unauthorized(address caller); +} +``` + +### Export to file + +Save the interface to a file: + +```shell +cargo stylus export-abi > IMyContract.sol +``` + +Or specify output path: + +```shell +cargo stylus export-abi --output=./interfaces/IMyContract.sol +``` + +### Export JSON ABI + +Generate JSON format ABI (requires `solc` installed): + +```shell +cargo stylus export-abi --json > abi.json +``` + +Output: + +```json +[ + { + "type": "function", + "name": "getValue", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setValue", + "inputs": [ + { + "name": "new_value", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + } +] +``` + +## Writing ABI-Compatible Contracts + +### Basic contract structure + +Contracts must use the `#[public]` macro to generate ABIs: + +```rust +use stylus_sdk::{alloy_primitives::U256, prelude::*}; + +sol_storage! { + #[entrypoint] + pub struct Counter { + uint256 count; + } +} + +#[public] +impl Counter { + // This function will be included in the ABI + pub fn get_count(&self) -> U256 { + self.count.get() + } + + // This function will also be included + pub fn increment(&mut self) { + let count = self.count.get() + U256::from(1); + self.count.set(count); + } +} +``` + +Generated interface: + +```solidity +interface ICounter { + function getCount() external view returns (uint256); + + function increment() external; +} +``` + +### Function visibility mapping + +Rust function signatures map to Solidity visibility: + +```rust +#[public] +impl MyContract { + // Immutable reference โ†’ view function + pub fn read_value(&self) -> U256 { + self.value.get() + } + + // Mutable reference โ†’ non-view function + pub fn write_value(&mut self, new_value: U256) { + self.value.set(new_value); + } + + // Pure computation (no self) โ†’ pure function + pub fn compute(a: U256, b: U256) -> U256 { + a + b + } +} +``` + +Generated Solidity: + +```solidity +interface IMyContract { + function readValue() external view returns (uint256); + + function writeValue(uint256 new_value) external; + + function compute(uint256 a, uint256 b) external pure returns (uint256); +} +``` + +### Type mapping + +Rust types map to Solidity types automatically: + +| Rust Type | Solidity Type | Example | +| ------------------------- | ------------------------------------- | ---------------------- | +| `U256` | `uint256` | Token amounts | +| `U128`, `u128` | `uint128` | Medium integers | +| `u64`, `u32`, `u16`, `u8` | `uint64`, `uint32`, `uint16`, `uint8` | Small integers | +| `I256` | `int256` | Signed integers | +| `Address` | `address` | Account addresses | +| `bool` | `bool` | Boolean values | +| `FixedBytes` | `bytesN` | Fixed-size byte arrays | +| `Bytes` | `bytes` | Dynamic byte arrays | +| `String` | `string` | UTF-8 strings | +| `Vec` | `T[]` | Dynamic arrays | +| `[T; N]` | `T[N]` | Fixed-size arrays | + +Example: + +```rust +#[public] +impl MyContract { + pub fn process( + owner: Address, + amount: U256, + data: Bytes, + flags: Vec, + ) -> Result { + // Implementation + } +} +``` + +Generates: + +```solidity +interface IMyContract { + function process( + address owner, + uint256 amount, + bytes calldata data, + bool[] calldata flags + ) external returns (string memory); +} +``` + +### Custom errors + +Define custom errors with parameters: + +```rust +use stylus_sdk::prelude::*; + +sol! { + error InsufficientBalance(address account, uint256 requested, uint256 available); + error Unauthorized(address caller); + error InvalidAmount(); +} + +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, amount: U256) -> Result<(), InsufficientBalance> { + let balance = self.balances.get(msg::sender()); + if balance < amount { + return Err(InsufficientBalance { + account: msg::sender(), + requested: amount, + available: balance, + }); + } + // Transfer logic + Ok(()) + } +} +``` + +Generated interface includes errors: + +```solidity +interface IToken { + function transfer(address to, uint256 amount) external; + + error InsufficientBalance(address account, uint256 requested, uint256 available); + error Unauthorized(address caller); + error InvalidAmount(); +} +``` + +### Events + +Events are automatically included in the ABI: + +```rust +use stylus_sdk::prelude::*; + +sol! { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + +#[public] +impl Token { + pub fn transfer(&mut self, to: Address, value: U256) -> bool { + // Transfer logic + evm::log(Transfer { + from: msg::sender(), + to, + value, + }); + true + } +} +``` + +Generated interface: + +```solidity +interface IToken { + function transfer(address to, uint256 value) external returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} +``` + +## Trait Implementation + +Export ABIs for trait implementations: + +### Define a trait + +```rust +// ierc20.rs +use stylus_sdk::prelude::*; + +#[public] +pub trait IErc20 { + fn name(&self) -> String; + fn symbol(&self) -> String; + fn decimals(&self) -> u8; + fn total_supply(&self) -> U256; + fn balance_of(&self, owner: Address) -> U256; + fn transfer(&mut self, to: Address, value: U256) -> Result; +} +``` + +### Implement the trait + +```rust +// lib.rs +use stylus_sdk::prelude::*; + +sol_storage! { + #[entrypoint] + struct MyToken { + // Storage fields + } +} + +#[public] +#[implements(IErc20)] +impl MyToken { + // Additional functions beyond the trait + pub fn mint(&mut self, to: Address, value: U256) { + // Mint logic + } +} + +#[public] +impl IErc20 for MyToken { + fn name(&self) -> String { + "My Token".to_string() + } + + fn symbol(&self) -> String { + "MTK".to_string() + } + + fn decimals(&self) -> u8 { + 18 + } + + fn total_supply(&self) -> U256 { + self.total_supply.get() + } + + fn balance_of(&self, owner: Address) -> U256 { + self.balances.get(owner) + } + + fn transfer(&mut self, to: Address, value: U256) -> Result { + // Transfer logic + Ok(true) + } +} +``` + +Generated interface with inheritance: + +```solidity +interface IMyToken is IIErc20 { + function mint(address to, uint256 value) external; +} + +interface IIErc20 { + function name() external view returns (string memory); + function symbol() external view returns (string memory); + function decimals() external view returns (uint8); + function totalSupply() external view returns (uint256); + function balanceOf(address owner) external view returns (uint256); + function transfer(address to, uint256 value) external returns (bool); +} +``` + +## Constructor Signatures + +Export constructor signatures for deployment: + +```rust +sol_storage! { + #[entrypoint] + struct MyContract { + address owner; + uint256 initial_value; + } +} + +#[public] +impl MyContract { + #[constructor] + pub fn new(owner: Address, initial_value: U256) { + self.owner.set(owner); + self.initial_value.set(initial_value); + } + + // Other methods... +} +``` + +Export constructor signature: + +```shell +cargo stylus export-abi constructor +``` + +Output: + +``` +constructor(address owner, uint256 initial_value) +``` + +For payable constructors: + +```rust +#[public] +impl MyContract { + #[constructor] + #[payable] + pub fn new(owner: Address) { + self.owner.set(owner); + // msg::value() is available + } +} +``` + +Output: + +``` +constructor(address owner) payable +``` + +## Export Configuration + +### Custom license + +Specify a custom SPDX license identifier: + +```shell +cargo stylus export-abi --license=GPL-3.0 +``` + +Output includes: + +```solidity +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.23; +``` + +### Custom pragma + +Specify a custom Solidity version pragma: + +```shell +cargo stylus export-abi --pragma="pragma solidity ^0.8.20;" +``` + +### Rust features + +Export ABI with specific Rust features enabled: + +```shell +cargo stylus export-abi --rust-features=feature1,feature2 +``` + +This is useful when your contract has conditional compilation: + +```rust +#[cfg(feature = "advanced")] +#[public] +impl MyContract { + pub fn advanced_function(&self) -> U256 { + // Advanced logic + } +} +``` + +## Integration with Front-End + +### Using ethers.js + +```typescript +import { ethers } from 'ethers'; +import MyContractABI from './abi.json'; + +const provider = new ethers.JsonRpcProvider('https://arb1.arbitrum.io/rpc'); +const contract = new ethers.Contract( + '0x1234567890123456789012345678901234567890', + MyContractABI, + provider, +); + +// Call view function +const value = await contract.getValue(); +console.log('Value:', value.toString()); + +// Call state-changing function (requires signer) +const signer = provider.getSigner(); +const contractWithSigner = contract.connect(signer); +const tx = await contractWithSigner.setValue(42); +await tx.wait(); +``` + +### Using viem + +```typescript +import { createPublicClient, http } from 'viem'; +import { arbitrum } from 'viem/chains'; +import MyContractABI from './abi.json'; + +const client = createPublicClient({ + chain: arbitrum, + transport: http(), +}); + +// Read contract +const value = await client.readContract({ + address: '0x1234567890123456789012345678901234567890', + abi: MyContractABI, + functionName: 'getValue', +}); + +// Write contract +const hash = await client.writeContract({ + address: '0x1234567890123456789012345678901234567890', + abi: MyContractABI, + functionName: 'setValue', + args: [42n], +}); +``` + +### Using wagmi/RainbowKit + +```typescript +import { useContractRead, useContractWrite } from 'wagmi'; +import MyContractABI from './abi.json'; + +function MyComponent() { + // Read contract + const { data: value } = useContractRead({ + address: '0x1234567890123456789012345678901234567890', + abi: MyContractABI, + functionName: 'getValue', + }); + + // Write contract + const { write } = useContractWrite({ + address: '0x1234567890123456789012345678901234567890', + abi: MyContractABI, + functionName: 'setValue', + }); + + return ( +
+

Current value: {value?.toString()}

+ +
+ ); +} +``` + +## Solidity Integration + +Use exported interfaces in Solidity contracts: + +### Import the interface + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +import "./IMyContract.sol"; + +contract SolidityContract { + IMyContract public stylusContract; + + constructor(address _stylusContract) { + stylusContract = IMyContract(_stylusContract); + } + + function interactWithStylus() external { + // Read from Stylus contract + uint256 value = stylusContract.getValue(); + + // Write to Stylus contract + stylusContract.setValue(value + 1); + } +} +``` + +### Cross-language composition + +Combine Solidity and Rust contracts: + +```solidity +contract Router { + IToken public token; + IStaking public staking; + + constructor(address _token, address _staking) { + token = IToken(_token); // Rust contract + staking = IStaking(_staking); // Rust contract + } + + function stakeTokens(uint256 amount) external { + // Transfer tokens (Rust contract) + require( + token.transferFrom(msg.sender, address(this), amount), + "Transfer failed" + ); + + // Stake tokens (Rust contract) + token.approve(address(staking), amount); + staking.stake(msg.sender, amount); + } +} +``` + +## How It Works + +### The export-abi feature + +The `export-abi` feature enables ABI generation: + +```toml +# Cargo.toml +[features] +export-abi = ["stylus-sdk/export-abi"] + +[lib] +crate-type = ["lib", "cdylib"] +``` + +When enabled, the SDK generates: + +1. A `GenerateAbi` trait implementation +2. A CLI entry point for running ABI export +3. Formatting logic for Solidity interface generation + +### Main function + +Your contract needs a main function for ABI export: + +```rust +// main.rs +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] + +#[cfg(not(any(test, feature = "export-abi")))] +#[no_mangle] +pub extern "C" fn main() {} + +#[cfg(feature = "export-abi")] +fn main() { + my_contract::print_from_args(); +} +``` + +This main function: + +- Runs only when `export-abi` feature is enabled +- Executes the ABI generation logic +- Outputs the Solidity interface to stdout + +### The #[public] macro + +The `#[public]` macro generates ABI code: + +```rust +// From stylus-proc/src/macros/public/export_abi.rs +impl GenerateAbi for MyContract { + const NAME: &'static str = "MyContract"; + + fn fmt_abi(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "interface I{} {{", Self::NAME)?; + // Generate function signatures + write!(f, "\n function getValue() external view returns (uint256);")?; + writeln!(f, "}}")?; + Ok(()) + } +} +``` + +Key transformations: + +- `snake_case` โ†’ `camelCase` function names +- Rust types โ†’ Solidity types +- `&self` โ†’ `view`, `&mut self` โ†’ non-view +- `Result` โ†’ return type `T`, error `E` + +## Best Practices + +### 1. Always export ABIs for integration + +```shell +# โœ… Good: Generate and version control ABIs +cargo stylus export-abi > interfaces/IMyContract.sol +git add interfaces/IMyContract.sol +git commit -m "Update contract ABI" + +# โŒ Bad: Rely on manual interface definitions +``` + +### 2. Use semantic function names + +```rust +// โœ… Good: Clear, descriptive names +#[public] +impl Token { + pub fn get_balance(&self, account: Address) -> U256 { } + pub fn transfer_from(&mut self, from: Address, to: Address, amount: U256) { } +} + +// โŒ Bad: Unclear abbreviations +#[public] +impl Token { + pub fn bal(&self, acc: Address) -> U256 { } + pub fn xfer(&mut self, f: Address, t: Address, amt: U256) { } +} +``` + +### 3. Document complex functions + +```rust +#[public] +impl Staking { + /// Stakes tokens for a specified duration + /// + /// # Arguments + /// * `amount` - Amount of tokens to stake + /// * `duration` - Lock duration in seconds + /// + /// # Returns + /// The unique stake ID + pub fn stake(&mut self, amount: U256, duration: u64) -> U256 { + // Implementation + } +} +``` + +### 4. Export JSON for tooling + +```shell +# โœ… Good: Generate both formats +cargo stylus export-abi > IMyContract.sol +cargo stylus export-abi --json > abi.json + +# Share with front-end team +cp abi.json ../frontend/src/abis/ +``` + +### 5. Version control constructor changes + +When adding or modifying constructors, regenerate and commit: + +```shell +cargo stylus export-abi constructor > CONSTRUCTOR.txt +git add CONSTRUCTOR.txt +git commit -m "Update constructor signature" +``` + +### 6. Test ABI compatibility + +```typescript +// test/abi.test.ts +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import MyContractABI from '../abi.json'; + +describe('ABI Compatibility', () => { + it('should match deployed contract', async () => { + const contract = await ethers.getContractAt(MyContractABI, deployedAddress); + + // Verify functions exist + expect(contract.getValue).to.exist; + expect(contract.setValue).to.exist; + + // Call and verify + const value = await contract.getValue(); + expect(value).to.be.a('bigint'); + }); +}); +``` + +### 7. Keep interfaces synchronized + +Use CI/CD to verify ABI is up to date: + +```yaml +# .github/workflows/check-abi.yml +name: Check ABI + +on: [pull_request] + +jobs: + check-abi: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Rust + uses: actions-rs/toolchain@v1 + - name: Generate ABI + run: cargo stylus export-abi > /tmp/abi.sol + - name: Check for changes + run: diff /tmp/abi.sol interfaces/IMyContract.sol +``` + +## Troubleshooting + +### solc not found + +**Error**: `failed to run solc: No such file or directory` + +**Solution**: Install Solidity compiler: + +```shell +# macOS +brew install solidity + +# Ubuntu/Debian +sudo add-apt-repository ppa:ethereum/ethereum +sudo apt-get update +sudo apt-get install solc + +# Or use solc-select +pip install solc-select +solc-select install 0.8.23 +solc-select use 0.8.23 +``` + +### Feature not enabled + +**Error**: `no main function` + +**Solution**: Ensure `export-abi` feature is defined and main.rs exists: + +```toml +# Cargo.toml +[features] +export-abi = ["stylus-sdk/export-abi"] +``` + +```rust +// main.rs +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] + +#[cfg(feature = "export-abi")] +fn main() { + my_contract::print_from_args(); +} +``` + +### Type not supported + +**Error**: `the trait AbiType is not implemented for MyType` + +**Solution**: Use supported types or implement `AbiType`: + +```rust +// โœ… Use supported types +pub fn process(&self, amount: U256) -> U256 { } + +// โŒ Custom types need AbiType implementation +pub fn process(&self, amount: MyCustomType) -> MyCustomType { } +``` + +For custom types, implement `AbiType`: + +```rust +use stylus_sdk::abi::AbiType; + +#[derive(Clone)] +struct MyType(U256); + +impl AbiType for MyType { + type SolType = alloy_sol_types::sol_data::Uint<256>; + + fn encode(&self) -> Vec { + self.0.encode() + } + + fn decode(data: &[u8]) -> Result { + U256::decode(data).map(MyType) + } +} +``` + +### Missing function in ABI + +**Error**: Function doesn't appear in exported ABI + +**Solutions**: + +1. Ensure function is in `#[public]` impl block: + + ```rust + #[public] + impl MyContract { + pub fn my_function(&self) -> U256 { } // โœ… Exported + } + + impl MyContract { + pub fn helper(&self) -> U256 { } // โŒ Not exported + } + ``` + +2. Check function visibility is `pub`: + ```rust + #[public] + impl MyContract { + pub fn exported(&self) -> U256 { } // โœ… Exported + fn not_exported(&self) -> U256 { } // โŒ Not exported + } + ``` + +## Advanced: Multiple Contracts + +Export ABIs for all contracts in a workspace: + +```shell +# Export specific contract +cargo stylus export-abi --contract=my-token + +# Export all contracts +for contract in token staking governance; do + cargo stylus export-abi --contract=$contract > interfaces/I${contract^}.sol +done +``` + +Or create a script: + +```shell +#!/bin/bash +# export-all-abis.sh + +contracts=("token" "staking" "governance") + +for contract in "${contracts[@]}"; do + echo "Exporting ABI for $contract..." + cargo stylus export-abi --contract=$contract > "interfaces/I${contract^}.sol" + cargo stylus export-abi --contract=$contract --json > "abis/${contract}.json" +done + +echo "โœ… All ABIs exported" +``` + +## Resources + +- [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) +- [Cargo Stylus CLI](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) +- [ERC-20 example](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/examples/erc20) +- [ABI specification](https://docs.soliditylang.org/en/latest/abi-spec.html) +- [ethers.js documentation](https://docs.ethers.org/) +- [viem documentation](https://viem.sh/) +- [wagmi documentation](https://wagmi.sh/) From ce71d8f9c9a3a40d5b5547936b00b30729027c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 14:32:38 -0800 Subject: [PATCH 056/162] fix title flag --- docs/stylus/how-tos/exporting-abi.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/how-tos/exporting-abi.mdx b/docs/stylus/how-tos/exporting-abi.mdx index 6696f81d9d..f75a1e2945 100644 --- a/docs/stylus/how-tos/exporting-abi.mdx +++ b/docs/stylus/how-tos/exporting-abi.mdx @@ -8,8 +8,6 @@ target_audience: Developers who need to understand how to export ABIs from Stylu displayed_sidebar: buildStylusSidebar --- -# Exporting Solidity ABIs - Stylus contracts written in Rust can automatically generate Solidity Application Binary Interfaces (ABIs) that enable seamless interoperability with existing Ethereum tools, front-end libraries, and other smart contracts. ## What is an ABI? From 1ac03282fabcd8064303094c392a140d67e2fc93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 14:38:19 -0800 Subject: [PATCH 057/162] docs: add comprehensive guide for deploying non-Rust WASM contracts Add detailed documentation for deploying WebAssembly contracts from languages other than Rust: - Overview of non-Rust WASM deployment with --wasm-file flag - When to choose non-Rust vs Rust (use case comparison) - WASM module requirements (exports, imports, memory) - WebAssembly Text (WAT) examples (minimal, echo, counter) - C/C++ development with Stylus C SDK - C SDK features and building with Makefile - Cryptography example in C - AssemblyScript contract development - Complete deployment workflow (prepare, optimize, check, deploy) - Best practices for size optimization and memory management - Troubleshooting common issues (entrypoint, imports, memory, size) - Language support matrix (Rust, C/C++, WAT, AssemblyScript, etc.) - Advanced custom language integration guide --- .../deploying-non-rust-wasm-contracts.mdx | 798 +++++++++++++++++- 1 file changed, 795 insertions(+), 3 deletions(-) diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx index 52c5e34f60..bf17673f71 100644 --- a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -1,13 +1,805 @@ --- id: deploying-non-rust-wasm-contracts title: 'Deploying non-Rust WASM contracts' -description: 'Deploying non-Rust WASM contracts' +description: 'Deploy WebAssembly contracts from C, C++, and other languages to Arbitrum Stylus' author: chrisco sme: chrisco target_audience: 'Developers who need to deploy non-Rust WASM contracts' content_type: how-to -sidebar_position: 2 +sidebar_position: 3 displayed_sidebar: buildStylusSidebar --- -TBD +# Deploying Non-Rust WASM Contracts + +While Rust provides the best developer experience for Stylus, any language that compiles to WebAssembly can be deployed. This guide explains how to deploy WASM contracts written in C, C++, or even pure WebAssembly Text (WAT). + +## Overview + +Stylus accepts any valid WebAssembly module that meets its requirements. You can: + +- Write contracts in **C or C++** using the Stylus C SDK +- Use **WebAssembly Text (WAT)** for direct bytecode control +- Compile from **any language** that targets `wasm32-unknown-unknown` +- Deploy **pre-compiled WASM** binaries directly + +The key is using the `--wasm-file` flag with `cargo stylus` commands to bypass Rust compilation. + +## Why Use Non-Rust Languages? + +Different languages excel at different tasks: + +| Language | Best For | Use Cases | +| ------------------ | -------------------------------------- | -------------------------------------------------- | +| **C/C++** | Low-level control, cryptography | Hash functions, signature verification, algorithms | +| **WAT** | Learning, debugging, minimal contracts | Simple logic, educational examples | +| **AssemblyScript** | TypeScript developers | Web3 integration with familiar syntax | +| **Other** | Specific requirements | Domain-specific computations | + +### When to choose non-Rust + +- **Existing codebase**: Port existing C/C++ cryptography libraries +- **Performance-critical**: Hand-optimized assembly-like control +- **Minimal size**: Ultra-compact contracts for specific operations +- **Team expertise**: Leverage existing C/C++ knowledge + +### When to stick with Rust + +- **Full-featured contracts**: Complex DeFi, NFTs, governance +- **Type safety**: Strong guarantees and tooling +- **Ecosystem**: Rich library support and examples +- **Productivity**: Higher-level abstractions and macros + +## WASM Requirements + +All WASM modules deployed to Stylus must meet these requirements: + +### Required exports + +```wasm +(export "user_entrypoint" (func $user_entrypoint)) +(export "memory" (memory 0)) +``` + +The `user_entrypoint` function: + +- **Signature**: `(param i32) (result i32)` +- **Parameter**: Length of input calldata in bytes +- **Returns**: Length of output data in bytes + +### Allowed imports + +Only functions from the `vm_hooks` module are permitted: + +```wasm +(import "vm_hooks" "msg_sender" (func $msg_sender (param i32))) +(import "vm_hooks" "storage_load_bytes32" (func $storage_load (param i32 i32))) +(import "vm_hooks" "storage_store_bytes32" (func $storage_store (param i32 i32))) +``` + +See the [hostio exports documentation](/stylus/advanced/hostio-exports) for the complete list of available VM hooks. + +### Memory requirements + +- Linear memory must be exported as `"memory"` +- Memory growth must be explicitly paid for +- Initial memory size should be minimal (often `0 0`) +- Maximum memory is limited by gas costs + +### Compilation target + +- **Target triple**: `wasm32-unknown-unknown` +- **No standard library**: WASM runs in a sandboxed environment +- **No floating point**: Not yet supported by Stylus +- **No SIMD**: Not yet supported by Stylus +- **No reference types**: Disabled for compatibility + +## WebAssembly Text (WAT) + +WAT provides direct control over WASM bytecode using human-readable text format. + +### Minimal contract + +The simplest valid Stylus contract: + +```wasm +(module + ;; Export linear memory + (memory 0 0) + (export "memory" (memory 0)) + + ;; Required entrypoint + ;; Takes calldata length, returns output length + (func (export "user_entrypoint") (param $args_len i32) (result i32) + (i32.const 0) ;; Return 0 bytes + )) +``` + +Save as `minimal.wat` and deploy: + +```shell +cargo stylus deploy --wasm-file=minimal.wat --private-key-path=./key.txt +``` + +### Echo contract + +Returns input data unchanged: + +```wasm +(module + (memory 1 1) + (export "memory" (memory 0)) + + ;; Import VM hook to read calldata + (import "vm_hooks" "read_args" (func $read_args (param i32))) + + (func (export "user_entrypoint") (param $args_len i32) (result i32) + ;; Read calldata into memory at offset 0 + (call $read_args (i32.const 0)) + + ;; Return the same length (echo) + (local.get $args_len) + )) +``` + +### Storage counter + +Increment a value in storage: + +```wasm +(module + (memory 1 1) + (export "memory" (memory 0)) + + ;; Import storage operations + (import "vm_hooks" "storage_load_bytes32" + (func $storage_load (param i32 i32))) + (import "vm_hooks" "storage_store_bytes32" + (func $storage_store (param i32 i32))) + + (func (export "user_entrypoint") (param $args_len i32) (result i32) + ;; Load current value from storage slot 0 + (call $storage_load + (i32.const 0) ;; key pointer + (i32.const 32)) ;; value destination + + ;; Increment the value at memory[32] + (i32.store (i32.const 32) + (i32.add + (i32.load (i32.const 32)) + (i32.const 1))) + + ;; Store back to storage + (call $storage_store + (i32.const 0) ;; key pointer + (i32.const 32)) ;; value pointer + + ;; Return 0 bytes of output + (i32.const 0) + )) +``` + +### Checking WAT contracts + +Validate before deploying: + +```shell +cargo stylus check --wasm-file=counter.wat +``` + +Output shows validation results: + +``` +Reading WASM file at counter.wat +Compressed WASM size: 142 B +Contract succeeded Stylus onchain activation checks with Stylus version: 1 +``` + +## C/C++ Development + +The [Stylus C SDK](https://github.com/OffchainLabs/stylus-sdk-c) enables C/C++ smart contract development. + +### Installation + +Install the C SDK: + +```shell +git clone https://github.com/OffchainLabs/stylus-sdk-c.git +cd stylus-sdk-c +``` + +Install dependencies: + +```shell +# macOS +brew install llvm binaryen wabt + +# Ubuntu/Debian +sudo apt-get install clang lld wasm-ld binaryen wabt +``` + +### Project structure + +Basic C project layout: + +``` +my-contract/ +โ”œโ”€โ”€ Makefile +โ”œโ”€โ”€ src/ +โ”‚ โ””โ”€โ”€ main.c +โ””โ”€โ”€ include/ + โ””โ”€โ”€ stylus_sdk.h +``` + +### Simple C contract + +```c +// main.c +#include "stylus_sdk.h" + +// Storage slot for counter +static uint8_t counter_slot[32] = {0}; + +// Main entrypoint +int main(int argc, char *argv[]) { + // Load counter from storage + uint8_t value[32]; + storage_load_bytes32(counter_slot, value); + + // Increment + value[31]++; + + // Store back + storage_store_bytes32(counter_slot, value); + + return 0; +} +``` + +### C SDK features + +The C SDK provides: + +```c +// Account operations +void msg_sender(uint8_t *sender); +void tx_origin(uint8_t *origin); +void contract_address(uint8_t *addr); + +// Storage operations +void storage_load_bytes32(uint8_t *key, uint8_t *dest); +void storage_store_bytes32(uint8_t *key, uint8_t *value); + +// Block information +uint64_t block_timestamp(void); +uint64_t block_number(void); +void block_basefee(uint8_t *basefee); + +// Call operations +void call_contract( + uint8_t *contract, + uint8_t *calldata, + uint32_t calldata_len, + uint8_t *value, + uint32_t gas, + uint8_t *return_data_len +); + +// And many more... +``` + +### Building C contracts + +Create a Makefile: + +```makefile +CLANG = clang +WASM_LD = wasm-ld +WASM_OPT = wasm-opt + +CFLAGS = -target wasm32 -nostdlib -O3 +LDFLAGS = -no-entry --export=user_entrypoint --export=memory + +SRC = src/main.c +OUT = build/contract.wasm +OUT_OPT = build/contract-opt.wasm + +all: $(OUT_OPT) + +$(OUT): $(SRC) + mkdir -p build + $(CLANG) $(CFLAGS) -c $(SRC) -o build/main.o + $(WASM_LD) $(LDFLAGS) build/main.o -o $(OUT) + +$(OUT_OPT): $(OUT) + $(WASM_OPT) -Oz $(OUT) -o $(OUT_OPT) + +clean: + rm -rf build + +deploy: $(OUT_OPT) + cargo stylus deploy --wasm-file=$(OUT_OPT) \ + --private-key-path=$$PRIVATE_KEY_PATH + +check: $(OUT_OPT) + cargo stylus check --wasm-file=$(OUT_OPT) +``` + +Build and deploy: + +```shell +make +make check +make deploy +``` + +### C cryptography example + +Verifying a signature: + +```c +#include "stylus_sdk.h" +#include + +// Verify ECDSA signature +int verify_signature( + uint8_t *message_hash, + uint8_t *signature, + uint8_t *public_key +) { + uint8_t recovered[65]; + + // Recover signer from signature + if (ecrecover(message_hash, signature, recovered) != 0) { + return -1; // Recovery failed + } + + // Compare with expected public key + if (memcmp(recovered + 1, public_key, 64) == 0) { + return 0; // Valid signature + } + + return -1; // Invalid signature +} + +int main(int argc, char *argv[]) { + uint8_t msg_hash[32]; + uint8_t sig[65]; + uint8_t pubkey[64]; + + // Read inputs from calldata + read_args(0); + memcpy(msg_hash, memory, 32); + memcpy(sig, memory + 32, 65); + memcpy(pubkey, memory + 97, 64); + + // Verify + int result = verify_signature(msg_hash, sig, pubkey); + + // Write result + memory[0] = (result == 0) ? 1 : 0; + write_result(memory, 1); + + return 0; +} +``` + +## AssemblyScript Contracts + +AssemblyScript is TypeScript-like language that compiles to WebAssembly. + +### Installation + +```shell +npm install -g assemblyscript +npm install @assemblyscript/loader +``` + +### Simple AssemblyScript contract + +```typescript +// contract.ts + +// Import Stylus VM hooks +@external("vm_hooks", "msg_sender") +declare function msg_sender(ptr: usize): void; + +@external("vm_hooks", "storage_load_bytes32") +declare function storage_load(key: usize, dest: usize): void; + +@external("vm_hooks", "storage_store_bytes32") +declare function storage_store(key: usize, value: usize): void; + +// Storage key +const COUNTER_KEY: StaticArray = [0, 0, 0, 0, /* ... 32 zeros ... */]; + +// Entrypoint +export function user_entrypoint(args_len: i32): i32 { + // Load counter + let value = new StaticArray(32); + storage_load( + changetype(COUNTER_KEY), + changetype(value) + ); + + // Increment + value[31]++; + + // Store + storage_store( + changetype(COUNTER_KEY), + changetype(value) + ); + + return 0; // No output +} +``` + +### Compile AssemblyScript + +```shell +asc contract.ts \ + --target release \ + --exportRuntime \ + --exportTable \ + -o contract.wasm +``` + +### Deploy AssemblyScript contract + +```shell +cargo stylus deploy \ + --wasm-file=contract.wasm \ + --private-key-path=./key.txt +``` + +## Deployment Workflow + +### 1. Prepare your WASM + +Ensure your WASM module meets requirements: + +```shell +# Check WASM structure with wasm-objdump +wasm-objdump -x contract.wasm | grep -A 5 "Export\|Import" + +# Should show: +# Export[0]: +# - func[0] +# - memory[0] +# Import[0]: +# - module="vm_hooks" func=... +``` + +### 2. Optimize the WASM + +Reduce size with wasm-opt: + +```shell +wasm-opt -Oz contract.wasm -o contract-opt.wasm +``` + +### 3. Check before deploying + +Validate the contract: + +```shell +cargo stylus check --wasm-file=contract-opt.wasm +``` + +### 4. Deploy + +Deploy to testnet: + +```shell +cargo stylus deploy \ + --wasm-file=contract-opt.wasm \ + --private-key-path=./key.txt \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +### 5. Verify deployment + +Check deployment succeeded: + +```shell +# Output shows: +Compressed WASM size: 245 B +Deploying contract to address 0x... +Confirmed tx 0x... +Activating contract at address 0x... +Confirmed tx 0x... +``` + +## Best Practices + +### 1. Minimize binary size + +```shell +# โœ… Good: Optimize aggressively +wasm-opt -Oz input.wasm -o output.wasm + +# Use wasm-strip to remove symbols +wasm-strip output.wasm + +# Check final size +ls -lh output.wasm +``` + +### 2. Test with cargo stylus check + +```shell +# โœ… Good: Always check before deploying +cargo stylus check --wasm-file=contract.wasm + +# Test on testnet first +cargo stylus deploy \ + --wasm-file=contract.wasm \ + --private-key-path=./key.txt \ + --endpoint="https://sepolia-rollup.arbitrum.io/rpc" +``` + +### 3. Use standard memory layout + +```c +// โœ… Good: Predictable memory layout +uint8_t calldata[1024]; // 0-1023: Input data +uint8_t storage[32]; // 1024-1055: Storage scratch +uint8_t output[256]; // 1056-1311: Output buffer + +// โŒ Bad: Unpredictable allocations +uint8_t *data = malloc(size); // No malloc in WASM! +``` + +### 4. Handle calldata properly + +```wasm +;; โœ… Good: Read calldata into memory +(call $read_args (i32.const 0)) + +;; Process the data +(call $process_calldata (local.get $args_len)) + +;; โŒ Bad: Assume calldata location +(i32.load (i32.const 0)) ;; Calldata not automatically loaded +``` + +### 5. Export all required functions + +```wasm +;; โœ… Good: Export entrypoint and memory +(export "user_entrypoint" (func $main)) +(export "memory" (memory 0)) + +;; โŒ Bad: Missing exports +(export "main" (func $main)) ;; Wrong name! +``` + +### 6. Use VM hooks correctly + +```c +// โœ… Good: Proper VM hook usage +uint8_t sender[20]; +msg_sender(sender); + +// โœ… Good: Check return values +uint8_t success; +call_contract(addr, data, len, value, gas, &success); +if (!success) { + revert("Call failed"); +} + +// โŒ Bad: Ignoring errors +call_contract(addr, data, len, value, gas, NULL); +``` + +### 7. Mind the size limit + +```shell +# Check compressed size +cargo stylus check --wasm-file=contract.wasm + +# Should show: +# Compressed WASM size: < 24 KB + +# If too large: +# - Remove debug symbols +# - Enable aggressive optimization +# - Minimize code and data sections +``` + +## Troubleshooting + +### Missing entrypoint + +**Error**: `WASM is missing the entrypoint export` + +**Solution**: Ensure `user_entrypoint` is exported: + +```wasm +;; WAT +(func (export "user_entrypoint") (param i32) (result i32) + ;; Implementation +) + +// C +int user_entrypoint(int argc) __attribute__((export_name("user_entrypoint"))); +``` + +### Invalid imports + +**Error**: `contract imports unauthorized function` + +**Solution**: Only import from `vm_hooks`: + +```wasm +;; โœ… Allowed +(import "vm_hooks" "msg_sender" (func $msg_sender (param i32))) + +;; โŒ Not allowed +(import "env" "print" (func $print (param i32))) +``` + +### Memory not exported + +**Error**: `WASM must export memory` + +**Solution**: Export linear memory: + +```wasm +;; WAT +(memory 1 1) +(export "memory" (memory 0)) + +// C Makefile +LDFLAGS = -no-entry --export=user_entrypoint --export=memory +``` + +### Size too large + +**Error**: `Compressed WASM exceeds 24KB` + +**Solutions**: + +1. Optimize with wasm-opt: + + ```shell + wasm-opt -Oz input.wasm -o output.wasm + ``` + +2. Strip symbols: + + ```shell + wasm-strip output.wasm + ``` + +3. Remove unused code: + + ```c + // Use static/inline for internal functions + static inline void helper(void) { } + ``` + +4. Minimize data section: + + ```c + // โœ… Good: Minimal data + const uint8_t PREFIX[4] = {0xEF, 0xF0, 0x00, 0x00}; + + // โŒ Bad: Large data + const char *STRINGS[1000] = { /* ... */ }; + ``` + +### Compilation errors + +**Error**: Clang fails to compile + +**Solutions**: + +1. Target wasm32: + + ```shell + clang -target wasm32 -nostdlib -c main.c + ``` + +2. Disable standard library: + + ```c + // Don't use stdio, stdlib, etc. + // Use SDK-provided functions + ``` + +3. Check imports/exports: + ```shell + wasm-objdump -x contract.wasm + ``` + +### Runtime errors + +**Error**: Contract reverts unexpectedly + +**Solutions**: + +1. Check gas usage: + + ```shell + cargo stylus deploy --estimate-gas --wasm-file=contract.wasm + ``` + +2. Add debug output (testnet only): + + ```c + emit_log(error_msg, sizeof(error_msg)); + ``` + +3. Test with minimal input: + ```shell + # Call with empty calldata + cast call $CONTRACT "0x" + ``` + +## Examples Repository + +Official examples for different languages: + +- [**Stylus C SDK**](https://github.com/OffchainLabs/stylus-sdk-c) - C/C++ examples +- [**Stylus Bf SDK**](https://github.com/OffchainLabs/stylus-sdk-bf) - Brainfuck educational examples +- [**Awesome Stylus**](https://github.com/OffchainLabs/awesome-stylus) - Community examples + +## Language Support Matrix + +| Language | Status | SDK | Best Use Case | +| ------------------ | --------------- | -------------------------------------------------------------- | --------------------------- | +| **Rust** | โœ… Production | [stylus-sdk-rs](https://github.com/OffchainLabs/stylus-sdk-rs) | Full-featured contracts | +| **C/C++** | โœ… Production | [stylus-sdk-c](https://github.com/OffchainLabs/stylus-sdk-c) | Cryptography, algorithms | +| **WAT** | โœ… Supported | Manual | Minimal contracts, learning | +| **AssemblyScript** | ๐Ÿ”ถ Community | Custom | TypeScript developers | +| **Go** | ๐Ÿ”ถ Experimental | TinyGo | Custom applications | +| **Zig** | ๐Ÿ”ถ Experimental | Custom | Systems programming | + +## Advanced: Custom Languages + +To support a new language: + +1. **Compile to wasm32-unknown-unknown** + + ```shell + your-compiler --target=wasm32-unknown-unknown input.src -o output.wasm + ``` + +2. **Export required functions** + + ``` + - user_entrypoint(i32) -> i32 + - memory + ``` + +3. **Import only vm_hooks** + + ``` + - vm_hooks:msg_sender + - vm_hooks:storage_* + - etc. + ``` + +4. **Test and deploy** + ```shell + cargo stylus check --wasm-file=output.wasm + cargo stylus deploy --wasm-file=output.wasm --private-key-path=./key.txt + ``` + +## Resources + +- [Stylus C SDK](https://github.com/OffchainLabs/stylus-sdk-c) +- [WebAssembly specification](https://webassembly.github.io/spec/) +- [WAT format reference](https://webassembly.github.io/spec/core/text/) +- [Cargo Stylus CLI](https://github.com/OffchainLabs/cargo-stylus) +- [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) +- [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) +- [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) + +## Sources + +- [GitHub - OffchainLabs/stylus-sdk-c: C/C++ Smart Contracts on Arbitrum](https://github.com/OffchainLabs/stylus-sdk-c) +- [GitHub - OffchainLabs/awesome-stylus](https://github.com/OffchainLabs/awesome-stylus) +- [GitHub - OffchainLabs/stylus-sdk-rs: Rust Smart Contracts on Arbitrum](https://github.com/OffchainLabs/stylus-sdk-rs) From 1b20ea7d5b004602b248d16b53c81d1abc044c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 15:12:32 -0800 Subject: [PATCH 058/162] fix deprecated GitHub links in sidebars.js --- sidebars.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sidebars.js b/sidebars.js index 8898bd368b..2195a7d6c4 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1356,7 +1356,7 @@ const sidebars = { { type: 'link', label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/cargo-stylus', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', }, { type: 'link', @@ -1366,7 +1366,7 @@ const sidebars = { { type: 'link', label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs', }, ], }, @@ -1795,7 +1795,7 @@ const sidebars = { { type: 'link', label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/cargo-stylus', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', }, { type: 'link', @@ -1805,7 +1805,7 @@ const sidebars = { { type: 'link', label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs', }, ], }, From fd9f5feebd3230e927b0a2535378fea58d800345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 15:22:32 -0800 Subject: [PATCH 059/162] reformat --- docs/stylus/concepts/webassembly.mdx | 1 - sidebars.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index bcea948e71..07d296b3ae 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -8,7 +8,6 @@ target_audience: Developers who need to understand how Stylus works with WebAsse displayed_sidebar: buildStylusSidebar --- - WebAssembly (WASM) is a binary instruction format that enables high-performance execution of programs in the Nitro virtual machine. This guide explains how WASM works in the context of Arbitrum Nitro and Stylus smart contract development. ## What is WebAssembly? diff --git a/sidebars.js b/sidebars.js index 2195a7d6c4..bff9cf567a 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1763,7 +1763,7 @@ const sidebars = { { type: 'doc', id: 'stylus/concepts/webassembly', - label: 'webassembly', + label: 'Webassembly', }, { type: 'doc', From adcb707d97a93e66478ea61abf27ab34a4ce9634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 24 Nov 2025 17:06:00 -0800 Subject: [PATCH 060/162] fix "recommended libraries" reference --- docs/stylus/advanced/recommended-libraries.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/stylus/advanced/recommended-libraries.mdx b/docs/stylus/advanced/recommended-libraries.mdx index 11f5485db1..213c1b47e3 100644 --- a/docs/stylus/advanced/recommended-libraries.mdx +++ b/docs/stylus/advanced/recommended-libraries.mdx @@ -1,11 +1,9 @@ --- id: recommended-libraries -title: Recommended Libraries -sidebar_label: Use Rust Crates +title: Recommended Libraries (Rust crates) +sidebar_label: Recommended Libraries --- -# Recommended libraries - ## Using public Rust crates Rust provides a package registry at [crates.io](https://crates.io/), which lets developers conveniently access a plethora of open source libraries to utilize as dependencies in their code. Stylus Rust contracts can take advantage of these crates to simplify their development workflow. From 20ad09796d244d3da7c5a5c4902d0590e893ae92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 25 Nov 2025 14:52:47 -0800 Subject: [PATCH 061/162] delete stub file --- docs/stylus/concepts/caching-strategy.mdx | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 docs/stylus/concepts/caching-strategy.mdx diff --git a/docs/stylus/concepts/caching-strategy.mdx b/docs/stylus/concepts/caching-strategy.mdx deleted file mode 100644 index 5208761d74..0000000000 --- a/docs/stylus/concepts/caching-strategy.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: 'Caching strategy' -description: 'Caching strategy' -author: chrisco -sme: chrisco -sidebar_position: 1 -target_audience: . -displayed_sidebar: buildStylusSidebar ---- - -TBD From 32c2f838221aa2a8dc975d6ee63a28382ddeef4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 1 Dec 2025 10:12:15 -0800 Subject: [PATCH 062/162] fix title --- docs/stylus/how-tos/check-and-deploy.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx index ea35051def..855667b2a6 100644 --- a/docs/stylus/how-tos/check-and-deploy.mdx +++ b/docs/stylus/how-tos/check-and-deploy.mdx @@ -8,8 +8,6 @@ target_audience: Developers who need to understand how to check and deploy Stylu displayed_sidebar: buildStylusSidebar --- -# Check and Deploy Stylus Contracts - This guide explains how to validate and deploy Stylus smart contracts using the `cargo stylus` CLI tool. The process involves two main steps: checking that your contract is valid, and deploying it to an Arbitrum chain. ## Prerequisites From 88422cc2de4d57368d4f52731021f79669a2cab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 2 Dec 2025 10:28:46 -0800 Subject: [PATCH 063/162] Revert "Merge branch 'master' into stylus-v0.1" This reverts commit 7375274d887a4e9f599ddca21b59d4733cf97cf6, reversing changes made to 20ad09796d244d3da7c5a5c4902d0590e893ae92. --- .../reference/04-development-frameworks.mdx | 4 + docs/for-devs/oracles/dia/dia.mdx | 67 +++ docs/for-devs/oracles/pyth/pyth.mdx | 77 +++ docs/for-devs/oracles/quex/quex.mdx | 97 ++++ docs/for-users/contribute.mdx | 8 + .../04-deploy-timeboost.mdx | 195 ++++++++ .../04-stake-and-validator-configurations.mdx | 456 +----------------- .../09-sequencer-timing-adjustments.mdx | 9 + .../10-per-batch-gas-cost.mdx | 9 + .../11-smart-contract-size-limit.mdx | 9 + .../12-customizing-anytrust.mdx | 9 + .../13-arbos-upgrade.mdx | 14 +- .../02-start-your-journey.mdx | 12 + .../03-arbitrum-license.mdx | 12 + .../04-maintain-your-chain/01-bridging.mdx | 9 + .../04-maintain-your-chain/02-monitoring.mdx | 9 + .../01-decentralization-security.mdx | 9 + .../04-guidance/02-guidance-on-altda.mdx | 9 + .../03-integrations.mdx | 15 + .../arbitrum-chain-node-providers.mdx | 9 + .../01-arbitrum-chain-portal.mdx | 9 + ...03-get-listed-arbitrum-chain-platforms.mdx | 9 + ...arbitrum-chain-supported-parent-chains.mdx | 60 +++ ...rum-chain-public-preview-banner-partial.md | 7 + docs/node-running/contribute.mdx | 8 + .../partials/parameters/_ipfs-parameters.mdx | 5 + .../node-running/node-running-content-map.mdx | 98 ++++ .../arbos51-arbsepolia-upgrade-notice.mdx | 23 - docs/notices/fusaka-upgrade-notice.mdx | 17 +- .../_macos-verify-tx-issue-banner-partial.mdx | 13 + .../_under-construction-banner-partial.mdx | 15 + docs/run-arbitrum-node/02-run-full-node.mdx | 12 +- .../arbos-releases/01-overview.mdx | 2 +- .../{arbos51.mdx => arbos50.mdx} | 60 +-- docs/stylus/concepts/how-it-works.md | 82 ++++ .../concepts/public-preview-expectations.md | 42 ++ docs/stylus/gentle-introduction.mdx | 77 +-- .../_stylus-public-preview-banner-partial.md | 7 + sidebars.js | 202 ++++++-- src/components/FloatingHoverModal/index.js | 2 + static/img/stylus-multivm.jpg | Bin 783499 -> 896146 bytes vercel.json | 5 - 42 files changed, 1168 insertions(+), 625 deletions(-) create mode 100644 docs/for-devs/oracles/dia/dia.mdx create mode 100644 docs/for-devs/oracles/pyth/pyth.mdx create mode 100644 docs/for-devs/oracles/quex/quex.mdx create mode 100644 docs/for-users/contribute.mdx create mode 100644 docs/launch-arbitrum-chain/02-configure-your-chain/advanced-configurations/04-deploy-timeboost.mdx create mode 100644 docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/09-sequencer-timing-adjustments.mdx create mode 100644 docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/10-per-batch-gas-cost.mdx create mode 100644 docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/11-smart-contract-size-limit.mdx create mode 100644 docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/12-customizing-anytrust.mdx create mode 100644 docs/launch-arbitrum-chain/02-start-your-journey.mdx create mode 100644 docs/launch-arbitrum-chain/03-arbitrum-license.mdx create mode 100644 docs/launch-arbitrum-chain/04-maintain-your-chain/01-bridging.mdx create mode 100644 docs/launch-arbitrum-chain/04-maintain-your-chain/02-monitoring.mdx create mode 100644 docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/01-decentralization-security.mdx create mode 100644 docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/02-guidance-on-altda.mdx create mode 100644 docs/launch-arbitrum-chain/06-third-party-integrations/03-integrations.mdx create mode 100644 docs/launch-arbitrum-chain/07-arbitrum-node-runners/arbitrum-chain-node-providers.mdx create mode 100644 docs/launch-arbitrum-chain/08-ecosystem-support/01-arbitrum-chain-portal.mdx create mode 100644 docs/launch-arbitrum-chain/08-ecosystem-support/03-get-listed-arbitrum-chain-platforms.mdx create mode 100644 docs/launch-arbitrum-chain/arbitrum-chain-supported-parent-chains.mdx create mode 100644 docs/launch-arbitrum-chain/partials/_arbitrum-chain-public-preview-banner-partial.md create mode 100644 docs/node-running/contribute.mdx create mode 100644 docs/node-running/how-tos/data-availability-committee/partials/parameters/_ipfs-parameters.mdx create mode 100644 docs/node-running/node-running-content-map.mdx delete mode 100644 docs/notices/arbos51-arbsepolia-upgrade-notice.mdx create mode 100644 docs/partials/_macos-verify-tx-issue-banner-partial.mdx create mode 100644 docs/partials/_under-construction-banner-partial.mdx rename docs/run-arbitrum-node/arbos-releases/{arbos51.mdx => arbos50.mdx} (85%) create mode 100644 docs/stylus/concepts/how-it-works.md create mode 100644 docs/stylus/concepts/public-preview-expectations.md create mode 100644 docs/stylus/partials/_stylus-public-preview-banner-partial.md diff --git a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx index a6a5475711..f67a2ade1f 100644 --- a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx +++ b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx @@ -20,6 +20,10 @@ The following tools will help you develop and test your decentralized apps (dApp [Foundry](https://github.com/foundry-rs/foundry) is a high-performance, portable, and modular toolkit designed for EVM application development, leveraging the Rust programming language. It offers a comprehensive suite of tools to streamline the process of creating, testing, and deploying smart contracts on the Ethereum, Arbitrum and, in general, any EVM network. Foundry facilitates seamless interaction with EVM smart contracts, transactions, and chain data, while also providing a local node and a user-friendly Solidity REPL environment for efficient development. +## Truffle + +[Truffle](https://trufflesuite.com/) is a comprehensive suite of tools for smart contract development, providing an end-to-end solution for building, testing, debugging, and deploying on Ethereum, Arbitrum and other EVM compatible chains. It features advanced debugging capabilities, fast EVM simulation with Ganache, a user-centered design with a VS Code extension, and robust parent and child chain support. Truffle prioritizes security and partners with ConsenSys Diligence to bring continuous security to projects, providing a seamless and secure developer experience. + ## thirdweb [thirdweb SDK](https://portal.thirdweb.com/sdk) covers all aspects of the Web3 development stack, including connecting to userโ€™s wallets, interacting with the blockchain and smart contracts, decentralized storage, authentication, and more; enabling you to build scalable and performant Web3 applications on any EVM-compatible blockchain. Out of the box, infrastructure is provided for everything required to create decentralized applications, including connection to the blockchain (RPC), decentralized storage (IPFS + pinning services), and tools to create powerful user experiences; such as gasless transactions, wallet connection components, FIAT on-ramps, data APIs, and more. diff --git a/docs/for-devs/oracles/dia/dia.mdx b/docs/for-devs/oracles/dia/dia.mdx new file mode 100644 index 0000000000..7366ea1761 --- /dev/null +++ b/docs/for-devs/oracles/dia/dia.mdx @@ -0,0 +1,67 @@ +--- +id: 'dia' +title: 'DIA' +description: Learn how to integrate oracles into your Arbitrum app +user_story: As a developer, I want to understand how to use oracles in Arbitrum to get offchain data onchain. +content_type: how-to +--- + +[DIA](https://www.diadata.org/) is a cross-chain oracle provider that enhances data transparency, customization, and accessibility. With a novel architecture aggregating raw trade data directly from first-party sources, namely centralized and decentralized exchanges, DIA offers 100% source transparency, bespoke customization, and chain-native asset price feeds. + +You can find an example on how to use DIA in your project on this [page](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle). + +### How to use DIA oracles on Arbitrum + +**Requesting a custom oracle**: DIA deploys oracles tailored to each appโ€™s needs. Each oracle is customizable, including data sources, cleansing filters, pricing, computational methodologies, update mechanisms, and more. This flexibility ensures that the data and oracle remain robust and resilient to the market conditions and provide a global market price and specific individual or cross-chain market prices. +โ†’ [Request a Custom Oracle for your dApp | DIA Documentation](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle) + +### Token Price Feeds + +DIA token price feeds provide smart contracts with real-time price information for [3,000+ cryptocurrencies](https://diadata.org/app/price), sourced from [80+ trusted, high-volume DEXs and CEXs](https://diadata.org/app/source/defi). + +### How to access DIA oracles? + +Here is an example of how to access a price value on DIA oracles: + +1. Access your custom oracle smart contract on Arbitrum. +2. Call `getValue(pair_name)` with `pair_name` being the full pair name such as `BTC/USD`. You can use the "Read" section on the explorer to execute this call. +3. The response of the call contains two values: + +- The current asset price in `USD` with a fix-comma notation of 8 decimals. +- The UNIX timestamp of the last oracle update. + +You can find DIA's oracle integration samples in Solidity and Vyper languages by visiting: +โ†’ [Access the Oracle | DIA Documentation](https://docs.diadata.org/products/token-price-feeds/access-the-oracle) + +### Arbitrum demo price oracles + +DIA has deployed the following demo oracles for the Arbitrum community. It provides a limited selection of cryptocurrency price feeds with predefined configuration settings. + +:::note + +DIA demo oracles are not intended for use in production environments. Developers can request a dedicated, production-ready oracle with custom price feeds and configuration settings. Start the request process: [Request a Custom Oracle | DIA Documentation](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle) + +::: + +### Demo Oracle Smart Contracts + +| Network | Contract address | +| ------------- | --------------------------------------------------------------------------------------------------------------------------- | +| Arbitrum | [`0xd041478644048d9281f88558e6088e9da97df624`](https://arbiscan.io/address/0xd041478644048d9281f88558e6088e9da97df624) | +| Arbitrum Nova | [`0xa707a5c6a180da0ae2ef17ebff54f1f3589d9670`](https://nova.arbiscan.io/address/0xa707a5c6a180da0ae2ef17ebff54f1f3589d9670) | + +### Included Price Feeds + +[DIA/USD](https://diadata.org/app/price/asset/Ethereum/0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419/), [BTC/USD](https://diadata.org/app/price/asset/Bitcoin/0x0000000000000000000000000000000000000000/), [USDC/USD](https://diadata.org/app/price/asset/Ethereum/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/) + +### Supported token API endpoints + +DIA supports API and GraphQL endpoints to return cryptocurrency price data. You can [visit the DIA Documentation](https://docs.diadata.org/products/token-price-feeds/access-api-endpoints) to see all API endpoints. + +### NFT Price Feeds + +DIA NFT floor price feeds provide smart contracts with real-time price information of [18,000+ NFT collections](https://diadata.org/app/floor-price), sourced onchain with 100% transparency from [multiple, cross-chain NFT marketplaces](https://diadata.org/app/source/nft). + +### Supported NFT API endpoints + +DIA supports API endpoints to return cryptocurrency price data. Developers can directly access the example endpoints listed below or [visit the DIA Documentation](https://docs.diadata.org/use-nexus-product/readme/token-price-feeds/access-api-endpoints) to see all API endpoints. diff --git a/docs/for-devs/oracles/pyth/pyth.mdx b/docs/for-devs/oracles/pyth/pyth.mdx new file mode 100644 index 0000000000..0b63b878b6 --- /dev/null +++ b/docs/for-devs/oracles/pyth/pyth.mdx @@ -0,0 +1,77 @@ +--- +id: 'pyth' +title: 'Pyth' +description: 'Learn how to use Pyth Oracle' +author: pete-vielhaber +sme: pete-vielhaber +sidebar_label: 'pyth' +content_type: how-to +--- + +The [Pyth network](https://pyth.network/) a first-party oracle network, securely and transparently delivering real-time market data to [multiple chains](https://docs.pyth.network/price-feeds/contract-addresses). + +The network comprises some of the worldโ€™s [largest exchanges, market makers, and financial services providers](https://pyth.network/publishers). These publish proprietary data onchain for aggregation and distribution to smart contract applications. + +## Pyth price feeds + +The Pyth network introduces an innovative low-latency [pull oracle design](https://docs.pyth.network/price-feeds/pull-updates), where users can pull price updates onchain when needed, enabling everyone in the blockchain environment to access that data point. Pyth network updates the prices every 400ms, making Pyth the fastest onchain oracle. + +Here is a working example of a contract that fetches the latest price of `ARB/USD` on the Arbitrum network. + +You have to pass Pyth's contract address for Arbitrum mainnet/testnet and the desired price feed ID to fetch the latest price. + +Install the Pyth SDK Solidity package in your project: + +```tsx +npm install @pythnetwork/pyth-sdk-solidity +``` + +And then, in a few lines of code you can fetch the latest price on the Arbitrum network. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; +import "@pythnetwork/pyth-sdk-solidity/IPyth.sol"; +import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol"; +contract MyFirstPythContract { + IPyth pyth; + // Pass the address of Pyth's contract for Arbitrum mainnet(0xff1a0f4744e8582DF1aE09D5611b887B6a12925C) + constructor(address _pyth) { + pyth = IPyth(_pyth); + } + function fetchPrice( + bytes[] calldata updateData, + bytes32 priceFeed + ) public payable returns (int64) { + // Fetch the priceUpdate from hermes. + uint updateFee = pyth.getUpdateFee(updateData); + pyth.updatePriceFeeds{value: updateFee}(updateData); + // Fetch the latest price + PythStructs.Price memory price = pyth.getPrice(priceFeed); + return price.price; + } +} +``` + +Here you can fetch the `updateData` from Pyth's [Hermes](https://hermes.pyth.network/docs/) feed, which listens to Pythnet and Wormhole for price updates; or you can use the [pyth-evm-js](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/sdk/js/src/EvmPriceServiceConnection.ts#L15) SDK. Check [How to Fetch Price Updates](https://docs.pyth.network/price-feeds/fetch-price-updates) to pull the latest data. + +## Pyth Entropy + +Pyth Entropy allows developers to quickly and easily generate secure **random numbers** on the blockchain. + +Check [how to generate random numbers in EVM contracts](https://docs.pyth.network/entropy/generate-random-numbers/evm) for a detailed walkthrough. + +### Supported networks for Arbitrum(Pyth Entropy): + +- Arbitrum: [`0x7698E925FfC29655576D0b361D75Af579e20AdAc`](https://arbiscan.io/address/0x7698E925FfC29655576D0b361D75Af579e20AdAc) +- Arbitrum Sepolia: [`0x549Ebba8036Ab746611B4fFA1423eb0A4Df61440`](https://sepolia.arbiscan.io/address/0x549Ebba8036Ab746611B4fFA1423eb0A4Df61440) + +## Additional resources + +Check out the following links to get started with Pyth: + +- [Pyth EVM Integration Guide](https://docs.pyth.network/price-feeds/use-real-time-data/evm) +- [Pyth Docs](https://docs.pyth.network/home) +- [Pyth API Reference](https://api-reference.pyth.network/price-feeds/evm/getPrice) +- [Pyth Examples](https://github.com/pyth-network/pyth-examples) +- [Pyth Price Feed Ids](https://pyth.network/developers/price-feed-ids) diff --git a/docs/for-devs/oracles/quex/quex.mdx b/docs/for-devs/oracles/quex/quex.mdx new file mode 100644 index 0000000000..7b85efa0dd --- /dev/null +++ b/docs/for-devs/oracles/quex/quex.mdx @@ -0,0 +1,97 @@ +--- +id: 'quex' +title: 'Quex' +sidebar_label: 'Quex' +description: 'Learn how to make verifiable HTTP requests from your Arbitrum dApp' +author: catena2w +sme: catena2w +user_story: As an Arbitrum developer, I want to learn how to use oracles in my dApp. +content_type: get-started +--- + +:::warning + +Quex contracts are currently undergoing security audits and infrastructure security improvements. Before using Quex oracles in production dApps, please reach out via [on Discord](https://discord.com/invite/NsuE32xHvj). Quex will be happy to assist you with the integration and, if needed, set up a dedicated data oracle pools if there is a need. + +::: + +[Quex](https://quex.tech/) is an oracle protocol designed to securely deliver verifiable offchain data to onchain smart contracts using confidential computing proofs. Quex oracles enable dApps on Arbitrum to reliably and securely access real-world data, empowering developers to build advanced financial applications, parametric tokens, prediction markets, and more. + +Unlike traditional oracles, Quex allows developers to securely make verifiable API calls to virtually any offchain data source โ€”โ€“ including private APIs protected by credentials. This means you're not limited to predefined data feeds and can securely access the entire internet. + +### Querying the API endpoint through Quex + +Here's an example of how to use Quex to securely fetch the TVL data for the AAVE protocol from DefiLlama's [API endpoint](https://api.llama.fi/tvl/aave). This example will also include basic post-processing to showcase Quex's capabilities for verifiable offchain computations. We'll build our example using [Foundry](https://book.getfoundry.sh) (Forge), but feel free to use your preferred tools. + +Quex provides a package with convenient libraries that simplify making requests and verifying responses. First, install this package in your project: + +```bash +forge install quex-tech/quex-v1-interfaces +``` + +Here's a complete Solidity example demonstrating how to use Quex for verifiable API calls within an Arbitrum smart contract: + +```solidity +import "quex-v1-interfaces/src/libraries/QuexRequestManager.sol"; + +contract ApiCallConsumer is QuexRequestManager { + /** + * Network: Arbitrum One + * Quex Core: 0xD8a37e96117816D43949e72B90F73061A868b387 + * Request Oracle Pool: 0x957E16D5bfa78799d79b86bBb84b3Ca34D986439 + */ + constructor(address _coreAddress, address _poolAddress) QuexRequestManager(_coreAddress){ + setUpFlow(quexCore, oraclePool); + } + + /** + * @notice Creates a new flow to fetch TVL data from the DeFi Llama API for Aave, multiplies it by 1e18, + * and rounds to the nearest integer. + */ + function setUpFlow(address quexCore, address oraclePool) private onlyOwner { + FlowBuilder.FlowConfig memory config = FlowBuilder.create(quexCore, oraclePool, "api.llama.fi", "/tvl/aave"); + config = config.withFilter(". * 1000000000000000000 | round"); + config = config.withSchema("uint256"); + config = config.withCallback(address(this), this.processResponse.selector); + registerFlow(config); + } + + /** + * Verify proofs and processes a response from Request Oracle Pool + */ + function processResponse(uint256 receivedRequestId, DataItem memory response, IdType idType) + external verifyResponse(receivedRequestId, idType) + { + uint256 lastTVL = abi.decode(response.value, (uint256)); + } +} +``` + +The most interesting part here is the `setUpFlow` function. It relies on two contracts, Core and the HTTP oracle pool, that are already [deployed on Arbitrum](https://docs.quex.tech/general-information/addresses). This function specifies the host (`api.llama.fi`) and path (`/tvl/aave`) for future requests that the oracle will perform upon request. + +Most APIs return JSON responses, which aren't very convenient to process directly in Solidity. To extract necessary data, Quex oracles support response post-processing: a script written in the [JQ language](https://docs.quex.tech/developers/https_pool/jq_subset) which is applied before passing the data onchain. Our example script defined in `config.withFilter(". * 1000000000000000000 | round");` multiplies the response by `1e18` and rounds it to the nearest integer. Since Quex supports operations with complex response structures, we must define a schema for the returned result. In our example, `config.withSchema("uint256");` specifies the return type as a simple numeric value. + +As we've mentioned, Quex is a pull oracle operating in a request-response model. Thanks to the efficient confidential computing security model, proof generation is extremely fast, and you can expect responses with proofs delivered in the next block. However, because this is still an asynchronous operation, we must define a callback, a function called once the response is delivered. This is done in the line `config.withCallback(address(this), this.processResponse.selector);`, specifying that the contract's own `processResponse` function will be invoked. + +### Making requests + +Quex supports both offchain and onchain initiated data [delivery modes](https://docs.quex.tech/general-information/data_delivery). This example relies on the on-chain mechanism, meaning that data requests must be initiated directly from your smart contract. To request data, simply call the built-in `request()` method, which triggers the entire process. Note that this method is payable, as you need to attach enough funds to cover the callback gas fees. + +Once the response is generated, it is passed to the `processResponse` method we've specified as a callback. The response arrives with confidential computing proofs, preventing any data manipulation. However, by the time the data reaches your contract, these proofs are already verified within the Quex core. Still, calling `verifyResponse(receivedRequestId, idType)` remains essential to ensure that the response originates from the correct Quex core address and corresponds exactly to the original request. After that, you only need to unpack the data according to the schema you've defined: + +```solidity +uint256 lastTVL = abi.decode(response.value, (uint256)); +``` + +Tada! You now have your response to the defined API call โ€“โ€“ with complete certainty about its authenticity and security! + +## Connect with us! + +Still looking for answers? We got them! Check out all the ways you can reach us: + +- Visit us at [quex.tech](https://quex.tech) +- Read our [Docs](https://docs.quex.tech) +- Explore our [examples repository](https://github.com/quex-tech/quex-v1-examples) +- Chat with us on [Telegram](https://t.me/quex_tech) +- Follow us on [X](https://x.com/quex_tech) +- Join our [Discord](https://discord.com/invite/NsuE32xHvj) diff --git a/docs/for-users/contribute.mdx b/docs/for-users/contribute.mdx new file mode 100644 index 0000000000..4f7c3501cf --- /dev/null +++ b/docs/for-users/contribute.mdx @@ -0,0 +1,8 @@ +--- +title: 'Contribute docs' +description: "Learn how to contribute to Arbitrum's documentation" +--- + +import ContributeDocsPartial from '../partials/_contribute-docs-partial.mdx'; + + diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/advanced-configurations/04-deploy-timeboost.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/advanced-configurations/04-deploy-timeboost.mdx new file mode 100644 index 0000000000..d871814667 --- /dev/null +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/advanced-configurations/04-deploy-timeboost.mdx @@ -0,0 +1,195 @@ +--- +title: 'Deploy and configure Timeboost for your chain' +sidebar_label: 'Deploy and configure Timeboost' +description: 'Learn how to deploy and configure Timeboost' +user_story: As a current or prospective Orbit chain owner, I need to understand how to deploy and configure Timeboost +author: Jason Wan +sme: Jason Wan +content_type: how-to +--- + +# Enabling Timeboost for your Arbitrum (Orbit) chain + +This guide walks you through the process of enabling Timeboost for your Arbitrum Orbit chain. For a conceptual introduction to Timeboost, see the [Timeboost Introduction](/how-arbitrum-works/timeboost/gentle-introduction.mdx). + +## Prerequisites + +Before starting, ensure you have: + +1. An `ERC-20` token address to use as the bid token +2. A Redis server for auctioneer coordination +3. A server to run the auctioneer service +4. A proxy admin contract address + +## Overview + +Enabling Timeboost requires completing these three steps: + +1. Deploy the `ExpressLaneAuction` contract +2. Run Auctioneer Services (bid validator and auction server) +3. Configure your sequencer node to support Timeboost + +## Step 1: Deploy the `ExpressLaneAuction` contract + +First, clone the `orbit-actions` repository: + +```shell +git clone https://github.com/OffchainLabs/orbit-actions.git +cd orbit-actions/scripts/foundry/timeboost +``` + +Create and edit the environment configuration file: + +```shell +cp .env.sample .env +``` + +Configure the following parameters in your `.env` file: + +```shell +## Configuration for DeployExpressLaneAuction.s.sol +PROXY_ADMIN_ADDRESS= # Your proxy admin contract address +AUCTIONEER_ADDRESS= # Address that will send resolve auction requests +BIDDING_TOKEN_ADDRESS= # Your ERC20 bid token address +BENEFICIARY_ADDRESS= # Address to receive bid proceeds +AUCTIONEER_ADMIN_ADDRESS= # Admin address for the auctioneer +MIN_RESERVE_PRICE_SETTER_ADDRESS= # Address allowed to set minimum reserve price +RESERVE_PRICE_SETTER_ADDRESS= # Address allowed to set reserve price +RESERVE_PRICE_SETTER_ADMIN_ADDRESS= # Admin for reserve price setter +BENEFICIARY_SETTER_ADDRESS= # Address allowed to change beneficiary +ROUND_TIMING_SETTER_ADDRESS= # Address allowed to adjust round timing +MASTER_ADMIN_ADDRESS= # Master admin address + +MIN_RESERVE_PRICE=0 # Minimum price for bids (0 recommended for testing) + +# Round timing configuration (in seconds) +ROUND_DURATION_SECONDS=60 # Total duration of each round +AUCTION_CLOSING_SECONDS=15 # Time before round end when new bids are closed +RESERVE_SUBMISSION_SECONDS=15 # Time allocated for reserve price submission +``` + +Deploy the contract: + +```shell +forge script --sender $DEPLOYER --rpc-url $CHILD_CHAIN_RPC --slow ./DeployExpressLaneAuction.s.sol -vvv --verify --broadcast +# Use --account XXX / --private-key XXX / --interactive / --ledger to specify the transaction signer +``` + +Verify successful deployment by checking that the contract returns your configured bid token: + +```shell +cast call --rpc-url= "biddingToken()(address)" +``` + +Example output: + +```shell +0xYourBidTokenAddress +``` + +## Step 2: Run auctioneer services + +There are two distinct services to run: the bid validator and the auction server. The bid validator verifies submitted bids, while the auction server sends the winning bid on-chain. + +### Prerequisites + +The services require the `autonomous-auctioneer` binary, which is included in the Nitro Docker image. Alternatively, you can build it locally by following the [Build Nitro Locally](https://docs.arbitrum.io/run-arbitrum-node/nitro/build-nitro-locally) guide. + +To build only the `autonomous-auctioneer` component during the local build process: + +```shell +make target/bin/autonomous-auctioneer +``` + +### Running bid validator service + +Start the bid validator with: + +```shell +./autonomous-auctioneer \ +--bid-validator.auction-contract-address= \ +--bid-validator.rpc-endpoint= \ +--auctioneer-server.enable=false \ +--bid-validator.redis-url= \ +--http.addr=0.0.0.0 \ +--http.port= +``` + +### Running auction server service + +Start the auction server with: + +```shell +./autonomous-auctioneer \ +--auctioneer-server.auction-contract-address= \ +--auctioneer-server.db-directory= \ +--auctioneer-server.redis-url= \ +--auctioneer-server.use-redis-coordinator=false \ +--auctioneer-server.sequencer-endpoint= \ +--auctioneer-server.wallet.private-key= \ +--bid-validator.enable=false +``` + +## Step 3: Configure your sequencer node for Timeboost + +Update your sequencer node configuration to enable Timeboost functionality. Add the following new config to your sequencer's node configuration file: + +```json +{ + "http": { + "api": [ + // existing APIs + "auctioneer", + "timeboost" + ] + }, + "ws": { + "api": [ + // existing APIs + "auctioneer", + "timeboost" + ] + }, + "execution": { + "sequencer": { + "timeboost": { + "enable": true, + "auction-contract-address": "", + "auctioneer-address": "", + "redis-url": "" + } + } + } +} +``` + +## Verifying your Timeboost setup + +There are multiple ways to confirm that Timeboost is correctly enabled on your chain: + +### Periodic startup logs + +When you start your sequencer with Timeboost enabled, you'll see periodic logs indicating the start of new express lane auction rounds: + +```shell +New express lane auction round +``` + +This log indicates that the Timeboost mechanism is active and running normally. + +### Transaction processing confirmation + +After finishing a bid request, look for messages in your sequencer logs such as: + +```shell +AuctionResolved: New express lane controller assigned round +``` + +This message confirms that your sequencer is processing express queue transactions from the express lane controller, and that Timeboost is functioning correctly. + +### User interaction verification + +Users can interact with Timeboost by submitting bids through the `auctioneer_submitBid` endpoint of your auctioneer service. +For detailed instructions on how users can interact with Timeboost, see [How to Use Timeboost](https://docs.arbitrum.io/how-arbitrum-works/timeboost/how-to-use-timeboost). + +A successful bid submission will trigger the auction resolution process and generate the corresponding logs mentioned above. diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx index db32663f22..b49d50fb0f 100644 --- a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx @@ -1,453 +1,13 @@ --- -title: 'Bond and validator configurations' -description: 'Learn how to configure your Arbitrum chain with a custom bond and validator configurations' -author: pete-vielhaber -sme: Jason-W123 +title: 'Stake and validator configurations' +description: 'Learn how to configure your Arbitrum chain with a custom stake and validator configurations' +author: +sme: content_type: how-to +tags: ['hide-from-search'] unlisted: true --- -Arbitrum chains are customizable Layer 3 (L3) chains that settle -to an Arbitrum Layer 2 (L2) chain, such as Arbitrum One. They support - validator - configurations to ensure chain security through bonding and - assertion - challenges. Validators post assertions about the chain's state on the parent L2 chain and can - challenge - incorrect assertions. Arbitrum chains can be permissioned, meaning validators must be allowlisted. -For chains that use that elect to use the BoLD protocol, permissionless validation is an option (BoLD -also supports permissioned validation). - -Bonding is required for active validation, where validators place bond funds to participate. If a validator loses a challenge (e.g., due to a faulty assertion), their bond is escrowed or burned. Configurations such as the `stakeToken`, `baseStake`, and `loserStakeEscrow` are configurable during chain deployment or post-deployment via contract calls. - -Arbitrum chains may utilize the BoLD (Bounded Liquidity Delay) protocol for efficient dispute resolution, which affects bonding tokens (e.g., `WETH` for BoLD-enabled chains like Arbitrum One/Nova, or `ETH`/native for other chains). - -## `stakeToken` - -The bonded token is the asset that validators must bond to participate in asserting the chain's state on the parent L2 chain. It serves as collateral for challenges. A bonded token can be `WETH` or the parent chain's native token. - -### Configuration details - -- Can be `ETH` (native gas token) or any `ERC-20` token. -- **For BoLD-enabled chains** (e.g., settling to Arbitrum One or Nova), it defaults to `WETH`. -- **For non-BoLD chains**, it defaults to the parent chain's native token (usually `ETH`). -- Currently, its value is often hardcoded to `ETH` in basic deployments, but customizable to an `ERC-20` contract address in advanced setups. Future updates will expand `ERC-20` support. - -### How to configure - -1. **Prepare the chain configuration**: - Generate the base chain config using `prepareChainConfig`. Set the `chainId` and initial owner. - - ```typescript - import { prepareChainConfig } from '@arbitrum/chain-sdk'; - - const chainConfig = prepareChainConfig({ - chainId: 123456, // Replace with your desired chain ID - arbitrum: { - InitialChainOwner: '0xYourOwnerAddressHere', // Wallet address that will own the chain - DataAvailabilityCommittee: false, // Set to true for AnyTrust chains (DAC) - }, - }); - ``` - -2. **Set up the public client for the parent chain**: - Create a public client to interact with the parent chain. - - ```typescript - import { createPublicClient, http } from 'viem'; - import { sepolia } from 'viem/chains'; // Example: Use 'mainnet' or 'arbitrumOne' as needed - - const parentChainPublicClient = createPublicClient({ - chain: sepolia, // Replace with your parent chain (e.g., arbitrumOne) - transport: http('https://your-parent-chain-rpc-url'), // Replace with actual RPC URL - }); - ``` - -3. **Prepare deployment parameters, including `stakeToken`**: - Use `createRollupPrepareDeploymentParamsConfig` to define the rollout config. This is where you configure the `stakeToken` (the `ERC-20` address on the parent chain) and `baseStake` (minimum stake amount in wei). - - ```typescript - import { createRollupPrepareDeploymentParamsConfig } from '@arbitrum/chain-sdk'; - - const createRollupConfig = await createRollupPrepareDeploymentParamsConfig( - parentChainPublicClient, - { - chainId: 123456, // Must match the chainId from Step 1 - owner: '0xYourOwnerAddressHere', // Must match InitialChainOwner from Step 1 - chainConfig, - stakeToken: '0xYourStakeTokenERC20AddressHere', // ERC-20 token address on parent chain for validator staking - baseStake: 1000000000000000000n, // Example: 1 token (adjust based on token decimals) - // Optional: Other params like confirmPeriodBlocks, loserStakeEscrow, etc. - }, - ); - ``` - -4. **Deploy the chain**: - Use `createRollup` to deploy. Provide validator and batch poster addresses. This step sends the transaction to the parent chain. - - ```typescript - import { createWalletClient } from 'viem'; - import { privateKeyToAccount } from 'viem/accounts'; - import { createRollup } from '@arbitrum/chain-sdk'; - - const deployerAccount = privateKeyToAccount('0xYourDeployerPrivateKeyHere'); // Securely manage this - - const walletClient = createWalletClient({ - account: deployerAccount, - chain: sepolia, // Match parent chain - transport: http('https://your-parent-chain-rpc-url'), - }); - - const createRollupResults = await createRollup({ - params: { - config: createRollupConfig, - batchPosters: ['0xYourBatchPosterAddressHere'], // Address for posting batches - validators: ['0xYourValidatorAddressHere'], // Validator addresses - // Optional: nativeToken: '0xCustomGasTokenAddress' for custom fee tokens - }, - account: deployerAccount, - publicClient: parentChainPublicClient, - walletClient, - }); - - console.log('Deployment Transaction Hash:', createRollupResults.transactionHash); - console.log('Core Contracts:', createRollupResults.coreContracts); - ``` - -5. **Post-deployment (if using AnyTrust)**: - If `DataAvailabilityCommittee` is `true`, set the DAC keyset in the `SequencerInbox`. - - ```typescript - import { setValidKeyset } from '@arbitrum/chain-sdk'; - - // Generate or provide your keyset (BLS public keys for the committee) - const keyset = '0xYourGeneratedKeysetHere'; - - const setKeysetResults = await setValidKeyset({ - coreContracts: createRollupResults.coreContracts, - keyset, - publicClient: parentChainPublicClient, - walletClient, - }); - ``` - -### Additional notes - -- Ensure the `stakeToken` is a compliant `ERC-20` on the parent chain; mismatches can cause deployment failures. -- Test on a testnet (e.g., Sepolia) first, as deployments are irreversible and cost gas. -- The owner address gains control over upgrades and settingsโ€”use a secure multisig in production. -- For production, consider a Rollup-as-a-Service (RaaS) provider for monitoring and scaling. -- **Verification**: This SDK-based method deploys directly via smart contract interactions and does not involve any UI or portal (the portal is for asset bridging, not chain deployment). - -## `baseStake` - -The `baseStake` is the minimum amount of the bond token that validators must deposit to bond and post assertions. - -### Configuration details - -- Specified as a float value (e.g., in `wei` for `ETH`). -- Must be greater than 0. -- **Balances security**: Low values ease entry but risk malicious challenges; high values deter attacks but exclude smaller validators. - -### How to configure - -1. **Prepare the chain configuration**: - Generate the base chain config using `prepareChainConfig`. Set the `chainId` and initial owner. - - ```typescript - import { prepareChainConfig } from '@arbitrum/chain-sdk'; - - const chainConfig = prepareChainConfig({ - chainId: 123456, // Replace with your desired chain ID - arbitrum: { - InitialChainOwner: '0xYourOwnerAddressHere', // Wallet address that will own the chain - DataAvailabilityCommittee: false, // Set to true for AnyTrust chains (DAC) - }, - }); - ``` - -2. **Set up the public client for the parent chain**: - Create a public client to interact with the parent chain. - - ```typescript - import { createPublicClient, http } from 'viem'; - import { sepolia } from 'viem/chains'; // Example: Use 'mainnet' or 'arbitrumOne' as needed - - const parentChainPublicClient = createPublicClient({ - chain: sepolia, // Replace with your parent chain (e.g., arbitrumOne) - transport: http('https://your-parent-chain-rpc-url'), // Replace with actual RPC URL - }); - ``` - -3. **Prepare deployment parameters, including `stakeToken`**: - Use `createRollupPrepareDeploymentParamsConfig` to define the rollout config. This is where you configure the `stakeToken` (the `ERC-20` address on the parent chain) and `baseStake` (minimum stake amount in wei). - - ```typescript - import { createRollupPrepareDeploymentParamsConfig } from '@arbitrum/chain-sdk'; - - const createRollupConfig = await createRollupPrepareDeploymentParamsConfig( - parentChainPublicClient, - { - chainId: 123456, // Must match the chainId from Step 1 - owner: '0xYourOwnerAddressHere', // Must match InitialChainOwner from Step 1 - chainConfig, - stakeToken: '0xYourStakeTokenERC20AddressHere', // ERC-20 token address on parent chain for validator staking - baseStake: 1000000000000000000n, // Example: 1 token (adjust based on token decimals) - // Optional: Other params like confirmPeriodBlocks, loserStakeEscrow, etc. - }, - ); - ``` - -4. **Deploy the chain**: - Use `createRollup` to deploy. Provide validator and batch poster addresses. This step sends the transaction to the parent chain. - - ```typescript - import { createWalletClient } from 'viem'; - import { privateKeyToAccount } from 'viem/accounts'; - import { createRollup } from '@arbitrum/chain-sdk'; - - const deployerAccount = privateKeyToAccount('0xYourDeployerPrivateKeyHere'); // Securely manage this - - const walletClient = createWalletClient({ - account: deployerAccount, - chain: sepolia, // Match parent chain - transport: http('https://your-parent-chain-rpc-url'), - }); - - const createRollupResults = await createRollup({ - params: { - config: createRollupConfig, - batchPosters: ['0xYourBatchPosterAddressHere'], // Address for posting batches - validators: ['0xYourValidatorAddressHere'], // Validator addresses - // Optional: nativeToken: '0xCustomGasTokenAddress' for custom fee tokens - }, - account: deployerAccount, - publicClient: parentChainPublicClient, - walletClient, - }); - - console.log('Deployment Transaction Hash:', createRollupResults.transactionHash); - console.log('Core Contracts:', createRollupResults.coreContracts); - ``` - -5. **Post-deployment (if using AnyTrust)**: - If `DataAvailabilityCommittee` is `true`, set the DAC keyset in the `SequencerInbox`. - - ```typescript - import { setValidKeyset } from '@arbitrum/chain-sdk'; - - // Generate or provide your keyset (BLS public keys for the committee) - const keyset = '0xYourGeneratedKeysetHere'; - - const setKeysetResults = await setValidKeyset({ - coreContracts: createRollupResults.coreContracts, - keyset, - publicClient: parentChainPublicClient, - walletClient, - }); - ``` - -### Additional notes - -- **Validators and staking**: After deployment, validators bond by depositing at least `baseStake` of the `stakeToken` into the Rollup contract. This can be done via contract calls (e.g., using the `RollupUserLogic` interface). -- **Warnings**: - - Ensure the `stakeToken` is a compliant `ERC-20` on the parent chain; mismatches can cause deployment failures. - - Test on a testnet (e.g., Sepolia) first, as deployments are irreversible and cost gas. - - The owner address gains control over upgrades and settingsโ€”use a secure multisig in production. - - For production, consider a Rollup-as-a-Service (RaaS) provider for monitoring and scaling. -- **Verification**: This SDK-based method deploys directly via smart contract interactions and does not involve any UI or portal (the portal is for asset bridging, not chain deployment). - -## `loserStakeEscrow` - -The `loserStakeEscrow` is the address where a validator's bonded funds are sent if they lose a challenge (e.g., due to an incorrect assertion). This mechanism acts as a penalty. The default configuration has no default specified; must be configured. - -### Configuration details - -- Funds are escrowed rather than immediately burned, allowing potential recovery or governance decisions. -- **Recommended**: Set to an address controlled by the chain owner(s) for management, or a burn address (e.g., `0x000000000000000000000000000000000000dEaD`) if funds should be permanently removed. - -### Configuring during deployment - -1. **Prepare chain config**: - - ```typescript - import { prepareChainConfig } from '@arbitrum/chain-sdk'; - - const chainConfig = prepareChainConfig({ - chainId: 123456, // Your unique chain ID - arbitrum: { - InitialChainOwner: '0xYourOwnerAddressHere', - DataAvailabilityCommittee: false, // True for AnyTrust chains - }, - }); - ``` - -2. **Set up parent chain client**: - - ```typescript - import { createPublicClient, http } from 'viem'; - import { sepolia } from 'viem/chains'; - - const parentChainPublicClient = createPublicClient({ - chain: sepolia, // Replace with your parent chain - transport: http('https://your-parent-rpc-url'), - }); - ``` - -3. **Prepare deployment params, including `loserStakeEscrow`**: - Set `loserStakeEscrow` as an address (string). There is no explicit default documented, but if omitted, it may revert to a system default (e.g., zero address)โ€”always specify for control. - - ```typescript - import { createRollupPrepareDeploymentParamsConfig } from '@arbitrum/chain-sdk'; - - const createRollupConfig = await createRollupPrepareDeploymentParamsConfig( - parentChainPublicClient, - { - chainId: 123456, - owner: '0xYourOwnerAddressHere', - chainConfig, - loserStakeEscrow: '0xYourEscrowAddressHere', // e.g., owner-controlled or burn address - // Optional: baseStake: 100000000000000000n, stakeToken: '0xERC20Address', etc. - }, - ); - ``` - -4. **Deploy the chain**: - - ```typescript - import { createWalletClient } from 'viem'; - import { privateKeyToAccount } from 'viem/accounts'; - import { createRollup } from '@arbitrum/chain-sdk'; - - const deployerAccount = privateKeyToAccount('0xYourPrivateKey'); - - const walletClient = createWalletClient({ - account: deployerAccount, - chain: sepolia, - transport: http('https://your-parent-rpc-url'), - }); - - const createRollupResults = await createRollup({ - params: { - config: createRollupConfig, - batchPosters: ['0xYourBatchPosterAddress'], - validators: ['0xYourValidatorAddress'], - }, - account: deployerAccount, - publicClient: parentChainPublicClient, - walletClient, - }); - - console.log('Rollup Address:', createRollupResults.coreContracts.rollup); - ``` - -5. **For AnyTrust chains**: - If `DataAvailabilityCommittee` is `true`, configure the DAC keyset post-deployment using `setValidKeyset` from the SDK. - -### Updating `loserStakeEscrow` post-deployment - -The chain owner can update it by calling `setLoserStakeEscrow` on the deployed Rollup contract (address from `createRollupResults.coreContracts.rollup`): - -```typescript -import { parseAbi } from 'viem'; - -const rollupAbi = parseAbi(['function setLoserStakeEscrow(address newLoserStakedEscrow) external']); - -await walletClient.writeContract({ - address: '0xYourRollupAddress', - abi: rollupAbi, - functionName: 'setLoserStakeEscrow', - args: ['0xNewEscrowAddressHere'], -}); -``` - -### Additional notes - -- This process requires the caller to be the owner. Changes affect how challenge losses are handled, so test thoroughly. -- Setting `loserStakeEscrow` to a burn address increases the cost of failed challenges, enhancing security. -- Deploy on testnets first; mainnet deployments are costly and permanent. - -## Validator configurations and how to setup them up - -Validators are configured during chain deployment and can be run post-launch. Arbitrum chains support permissioned validators, that can be added to an allowlist. - -### Step 1: Configure and run the validator node - -Start with the base configuration for a full node, then add validator-specific flags. Use a Docker command to run the Nitro node image (replace placeholders like version numbers, RPC URLs, and chain IDs with your specifics). For example, on Arbitrum One (chain ID 42161): - -```shell -docker run --rm -it -v /path/to/local/dir/arbitrum:/home/user/.arbitrum offchainlabs/nitro-node:v3.8.0-62c0aa7 \ - --parent-chain.connection.url=https://your-l1-rpc-url:8545 \ - --chain.id=42161 \ - --node.staker.enable=true \ - --node.staker.strategy=Defensive \ - --node.staker.parent-chain-wallet.password="YOUR_SECURE_PASSWORD" -``` - -Key configuration parameters to include: - -- `--node.staker.enable=true`: This flag enables validation mode. -- `--node.staker.strategy=[Strategy]`: Choose a strategy based on your intended behavior: - - `Defensive`: Monitors the chain and challenges incorrect assertions by posting a bond (recommended for most users). - - `StakeLatest`: Bonds on the latest correct assertion and challenges bad ones (available only on pre-BoLD chains). - - `ResolveNodes`: Bonds on the latest assertion, resolves unconfirmed ones, and challenges bad assertions. - - `MakeNodes`: Creates new assertions, resolves unconfirmed ones, and challenges bad ones (use cautiously, as it may lead to reverted transactions if multiple validators act at once). - - `Watchtower`: Passively monitors and logs errors without active challenging (enabled by default; no wallet needed, but set `--node.staker.enable=false` to disable if not wanted). -- `--node.staker.parent-chain-wallet.private-key=[0xYourPrivateKey]` or `--node.staker.parent-chain-wallet.password=[YourPassword]`: Provides access to the wallet for on-chain operations. Use a secure method; password-protected keystores are safer than direct private keys. -- `--node.bold.enable=true`: Enable this if the chain has BoLD activated (required for versions before Nitro v3.6.0). - -For custom Arbitrum chains: - -- Add `--chain.info-json=[JSON string or file path with Arbitrum chain info]` to specify the chain's details. -- BoLD parameters may not be needed if BoLD isn't activated on that chain. - -Run the command in a persistent setup (e.g., using Docker Compose or a systemd service) to keep the node online. - -### Step 2: Verify the validator is running correctly - -- Monitor the node logs for confirmation messages: - - Look for `INFO [...] running as validator txSender=[your_wallet_address] actingAsWallet=[your_wallet_address] whitelisted=true strategy=[YourChosenStrategy]`. This indicates the node is in validator mode with a valid wallet. - - `validation succeeded`: Shows the node is successfully validating blocks. - - `found correct assertion`: Confirms the node is detecting and agreeing with on-chain assertions. -- If issues arise, check for errors related to wallet funding, RPC connectivity, or chain syncing. - -### Advanced: Creating a dedicated validator wallet - -If you need a new wallet specifically for validation, use Nitro to generate one: - -```shell -docker run --rm -it -v /path/to/local/dir/arbitrum:/home/user/.arbitrum offchainlabs/nitro-node:v3.8.0-62c0aa7 \ - --parent-chain.connection.url=https://your-l1-rpc-url:8545 \ - --chain.id=42161 \ - --node.staker.enable=true \ - --node.staker.parent-chain-wallet.only-create-key \ - --node.staker.parent-chain-wallet.password="YOUR_SECURE_PASSWORD" -``` - -This creates a wallet file in your mounted directory (e.g., under `arb1/wallet/` for Arbitrum One). Back it up securely, as it's needed to withdraw any staked funds later. Load it in your node run command using the password. - -### For permissioned chains - -If the Arbitrum chain is permissioned (not fully permissionless), add your validator wallet address to the allowlist: - -1. Identify the `upgradeExecutor` contract address for the chain. -2. Call the `executeCall` method on it: - - Set `target` to the Rollup contract address. - - Set `targetCalldata` to `0xa3ffb772` followed by your validator address (this is the encoded signature for `setValidator(address[],bool[])`). -3. Verify by calling `isValidator(your_address)` on the Rollup contract, which should return `true`. - -This step requires administrative access to the chain. - -Keep your node synced and monitor it regularly to ensure it contributes effectively to chain security. Always use the latest Nitro version for security and compatibility. - -:::info Additional information - -Refer to the [Run a full node](/run-arbitrum-node/02-run-full-node.mdx) article for instructions on how to get up and running. - -::: - -### Assertion interval - -Default to 15 minutes for new assertions (via `--node.bold.assertion-posting-interval` (BoLD) or `--node.staker.make-assertion-interval` (Legacy ~1 hour is default)); must exceed the Rollup's `minimumAssertionPeriod` (~15 minutes). - -For production, run multiple validators in a network. Test on devnets first. Always back up keys, as they're needed to withdraw bonds. If issues arise, refer to the official Arbitrum docs for updates, as configurations evolve. +- **Base Stake**: Minimum bond required for validators. +- **Stake Token**: Token used for staking. +- **Loser Stake Escrow**: Address for escrowed funds from losing validators. diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/09-sequencer-timing-adjustments.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/09-sequencer-timing-adjustments.mdx new file mode 100644 index 0000000000..9d3ce1e017 --- /dev/null +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/09-sequencer-timing-adjustments.mdx @@ -0,0 +1,9 @@ +--- +title: 'Sequencer Timing Adjustments' +description: 'Learn how to configure sequencer timing adjustments for your Arbitrum chain' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/10-per-batch-gas-cost.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/10-per-batch-gas-cost.mdx new file mode 100644 index 0000000000..dfaa300451 --- /dev/null +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/10-per-batch-gas-cost.mdx @@ -0,0 +1,9 @@ +--- +title: 'Per batch gas cost' +description: 'Learn how to configure per batch gas cost for your Arbitrum chain' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/11-smart-contract-size-limit.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/11-smart-contract-size-limit.mdx new file mode 100644 index 0000000000..f6f3c94abe --- /dev/null +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/11-smart-contract-size-limit.mdx @@ -0,0 +1,9 @@ +--- +title: 'Smart contract size limit' +description: 'Learn how to configure smart contract size limits on your Arbitrum chain' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/12-customizing-anytrust.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/12-customizing-anytrust.mdx new file mode 100644 index 0000000000..46a0ea59a0 --- /dev/null +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/12-customizing-anytrust.mdx @@ -0,0 +1,9 @@ +--- +title: 'Customizing AnyTrust' +description: 'Learn how to customize AnyTrust on your Arbitrum chain' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx index 67eaeab929..f531d4b465 100644 --- a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx @@ -16,7 +16,7 @@ The specific upgrade requirements for each ArbOS release are located under each #### Step 1: Update Nitro on nodes and validators -Refer to the [requirements for the targeted ArbOS release](/run-arbitrum-node/arbos-releases/01-overview.mdx) to identify the specific [Nitro release](https://github.com/OffchainLabs/nitro/releases/) that supports the ArbOS version that you're upgrading to. For example, if your upgrade targets ArbOS 51, you'd use Nitro `v3.9.3` (Docker image: `offchainlabs/nitro-node:v3.9.3-8bc5554`) or higher. This is the version of the Nitro stack that needs to be running on each of your Arbitrum chain's nodes. A list of [all Nitro releases can be found on Github](https://github.com/OffchainLabs/nitro/releases). +Refer to the [requirements for the targeted ArbOS release](/run-arbitrum-node/arbos-releases/01-overview.mdx) to identify the specific [Nitro release](https://github.com/OffchainLabs/nitro/releases/) that supports the ArbOS version that you're upgrading to. For example, if your upgrade targets ArbOS 50, you'd use Nitro `v3.9.0` (Docker image: `offchainlabs/nitro-node:v3.9.0-cca645a`) or higher. This is the version of the Nitro stack that needs to be running on each of your Arbitrum chain's nodes. A list of [all Nitro releases can be found on Github](https://github.com/OffchainLabs/nitro/releases). Begin by upgrading your validator node(s) to the specified Nitro version, then update each remaining Arbitrum chain node to match this version. @@ -26,7 +26,7 @@ Note that upgrading your node version _must occur_ before the deadline establish While every ArbOS upgrade will require an update to the WASM module root, not every ArbOS upgrade will require an upgrade to the chain's `nitro-contracts` version. -If necessary, as defined in the release notes for each ArbOS release ([example of ArbOS 51](/run-arbitrum-node/arbos-releases/arbos51.mdx)), you may need to deploy new versions of some (or all) of the Nitro contracts to the parent chain of your Arbitrum chain. These contracts include the rollup logic, bridging logic, fraud-proof contracts, and interfaces for interacting with Nitro precompiles. To verify the current version of your Nitro contracts, follow [these instructions](https://github.com/OffchainLabs/orbit-actions/blob/main/README.md#check-version-and-upgrade-path) while replacing the inbox contract address and network name with that of your Arbitrum chain. This information will allow you to find the correct upgrade path for your Nitro contracts. +If necessary, as defined in the release notes for each ArbOS release ([example of ArbOS 50](/run-arbitrum-node/arbos-releases/arbos50.mdx)), you may need to deploy new versions of some (or all) of the Nitro contracts to the parent chain of your Arbitrum chain. These contracts include the rollup logic, bridging logic, fraud-proof contracts, and interfaces for interacting with Nitro precompiles. To verify the current version of your Nitro contracts, follow [these instructions](https://github.com/OffchainLabs/orbit-actions/blob/main/README.md#check-version-and-upgrade-path) while replacing the inbox contract address and network name with that of your Arbitrum chain. This information will allow you to find the correct upgrade path for your Nitro contracts. To update the WASM module root and deploy your chain's Nitro contracts to the parent chain for the most recent ArbOS release, you will need the following inputs (obtained from the [requirements for the targeted ArbOS release](/run-arbitrum-node/arbos-releases/01-overview.mdx)): @@ -35,7 +35,7 @@ To update the WASM module root and deploy your chain's Nitro contracts to the pa Once you have the WASM module root and have identified the required `nitro-contracts` version for the target ArbOS release, if any, [please follow the instructions in this guide](https://github.com/OffchainLabs/orbit-actions?tab=readme-ov-file#nitro-contracts-upgrades) for specific actions based on the `nitro-contracts` version you are deploying. Note that each ArbOS release will require performing this step with a different WASM module root and may require a different version of `nitro-contracts`. The guide linked above will be kept updated with the instructions for each specific ArbOS release. -The `WASM module root` is a 32-byte hash created from the Merkelized Go replay binary and its dependencies. When ArbOS is upgraded, a new WASM module root is generated due to modifications in the State Transition Function (STF). This new WASM module root must be set in the rollup contract on the parent chain. For example, the WASM module root for ArbOS 51 Dia is `0x8a7513bf7bb3e3db04b0d982d0e973bcf57bf8b88aef7c6d03dba3a81a56a499`. +The `WASM module root` is a 32-byte hash created from the Merkelized Go replay binary and its dependencies. When ArbOS is upgraded, a new WASM module root is generated due to modifications in the State Transition Function (STF). This new WASM module root must be set in the rollup contract on the parent chain. For example, the WASM module root for ArbOS 50 Dia is `0x2c54f6e9e378ba320ed9c713a1d9f067a572b1437e4f1c40b1a915d3066c04f2`. To set the WASM module root manually (i.e., not using the above guide), use the `Rollup proxy` contract's [`setWasmModuleRoot`](https://github.com/OffchainLabs/nitro-contracts/blob/38a70a5e14f8b52478eb5db08e7551a82ced14fe/src/rollup/RollupAdminLogic.sol#L321) method. Note that the `upgrade executor` contract on the parent chain is the designated owner of the Rollup contract, so the **chain owner account** needs to initiate a call to the `upgrade executor` contract in order to perform the upgrade. This call should include the correct calldata for setting the new WASM module root. @@ -49,7 +49,7 @@ WASM module roots are backward compatible, so upgrading them before an ArbOS ver To schedule an ArbOS version upgrade for your Arbitrum chain, [follow this guide](https://github.com/OffchainLabs/orbit-actions/tree/main/scripts/foundry/arbos-upgrades/at-timestamp). In addition to the upgrade action contract address and the account address for the chain owner account, you will need the following inputs: -1. **`newVersion`**: Specify the ArbOS version you wish to upgrade to (e.g., `51`). +1. **`newVersion`**: Specify the ArbOS version you wish to upgrade to (e.g., `50`). 2. **`timestamp`**: Set the exact UNIX timestamp at which you want your Arbitrum chain (Orbit) to transition to the new ArbOS version. If you would prefer to do this manually, simply call the [`scheduleArbOSUpgrade`](https://github.com/OffchainLabs/nitro-precompile-interfaces/blob/fe4121240ca1ee2cbf07d67d0e6c38015d94e704/ArbOwner.sol#L116) function on the `ArbOwner` precompile of the Arbitrum chain(s) you're upgrading. Because this is an administrative action (similar to upgrading your Wasm module root), the **chain owner account** must call the target chain's `upgrade executor` contract with the appropriate calldata in order to invoke the `scheduleArbOSUpgrade` function of the ArbOwner precompile. This will schedule the ArbOS upgrade using the specified version and timestamp. @@ -64,14 +64,14 @@ To upgrade immediately (without scheduling), set the timestamp to `0`. You can obtain the current ArbOS version of your chain by calling `ArbSys.ArbOSVersion()`. Keep in mind that this function adds `55` to the current ArbOS version. For example, if your chain is running on ArbOS 10, calling this function will return `65`. -When scheduling the ArbOS upgrade through `ArbOwner.scheduleArbOSUpgrade` you must use the actual ArbOS version you're upgrading to. For example, if you're upgrading to ArbOS 51, you will pass `51` when calling this function. +When scheduling the ArbOS upgrade through `ArbOwner.scheduleArbOSUpgrade` you must use the actual ArbOS version you're upgrading to. For example, if you're upgrading to ArbOS 50, you will pass `50` when calling this function. #### Step 4: Enable ArbOS specific configurations or feature flags (not always required) -For some ArbOS upgrades, such as [ArbOS 51 Dia](/run-arbitrum-node/arbos-releases/arbos51.mdx), there may be additional requirements or steps that need to be satisfied to ensure your Arbitrum chain can use all of the new features and improvements made available in that particular ArbOS release. +For some ArbOS upgrades, such as [ArbOS 50 Dia](/run-arbitrum-node/arbos-releases/arbos50.mdx), there may be additional requirements or steps that need to be satisfied to ensure your Arbitrum chain can use all of the new features and improvements made available in that particular ArbOS release. -If there are additional requirements for the targeted ArbOS release you're attempting to upgrade to; the additional requirements will be listed on the reference pages for [the targeted ArbOS release](/run-arbitrum-node/arbos-releases/01-overview.mdx#list-of-available-arbos-releases). For example, the additional requirements for Arbitrum chains upgrading to ArbOS 51 can be found [here on the ArbOS 51 docs](/run-arbitrum-node/arbos-releases/arbos51.mdx). +If there are additional requirements for the targeted ArbOS release you're attempting to upgrade to; the additional requirements will be listed on the reference pages for [the targeted ArbOS release](/run-arbitrum-node/arbos-releases/01-overview.mdx#list-of-available-arbos-releases). For example, the additional requirements for Arbitrum chains upgrading to ArbOS 50 can be found [here on the ArbOS 50 docs](/run-arbitrum-node/arbos-releases/arbos50.mdx). Congratulations! You've upgraded your Arbitrum chain(s) to the specified ArbOS version. diff --git a/docs/launch-arbitrum-chain/02-start-your-journey.mdx b/docs/launch-arbitrum-chain/02-start-your-journey.mdx new file mode 100644 index 0000000000..7efc94581b --- /dev/null +++ b/docs/launch-arbitrum-chain/02-start-your-journey.mdx @@ -0,0 +1,12 @@ +--- +title: 'Start your journey into Arbitrum chains' +sidebar_label: 'Arbitrum chain: get started' +description: 'Learn how to get started with Arbitrum chains' +sidebar_position: '2' +author: 'anegg0' +sme: 'mahsamoosavi' +editor: 'anegg0' +target_audience: 'Prospective chain owners, and operators' +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/03-arbitrum-license.mdx b/docs/launch-arbitrum-chain/03-arbitrum-license.mdx new file mode 100644 index 0000000000..b727357f1a --- /dev/null +++ b/docs/launch-arbitrum-chain/03-arbitrum-license.mdx @@ -0,0 +1,12 @@ +--- +title: 'The Arbitrum chain license' +sidebar_label: 'Arbitrum chain license' +description: '' +sidebar_position: 2 +author: +sme: +editor: anegg0 +target_audience: +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/04-maintain-your-chain/01-bridging.mdx b/docs/launch-arbitrum-chain/04-maintain-your-chain/01-bridging.mdx new file mode 100644 index 0000000000..598237adc9 --- /dev/null +++ b/docs/launch-arbitrum-chain/04-maintain-your-chain/01-bridging.mdx @@ -0,0 +1,9 @@ +--- +title: 'Bridging' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/04-maintain-your-chain/02-monitoring.mdx b/docs/launch-arbitrum-chain/04-maintain-your-chain/02-monitoring.mdx new file mode 100644 index 0000000000..649e63f45f --- /dev/null +++ b/docs/launch-arbitrum-chain/04-maintain-your-chain/02-monitoring.mdx @@ -0,0 +1,9 @@ +--- +title: 'Monitoring' +description: 'Learn how to configure your Arbitrum chain with a custom bond and validator configurations' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/01-decentralization-security.mdx b/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/01-decentralization-security.mdx new file mode 100644 index 0000000000..272aab0202 --- /dev/null +++ b/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/01-decentralization-security.mdx @@ -0,0 +1,9 @@ +--- +title: 'Decentralization and Security' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/02-guidance-on-altda.mdx b/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/02-guidance-on-altda.mdx new file mode 100644 index 0000000000..eca5d9a361 --- /dev/null +++ b/docs/launch-arbitrum-chain/04-maintain-your-chain/04-guidance/02-guidance-on-altda.mdx @@ -0,0 +1,9 @@ +--- +title: 'Guidance on AltDA' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/06-third-party-integrations/03-integrations.mdx b/docs/launch-arbitrum-chain/06-third-party-integrations/03-integrations.mdx new file mode 100644 index 0000000000..34c95d1a99 --- /dev/null +++ b/docs/launch-arbitrum-chain/06-third-party-integrations/03-integrations.mdx @@ -0,0 +1,15 @@ +--- +title: 'Integrations' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- + +## Compatible third-party integrations + +## LayerZero OFT + +## xERC-20 Gateway diff --git a/docs/launch-arbitrum-chain/07-arbitrum-node-runners/arbitrum-chain-node-providers.mdx b/docs/launch-arbitrum-chain/07-arbitrum-node-runners/arbitrum-chain-node-providers.mdx new file mode 100644 index 0000000000..142b208a4a --- /dev/null +++ b/docs/launch-arbitrum-chain/07-arbitrum-node-runners/arbitrum-chain-node-providers.mdx @@ -0,0 +1,9 @@ +--- +title: 'Arbitrum chain Node Providers' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +robots: noindex +--- diff --git a/docs/launch-arbitrum-chain/08-ecosystem-support/01-arbitrum-chain-portal.mdx b/docs/launch-arbitrum-chain/08-ecosystem-support/01-arbitrum-chain-portal.mdx new file mode 100644 index 0000000000..7c7c6b0fe6 --- /dev/null +++ b/docs/launch-arbitrum-chain/08-ecosystem-support/01-arbitrum-chain-portal.mdx @@ -0,0 +1,9 @@ +--- +title: 'Arbitrum chains Portal' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/08-ecosystem-support/03-get-listed-arbitrum-chain-platforms.mdx b/docs/launch-arbitrum-chain/08-ecosystem-support/03-get-listed-arbitrum-chain-platforms.mdx new file mode 100644 index 0000000000..416349caf7 --- /dev/null +++ b/docs/launch-arbitrum-chain/08-ecosystem-support/03-get-listed-arbitrum-chain-platforms.mdx @@ -0,0 +1,9 @@ +--- +title: 'Get listed on Arbitrum platforms' +description: 'PLACEHOLDER' +author: +sme: +content_type: how-to +tags: ['hide-from-search'] +unlisted: true +--- diff --git a/docs/launch-arbitrum-chain/arbitrum-chain-supported-parent-chains.mdx b/docs/launch-arbitrum-chain/arbitrum-chain-supported-parent-chains.mdx new file mode 100644 index 0000000000..01cd8daf02 --- /dev/null +++ b/docs/launch-arbitrum-chain/arbitrum-chain-supported-parent-chains.mdx @@ -0,0 +1,60 @@ +--- +title: 'Supported parent chains' +sidebar_label: 'Supported parent chains' +description: 'List of officially supported parent chains for Arbitrum chains' +sidebar_position: '2' +author: 'mahsamoosavi' +sme: 'mahsamoosavi' +editor: 'anegg0' +target_audience: 'Arbitrum chains owners and operators' +--- + +This page lists the parent chains that are officially supported for Arbitrum chains, including mainnets, testnets, and options for local development. While the Arbitrum chain SDK provides functionality to enable custom parent chains, support is limited to the chains explicitly listed on this page. Developers are welcome to use the Arbitrum chain SDK to configure and deploy custom parent chains; however, such setups, including deploying the required creator and template contracts, are beyond the scope of our official support. + +:::caution Supported Chains Only + +Please note that we cannot guarantee compatibility or offer assistance for custom configurations outside of the supported chains detailed below. + +::: + +#### Supported chains + +
+ +- **Ethereum Mainnet** + **Chain ID:** `1` + +- **Arbitrum One** + **Chain ID:** `42161` + +- **Arbitrum Nova** + **Chain ID:** `42170` + +- **Base** + **Chain ID:** `8453` + +- **Sepolia** + **Chain ID:** `11155111` + +- **Arbitrum Sepolia** + **Chain ID:** `421613` + +- **Base Sepolia** + **Chain ID:** `84531` + +- **Nitro Testnode L1** + **Chain ID:** `1337` + +- **Nitro Testnode L2** + **Chain ID:** `412346` + +- **Nitro Testnode L3** + **Chain ID:** `333333` + +
+ +### Adding custom parent chains + +Although Arbitrum chains primarily supports a predefined set of chains, it provides developers with the flexibility to add custom parent chains through [the `registerCustomParentChain` function of the Arbitrum (Orbit) chain SDK](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/729facd4d50156d7a84cf1204552c900eb86655c/src/chains.ts#L102). This capability enables integration with chains beyond the officially supported list, offering opportunities for customization and expanding the Arbtrium ecosystem. + +However, adding a custom chain requires deploying essential contracts, such as the creator contract and template contract, on the target chain. These contracts are fundamental for ensuring the proper functioning of the Arbitrum chain framework on the custom chain. diff --git a/docs/launch-arbitrum-chain/partials/_arbitrum-chain-public-preview-banner-partial.md b/docs/launch-arbitrum-chain/partials/_arbitrum-chain-public-preview-banner-partial.md new file mode 100644 index 0000000000..3b33fd052a --- /dev/null +++ b/docs/launch-arbitrum-chain/partials/_arbitrum-chain-public-preview-banner-partial.md @@ -0,0 +1,7 @@ +:::info PUBLIC PREVIEW, MAINNET READY + +Arbitrum chains are now [Mainnet ready](/launch-arbitrum-chain/concepts/public-preview-expectations.mdx#arbitrum-chains-are-mainnet-ready-but-deploy-to-testnet-first)! Note that Arbitrum is still a **[public preview](/launch-arbitrum-chain/concepts/public-preview-expectations.mdx)** capability - the Arbitrum product and its supporting documentation may change significantly as we capture feedback from readers like you. + +To provide feedback, click the _Request an update_ button at the top of this document, [join the Arbitrum Discord](https://discord.gg/arbitrum), or reach out to our team directly by completing [this form](http://bit.ly/3yy6EUK). + +::: diff --git a/docs/node-running/contribute.mdx b/docs/node-running/contribute.mdx new file mode 100644 index 0000000000..4f7c3501cf --- /dev/null +++ b/docs/node-running/contribute.mdx @@ -0,0 +1,8 @@ +--- +title: 'Contribute docs' +description: "Learn how to contribute to Arbitrum's documentation" +--- + +import ContributeDocsPartial from '../partials/_contribute-docs-partial.mdx'; + + diff --git a/docs/node-running/how-tos/data-availability-committee/partials/parameters/_ipfs-parameters.mdx b/docs/node-running/how-tos/data-availability-committee/partials/parameters/_ipfs-parameters.mdx new file mode 100644 index 0000000000..2ff2d05dfe --- /dev/null +++ b/docs/node-running/how-tos/data-availability-committee/partials/parameters/_ipfs-parameters.mdx @@ -0,0 +1,5 @@ +| Parameter | Description | +| --------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| --data-availability.ipfs-storage.enable | Enables storage/retrieval of sequencer batch data from IPFS | +| --data-availability.ipfs-storage.profiles | Comma separated list of IPFS profiles to use | +| --data-availability.ipfs-storage.read-timeout | Timeout for IPFS reads, since by default it will wait forever. Treat timeout as not found (default 1m0s) | diff --git a/docs/node-running/node-running-content-map.mdx b/docs/node-running/node-running-content-map.mdx new file mode 100644 index 0000000000..01e0c38fb9 --- /dev/null +++ b/docs/node-running/node-running-content-map.mdx @@ -0,0 +1,98 @@ +--- +id: node-running-content-map +title: Run an Arbitrum node +sidebar_label: Run an Arbitrum node +--- + +import Card from '@site/src/components/Cards/Card'; + +# Run an Arbitrum node + +Learn how to run an Arbitrum node. + +
+ + + + + + + + + + + + + +
diff --git a/docs/notices/arbos51-arbsepolia-upgrade-notice.mdx b/docs/notices/arbos51-arbsepolia-upgrade-notice.mdx deleted file mode 100644 index bd51d461ee..0000000000 --- a/docs/notices/arbos51-arbsepolia-upgrade-notice.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: 'ArbOS 51 activation on ArbSepolia' -description: Upgrade notices for ArbOS 51 activation on ArbSepolia -user_story: As an Arbitrum chain owner or node operator, I want to configure my chain/nodes to run on ArbSepolia. -content_type: notice ---- - -On Monday, December 1, 2025 at 17:00 UTC, ArbOS 51 will activate on the Arbitrum Sepolia chain. - -:::warning Action required - -Arbitrum Sepolia node operators **must upgrade** to Nitro **`v3.9.3`** ahead of this activation to continue syncing the chain. - -- **Docker image:** `offchainlabs/nitro-node:v3.9.3-8bc5554` -- **Release notes:** https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3 - -::: - -### **Context** - -ArbOS 51 is a follow-up to ArbOS 50 that fixes issues with the Pricing Framework. ArbOS 50 was previously activated on Sepolia, but the Gas Target & Pricing Framework changes remained disabled pending this fix. ArbOS 51 now completes that work. - -Upstream governance items (ArbOS 50 + Gas Target & Pricing Framework) are being bundled into a single on-chain vote. Both components have passed Snapshot temperature checks, with the Tally vote expected to open on or around **December 4, 2025**. diff --git a/docs/notices/fusaka-upgrade-notice.mdx b/docs/notices/fusaka-upgrade-notice.mdx index 3a99ceabde..e1b0b6c44f 100644 --- a/docs/notices/fusaka-upgrade-notice.mdx +++ b/docs/notices/fusaka-upgrade-notice.mdx @@ -7,7 +7,7 @@ content_type: notice :::danger ๐Ÿ›‘ IMPORTANT ๐Ÿ›‘ -Arbitrum chain operators must ensure that their nodes are properly configured before or shortly after the parent chain upgrades to Fusaka or the child chain upgrades to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx). +Arbitrum chain operators must ensure that their nodes are properly configured before or shortly after the parent chain upgrades to Fusaka or the child chain upgrades to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx). ::: @@ -23,9 +23,8 @@ The following dates are relevant for Arbitrum chain operators. | Date | Network upgrade | Affected audience | | ---------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to ArbOS 50 | Node operators for Arbitrum Sepolia | -| `Dec 1st 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum Sepolia | -| `Jan 8th, 2026, 17:00:00 UTC (proposed)` | Arbitrum One/Nova upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum One/Nova | +| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx) | Node operators for Arbitrum Sepolia | +| `Jan 8th, 2026, 17:00:00 UTC (proposed)` | Arbitrum One/Nova upgrade to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx) | Node operators for Arbitrum One/Nova | | `Oct 14th 2025, 07:36:00 UTC` | Ethereum Sepolia Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Sepolia (Orbit L2s, Arbitrum Sepolia) | | `Dec 3rd 2025, 21:49:11 UTC` | Ethereum Mainnet Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Mainnet (Orbit L2s, Arbitrum One/Nova) | @@ -35,18 +34,12 @@ Outlined below are different types of Arbitrum chains, along with node software | Layer | Data Availability | Fallback to blobs enabled? | Required Nitro node version | Configurations for the Ethereum Consensus Layer client | | ------ | -------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **L2** | **Rollup** | N/A | Update to [`3.9.3`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) (ArbOS 51); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | -| **L2** | **AnyTrust / AltDA** | Enabled | Update to [`3.9.3`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) (ArbOS 51); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | +| **L2** | **Rollup** | N/A | Update to [`3.9.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) (ArbOS 50); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | +| **L2** | **AnyTrust / AltDA** | Enabled | Update to [`3.9.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) (ArbOS 50); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | | **L2** | **AnyTrust / AltDA** | Disabled | No nitro update required | Doesn't require historical blob data | | **L3** | **Rollup** | N/A | No nitro update required | Doesn't require historical blob data | | **L3** | **AnyTrust / AltDA** | Enabled or Disabled | No nitro update required | Doesn't require historical blob data | -:::warning Exceptions - -For batch posters settling to mainnet Ethereum, Nitro >=3.8.0 is required. - -::: - ### How to ensure your node has access to all historical blob data and blob data from all subnets #### If you run a Nitro node and use an external L1 Ethereum beacon chain RPC: diff --git a/docs/partials/_macos-verify-tx-issue-banner-partial.mdx b/docs/partials/_macos-verify-tx-issue-banner-partial.mdx new file mode 100644 index 0000000000..11df1da02c --- /dev/null +++ b/docs/partials/_macos-verify-tx-issue-banner-partial.mdx @@ -0,0 +1,13 @@ +--- +partial_type: banner +title: 'MacOS Verification Issue Banner' +description: 'Warning banner for MacOS transaction verification limitations' +author: anegg0 +last_reviewed: 2025-01-15 +--- + +:::caution MacOS Users + +This feature is currently unavailable to MacOS users. We are working on a solution and will update this page when this limitation is resolved. + +::: diff --git a/docs/partials/_under-construction-banner-partial.mdx b/docs/partials/_under-construction-banner-partial.mdx new file mode 100644 index 0000000000..1a30c582f3 --- /dev/null +++ b/docs/partials/_under-construction-banner-partial.mdx @@ -0,0 +1,15 @@ +--- +partial_type: banner +title: 'Under Construction Banner' +description: 'Banner indicating document is under construction' +author: anegg0 +last_reviewed: 2025-01-15 +--- + +:::caution UNDER CONSTRUCTION + +This document is currently under construction. + +If you're waiting for this content to be completed, click the `Request an update` button at the top of this page to let us know. We incorporate these requests into our content prioritization discussions. **Thank you!** + +::: diff --git a/docs/run-arbitrum-node/02-run-full-node.mdx b/docs/run-arbitrum-node/02-run-full-node.mdx index 6890c0ff22..65f5b3bf7e 100644 --- a/docs/run-arbitrum-node/02-run-full-node.mdx +++ b/docs/run-arbitrum-node/02-run-full-node.mdx @@ -150,17 +150,7 @@ If you are running more than on node, you should [run a feed relay](/run-arbitru ### Pruning - Pruning a full node refers to removing older, unnecessary data from the local copy of the blockchain that the node maintains, thereby saving disk space and slightly improving the node's efficiency. Pruning will remove all states from blocks older than the latest 128. -- If you are using the default setting `--execution.caching.state-scheme=hash` then you can activate pruning by using the parameter: -- `--init.prune ` - - `minimal`: Only genesis + latest head state is left, takes the least amount of time (several house for Arbitrum One-sized database) - - `full` : Genesis + head state + state for latest confirmed block (will take a long time ~50 hours or more) - - `validator`: All of above + state of latest validated block (will take a little less than twice what `full` will take) - -:::note - -This process occurs when the node starts and will not serve RPC requests during pruning. - -::: +- You can activate pruning by using the parameter `--init.prune` and using "full" or "validator" as the value (depending on the type of node you are running). Note that this process occurs when the node starts and will not serve RPC requests during pruning. ### Transaction prechecker diff --git a/docs/run-arbitrum-node/arbos-releases/01-overview.mdx b/docs/run-arbitrum-node/arbos-releases/01-overview.mdx index 46c762998b..5d1dbc91ad 100644 --- a/docs/run-arbitrum-node/arbos-releases/01-overview.mdx +++ b/docs/run-arbitrum-node/arbos-releases/01-overview.mdx @@ -31,7 +31,7 @@ Visit [How Arbitrum works](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx) to ## List of available ArbOS releases -- [Dia (ArbOS 51)](/run-arbitrum-node/arbos-releases/arbos51.mdx) +- [Dia (ArbOS 50)](/run-arbitrum-node/arbos-releases/arbos50.mdx) - [Callisto (ArbOS 40)](/run-arbitrum-node/arbos-releases/arbos40.mdx) - [Bianca (ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx) - [Atlas (ArbOS 20)](/run-arbitrum-node/arbos-releases/arbos20.mdx) diff --git a/docs/run-arbitrum-node/arbos-releases/arbos51.mdx b/docs/run-arbitrum-node/arbos-releases/arbos50.mdx similarity index 85% rename from docs/run-arbitrum-node/arbos-releases/arbos51.mdx rename to docs/run-arbitrum-node/arbos-releases/arbos50.mdx index 7d17633b02..deb96184bc 100644 --- a/docs/run-arbitrum-node/arbos-releases/arbos51.mdx +++ b/docs/run-arbitrum-node/arbos-releases/arbos50.mdx @@ -1,9 +1,9 @@ --- -title: 'ArbOS 51 Dia' -sidebar_label: 'ArbOS 51 Dia' +title: 'ArbOS 50 Dia' +sidebar_label: 'ArbOS 50 Dia' sidebar_position: 2 -description: 'Learn about ArbOS 51 Dia release, including Fusaka upgrade support, new EIPs, bug fixes, and upgrade requirements for Arbitrum chain owners and node operators.' -user_story: As an Arbitrum chain owner or node operator, I want to know what ArbOS 51 implements. +description: 'Learn about ArbOS 50 Dia release, including Fusaka upgrade support, new EIPs, bug fixes, and upgrade requirements for Arbitrum chain owners and node operators.' +user_story: As an Arbitrum chain owner or node operator, I want to know what ArbOS 50 implements. author: zk-Lumi sme: zk-Lumi content_type: release note @@ -13,37 +13,37 @@ import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition'; -ArbOS 51 Dia is still pre-release. This document may change. +ArbOS 50 Dia is still pre-release. This document may change. -This page is intended for all Arbitrum node operators and Arbitrum chain owners chains. This page summarizes the changes brought by ArbOS 51 Dia, and what you should do to ensure a seamless upgrade. +This page is intended for all Arbitrum node operators and Arbitrum chain owners chains. This page summarizes the changes brought by ArbOS 50 Dia, and what you should do to ensure a seamless upgrade. Before Ethereum Parent chain Sepolia and Mainnet upgrade to Fusaka: ensure that your Nitro node version is upgraded and consensus layer client is configured as per the [Fusaka upgrade notice](../../notices/fusaka-upgrade-notice.mdx). -The minimum Nitro version that supports ArbOS 51 "Dia" is [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3), which is available on Docker Hub with the image tag `Noffchainlabs/nitro-node:v3.9.3-8bc5554`. This release of Nitro is a mandatory upgrade for Arbitrum One and Nova node operators if adopted. For Arbitrum One and Nova, the ArbOS 51 "Dia" upgrade will require a governance vote to activate. +The minimum Nitro version that supports ArbOS 50 "Dia" is [Nitro v3.9.0](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0), which is available on Docker Hub with the image tag `Noffchainlabs/nitro-node:v3.9.0-cca645a`. This release of Nitro is a mandatory upgrade for Arbitrum One and Nova node operators if adopted. For Arbitrum One and Nova, the ArbOS 50 "Dia" upgrade will require a governance vote to activate. -As a refresher, ArbOS upgrades get treated as Arbitrum's equivalent of a hard fork. To learn more, refer to the [Arbitrum ArbOS upgrades forum post](https://forum.arbitrum.foundation/t/arbitrum-arbos-upgrades/19695). Note that ArbOS 51 Dia is an upgrade that builds upon [ArbOS 40 Callisto](./arbos40.mdx). +As a refresher, ArbOS upgrades get treated as Arbitrum's equivalent of a hard fork. To learn more, refer to the [Arbitrum ArbOS upgrades forum post](https://forum.arbitrum.foundation/t/arbitrum-arbos-upgrades/19695). Note that ArbOS 50 Dia is an upgrade that builds upon [ArbOS 40 Callisto](./arbos40.mdx). ### Requirements - Having read and understood the [ArbOS Software Releases Overview page](./01-overview.mdx). -- Running [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) or higher, which is available on Docker Hub with the image tag `offchainlabs/nitro-node:v3.9.3-8bc5554`. - - Note that it's important to run Nitro v3.9.3 only against trusted databases. If you want to use an untrusted database, you can first remove the `wasm` directory if it exists (potentially inside the `nitro` folder). Otherwise, the database may have malicious, unvalidated code that can result in remote code execution. Avoiding unvalidated code is also mitigated by ensuring you run the Arbitrum Nitro node inside Docker. +- Running [Nitro v3.9.0](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) or higher, which is available on Docker Hub with the image tag `offchainlabs/nitro-node:v3.9.0-cca645a`. + - Note that it's important to run Nitro v3.9.0 only against trusted databases. If you want to use an untrusted database, you can first remove the `wasm` directory if it exists (potentially inside the `nitro` folder). Otherwise, the database may have malicious, unvalidated code that can result in remote code execution. Avoiding unvalidated code is also mitigated by ensuring you run the Arbitrum Nitro node inside Docker. - Running [nitro-contracts v3.1.0](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.0) or higher - If your chain isn't ready to activate BoLD, use [nitro-contracts v2.1.3](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v2.1.3) instead; v3.0.0 or higher can't be used without activating BoLD. - If you want to enable [Native Token Mint/Burn capabilities](#native-token-mint-and-burn) for your chain, you must use [nitro-contracts v3.1.1](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.1) or higher. -- WASM module root: `0x8a7513bf7bb3e3db04b0d982d0e973bcf57bf8b88aef7c6d03dba3a81a56a499` +- WASM module root: `0x2c54f6e9e378ba320ed9c713a1d9f067a572b1437e4f1c40b1a915d3066c04f2` - If the Arbitrum chain posts blobs to a Fusaka-enabled parent chain, ensure that the consensus layer client is configured correctly as per the [Fusaka upgrade notice](../../notices/fusaka-upgrade-notice.mdx). -### High-level description of ArbOS 51 changes +### High-level description of ArbOS 50 changes -ArbOS 51 Dia is an upgrade to support the relevant EVM changes that are a part of Ethereum's [Fusaka upgrade](https://ethereum.org/en/roadmap/fusaka/). Ethereum's mainnet upgrade to Fusaka is tentatively scheduled for [December 3, 2025 at epoch `411392`](https://notes.ethereum.org/@bbusa/fusaka-bpo-timeline). As a result, the majority of the ArbOS-specific changes revolve around implementing the relevant [Fusaka EIPs](https://eips.ethereum.org/EIPS/eip-7607) on Arbitrum Chains. +ArbOS 50 Dia is an upgrade to support the relevant EVM changes that are a part of Ethereum's [Fusaka upgrade](https://ethereum.org/en/roadmap/fusaka/). Ethereum's mainnet upgrade to Fusaka is tentatively scheduled for [December 3, 2025 at epoch `411392`](https://notes.ethereum.org/@bbusa/fusaka-bpo-timeline). As a result, the majority of the ArbOS-specific changes revolve around implementing the relevant [Fusaka EIPs](https://eips.ethereum.org/EIPS/eip-7607) on Arbitrum Chains. -Here's the list of all changes included in ArbOS 51 Dia: +Here's the list of all changes included in ArbOS 50 Dia: #### [EIP-7951: Precompile for secp256r1 curve support](https://eips.ethereum.org/EIPS/eip-7951) @@ -71,15 +71,15 @@ This EIP increases the gas cost of the ModExp cryptographic precompile to addres #### [EIP-7910: eth_config JSON-RPC method](https://eips.ethereum.org/EIPS/eip-7910) -This EIP provides a new RPC method that allows the Arbitrum Nitro node to respond with key configuration variables, offering node operators the ability to gain greater confidence that their Nitro nodes are correctly configured and prepared for upcoming forks. In future Nitro releases, we expect to include additional fields specific to Arbitrum chains. This update is at the RPC level and may be enabled later than the ArbOS 51 Dia upgrade. +This EIP provides a new RPC method that allows the Arbitrum Nitro node to respond with key configuration variables, offering node operators the ability to gain greater confidence that their Nitro nodes are correctly configured and prepared for upcoming forks. In future Nitro releases, we expect to include additional fields specific to Arbitrum chains. This update is at the RPC level and may be enabled later than the ArbOS 50 Dia upgrade. #### [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) -As [disclosed previously](https://forum.arbitrum.foundation/t/disclosure-of-support-for-eip-2537-on-arbitrum-one-and-nova/29720), the precompiled contracts for performing various operations over the BLS12-381 elliptic curve, including BLS Signature verification, were added but not properly enabled in [ArbOS 40 Callisto](./arbos40.mdx) as originally expected. ArbOS 51 Dia will now enable `EIP-2537`. +As [disclosed previously](https://forum.arbitrum.foundation/t/disclosure-of-support-for-eip-2537-on-arbitrum-one-and-nova/29720), the precompiled contracts for performing various operations over the BLS12-381 elliptic curve, including BLS Signature verification, were added but not properly enabled in [ArbOS 40 Callisto](./arbos40.mdx) as originally expected. ArbOS 50 Dia will now enable `EIP-2537`. #### ArbOS block limit change: Effective block gas limit -Since ArbOS 51 introduces a `MaxTxGasLimit`, the State Transition Function (STF) will be relaxed in ArbOS 51 to allow the final transaction in a block to use up to the `MaxTxGasLimit` even if it would cause the block to exceed `MaxBlockGasLimit`. This means that the "Effective Block Gas Limit" is really `MaxBlockGasLimit + MaxTxGasLimit`. In previous versions of ArbOS, the Sequencer would skip transactions if the transaction request's `GasLimit` minus the parent chain data posting gas exceeded the gas remaining in the block. +Since ArbOS 50 introduces a `MaxTxGasLimit`, the State Transition Function (STF) will be relaxed in ArbOS 50 to allow the final transaction in a block to use up to the `MaxTxGasLimit` even if it would cause the block to exceed `MaxBlockGasLimit`. This means that the "Effective Block Gas Limit" is really `MaxBlockGasLimit + MaxTxGasLimit`. In previous versions of ArbOS, the Sequencer would skip transactions if the transaction request's `GasLimit` minus the parent chain data posting gas exceeded the gas remaining in the block. The new algorithm is more efficient because the sequencer doesn't need to keep searching through the queue of transactions to find one that fits in the remaining block gas, and can continue to add transactions until the unused block gas is 0. @@ -90,14 +90,14 @@ This change doesn't affect the `GasTarget`, and therefore doesn't affect how muc - ArbOS didn't get updated for parent chain calldata price increase - This change standardizes the calculation of gas units for compressed Batch calldata across the codebase by replacing hard-coded values with a method call (tokenGasUnits). - `EIP-7702` precompile delegation behavior divergence - - Previously, calls to precompiles could execute an INVALID opcode instead of succeeding with no execution. ArbOS 51 Dia will update code to align with `EIP-7702` spec to treat precompile code as empty during delegation. + - Previously, calls to precompiles could execute an INVALID opcode instead of succeeding with no execution. ArbOS 50 Dia will update code to align with `EIP-7702` spec to treat precompile code as empty during delegation. - ARM and x86 divergence - This change adds a map to store transaction hash along with its gas used to bypass transaction execution for a problematic transaction execution which diverged between ARM and x86 architectures. This was added in to hardcode one transaction that caused the divergence on Arbitrum Sepolia, as disclosed in the [security council emergency Action report](https://forum.arbitrum.foundation/t/security-council-emergency-action-10-13-2025/30093). - The default WASM Stack Depth value in ArbOS is now set to 22,000, preventing new chains from encountering the same divergence issue. #### Raising the gas target, increasing the min L2 base fee, & improving the pricing algorithm -As part of our strategy for scaling Arbitrum technology, the ArbOS 51 release includes a slight change to improve the pricing algorithm for Arbitrum One and Nova. This improvement is aimed at reducing the severity, frequency, and duration of high L2 gas prices during periods of elevated demand on the network. Concretely, the changes are to: +As part of our strategy for scaling Arbitrum technology, the ArbOS 50 release includes a slight change to improve the pricing algorithm for Arbitrum One and Nova. This improvement is aimed at reducing the severity, frequency, and duration of high L2 gas prices during periods of elevated demand on the network. Concretely, the changes are to: - Replace the current single gas target and single adjustment window, with a new model that employs multiple (higher) gas targets, measured over multiple adjustment windows. - Increase the default minimum L2 base fee from 0.01 gwei per gas to 0.02 gwei per gas. @@ -114,7 +114,7 @@ To read more about this feature, see the [dynamic pricing explainer](https://blo Native token mint and burn is a feature that allows Arbitrum chains to use interoperability-enabled token standards (e.g., LayerZero OFTs, xERC20s, native USDC) as native gas tokens on their chains. Currently, Arbitrum chains are designed to "lock and mint" native gas tokens on the chain's canonical Bridge. However, doing so means that these "locked and minted" native gas tokens can't interact with third-party cross-chain adapter contracts. This new feature lets an Arbitrum chain delegate minting and burning of its native gas token to a trusted bridge provider (e.g., LayerZero OFT). -Native token mint and burn is included in ArbOS 51 Dia for the benefit of Arbitrum Orbit chains (reducing the need for forks) and to streamline development and testing into a single codebase. There are no plans to enable this feature on Arbitrum One or Arbitrum Nova, consequently this feature will be explicitly left disabled for Arbitrum One and Arbitrum Nova. +Native token mint and burn is included in ArbOS 50 Dia for the benefit of Arbitrum Orbit chains (reducing the need for forks) and to streamline development and testing into a single codebase. There are no plans to enable this feature on Arbitrum One or Arbitrum Nova, consequently this feature will be explicitly left disabled for Arbitrum One and Arbitrum Nova. To read more about this feature, see the [Native Token Mint/Burn enablement guide](https://arbitrum.notion.site/Enable-Native-Mint-Burn-for-your-chain-s-gas-token-22601a3f59f880be9b99d3d55f982a17). @@ -124,9 +124,9 @@ If you want to enable Native Token Mint/Burn capabilities for your chain, you mu -### Fusaka EIPs that aren't proposed to be in ArbOS 51 Dia +### Fusaka EIPs that aren't proposed to be in ArbOS 50 Dia -Support and implementation for the following EIPs aren't planned to be part of ArbOS 51 Dia: +Support and implementation for the following EIPs aren't planned to be part of ArbOS 50 Dia: - [EIP-7594](https://eips.ethereum.org/EIPS/eip-7594), [EIP-7918](https://eips.ethereum.org/EIPS/eip-7918), and [EIP-7892](https://eips.ethereum.org/EIPS/eip-7892), since Arbitrum chains don't have blob data markets (though they do support posting blob data to a non-Arbitrum parent chain) - [EIP-7917](https://eips.ethereum.org/EIPS/eip-7917), since Arbitrum chains don't have a beacon chain and therefore don't have a peer-to-peer layer like Ethereum does @@ -134,19 +134,19 @@ Support and implementation for the following EIPs aren't planned to be part of A - [EIP-7907](https://eips.ethereum.org/EIPS/eip-7907), this EIP is no longer Scheduled For Inclusion (SFI) for Fusaka, as agreed upon by Client teams during [ACDE 216](https://ethereum-magicians.org/t/allcoredevs-execution-acde-216-july-17-2025/24770/2) on July 17, 2025. We're currently exploring alternative ways to increase the Smart Contract size limit that don't interfere with the ability for Arbitrum chains to support `EIP-7907` in the future. See this [forum post reply](https://forum.arbitrum.foundation/t/non-constitutional-proposal-to-direct-the-arbitrum-foundation-to-implement-an-extended-version-of-eip-7907-and-for-the-dao-to-ratify-its-deployment-on-arbitrum-one/29375/3) for more details about this. - [EIP-7935](https://eips.ethereum.org/EIPS/eip-7935), since Arbitrum chains already have a default gas target of 28Mgas/s and we have separate, alternative plans for increasing the gas limit through other means, as mentioned in [Scaling Arbitrum everywhere](https://blog.arbitrum.io/scaling-arbitrum-everywhere/). -### Special note about ArbOS 51 Dia for chains that haven't yet upgraded to use Arbitrum BoLD +### Special note about ArbOS 50 Dia for chains that haven't yet upgraded to use Arbitrum BoLD -While ArbOS 51 Dia will be compatible with both `nitro-contracts 3.1.X` and `nitro-contracts 2.1.3`, only chains that have Arbitrum BoLD enabled can use `nitro-contracts 3.x`. This requirement means that if your chain hasn't yet upgraded to use BoLD, only use `nitro-contracts 2.1.3` for your ArbOS 51 Dia upgrade. +While ArbOS 50 Dia will be compatible with both `nitro-contracts 3.1.X` and `nitro-contracts 2.1.3`, only chains that have Arbitrum BoLD enabled can use `nitro-contracts 3.x`. This requirement means that if your chain hasn't yet upgraded to use BoLD, only use `nitro-contracts 2.1.3` for your ArbOS 50 Dia upgrade. -### Reference links for ArbOS 51 Dia +### Reference links for ArbOS 50 Dia - [Guide for how to upgrade ArbOS on your Arbitrum chain](../../launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx) -- [README for how to upgrade your rollup contracts to support ArbOS 51 on your chain](https://github.com/OffchainLabs/orbit-actions?tab=readme-ov-file#nitro-contracts-upgrades) -- [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) +- [README for how to upgrade your rollup contracts to support ArbOS 50 on your chain](https://github.com/OffchainLabs/orbit-actions?tab=readme-ov-file#nitro-contracts-upgrades) +- [Nitro v3.9.0](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) - [nitro-contracts v3.1.1](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.1) - [nitro-contracts v2.1.3](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v2.1.3) (only relevant for Arbitrum chains that don't have BoLD enabled yet) - [AIP: ArbOS Version 50 Dia Forum Post](https://forum.arbitrum.foundation/t/constitutional-aip-arbos-version-50-dia/) - [Temperature check vote on Snapshot for ArbOS 50 Dia](https://snapshot.box/#/s:arbitrumfoundation.eth/proposal/0x33754da4006d0ef38666ec5d5e85fd0966a891a594ab9dc21f23beedea2d330b) -- [AIP: ArbOS Version 51 Raising the gas target & improvements to pricing algorithm Forum Post](https://forum.arbitrum.foundation/t/aip-raise-the-gas-target-implement-improvements-to-the-pricing-algorithm/30182) -- [Temperature check vote on Snapshot for ArbOS 51 Raising the gas target & improvements to pricing algorithm](https://snapshot.box/#/s:arbitrumfoundation.eth/proposal/0x4a96a91d162975de0d402b83ca8b8a24e808ca357150120fc0d44ae0bf1cc4a5) -- Coming Soon - ArbOS 50 & ArbOS 51 Audit Report, from Trail of Bits +- [AIP: Raising the gas target & improvements to pricing algorithm Forum Post](https://forum.arbitrum.foundation/t/aip-raise-the-gas-target-implement-improvements-to-the-pricing-algorithm/30182) +- [Temperature check vote on Snapshot for Raising the gas target & improvements to pricing algorithm](https://snapshot.box/#/s:arbitrumfoundation.eth/proposal/0x4a96a91d162975de0d402b83ca8b8a24e808ca357150120fc0d44ae0bf1cc4a5) +- Coming Soon - ArbOS 50 Audit Report, from Trail of Bits diff --git a/docs/stylus/concepts/how-it-works.md b/docs/stylus/concepts/how-it-works.md new file mode 100644 index 0000000000..f9bfda604c --- /dev/null +++ b/docs/stylus/concepts/how-it-works.md @@ -0,0 +1,82 @@ +--- +id: how-it-works +title: 'Architecture overview' +sidebar_label: 'Architecture overview' +description: 'Learn what powers Stylus' +author: srinjoyc +SME: srinjoyc +user_story: As an Ethereum developer/project owner, I need to vet the Stylus. +content_type: concept +--- + +import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition/'; + +There are four main steps for bringing a Stylus program to life: **coding, activation, execution, and proving**. + +## Coding + +Developers can now write smart contracts in any programming language that compiles to WASM. + +:::note +Some high-level languages generate far more performant WASMs than others. +::: + +Currently, there is support for Rust, C, and C++. However, the levels of support vary. Rust has rich language support from day one, with an open-source SDK that makes writing smart contracts in Rust as easy as possible. C and C++ are supported off the bat, enabling the deployment of existing contracts in those languages onchain with minimal modifications. + +The Stylus SDK for Rust contains the smart contract development framework and language features most developers will need to use in Stylus. The SDK also makes it possible to perform all EVM-specific functionalities that smart contract developers use. Check out the [Rust SDK Guide](/stylus/reference/rust-sdk-guide.md) and the [Crate Docs](https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html). + +## Activation + +Starting from a high-level language (such as Rust, C, or C++), the first compilation stage happens using the CLI provided in the Stylus SDK for Rust or any other compiler, such as Clang for C and C++. Once compiled, the WASM is posted onchain. Then, in an activation process, WASM gets lowered to a node's native machine code (such as ARM or x86). + +Activating a Stylus program requires a new precompile, ArbWasm. This precompile produces efficient binary code tailored to a node's native assembly. During this step, a series of middlewares ensure that user programs execute safely and are deterministically fraud-proven. Instrumentation includes gas metering, depth-checking, memory charging, and more to guarantee all WASM programs are safe for the chain to execute. Stylus contracts can be called only after activation. + +Gas metering is essential for certifying that computational resources are paid for. In Stylus, the unit for measuring cost is called **ink**, which is similar to Ethereum's gas but thousands of times smaller. There are two reasons why a new measurement is used: First, WASM execution is so much faster than the EVM that executing thousands of WASM opcodes could be done in the same amount of time it takes the EVM to execute one. Second, the conversion rate of ink to gas can change based on future hardware or VM improvements. For a conceptual introduction to Stylus gas and ink, see [gas and ink (Stylus)](/stylus/concepts/gas-metering.mdx). + + + Stylus smart contracts will need to be reactivated once per year (365 days) or whenever an upgrade + to Stylus (which will always involve an ArbOS upgrade), even if they are in the cache. To complete + this reactivation, you can use + [`cargo-stylus`](https://docs.arbitrum.io/stylus/using-cli#cargo-stylus-commands-reference) or + directly through the [ArbWasm + precompile](https://docs.arbitrum.io/build-decentralized-apps/precompiles/reference#arbwasm). If + contracts do not get reactivated, they will no longer be callable. + + +## Execution + +Stylus programs execute in a fork of [Wasmer](https://wasmer.io/), the leading WebAssembly runtime, with minimal changes to optimize their codebase for blockchain-specific use cases. Wasmer executes native code much faster than Geth executes EVM bytecode, contributing to the significant gas savings that Stylus provides. + +EVM contracts continue to execute the same way they were before Stylus. When calling a contract, the difference between an EVM contract and a WASM program is visible via an [EOF](https://notes.ethereum.org/@ipsilon/evm-object-format-overview)-inspired contract header. From there, the contract executes using its corresponding runtime. Contracts written in Solidity and WASM languages can make cross-contract calls to each other, meaning a developer never has to consider which language the contract is in. Everything is interoperable. + +## Proving + +Nitro operates in two modes: a "happy case" where it compiles execution history to native code, and a "sad case" during validator disputes, where it compiles execution history to WASM for interactive fraud proofs on Ethereum. Stylus builds on Nitro's fraud-proving technology, allowing it to verify both execution history and WASM programs deployed by developers. + +Stylus is made possible by Nitroโ€™s ability to replay and verify disputes using WASM. Validators bisect disputes until an invalid step is identified and proven onchain through a [โ€œone-step proof.โ€](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx#step-5-ensuring-correctness-validation-and-dispute-resolution). This deterministic fraud-proving capability ensures the correctness of any arbitrary program compiled to WASM. The combination of WASM's and Nitro's properties enables this technological leap we call Stylus. + +For more details on Nitroโ€™s architecture, refer to the [documentation](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx) or the Arbitrum whitepaper. + +## Why does this matter? + +Stylus innovates on many levels, with the key ones described here: + +### One chain, many languages + +There are roughly 20k Solidity developers, compared to three million Rust developers or 12 million C developers [[1](https://slashdatahq.medium.com/state-of-the-developer-nation-23rd-edition-the-fall-of-web-frameworks-coding-languages-711525e3df3a)]. Developers can now use their preferred programming language, which is interoperable on any Arbitrum chain with Stylus. By onboarding the next million developers, scaling to the next billion users becomes possible. + +### A better EVM + +Stylus' MultiVM brings the best of both worlds. Developers still get all of the benefits of the EVM, including the ecosystem and liquidity, while getting efficiency improvements and access to existing libraries in Rust, C, and C++, all without changing anything about how the EVM works. EVM equivalence is no longer the ceiling; it's the floor. + +### Cheaper execution + +Stylus is a more efficient execution environment than the EVM, leading directly to gas savings for complex smart contracts. Computation and memory can be significantly cheaper. Deploying cryptography libraries can be done permissionlessly as custom application layer precompiles. Use cases that are impractical in the EVM are now possible in Stylus. + +### Opt-in reentrancy + +Stylus doesn't just improve on cost and speed. WASM programs are also safer. Reentrancy is a common vulnerability developers can only attempt to mitigate in Solidity. Stylus provides cheap reentrancy detection, and using the Rust SDK, reentrancy is disabled by default unless intentionally overridden. + +### Fully interoperable + +Solidity programs and WASM programs are completely composable. If working in Solidity, a developer can call a Rust program or rely on another dependency in a different language. If working in Rust, all Solidity functionalities are accessible out of the box. diff --git a/docs/stylus/concepts/public-preview-expectations.md b/docs/stylus/concepts/public-preview-expectations.md new file mode 100644 index 0000000000..89a7854c02 --- /dev/null +++ b/docs/stylus/concepts/public-preview-expectations.md @@ -0,0 +1,42 @@ +--- +title: 'Public preview: What to expect' +description: 'Stylus is currently tagged as a `release-candidate` supported by *public preview* documentation. This concept document explains what this means, and what to expect.' +author: symbolpunk +sidebar_position: 10 +--- + +Stylus is currently tagged as a `release-candidate` supported by _public preview_ documentation. This concept document explains what "public preview" means, what to expect from public preview capabilities, and how to engage with our team as you tinker. + +### How products are developed at Offchain Labs + +Offchain Labs builds products in a way that aligns loosely with the spirit of "building in public". We like to release things **early and often** so that we can capture feedback and iterate in service of your needs, as empirically as possible. + +To do this, some of our product offerings are documented with **public preview** disclaimers that look like this: + +This banner's purpose is to set expectations while inviting readers like you to express your needs so that we can incorporate them into the way that we iterate on product. + +### What to expect when using public preview offerings + +As you tinker and provide feedback, we'll be listening. Sometimes, we'll learn something non-obvious that will result in a significant change. More commonly, you'll experience incremental improvements to the developer experience as the offering grows out of its **public preview** status, towards **stable** status. + +Public preview offerings are evolving rapidly, so don't expect the degree of release notes discipline that you'd expect from a stable offering. Keep your eyes open for notifications regarding patch, minor, and major changes, along with corresponding relnotes that highlight breaking changes and new capabilities. + +### How to provide feedback + +Our product team primarily uses three feedback channels while iterating on public preview capabilities: + +1. **Docs**: Click on the **Request an update** button located in the top-right corner of any document to provide feedback on the docs and/or developer experience. This will lead you to a prefilled Github issue that members of our product team periodically review. +2. **Discord**: [Join the Arbitrum Discord](https://discord.gg/arbitrum) to engage with members of the Arbitrum community and product team. +3. **Google form**: Complete [this form](http://bit.ly/3yy6EUK) to ask for support. + +### What to expect when providing feedback + +Our ability to respond to feedback is determined by our ever-evolving capacity and priorities. We can't guarantee responses to all feedback submissions, but our small-but-mighty team is listening, and we'll try our best to acknowledge and respond to your feedback. No guarantees though! + +:::info +[Our small-but-mighty team is hiring](https://jobs.lever.co/offchainlabs). +::: + +### Thank you! + +Thanks for helping us build things that meet your needs! We're excited to engage with OGs and newcomers alike; please don't hesitate to reach out. diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index bf27a82d94..f4e9b8b3d4 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -1,7 +1,7 @@ --- id: gentle-introduction title: 'A gentle introduction to Stylus' -description: 'An introduction to Stylus, which enables writing EVM-compatible smart contracts in programming languages that compile to WASM, such as Rust, C, and C++.' +description: 'An educational introduction that provides a high-level understanding of Stylus, a new way to write EVM-compatible smart contracts using your favorite programming languages.' author: amarrazza sme: amarrazza target_audience: 'Developers who want to build on Arbitrum using popular programming languages, like Rust' @@ -13,66 +13,39 @@ import ImageZoom from '@site/src/components/ImageZoom'; ### In a nutshell: -- Stylus lets you write smart contracts in programming languages that compile to WASM, such as Rust, C, C++, and others, allowing you to use their ecosystem of libraries and tools. Language and tooling support exists for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). -- Solidity contracts and Stylus contracts are interoperable. In Solidity, you can call a Rust program and vice versa, thanks to a second, coequal WASM virtual machine. -- Stylus contracts offer reduced gas costs for memory and compute-intensive operations because WASM programs execute more efficiently than EVM bytecode for these workloads. +- Stylus lets you write smart contracts in programming languages that compile to WASM, such as **Rust, C, C++, and many others**, allowing you to tap into their ecosystem of libraries and tools. Rich language and tooling support already exist for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). +- Solidity contracts and Stylus contracts are **fully interoperable**. In Solidity, you can call a Rust program and vice versa. +- Stylus contracts offer **faster execution and lower gas fees** for memory and compute-intensive operations, they also enable complex computation Solidity doesn't support. ### What's Stylus? -Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. This paradigm is called MultiVM because it is additive to existing functionality. +Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. We call this paradigm MultiVM. -This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a binary format used in web standards and browsers for efficient computation. Its design is to be portable and human-readable, with sandboxed execution environments for security. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fraud proofs. +This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a modern binary format popularized by its use in major web standards, browsers, and companies to speed up computation. WASM is built to be fast, portable, and human-readable. It has sandboxed execution environments for security and simplicity. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fully functioning fraud proofs. -With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile to WASM, some compilers are better suited to smart contract development than others, such as Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and JavaScript, are more complex for Stylus to support, although not impossible. WASM programs tend to be more efficient than EVM bytecode for memory-intensive applications. This efficiency comes from mature compiler toolchains for languages like Rust and C, which have benefited from decades of optimization work. The WASM runtime also executes faster than the EVM interpreter. Third-party contributions in the form of libraries for new and existing languages are welcome. +With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile into WASM, some compilers are more suitable for smart contract development than others, like Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and Javascript, are more complex for Stylus to support, although not impossible. Compared to Solidity, WASM programs are more efficient for memory-intensive applications. There are many reasons for this, including the decades of compiler development for Rust and C. WASM also has a faster runtime than the EVM, resulting in faster execution. Third-party contributions in the form of libraries for new and existing languages are welcomed! -### How Stylus works +### Use Cases -Bringing a Stylus program to life involves four stages: coding, activation, execution, and proving. The following sections describe each step. +While many developers will be drawn to new use cases, rebuilding existing applications in Stylus will also open the door to innovation and optimization. dApps have never been faster, cheaper, or safer. Stylus can integrate easily into existing Solidity projects by calling a Stylus contract to optimize specific parts of your dApp or building the entire dApp with Stylus. It's impossible to list all of the use cases Stylus enables; think about the properties of all WASM-compatible languages! That said, here are some particularly exciting ideas: -#### Coding +- **Efficient Onchain Verification with ZK-Proofs**: Enable cost-effective onchain verification + using zero-knowledge proving systems for privacy, interoperability, and more (see [case + study](https://blog.arbitrum.io/renegade-stylus-case-study/)). +- **Advanced DeFi Instruments**: Power complex financial instruments and processes like custom + pricing curves for AMMs, synthetic assets, options, and futures with onchain computation via + extending current protocols (i.e., Uniswap V4 hooks) or building your own. +- **High-Performance Onchain Logic**: Support memory and compute-intensive applications like + onchain games and generative art either by writing all of the application in Stylus or enhance + performance of existing Solidity contracts by optimizing specific parts. +- **Innovations**: generative art, compute-heavy + AI models, onchain games, advanced cryptography. -You write your smart contract in any programming language that compiles to WASM. Rust has the most developed support with an open-source SDK for smart contract development. C and C++ are also supported, so that you can deploy existing contracts in those languages onchain with minimal modifications. +### Getting Started -The [Stylus SDK for Rust](/stylus/reference/rust-sdk-guide.md) provides the development framework and language features for smart contract development. It also provides access to EVM-specific functionality used by smart contract developers. - -#### Activation - -Once you've written your contract, compile it to WASM using the Stylus CLI (or another compiler, like Clang for C/C++). Then you post the compiled WASM onchain. - -To make your contract callable, it must undergo an activation process. During activation, the WASM compiles down to a node's native machine code (e.g., ARM or x86). This step also includes safety checks, such as gas metering, depth-checking, and memory charging, to ensure your program runs safely and can be fraud-proven. - -Stylus measures computational costs using ink instead of gas. Ink works like gas but is thousands of times smaller. WASM executes faster than the EVM, so a single EVM operation takes as long as thousands of WASM operations. A finer-grained unit makes pricing more precise. - -:::note -Stylus contracts need to be reactivated once per year (365 days) or after any Stylus upgrade. You can do this using [`cargo-stylus`](/stylus/using-cli.mdx#cargo-stylus-commands-reference) or the [ArbWasm precompile](/build-decentralized-apps/precompiles/reference#common-precompiles). If a contract isn't reactivated, it becomes uncallable. -::: - -#### Execution - -When your Stylus program runs, it executes in a fork of [Wasmer](https://wasmer.io/), a WebAssembly runtime. Because Wasmer compiles to native machine code, it executes faster than Geth's EVM bytecode interpreter. This performance difference reduces gas costs for compute-intensive operations. - -EVM contracts continue to work exactly as before. When a contract is called, the system checks whether it's an EVM contract or a WASM program and routes it to the appropriate runtime. Solidity and WASM contracts can call each other, so the language a contract was written in doesn't affect interoperability. - -#### Proving - -Stylus builds on Nitro's fraud-proving technology. In normal operation, execution compiles to native code for speed. But if there's a dispute, the execution history compiles to WASM so validators can run interactive fraud proofs on Ethereum. - -What makes Stylus possible: Nitro can already replay and verify disputes using WASM. Stylus extends this capability to verify not just execution history, but also the WASM programs you deploy. The result is a system where any program compiled to WASM can be deterministically fraud-proven. For more details, see the [Nitro architecture documentation](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx). - -### Use cases - -Stylus can integrate into existing Solidity projects by calling a Stylus contract to optimize specific parts of your app, or you can build an entire app with Stylus. Developers can also port existing applications written in Rust, C, or C++ to run onchain with minimal modifications. Here are some use cases where Stylus may be a good fit: - -- Onchain verification with zero-knowledge proofs: Reduce gas costs for onchain verification using zero-knowledge proving systems. See [case study](https://blog.arbitrum.io/renegade-stylus-case-study/) for an example implementation. -- DeFi instruments: Implement custom pricing curves for AMMs, synthetic assets, options, and futures with onchain computation. You can extend existing protocols (such as Uniswap V4 hooks) or build your own. -- Memory and compute-intensive applications: Build onchain games, generative art, or other applications that benefit from reduced memory costs. You can write the entire application in Stylus or optimize specific parts of existing Solidity contracts. -- Cryptographic applications: Implement applications that require advanced cryptography or other compute-heavy operations that would be cost-prohibitive in Solidity. - -### Getting started - -1. Follow the [quickstart](/stylus/quickstart.mdx) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview.md) documentation. -2. Join the Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for community support. -3. Browse the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for community-contributed projects, examples, and tools. -4. Subscribe to the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter for tutorials and technical content. +1. Utilize our [quickstart](/stylus/quickstart.mdx), [Rust SDK](/stylus/reference/overview.md), to help you start building. +2. Join our Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for support as well as the official Arbitrum ([@Arbitrum](https://twitter.com/arbitrum)) and Arbitrum Developers ([@ArbitrumDevs](https://twitter.com/ArbitrumDevs)) X accounts for announcements. +3. Check out the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for various community contributed Stylus projects and tools. If you build something useful, we'd be happy to add it there. +4. Stay updated with the latest from the Stylus community through tutorials, builder interviews, technical deep dives, and more with the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter. diff --git a/docs/stylus/partials/_stylus-public-preview-banner-partial.md b/docs/stylus/partials/_stylus-public-preview-banner-partial.md new file mode 100644 index 0000000000..729f55610d --- /dev/null +++ b/docs/stylus/partials/_stylus-public-preview-banner-partial.md @@ -0,0 +1,7 @@ +:::info ALPHA RELEASE, PUBLIC PREVIEW DOCS + +Stylus is currently tagged as a `release-candidate`. The code has been audited, and testing in production environments is underway. Caution should be taken when used in production scenarios. This documentation is currently in [public preview](/stylus/concepts/public-preview-expectations). + +To provide feedback, click the **Request an update** button at the top of this document, [join the Arbitrum Discord](https://discord.gg/arbitrum), or reach out to our team directly by completing [this form](http://bit.ly/3yy6EUK). + +::: diff --git a/sidebars.js b/sidebars.js index 1967b02e4b..bff9cf567a 100644 --- a/sidebars.js +++ b/sidebars.js @@ -235,11 +235,6 @@ const sidebars = { id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/timeboost-for-arbitrum-chains', label: 'Timeboost for Arbitrum chains', }, - { - type: 'doc', - id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/stake-and-validator-configurations', - label: 'Stake and validator config', - }, { type: 'category', label: 'Data Availability Committees', @@ -618,8 +613,8 @@ const sidebars = { }, { type: 'doc', - id: 'run-arbitrum-node/arbos-releases/arbos51', - label: 'Dia (ArbOS 51)', + id: 'run-arbitrum-node/arbos-releases/arbos50', + label: 'Dia (ArbOS 50)', }, { type: 'doc', @@ -1641,41 +1636,181 @@ const sidebars = { items: [ { type: 'doc', - id: 'stylus/reference/opcode-hostio-pricing', - label: 'Gas & Ink Pricing', + id: 'stylus/reference/overview', + label: 'Overview', }, { - type: 'link', - label: 'Stylus by Example', - href: 'https://stylus-by-example.org/', + type: 'doc', + id: 'stylus/reference/project-structure', + label: 'Structure of a Contract', }, { - type: 'link', - label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/cargo-stylus', + type: 'category', + label: 'Data types', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/reference/data-types/primitives', + label: 'Primitives', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/compound-types', + label: 'Compound types', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/storage', + label: 'Storage', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/conversions-between-types', + label: 'Conversions Between Types', + }, + ], }, { - type: 'link', - label: 'Rust SDK Crate', - href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + type: 'doc', + id: 'stylus/reference/global-variables-and-functions', + label: 'Global variables and functions', }, { - type: 'link', - label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus', + type: 'doc', + id: 'stylus/reference/contracts', + label: 'Contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/testing-contracts', + label: 'Writing Tests', + }, + { + type: 'category', + label: 'Advanced', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/advanced/solidity-differences', + label: 'Solidity differences', + }, + { + type: 'doc', + id: 'stylus/advanced/recommended-libraries', + label: 'Recommended packages', + }, + { + type: 'doc', + id: 'stylus/advanced/minimal-entrypoint-contracts', + label: 'Minimal entrypoint contracts', + }, + { + type: 'doc', + id: 'stylus/advanced/hostio-exports', + label: 'Hostio exports', + }, + ], + }, + { + type: 'doc', + id: 'stylus/troubleshooting-building-stylus', + label: 'Troubleshooting', + }, + { + type: 'category', + label: 'Using the CLI', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-binaries', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], + }, + { + type: 'category', + label: 'WM Concepts', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/concepts/webassembly', + label: 'Webassembly', + }, + { + type: 'doc', + id: 'stylus/concepts/evm-differences', + label: 'EVM differences', + }, + { + type: 'doc', + id: 'stylus/concepts/activation', + label: 'Activation', + }, + { + type: 'doc', + id: 'stylus/how-tos/caching-contracts', + label: 'Caching Strategy', + }, + ], + }, + { + type: 'category', + label: 'Reference', + collapsed: true, + items: [ + { + type: 'link', + label: 'Stylus by Example', + href: 'https://stylus-by-example.org/', + }, + { + type: 'link', + label: 'Cargo Stylus CLI GitHub', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', + }, + { + type: 'link', + label: 'Rust SDK Crate', + href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + }, + { + type: 'link', + label: 'Source Code Repository', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs', + }, + ], }, ], }, - { - type: 'doc', - id: 'stylus/how-tos/adding-support-for-new-languages', - label: 'Using other languages', - }, - { - type: 'doc', - id: 'stylus/troubleshooting-building-stylus', - label: 'Troubleshooting', - }, ], }, { @@ -1702,11 +1837,6 @@ const sidebars = { id: 'notices/fusaka-upgrade-notice', label: 'Upgrade for the Fusaka transition', }, - { - type: 'doc', - id: 'notices/arbos51-arbsepolia-upgrade-notice', - label: 'Upgrade for ArbOS 51 on ArbSepolia', - }, ], }; diff --git a/src/components/FloatingHoverModal/index.js b/src/components/FloatingHoverModal/index.js index 12a385372b..71b07d2871 100644 --- a/src/components/FloatingHoverModal/index.js +++ b/src/components/FloatingHoverModal/index.js @@ -32,6 +32,7 @@ import ConfigPermissionedValidators from '@site/docs/launch-arbitrum-chain/parti import ConfigL1ChallengePeriod from '@site/docs/launch-arbitrum-chain/partials/config-l1-challenge-period.mdx'; import ConfigForceInclusion from '@site/docs/launch-arbitrum-chain/partials/config-force-inclusion.mdx'; import ConfigAccountAbstraction from '@site/docs/launch-arbitrum-chain/partials/config-account-abstraction.mdx'; +import ConfigChallengePeriod from '@site/docs/launch-arbitrum-chain/partials/config-challenge-period-l1.mdx'; import ConfigCustomizableGovernance from '@site/docs/launch-arbitrum-chain/partials/config-customizable-governance.mdx'; import ConfigDataPostingCosts from '@site/docs/launch-arbitrum-chain/partials/config-data-posting-costs.mdx'; import ConfigEVMCompatibility from '@site/docs/launch-arbitrum-chain/partials/config-evm-compatbility.mdx'; @@ -53,6 +54,7 @@ const contentMap = { 'config-l1-challenge-period': ConfigL1ChallengePeriod, 'config-force-inclusion': ConfigForceInclusion, 'config-account-abstraction': ConfigAccountAbstraction, + 'config-challenge-period-l1': ConfigChallengePeriod, 'config-customizable-governance': ConfigCustomizableGovernance, 'config-data-posting-costs': ConfigDataPostingCosts, 'config-evm-compatibility': ConfigEVMCompatibility, diff --git a/static/img/stylus-multivm.jpg b/static/img/stylus-multivm.jpg index ee2288c8ccdca892786b8fbf1d077f7f2eaccf25..89f67ece76aa18392532ce75eb0bb5b6e0d72914 100644 GIT binary patch literal 896146 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%0Au-?(@ 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

hGurPR|FwEfU8?#^p@Xc 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

&YW`FNWxUEqM<7dv>W1>M8=Ro|dc zb(;QQmTXF)bh|13UAD%bZH`PhhsIBqKC-Y&c=Jy;vRk2x?>J$~))s6;hcQPyM1yEE`SG^CA@+2d2rJM2VBfjh1v3G}MpN zcFTC$w;X9PRe{k*U?@_-C3f=u4%Dg%U5Rza zE;cNGsardvD^)AxE9A#I`o&4*Y8;*9*<{FGE7$ol$M!OSc!c|MhOG=bw%#hrebYGC z=;z~M$--pftxa1`rW?NPJCMh19-EnE_6%h=8DR303pYtWQ`|MZ@OkILKi1$2)Ohj> zW_1F=rzPq7T`TLd@><&*P)~m6b|M_jbJ2K+ezr-zVg?&xnA_2YAoDC0q)?%$`E(KX z9?dG-09O>ORY=*VBrK_tNY4I?3zsSH3vRt+`O*7wTe^M$OfR?Nf)Ftp#|gV@AD?L@+~K4R>r_gn(#G`nmR>$23T_bnvboRV76ELc{}7N^EyvUG#;3^%RLDh@g1sZ7=Jjzd z`aeVkO#i*8o?%^zs^-%7E6Nu5t`x(7p~LX(0gSjlan6X~OTC1VhGuQxMW&%OOGkrq z+!d->*25@;=3?Tc#A~fov@a4gPxSgrc zJSF-4(uefs3*u^7T|D%r`-66T(kk;sa+3%L2(^ese+4~K7w3vVp^dbQ;7;75tP86C zu$hr`S!A!(?rRn^_4S2>HN3YHJ!)D0c40_~b?91vpwh zHkvs(cpcB$v}d1AeH$o{8kTxpB?Rr1b#Y-u7f*rwC>(?id~5~;{pj&NW5h*w1lt?A zb=3L}k$4SXhbIK?7Ui!e^<~9=Uz^(;45NW#6RFfE&3ew*Mjng`d}!d}A)-}yFZ9&( z(u6n^bqe9x#EWlLv)I&j-N!LA(1}@|_JdgSTJyjmzmVO32pk%GEuu@G>32x!lxT)0 z)-1Lul|ZD2+R;g>rTp{J2=z}MxNJA0%_6n|(&%AHDi zT1_0!n+|>W@w~P6EO)c_p|e?tli6mGgGe1^o>Xt?na?jei%U|ZSmImRB$zk^6{SP{ zz=I0zU$Y@95@~)K6I|x34`P*s)e0+YmMmUr&Z+kIw+?~gkL{_)nJ=n9X+K7t_Ih|g zZURH8>EvtiKfU9A^O%SjH(}1w)zvy5o8|4iO1I{x8eR1Ikh=xF`;tmJikKK8fD0kp z3bl{LD;oJ>vLBceqKFoWZKP>xbKD^VsokX*V0`Dc;W8Lm@q%u6sI3_< z-6p}AJL+tUqSavS@}(Peijc{T5frz1w;S#-SB+(>Lx>vIU-J)v{!L5UC7R^pf%KLue234xp*%Y0dyUm&kazL)RAw zYFw^RS-Y|wCVsdTd-lp^aQY0AxN;LC@mKlC+HLw66REfA$C{o%P1j~G`5sfu1iFArej4ZYneNgSQ<4w?4eRA@grmOD+ z_DkYYD03Ud042s__~}&=WopwO3ZPSZ_^X~S;di2eyIlI+w~q)fe@WRfOR)S7Oiw=7 zF}P?(CnHJ=2(iz2*+(sNH~3~P@$`!@0s=A|gb1}>UwWbfv7ZS}Yu*KV>55aP>|{Ll zCcZg*SybVCr-=UINwbF#KOu6Tz*F;$CD~VDR2SzNi;2!me_+8s1V*3_4geF0?qX^I z6#%4%3n=~?>lmf%R&S-B9E1SEW&qb@K6{EwONH-X3wfR&BX{mDd9QI|T|UL6S>Od! z00;~mU3%dCFL51;3-6sm`3o;w^hkSmPXBZF)gSrD{Tw=8c;KaQRJ!0pJP{Q~ZlBDI zzlzXm@UlW4DSoI(rq_)A50IqSi~$UP27v(E@mA}KDN?fwjxyo^#9|iQ!Sqskv>JO3 z=f#sd@CCM~{|-M~1c-bBSOC`$0^!F#2ST1tdczYSmCZEZ4(ART>z%G=!>2bkZlzxh zIFNgB2*|y`>6lu5JmWR}0?>_B?OdT#O?TalppjltzyYX)8(4Pb`sQ!qs<0y}aGyw7 z?ppvxGWbM8BJ=q$9FeiWrG+7WpAcTa-HcyMu9}md>#!TD0Z5;eLH#8=ZjLBgk6pb}zEwY)U9$@i4eR*2o69%f>aJ3&ZoT@Z@mEICX z{feR~cqat?Qyvvet-{<44WK^1JUw3s+(-CTVhZ+)6bGOKjZ8Bslu;;)6LFba0)2+t zl!5&o(Ttzo{g0pkr(WB6E}WF_M+{oJquHud9n*+&1kKg!(E#7^ts*GM0mkgQXv+$lit-14!2Ex)21Nj2#YGJ{(2Vb!qNo zT-ng|?i6um#|iJC$o!%TM!>)&;vU@Vb^iU9GS!_qpH#w{{x9Q%>{g0;i9#c|_cz*W zDwXndR2SZ#nz*{fn?`THz0STd-#kK4rb@IeBbXb147vP%Y0dWV;EOqW`HnbT$KW<| zKxt)QgEW{Fzzjb#&v{CG_hRuD={=RQ)%afd%CprTWL&cL!U9Ro!G4+>`>y)-!1Lc| z@s|`&xoz9H0qw=UUCcDJLZ5=_6u3R{`GbOHEIZ&B1X;(z-H9aVnVkc0?2Z95shh*n zJyy~Y_V?9sHGP)2y-kfdR;31MFkCji}Rg_4=PW zeJg8AcEi_ali`X0W*L#x4LmJzB%s^pX%@j27^MQ?y$`842ugq;7x z{{RR96X9sztA0S)mqIr3J{kll7AN7dM@=|}3Oqhyts;VzXvXZWNWc@Xx1QFA_3S^C zQUXvhzBH!eVFAIVl;%&oY`=Pqkv5z*jE=C~g;R;*aHtS8g;`H>-C=J5Af_JxBCVOM zN;uFs40uprI)y)|V|%y+nY!)sE|mRfY*7@5TsJ}u>lN)BFcEg-At`fI{RazfygpSU zfs>0L<)!$HLMhywzFYXa)5hq-#fRTg{WSJ~Y54myC-bJN)0F4i0JtCxe|RQnoIMa0 zw>0X*8_6AJ3VLvu9>BmKQD6piid=+5f?YDaF(hBNX|TT-MxHK#4ve7ik^aLP_gfmZ z^Az|H-VKoSvH4>FQ>Yt0Yy!+h11h-2&VM|daGyqcf|e|5@~;OznTlWiG(%~CO7|1A zua~&mWvZ!G7%vY@))9*+M-#tIL$nVbNx8zNni{*g2>AuOM0q6O-r7~NDV)V2*9+uf zub(DRx9d&(Av>Bvy**9~OW9Lm+zA?Syu~H_$I4EhT1a9}4_^>eW*{ za(xQ}!jfYQ-K}^oqr2Ja6Z$(3{}6ufY|N%)gdyYNI(E*7;PpCw_|Oc<|}^ zpjbgik+e91PxUuH2%q1yO|{nL-o;bEP!Q)e4ULKf)9OR_|u1WkCV~ZpE3s5K-x1 z3J|A8(;bbV^65|?lSHCyvYz|~Kf918H`;CtuSqro=<)6_zIPIm9IN}E zlhC4CB_+K{2OX>uqdB;VIN~?(H?Rq*ndEE62a<~%23B>D`>9Dtv3)ihQ!bfE;GUe4 zbWk_S$LW(QXI_V1$WapE^M9~PCn6wR1a(tdIi#hDYFVY(N-u#xLmU1Sp$a_lf6%;5 znL1`Zk|?p8xkOYN4bhUtF?@JSj|uh1!<);yQ_wH2OSJRb9NrdUo7ac^YkRDZf5-ilo4c%e!hJ?heF-l)z3i= z=GH$vSjy@bOu^^jsivCez*aqy`8hI(+eE%dqZGcNKu0uv^p|z{H3*La9i~`1&(1dN zs?F)ec{m&DW=JTu$=|CT?DXe(k@9#Ac&W^c6IQ6o*rpnI+CjvP-Oq{drlKxUdUH}3 zhSO@V8qX>i4U3J=OI1$zKuseV7A6_%RuJrt%IxL#Xs^ZPjwyLVVBAdX0CnSegBdrk zRkLFiD~!^Yg^iMsMXF#1qi~AX?=$Ip<7Drg`kA2uSh`Z`tQVp{L{v2uJTiouAwW%_FSrga)pHP#92xTpV57_f<3zmKd0S!;~sMqY(-Uz3HM<}NvGZB z+6E;_2ahdInF9fevYTaKx8n`Y;eFizP3yV&z}%z<-uRu2%8_o`U6gqqtAnbPlH^hK z2=HItBh(SGv;9YRonn+s*SC42ZvPMz=E-Da8$L7KI!}5Be|Kp7I-yyje3n&ohoO<6 zgE$r!nXfZ;n&b1PIIJ4I25V(+#847 zD`@Sv%h$j6u&CFN;dFbovAr67;Gd2@oV&}CN*zSIYQ*E-8?%cSi;cPSuNiD?t-y_Z z+)b52uC7Tg+e$zRsM0J>N)-vffZ!IVIA&&MrW4^gSBMO8(i7$CONm^4>g(R;OUs*0 z_qO!)zSe&Kl*tToLtzfHn^)`~bjy!1B-U>wxv5X3L%!(jDAk|!tHt~NgsD`qKM)&M z_wa~t_TBSxnzXXp#|kK!dBlu25R2{L@Z4F%ligAVBmeQUxBTrZr1LU8Jtj`=^^)u{ zcAYI`LZ$FGc)n~`N&@Qc76GpP$oS>QgI}zqO9=Pu)vr276Dbn2Av+}@LGsv;7OwVi zi(2zWqsdAoXbT1L>&(KnOfEOMkp-sO%d0m|5xI2AWmT*CQ*z4X+m1ct(>@fpC0>PR zpJ#cE9G`_G;as0S*j`3%wl&1g(hr-5^-ddXo=QiCyILGCjS+z>&78= zzhM!nKqX`a*7fgLvM#YBF0>E?^0pqD`;U(!xylhJU*TNC|bJW6u)Mg`Z zA{SlHqDTMC0*vCeMgkhe6sbAy<;R`bpVwQc{D)#E7>~*$KkPOMbW$T+9R49F zmuW2Eut+-3gJPU+j~`@KTV8lC1+SL4$CS3cS({*ty5Y_=^5qu#8lzhMXD845=dIT^ z{rO|bJ*GfPb@bJaX_f8YJYFB46~x6M(2a;3*9nC2*N)7mS``3YbZk~bcWiN80W_dL zoO}Kur0HEQM%uPYYiC^xJi0Ia&0~Um9_s{lRueK$4kv4QM7__9Ip1K1PJ5(`X;u>( z9Xnuh3OT%IxQ9CEJo2pT4^6mw{3sA0ueeJA_Sp`OV<=Y66XE|F&+0Y3NF~mQO3xZt z4%Wb2(HkK6hj4oqTjYBxVLEfF?0x2^_zwZw2|N-fuq1tv_|A2v?C>G>toPjab&KxD zD?|#Vs*7exv@RLuwFS0anQ9(>&6^H&Id)Gh4+qZ>AshjGtm0rX?W~pKt82%xDhuh% zl_DW!&=hn4E6u}IXmlc#9}<>VSKqZ($nWyD+^WHlcFwZd`|=}JDM^K_yjO7L-P-M! zb<1|cm~!ptHS_wiIBhaWXVRO792io7Kbi%!#OS5*z#h-na$im!``X;MBNyPE2i zw0O1VP8RpDIKeR`8)IiIlND5Riy)U%~V*|hG?j>-B*ZyY@z;|IrQV?LKC_q`MB z6PHNhAF+VV?AlLDN$*$dI=}5ly#!OsK+G3>K$-xG2K(DzV`4iJs}&_+bi~wb|09gn z=;MM+(`UJY1ba!hxC30K8Aljryj7pgXt#X3qQ)2s4n)e#r=X|fhk$Vdn`QgroBh%^ z%O~02mnY~%!eG;0xsY;gqJlWurj(ydcjCX^hT$jtNc)nJNn($~TZ!PE2rB>Z-ms^} zW|rNq@XsYncw=LgI@vH1x_f97#8Q)!6pKosaM8?%$ZXzeXS8O*gTJYsx?jDR%ZpzY zS?7^c%}2dN&?AdH!zM8h3XX=Qss>V}lAE(aXh`7$P@9o?c1)CAd9!YG2JOZ2lfGYX zDgmqE-Oy`w-D&dLICtrl$~`fwRz(HAMj_^m{;EMR=&e_}6@^A7VQhhEdJVg?K>hEf z&@`=6vN6^4Lz9RJfCOchVl(yHs}dn_K_S*TP%f1uCIWcfjWB>)T5xT)=u304#;Gw0 zDg$R*%~hGjL()_&C4ifsjf`M;GQxnF*vN2QWb34}HjOc4CZSFfGg2glw=#5ArdY1V z={~r|!suiLU26g}36IqxkSvPJ6lEAfWz>)qmVN8dWA>xG&$wDl%Nk=vU|f{>W|$C6 ze*+r4poz+_2?X31b#Q&XJDXVQkE~U%dPwl5G=%w6deK4biiN{Nh;SO7d z)_37a{gSYjl@$ZYyhm<&(WWPRAW*=fDa%xK?=?rxuPJ*B?rO&u$(*o&sbq6A{?0|l zv0HUG%((&gjaDmHb<0O6DY~9k66gFwh@Bb`+Og^LzYi?+<@67~Pus3&g%EN3c7Qw- z8(I(So1Gshosfed<4*myWOSJh0Wb-l7c|3Iea5F7*&-V^ddrcz!5ICAMG;(RIian* zP2^K{HNznBG!C=TAC<8Q&PW^FI(?FD`JftFJ~73F#Jp@=$$h!^#kvks>CW5A31HS; zNls&O?;b5(m5~Pc2m-m2z!I_Aa1?GKsdoeTEW(>NSeFCwYFp|qLKWxoROjyhPdz}(&2 zLCKp7;4+ycE>R|S9K}QL3nIze$No~A(}9(#-wG-v_sx0v4bo{$yNvxgGWgk)adySfaxDpU^&O>f9TQv$ z*6N5`I6Y6KG8sa(6FmYFM%@KPDmp}&gd{b|33$Cfkbhb!N&-ZlH+E$~v`uF0SZu-{ z>MS2g*}(w-K&(No>gxb4}%+kBT=V2@jGsGLo?L>H`j{Yp5U5Ck@tFL(?}%tNlN; zAT)C-9}+&JzTZ_uP8`{EepAg3f=VaGh4O6CGMOYe@sMgJWC_piGbW6WV{%C?DRxla z*(7zbadMeB)+ocI(oCZ$%grm|+?SGQXx#zExNm&!G&l{TOERn|RPI>Kp-cr4fm2KQEpLanM z-L%Kl)?hw1ePfNAPVV*P@I*kDSzP?Q*~bWlRSph0M^+E}R71INC9%4u9u^UzHHDen z2@%{hv7i%Ke$&7c(MdOipPKG$-OWm~ZqPqCyR29=V6!R)2bK~=F zjUid%SCh*Fk(iZ980R~C&{!Fz$lVMfO<=m5NUj`JlhcXcsTMRGC=N-I%-REs!bG=)( zDiN)DOWn@9#mdz`?av^zX-3-Ag=!xvq?Ie3Jtj(PlpIHi)2R^7USHoUbf+kh=pMyp zSTnbeX{^&_mXTVPNFW~ z6(6!Std?J7Rt#l0u37JsCRzlm#7&gWo0@bMSgXd}b(IW> z&YM7tU}6#3I?Mq{&90BrJFX1zUj09SJpE{eth%X4S2@gAGV}cs;e7=2X2Qk{#su#` z3hxHS)X?IRVHJ{8B=>LqO7(vE0CroGkDc1G$2UtjiUaZD-j-wlWE%g5O&@!f;WD{V_-WCakf>)kn`n0@&$h zAu(D`q?#caZ;A&ikxUS`lx4QJERoWUKTs}wR~b+FigUnFJt;IRYWB-**6_PK-;2JJ z7MVkKE~eI#e(65F58L@k>Adq>cuDVL^@s2!%Va<(G+*g;&Eiea(S=925O?;qSXMB@ zkyYyF^a&GUi+#10=Y6f#z-~M_)|`3!P0|}Racy_JBeUF>8-csB)?nEn(JkaK&`|rI zjP&HDmIe)!U-cb%#SaII{^X!|?q_Dv`55nvBdg7m<0(is=(zHr@wJ2dlUX%m88Q3S zM#biq_)y&kYo4w5^VKN;aS9O)+tTm2|N$2l*Getyyv@!RUP2+R|RR%2Ms~7gJhB+R^V)l zTNxw~d>H^4*IiO-w+UZ zv~OcQMbZ}>#`}r-fNfr7`=_RTJ|MH0Vng036wmZ^9<{1a8}%rA%VK74*Y9(z3rFb@ zOHAo%Yz3}Z11wt^u|` zy>Z(_?lpRkZuwcg$sYOKt>@^rEV=YHILz4niM&%xW+N9MOl7ikkE7F5(&-evc_bKr z_rpvY1Q&iDqFqr^niwV0N7`M!A4ChHllObz$SG0)_Kgw?MyPN*ZFjsorWP1>=v-(l z<`wG%OOt1pXOu{-T?!KfK%ru;7d?st!F0;N6Hqq!G9@Z!}$tT{5#Fkaz6w4<& zQ$ar#MGJd~_xAO#j9>+QCogUrSd&%saXcfQG8t4rME0j+)^yQewok4qPa;~i5S$~= zb^2nJGp)S4IT|~`mRpiZB0Wz{BawxVYLLUanc_|O5xoY=e!TZsg5 zuaZ86iRxL4o($PMvWCexu~t}{?2ws%zg_A{fiGU7hl@+pBxPIFK5h)^MUqkQt=c}~ zby0lJrZ?zHP2y2O^D35qC%0v5#`mMty6{fNZv8)mat1Pi6Ix!Nq^piv?85wL4D5)( zCysU_0_fFwHrB1__b%MTig2%G8{W|1^qp_Bk_F1DvUSDpruQfWp$2HP=IR0Ib)Vim(%S0c{ zAa^^R41#EIi(~oCac*$(!VH3ngtVqdao%o1tcHvdSWIS-!15EbcKl2Gasdoj1RmUD zRFBL!c3uVUndlmr#b(}PH42K?A6u~#gdZk|SkHS_8A|YKIw~XI?RmI5c}k_b%;YG7 zLcb(d7yJmbP01jMv&?2;%bQEHz_3|C~DR)A+4Mb{^QbUAG#TAPZ|{ z<`BBvcrj#GHNJm~J{i~G68z5oen*#KCL*d|K#}~Mdmw6myq*7e&hGpnUi;#l<2Pih zz@GEfK3HxA(32g~@hf{H?3V6ATgy5qQ73pi{tw%B9=tws70t_m%D<%{0K98lNsqH8 zdmk;dN*~FsgO8+HJ$-urA&iwQN9La9xy!!tUd+F4$Rc};7CKwG6gt}r1O#hU+YfZA z_4nu@kw>ou^1vTYO9Vg!-U3(n5|1Q>$&YexX@^^;54N^;h>J%20Z02|XiGlyj5T+; zz-6-4Pt}0`)hx%Yh}0=qm%jL7>Dfa^60lb@nJ}tn1l7!`@j_?$9#!{#zx5^+ah3<& zcN+Ck=^uik*F+UPn7ABx@5b_p1H|1+S|HuK{Ag~sU;7V14N$MOJ}^c0=-#dULrD6E zF!B`dmFE8c)w%tD#e2h6jutq56r_e&ZWg0PO?y!HblX~QGI3u%#vvyOgv=87D6CMP zhs!-`T0A@mozn;2{mAhphd%Bi&XI;Wjch`9qXgK(7Fyc(#jf+>dvGjIw{WL)p|KNJXYV1hxuFW%FVJC*)Sx38B&sSW}!zH~qeGU=V8GoQ6ehzN53^DVcwg2gwq#1jJp35iAF2T!ML{ONCzJW zMoXGNOz|iEku}oSuRb1XW;HrGoeS0&L6i8NDkGL@)C=vS9hUGBT6rG{rj#|;d>)CT zQ7R*JV!c*)haP&%A~^4@Fb3wI4aX=MkEBoOi4&NQi2Bt-uuI79rojBg+)SrP?$erc zaNOYQWgPYOJ2sW?3fHH;DJE2bKRbp?a*Z&PHO^mfWoO7It;u2Km}r^K)sYu?>Q?r= zu}#EF<%udp^_*w)0|qu3h3lxKV}DWmd$!Rl(Q8e&;(=v*&`Hb#kR?p^QojAZ=cx~y z_2??goUjhFQpi!ODiufvVd*hj1R*ICNhPg*B>0*}F(k)^lDPNYEI>K3)GRjpFFTzJ zxMt5du}er>(^y@f}4V(@=cFA(ed>E_WT*_z%n!iwonhd~-<$pl&d5nbOrgrty%BxN>&!1;LkHI_@BT zpE7uH+|}y7$cvjY2?Eu~Gp|Y|f1m%R246I@toS5Pc#bOC23gk5hdsw)+VoxlZ0`#_uq)PxNA3RMzQ~V$rjk03OKKC3?)fC-cztFUt z$h#%w>Sp#$!=D*fZ5bQ8+%x{uKOmX+M@w%5bH$Z3r?oiPW_Bx}#K7I%0@(b%M$xEb zv)Jeo4(xk(fqJI```@9!{&$Nh8H{{tNfs71Q=A9XSsQ9Q#jvpUT+7^3T4MZtXU`QB zF}kVDih%-OLH(PbcPTeK9f>M`^9RtX`>HgY=7zGO%x8{nO@FrHDqXS3v2+k`4<}xu zJ?x`yegf8YQU4GWdwo1Bj?qJSOBS&wRM0rs@U0?Zn)&HZd0$SlbheTG9KnmRMdbaJgEPHp{DcljP#kq02@~XlMErza)*=8nSj?xx zhQO&`#*3bfBxGlBj}6Z2CyC8BGP(}_yZ+zk4cb@HfX!|FKYtqT3y$5m@&9SPW*{jz zp#h}XrtmK*`%f%R9IbK)&)rDtfOBFIn)H4R7}e}Eo~I6m`^v`v$wGJ&^>-)@_M}sm z+w)Nb1O#|rmiB3R+D^)jyi(Wtaa1qyuSsB0!yAC$Vt%^AXW`T5FMomdyE%`ZeYZ6v zaE%#a5R~h}={Vvo05oyY!!0N7ui5Iqr{yoZBim=ZHUkg%+C_KqU-b?mz`y=RRyy*E zF!7c<@M_2A8)Nxl1AL4ub-#+xzsghqz6r7e?GJMveNNR`Z<)CZV3e{aeFCUDUe-S6 zYE`(?M-z_qh#1f(I)44cPd(QH*2*K`;Ki z`Hq`Tl$UPWtuR6PxfnLGQxl9-#Q<*uc)B!&mNgcp=6)W{I{kzpk(iNoMnqiVgiDlW ziX=~OB8MC?L)Z*|eeG~0E3em%0mr3D?J2xYb>$sQW@hdTLN17#uJ~k5+LI>~u8EsG z@P4pA0x+iq6IR8*(JZ~M1yJGMR7DT!A-mtSthf$mI;2zp4?zX1Xx91C8}$M4b=9;~ z#5PIZhZRA-b`V<%IoT;KYl`7GTnZ=p8aVyD9Aa`W)cao;g#0a*@+ipA=t<#q%Dcj8RI@!v(!8SkuJLMxOo$yz1j8ZYNI2Jk8 zelunYu7M!)j|Za(8J#KsSW)JEB?JFE&?rhr#eI!z8Y^)f`1dYE-U8u(pCa!=F2DWoU}5iQ|U|UwV7D-6AYvmy&6j$zoD4 zk$>&}?*1yD4F|-GMHESS_U!+}p>);hr5n2x#=MZg{h%+60Ly!K3@5L;-zR5=CI6xH zsj0~&<*<-5WPbhZYfQ}O$#e61*0g5kcks$*c*BG2xgzx+>~TF@ZFeo>aluc|ej(tM z!ewu7I#R!jmuR&7a@3T(B^g;ZfvPS4InhSd%f7DOWT)J(_Q7b{UfKSAbN5EN2A97| z&q|1L+Ul7XmesSmLi!jut&r(yx5w(CQwe0mXFKF%gF= z%kZhSVi$B?jjGXJ{SR5BQT3Po6I2hSsC#340R0E$ug2dE0I2n9?8i|y7C9Wk3ESWc z1z04Y=t>zlS2-rwT4%!4FQ;kJ`59`!%t8&oZcsQO0|&A`Xyu2ShyY+wVqWN*Bp|)& zP8J56*!jXvN*MCt&jd0(&&dmubQ{ZD4c0;)SpdX&>cj#?RD=J_WPlm%KuXhSI9M_J z>g*Zxojc$f>;%kma5xOdn%uLug{e^yxCDe(Nk0Qs(H6LUZ6F#v=_x&UM?+dJmp2p0 zbHP>?1BZ98{@2$AfJ{~YN#_1H^}1U1RB(k8KL{-!=I&qKHygzY)Ev?Pt~`Jfl12%E zi|IOZCHCo0g2vUF!dD0@euLwuSL?zj@{FD!vaFZ^?PMQD27s^$*2>w>r##t`55P#y&FyJiFe`id`!sbq4EN$V`la?$z`xLT;*SHh$s|OT; z#_eP^nR@(|`EPQ7Q2S3{2YyoVNj>S=Jx;|Tf_ekb{42JC*YB^f6n$=0Kdue9o|VVa2u0Z2EOO|Upg z_v25Hye*&b?-nM9ZNW1>3U7*6$9}GhMex{p!|(d9bP4+@WZ@`()qgH|z-@0|G=XUA ze?mAcDqEvaIH}d!!%G#7O~cT(`kXg1>a&%3er7IN951&}(%1%rye+xIfBahv8z6;~ z79(&?EaHf*|44?r=Bf^80GWHA`oN*^LN4volPTvDYckc!ywrT>4l^=+S&LO9V)aCS zNgenkB~fu?{^yJP0OV)GQr$_(p2%x}3rfv*{mT0U4hyH|dk&w%gSE?ZFQ*8ObO2`A z1DMRvfwgm%WaSB68DTy3q5<>t_In@0PZUMAuK&qaErMJbD95|tbMZ%2=Z3wA(c_Mv z4ZmZ5*0jofPK6`Gl$~PDCXR5*_uGNn0Oz`C7`&#GDJx%}Zh87u+y z>q2z1jgD>}WJdGQRurR0hd0l7Dx^($A6NJJ>kftUD|rnd4BOv^y%5deV;vwe2T0$9 zVGizJie;CThK-jDIj1)*M?_ES^Z8Nx%fF}FFPY1UE@Jl$7A@9Cr5=uvsuuhhh*d5$ zyy9lnEkn`R93BYCUU=<=fI2!2yy#2W4KBJH;3m3d>Y_PYQap z$?6SA4*F4DsJQqo4PHJ@e9cmju#sFq99s(BpHtb7^2$zA#rqIH`}=L+($(_AedQgA z6G#SW);3_&=~!W$4`PvjlnWk`!hhhU6*_YD-yG7Bopkdc$!mGiRSqzjNBZg7>`kDpe_}Jg?VeDN9Sa=)m%}j6lO3|1# z&adx@ymQGm92Yh&RE=Q~EC^eCpS$4BQJtZmB0R$@I5c#??zdx=XtX58=?;_HEm)Ve zQ;`~6tjo`rw5qG{%cdr!+uvWdVuM7cm$?*8U*ald@@gN9VDD#Y2IA55(4(4fFA*L-e8Li1V0^E4EBDNh++_Tt*Q~N%RJ%gLKLi@ey^+dNG1by+ zP6Z2lFA*t~ck(0ext&a@@0P5=ZjI%(U#Ia#7XKk!wZsf?02_}sas-0Xon4|FRdp>& zeP#yMvwp%7BOAIb-5m1O)>&>>qecqPUOsv*6`f2Kj)0QqK&j)2(;P+z8q{Wric@cc zMR1C(2K&RmvKfuB(Ih&OQ}&Y*>-^P<9gUHjr}>9q^bj+n*n=;Jusy;tubO;g;PZ}p zSpvIoSFEfDv^8O|J>8ftypTzpZ98nwX*tmmAxdz0_<-u`WKn}ED>p1Ndc1qSzX&XG zHnG_B{kOy^s2uHPl#lC>OMkujXRNXqSJ3IiKuy9GB$W~JSX_^2{AnYhMV$RbJW`{H zjDgZamSC#P;4Hetd)4mo_Lw58h|>!CR3H%0j#r$%hHA1+hz3AhzW56pCuwr04odOz8$2lBf;HteEt% zjqBQ*?XD!|<|m6+&g3?}W0fADl6|lEat+t4#z@PN$~mRA7cxh4ksTM-Tp};De5@o% zLqItG-WGq%#!+giZY}J7XN|vc=1f{C_jd-DVp*k>|6#Rw&ys99~Lk;%(rs7!1!UE!Uyy8g?6RZRle#JITd64{t!T14`^(5*m4t zL+SZs9D02*#mKzOh;N)j*d;NlIFg~xsdIQkmUo-qEBWwq%3Qd_4x%He@3~G3PmGT5 zF?>q@ZXs@D!`??#$|k<6EX19u1Xl&R^UfcB4y4d^yY{x9xFEV-g$W0EDd(# zGAEgf4ZE%CW%-uMUy2K7x!!vUrt?38B|vvO%yHJpJ2LIqBPvs!QC`Ndg?@Do9(lN z!lUmBhHh!9iWG;A!^yyh)9e^T~q(JN$cweSYEh=1CSb!W>Y8F6@6o{4TV*Mho zkXj2^^;s*;ph=H9@KX9-XizpsKdY*hF5kA2MS7JJ;5XAI!QMv|4VRO97s#(b70j33IFZd`z z<;Y}BLA7c+2~!qk(eFJdr#GX9jQCbmHemb6v|bCGC;D!!i^Y&`PD^C`&qgN~l$kWR zz5~QJOeb&pQGyDpg|VAwiVFo}uZ4lUa7R_|wOoD_;tn+Ut>&K;Ylojz;$4(skX?+a zojdqQ%qV@^jpvQWvfruDZl?+7bCzDG*7E9HehdTOO;PR5vpRzC z7~aJf^(`;8reqAE<-sIX1JR>l`Ql*d_ylrcQAx?Lyu1`#TwE=~O|egp4w=O~e098=B3l3dD*U#M$#cCjY(=CC*;(Lye07L;e9HzJB+Rrbl89DR@JNNmVRO}Va2W< zWG_3Uv$#TUJzW@bK7uLqk(~KkyWaZ~ob<27sS@GwpI1r}gi&a{8zLhs=d2S`^zu!^ zj|}CmIn#xp%=nql+wMkE;nyv zN+hjOR&!Kg!C8g;Wg%_>RLng~(Ktb^qQ)?uUbOPsFICv;R?neUlUwijxCW9csT8Ya zEb&ON+9poo6eLtoWK?zqY$YbLe!Jo%S(2v;a zp89;O4`Lkm2Ro8aPPs|;D8i@l_}=I-{ihq9LxQujBS&#q&k9<&PZD12+icE~egmqA zVTN!S6w#~{NB5IN2W9`S%^yXm#RX?8hK||i_O(cUanLbVb15V}tb>DZm*|!!Fx(D^ z%{0x+EYBPt(!~Z^^6x0SRpr|1+NYKYBqDsNHPte-YqGF2?0(lKSVIXMwmwL<6|;pH6CQC>2I`|rfMBu5$y5>+8_0XP!w2~WZhbA$+|@KZfgkh zU=yTG5Os`-N_xoM9wttyrLtuEy9kp4_Z5s&?twD)3*4dZHC)UZO#s?UFD*l63arfi znz@V3(hrhZ(x>)F`)nH}9h;X=w?c$Id0pt74<+>sPp*sed<$lur$68K- zL%ytYyW7Hm3pI&{2emb+ZI-h+H<`!G{UQP5o7x+3J{vpV1y6zPl?(Czi?X+jYNKla zZmHvxQrwEWyFbO9;_g=5-P+<1ELibEkOp^`0>#}4?o!;H=T7MResaIN?z*?XQj*Rb zPG@D3nSJ(dq07D0Exh*%aM};o4Z;dh@eEFPmg%=-hISx2pr!Y-G00Dsu!;_yEPx%* zTkAzX!IFbGs6l6AS?QTTk^w4ZT9jrzFd5@SrV?U9K<$ZXMw3S!!ry9)!gKcid zJKO%OV0W*|-CEUt*i?kh!MaJEC{^DJ$$g zd|i*GvBX1f)V5#?a}LK;2CjlTUX#tLC%(#6_M_eu(kAXhq_WkUiz}TxH^-eKbP8EA z^ZSj(m#_(tPr4RlEs5%m=I~KgxNw32|2Yd{pt+re3R+v=>(j%2HZGY@TR8eQ=%oXX z30LoohKXwAoVtr6xr%t+1&bmzj@QzM3uNaI2wXo<%x+80fHomaSQS%;raaxMe`YRw zFV?cuqBrA%r~6ewcGc^j3t9!kAEc&Sy@${61$7rw&818-x(THi*QU&qWpcFr zygZI+BXQ8?xZDDQx)waAu3tKJFmAtf3NVuUEKf>S0;9_5ds%gZUE5W+=8WF?p*9%`6h5?BiM+U?gOcM#b*y2nf=7 z(eicfy}}SUrB(hkp@&%k%Qp53kFp@rZjVz(Er!3s*3~{&G0dcf%jEDd*#Y9tGp?SP z56iLS;l~OkMm$V6$5T8C#izN+6rt!uA?A@Bu?P9X@SPm;nc2bD^@gCGUg6)qH~CeP z(j#aVY8(7(bP0|JgY946A`oXk$b@c1&Wr5Q0urPd>XQ`#3ct?EM@@`{86nH(kGpds zm?BH#BH3Zr73ZDTbLI>WPSgJ)Jn|ptUb~Qz78HvN76(KWoMIl&8=e&cm`7HoRBp(a z%md$pqC!diT-M8nKrwA$vO^BjGqj)Dl>O4Sb_zqcxI*33J1^4In5AgY za20BN6XVK8ye36wtgLbb!)S^X!>+O7LbL#lcjbGF}{Y*O8^OO>{$ z+J#6m1qPxUrF~!yxxS0vEQ4)UwpAE)M)_MY6E=65pFC2I2Ws;RG|kE3MNXlDlit3n zHH_%qyMAUHl@|1VS5Zs7HeuKLs75U&CbGdT;ka>#{+3)d#9h0iAW)BVpzT)xxAK+h z#>%rLk;y16Jp)`zF9UN@Y!_Wx!96bR#hAVk1w1US8oLjjrW3Z8wF;>ed`+oyO3ree z(3E&#euCrR?GpTAe+3vb3~6R832z`-lA}mu1Pl@uzqcIo#I#7T(k)R+(fAY;z<&9t zrZ}KShSRuibc4ESW8-iX?yQ#<{{U?fC7`p@O7kkDpzHboHseD}Vc?6@gx1o%auXeQ z6J35+nD{1ewARvg{FZw#iJ84d;1SgFrdAgW-hIX;5^evIE9m~&EtS=ZAhbVcu*>&-V>adTP zOd${Hs8nw&i_6ku4Bi^^?)uT;yCmi}o~Wl>2@yD(8jiPx12sgZRyTKU%Pde}sn+p|g=LmdM*`Ce|1DR;V$ zxW7Yp718{DjR8jS8%$xsg4X?AkshUCe;+FCIacD%WPIZ`^(*l6_4B*0E@!HhK$(#E zQ(N;%+;+Y81JU@u2;u&&Zr6NQ*6r6br`iu%q1!JGXa@Q0{zcFZ(KO5pSr&;%DRYYFb0W zJu`po)x&{{M$UaDG|$j{z8F-`%@aGU^z2kOYt^o<&)8vcq)5)r5AbdPs%f0_QKCKuqk* zwJqYAPF`E3oa{#?HEw?dvxt+(q1!rB6ygicl2)g!pURQf3c~@^DQCkZI;p|mx-(|e z|FqV)lAY#zwf%3*Qja-?##g%1{tCc~C;4Mvp}RDbd!HLDkym~S@71RXJD`^KQP&f8#Fdd2!F*1(ebRCh zNFR&stUXl{B!`l}e#}Ayg-d1TV$(u6@BDk?oL9Q?7@`&UFlc@}JS}=`<9QOOtNcPDtPJ-{3 zJ6k9$$MvXc)v~!XqEbXb=D6X4D9NEq>&`kg!XB=EZQqjUYnhNNg0-C7Y#P)P44_hk zQvr%E8*3;oUAt_*A1Tkr~j4V;tsrv%>EbQ3F3mSN4Q~Z$Nb6IC-9B) z{D?lE^@B|vHdGJG{W5Ksrt$~o_#&0^J9}>Ld9K5*iTrF2@xqU{$rl1pS)B}stuC2l z`Z@ap#%!mwcG0m&ciBnT9y?iK^;^<@qpV9-WB>o?&KT~5VObbct88>ef+0uvDm%!|`&eH*k}>mD0Y zSR!l^Gw&{5@XQ|^?}d!O`n0(@qwcs9tAU;icr2mR-H(c%9SR&YpA$BT1o%{v8CH6n zvNhU8TUxsuGVa|%xYR_BO!4|3b8CF*NF~r-_}&v=NNRs14m`(yzi?ApiB-F~2Ndo{xT-w75dHBq9X!bRjR3yEl>1&^B)ovpciHtDArrjzOq$*@xo zW-iWF%cS62axjGM51}Y#7+~zAs#8Q~$PvF>Z)FCNub(IlHmazEd>_XODj!bFuZA#R zDnl7!{xlh1W}wwJ;Z`!32Ihf{xyvlriE}%_U2?kAiX6X-kW(_W$?Q;g$CKE^3%XC5 z4GBV(uP>L)GQKU_mXBna7O5mO?hbWsiAZZ5ysd#TCjE4=Q(IN`_f>1FcJYeVOD;h2 z7NAuarRAKVSNNorTgNegMa0&@!y*sfx9eKNC-^G$qXGv_AM)0+*Jfg(X`-l;8bpF8 z$Y}yg9j%i2GhU=KqLGm^q@iX5+r;m1j0dgqHp?m}xIt-LK*{vXTPbe9I`57=`f_!; zDMfZr;vZ#jLw;s{>g2?>8;L6lM*FgwgPpnAJw8q#qks@ruE`S9>tWjnqFOt(&<@v& zP4^hK_?I946j+QOWc*IgL<4TEv$=hkRM25372nr3a$mxMG1RYxMCEBTE&7wt<6bBh zg8wXftzG-rY8ar;(Ls$eDqVNWqPpcSjV5LiqU-$gUs38&#!XB-pk8LT+Es}iuw57o zMBb|d>Zt2R5%P)^0b-j~G|ko#)y)Z!Y}Wfhzrp*=)&Bc_y$az@%8_-Ge@G@Omd{5% z`m+}tT4x%DWQ|2J9h2S7S)RQmEyEbz2&XPqJk-5KC32`Q4}@3%6hjzBvPZCh zyRn|Pa{NHO$H0KF!F5tdPaRFFZvr5IZi0Kc0$+MyQhC%1#~5tH*lwxBCZ?ooZg33o)Pb&oh6%!+zm0Hu3Ydu8=QjAa9 zDHMR!dcy+g=YZdm4naJm2=Tj0d}6AA7-zUX^Ih-LGoXb!GS{XfGG_S50j(CCM1#9V zR-G3>#(sC_$0>tC=9jtbQpiU$1wlPeQZ0ZK8#Z=!CGCDeYIEK^Y~}sVpB4kCZ1U#J z+?jnP0me53zfle!Xp*swV!z-KQsB<=Q=Qag zvjM-wL6YN%95aeur~VAYIs*adi&cuXCi8FwsG2_QpUq|Q9U$%MhU-o`_?vn*$xYdG z>XJRbkW&F-m1VS%iH?`jPgoc#hRbP^NtVxs#nVQ=GHfp0NWygmPfjCoFPX_!fcBc9lpQcFlv zbOiYXQ2|yVR=@>?Ou^_-nt2kEI)qPdrWrRnfG&ndoj>h8NFZOz@_yiBSU;fZk&zV= zcR@TB9>?xy7NSkjPCRG0bVp24C{Dp57nC;6J(F}A@Y05;->y9W(s6w58x%VO0iYae_d~Mq7q~|{!P)v59{3!ldR8wO0t%gEVD%~i-$)-bt z^{7d;Aqjq1{WB^RyeL}IoHn@Zyvd%8MU6&T>PM0)3CGab)3n*YBK7bY7;xCEtM)ZE z7X8pb0IHvv|NQKov@lbr=q!4HmRcKzSF%ID4RU`2NercI(f=! zt{Zdm%t|F50HX|>Pj93-bJAqD!af!0^OEd)Ntg`=YFZm*OR1K2Y#|t-=J`lR+{eSF zMLD*rIJVhy+VvK5>Bx=Hz938)f_?aVC5a}HB~*qk0#oNS$8h}bxKdmHXA!hQ#JuP@ zZ(HiE6j;}L@Cgz7?Ilt7^S9-Y#US6$dg<99ojoJ8UY9s$LGb*vNn;ucAlT9ZL(e|l zqK3eUG1-lzwN<1ufaTgG{1sjYw|PAgU5Vb)wYc3ptwGX84UAxkC#(rAs8R+6^jLj0 zQU7bMfUvZQQh{!G;tL>$I?Bd<=B-&>_XL+QK+78#z`BvrP(^uxn-j$DM^$dR?(;^s z6f8K)HTNIV$x0}A=`YMR8~F-|e!>M)yB$fUghzoK=kQs6gkjx3gsg$bRUd2t?(9GDPvG)PEc~6g0&jIb#jTH7|BpyF z14{wnMV=2k9I1LW_M}Oy!CQpd*gjEOnE!Qkc@_h#neJdJa)G|Sks+MzaveLcf6!#= zaRheLmJ1ht0rIPG$@p3Qb+p_vFI;%nwEQm|R@J*%Iw*n%%-h8~Sr^x}*OTz}C-Th$ zF7Ts0FWfkwl==)XokiMlmj>m|{0&=II25#8k7FunTQ6|JKc^d!2O@tBR_@-JD-f>d^g-&MdejhAmK%50< zkM=NUXvPhn=BGR?@;Tanq+e!b6q9D;hKMG+>cE~doncR7#96d0|5&?t#J&UP!=A>A2UmV|04A)bvS=)z zCHqB)ObGkW0Re0_7AH4J`mZ_-ZsPg{pmJ^>UX2!{NlF7&Ga}7D(Y5+`dKbX)0LRBV z(QY?O0N4xQwE$CED76r75-k zbnppfl3|Sd!1QTpP&Hu$QvRj(t>Rsco-`b*vnGV4!%wCw3aUz!a*>;h+t0fcO0+5X z;D*O%iAp|C@-VLdAp?s6PO%Cfn-hDJo=!*N^{w%ga0eRZhN~CqPpZsH?YteC>m2cQ zIY>7L%7kRc4;*^Crm`m+=4*9gm?y}BM&s=0xqfM*kl-g`F? zMhA9mDlXEe^!E7`R1970?TvY_mu0QL@)72?7u}{9o6lqMN02o?0%UL{LNl(mU#8OO zv-80gwdOq83Khs0R7EXin4!gx9gqwEpv?&9D&@J6CPXIQ&^ZzQMVAy4s8hwj<2+?x zO1}SexAxraa39cWEv3qzTko)?J2-O|K)ARDrOsNya>wA$1s)PD&FrV?bYm*D zuvOct9&8`-hP>en!ADLKI@)d5%=s9=@?vgjoI%!c@WNy@>kT7&t<@pQL^{)Zs~&7Q zg>Onx$+&n0bW@dzszu1MyNVfdl0ibX z!u`{Z!-AJr?*l3#B`tB>!K)5OOsRs+0;cvRdIfBe!g{)EugEldx z`fhCwq#o%neD7%mIkdHQ_K9$~>)essEeMvYuUx(1w7nK-zf&wcE8-H+FGRW{I(DX2 z@lAKlrUz%t>Kibt0^c*-3%r(;tHNbXvn*lJn6!PBAhJ^-_Q8tn?oT`7IGE^W`9}^% zM-Ir8RVG1XI+J;Hw4!P?n54-Cih0(td9vtvve7$T7Rv?sN5hQ*Qo7YOjeQVKb8uek zvOSbQ?elnK`k!I@oeoUxz8enjm@R0Be&U2}gL89rnv<*9{T`(yuMD>~N;sA6(rT>( zeO^;Fngja4XNZemm~gWM1Vf%9Aqm5U!ktzn_S>gB?%;AJT*wZLc)@yesHZW#>bem^ z5|%Z^+$|K9jBt&cbB<<7kSe>YS*u9&vq{}1PZhPc8w{dtzxtGiyGZ()4|+&&zx~e1 zy1--BXQJsWzLQ-vp=)=nlCY^(R)=yNBBo)b{4T8b%t1C(yM~H(fR18juA0+QF^@mt zM6}SVXZad3q2!kNIchUiYTw*~OmOC1(mCXh*^+z;Y&kMN;da4%U zEbX|TVTD$|%E*p&&hsqGbb>AvL3wYEa}IA}HgJ;0YBNysIHSXAB|4^Z_NJ>Q6^uQ1 zhSfF;A9U6pxUz!v*cZ^T>JVRUlFerX4ZoAGvU!)A**{|8VS8d?+I6uLF3 znB{Y81R#sniwq;x?&QGLmwHU|y3hJTrX`=pGzy#j=o2WAhNHAa-=>=*_2WSmSpzqQ zuVvXc zjTybSM(J0`=U^r*dfD8P_t{EVCHQ?t?Hak6Bur~vc>A3JE;qMzIx}4qTaEST{Z<(eHh#z%UkjH?xXsCC|&BfAZB%3Y>{9RH9=NJU+6*G6ERE1E5$PXH5JmV6&^lHE+omI~SJ*>_tCf0HNa54Z> zX;c2b9cGb*-SJ)OUxZ-D=^seaZEo(iqp1R=;bL^}$fJ80q9euO!BdSj)YRI#0BN`9 zKG=a>B%|^BF4JP?{`bx1y9Zs8>#YEZEY-4v_sFxJJR1yx=9nf+u6^TXY5V>5p`2b+ z;`m}F@k9omaXBG>sz!{F?3m<1dcoNKniOaV)2u+#5s&^^SEZX-Vu4mj*f6ycbX@tew;)zp@UiSl6l!D)8?i zqd2YkW++!1=vW%JR={L@Ji_M6INt9d|mtSZh#K(=v4e#J^}<>cz)h>r{ee6g}haajTA8fgL%4 zmUA7I=*!Z+D#)bePF(0y zhDH{t5sBEZS0BAldXc~r=#IuUk6k72Jh`2aaKS?U3Nzv#jbkW#znOTAN96BKFLyd@ zcMluv@Ydf%>GKk6QCj8ZDR10doz40d)8;4TemQ0ZEtL#sBn=>`mXCQXGW*G#nbJ`~ zDQhH!m|7x4gjX>TNs`lTFLj*rfOCviX%F9~kDQ8JLyW@djC0J0+tP24NU>S-BlFV@{~hmyedwkoqVOke{GPSw z*uG3UPPYE%LkpRytVYn3G%x=*lyj=_-{zq7p5YCAa_ki2#Btr6pLfP?HfhChsrN{v zDoJ9B=(Nt$O(W7xe-B+XLltq)1-2?28tkM1!(xbIV(JXGFZ0^6WF77GiCm|LZ}b?x zrCAHDc~<iO}#e^zg%H|zy!<6S`=ofOP6XwNwBBu}n5`qR_| z)c&?|NSK-d#mQ3%R7xkmGx<1gx@!NmRwY<*DJs>&Ia@c5_HKT&H+icLYj$FspTC*S zsXx65cB=C@(iJZh2_}W!ufFML9?h#GRH%T3(lAibb|zOv{!>E{Di>Gp`U>Os_aZtS zQC}}L69G0(N0W;c@j4vVb-S*#^}8mVpE|qazMP}A1lYtVYIf5_4Q~tj6?Iv%*qHAU z{WpdLG-4~pLG_Ih)t6Ldm&ufm@t=O$dZmYAn~v5O9v;% zthqQjE6l!e(GCtLa*(3g^{d1WE1vb&&f9H`Y=8ZeS_w`(=nQ&JYymb?m}Wuh%O5nZ zwPF|MtFbu!lO`A0y>{lhj$w4#)1|XOL=OJVb&x_Q>mL4bIU{w8+iWaVclNAGxZ(Uh|B6g~fK;tv27Dm;v&l{#rE{`zfUB$iULAs~6y`V(I5Fnlr(0b8FT$l? zrB;o(Y;H}x&{&e=POH#xi)^fu->jQO)~Qdzeru*xYyMJ9GTgL!GqvtJGAh{ z-59)(!?I|H=%^II_I2hF(D!COk%n5M+l}-6zRj^Foc+-;Vc9<0>RCI^0}cM+C~w8{ znUsBNZO#iBYjXwaQZHf__KFKy_cp}uYhw$bk`9>+%FyKG(4W46_AHqAvR+^L>GQjB z4tNJt?)I6T>=X5rFwns_@7{w|aHrd4_}=oX*XQ`=X-xw*$-k!zpwEZDq! z9WAOX%nE`$3pHiy%!J;^re_ei?F}?U1er85t4ysZ{mj>}l0A?iuJL5$C8=~<>H8wF z29Do5D4fq-#xO@sKWMZGs_!%jeIxq4&Wb_0oW^|w2~71mrdYdKP#|yj;N+$Whdv;{ z%WP+@Yhr8R!>Uk|Qa{_z#MCZ@wP3vd>*b+Fi9PYNu59EHijQ#E3IV&eF-J$JyH)?b0;?tQlHFyx~2x*dD zG@6A!@)yLcaA2MrbT5y%X02tP!iLA4S~IxoGDvJ^!wv}kx#LRof2=1p#wecoZwc7S z88SMuKP$pa()@prqs<79(G&M}h6yn&c@V!+T^6_n&men$Sbo*-woLv(YQ>~K_f%q) zsIPl0hs{BU(yP?Q(ljZ(b_B&egecOwdsy8oOj2XWic2&b^QysHFsC(&O2cN*z&P8$ zCs>DPO5u%tRX5L60SSAuUvyG4+irqG=r-=oZRwCLgwENN#lqIHGN-3IB)DV2BDuz!}ucU*Y8U zJ#~Q9QrcJ2B8;!xy4F69H(eoq3Q>S*%2{Qt)$|n9R;I(C*=R63p~{Qb z2-yk^e+HQ=!Q70bVu)1LNXo-XPr>SBhjiw04W3O0aj@UDJ$H2(n|s~6NyKHBWuLWu zCNf3q>@HK)xm);9VGngJ4JHxy#ebZpIAQDs{q)4prClzua7qO(atn~$rU}1o@S)Tz zrl`fV9=pYB5@r;>0rppj%9F2PZWi#x$_>$?Zr)?=SDPlwgsM{#U&gB!>J3`dJ zAdSt%$+r5MnRrJwRaLSZW|6;XHCES@>j^9_J$(r z_u_bt@#-jrzsYUL%WK#;UVgum$DMuH>ScKCSOGDa>g1iCMzeB!0i8q8TAs5{fg8+_ z*=faYfw*=Q%3~g5_vz5FemzD!zVWg8UTUO)_cr4ZYrs7-8+<=+qQLG0e*f5&Fkq$8 zPVhx6-N^A&w{e-ElL}GZc#VtmchnHX)Xi*vE0nurHoj?6rX5+egZto~XXPR~Ay08? zeyVh%1DsIdOIL$Odo?qFvq>H){AHYL8*ezqrn52OaO0Y9{Co!MmU_bl9F?*m6Yuuj zY{0BI3zrsFj9--9O`hN7)K_X8(bgiFpVBG_`}QulD@XOE=!f%aGRiI(8mys-EDiD+ zHSUC%F4tz)#|=w2k z;;jp{ zASX4EctJV2J%&A`vgcd&{3xbNNi{Mtp#Xe@cwd8*wN_fr$3hDu;4z9}tB+V*T#far z6d_2a_Ih@3v0FKA-|L;4r^(BXt7;JvZ-O%m?t49zT(mkJ18&HsbD<>;c5HFI>ZRlS>$Ta_~ zCI$FP@R0KRG`4Sx1}D6mQaT~-eX!6RYQb|~ug}M;G{azd4eD+xoESbfl?;FgLpH~B z4KVpLbda-dsXBz2br zO}F@>(7lAmx=QBMaU1WdQg2`R2;$G;GbGGhDg2`K{k%zP`lhFWG)@{tmHpx(#spU> zKfktZ(Hqy#V~BQ`zTv|x%tNHJY@$`u-9+s-7gn<2fe`btH&fNeb%B>UE>I>a#k!V) z%N`b=5Zp52v8(Px;#YY^GVNNMvJX`oQkSi^Dk8aW-nh#!p5pelwzF&Sg(u7b7ZIHY z)zjPA1la7mIv98qRc*UIyFfg}XmaG#{+Zxbh)c4638S@DwEgbXD<-Cbb=<;}+oCyM zJ4DrWqFmi)9KF*)|F&(}IHK#QOgIi=n^`bxd&wotHl}!0ltITQdl;hFU(EN^1r{8V8aboJvkW<#HP%C38SL-jrBe5%rcbM>O2F>c zT*B#;Ij@MLs{LeinQj%Gtb+-B0w3>#3sb9L`?8v9P-eEf*)HC) zD4L>`svO?i-4$~pO`FCQZe$tkD=Ur?rL<@AfD6JXEKES`HXdULw>Ds0836BkN)-U( zy5wD``F$yAL#g-htA~kdfAWBq+yF7m6Vu($lj?rW+x3!v5$@gQ>W;UBMU=DxQnda> zz*gFzSgmc_R{s|PUqmoQ1}!JPiU(S_N|t=8(9dkv2cETf!{^^s`NQ`c#}|2JkDx|T zGaHAXcxl(_i?_bE=OL`UMD3{FR!DyK)n!}{9nWh@U}I_P#;d#@KMHb-InSe#(x6sj z{hD2t{OmK#4WfEK&-u0vg`{4&=GtmBXfw#6Wx_&szg|bmhfs6WPjQg^>opx zLoG`bTkv_+Ayl+|miQ8Dpk!6y6qUC{NUG^-yOWCSO4OP8S=yt7EF!8Hi8V=cjD4&d za_AwONG8f!k&~i2iH6(wCK@$;Bm^^jD=TqZs_C-$=xMY3+fL|5quX7=t=V9WIlRN^ zhUL$r3nF8+h3{AMHuiDq8S<#!(5w2LJ4*E9UdbvqIK-VPP_+}<5maWzMAT?++_1Gs zI_c*5jU|!X$YC8RNpCd#vE-FJNOcJo&c**cuk6>hf4)MD@ zPsilpG#f#Hr!DM}k5fLTba+r1GsVOyIeBL0a@VX6#nV@t&8#azyF#k#JS4W-O3vKJ zuhMgGj)bO>!OXNl!r64xkGsb#&$vpt61M6_&(LwVE1Yyu1$8KlStU;RUANsJ~@r)Jm+4K4JVXEN*6IRiQC z-wgxBe%fagGv`^tB0rZA{FN&&m5K21dGm?i8(nbBCNwu8WM;oSSHf__%lHmuh3dn0 zKxZi&-c?Cp-Me@B*4pBI5%SlGs%OinwjAZhAxn8goCnV9KduVXp`HcN!Y}rT@M}b; zviD1b^)sAQbkn(5qKMd!)Axdp0#&d&?Bbtk`wANe_qn%No?%oq5oS;@kFdPelnH-3 z^V3X4Jw>4l#nYHxl57Ogo33%I$_!iVOJJ>)p85fIpZq*#mS5Lra@6H@>kqEk znEu%^>bkjd%@VvQDBv9=E+XPNyYAQYWjuKt+IAv&?T;v9`t5MYqA%Ysh3e*rPEO4= zv`L5Y0MTL*R6x@o+x>`-QMF5T%6!^1D^X41HcU54CMmPoPq8SNDsnygC^l?qHZi*^&c68Rxx zGK>1ky;NRlfo)?%I)K_92qtqp1(TPLTPa0k9c>O@hXKLl-tgl^p({(7M}9!Vx#EE? z^NpPyYV;~LNxA+(WJT|Oaz6}svs7a_5;XHV#0ik%Y+EzTAZ|tXn=AL{x=#wwAiMc> zCv%3b8!&C0IJ0Y9H?o#*ON@qjWh&vXEOk}Rc^3nce-TXY zaBUpjhm?CzOA_g)0tjCQSYRe^lM=7`71VMrer7Bl4Hlv1^Rie6^u7hqceljmJ(pI- zq@H%XUiSTl!<>Mz@f4aF`bD@s*Z)8KGtH>t|2O`bKf+OOlkIii8391$D_pAp}!!gvKr^k$1mu)My=wJAVorAJW~yKQnUG<`=A-*&F!uG(TV|0 zSY4<3D9B?t0iuC&mWNn|w8BYM%P%6QWv99^Q6R{1Ri2ta)W*ffaogP_*d#0<(Apr# z=HudR)VDdc3oGJ298nyCC0;Y};;|6ijBtAq&o7=f@bhvGCjFoZ6!>Ld~L; zaK`Cv<*^R6$1F~8_KBD~%_+`*T^os6$%lVx~Iw;xzpSIgMQf*^Sr77Om{&(3tRRm9&Z(Ulc)9;m3mx$Jb#-pYl zmlKX&P&~ikZ5hkso4QALk^3Qvef{v8X0m?~HbpLI2Je8b`C-7L>AwgcyknOi5tSaT zmhZiV>B6D zUiwfTs`;BkJMDEDyHW*j#JfULEJ6zrw&TN20Su(`B;Fbnz4~k68+Fb8L+E-O*U`(6}oO5AR1{VX|AaFMfNMBuydsPF(EV!<0@|4+pR{46BssW*jF?tm*N| z5_soCbkrC6o8BUttv)#5pgmGEHeF*pC(UwAUL*`y|MPe%1+)F{8mL33TszW%y-)?3 zvsvd}j$hk+)S>?(P}X|uuV1hrEHNW}*1GF^ye--O#cTLLKHi2*+7y1nE0nSw-SL?3 zL#vd6fml?M{Cl~XM898hFn>>Iji6>tPu3|>i+Y@jXRDt(Tt?WFv4mYrUq%~tU{Oki zv`&zd#j~Fc@o@=su94&|{M=t&bd*4I3GFFLMr!-&wO{|nPQ#9mP%y8zPBmRbSg`&+ zMZzs>Ox)i=cmV<7jYN#Pc>=P9FA(bKD}8^RRLU)5QBfq9qTN(YVG&+9wa%FBcx@(; z!kl}%&CrX^Vq5r)vON7yVi`zB`RedD0h{tzs*>z5QIomWMCdOF;X<-_fpSmjo1P|$ zdCvj2Z|z9dl@o4M$AyA)!ry-yPH_~{VNVKNx?@z3@^~yl4FuQaMJ&_-E z(3@J9T4t0YBo7}Sxee!Da*h^|6af$msi2cJ_YDV@jD6EiqhhOSh*q#LgA_((;fW_O zA+Zc)fNhB(9S7uVr3LnCdp&0>5Rr@Wl*`ALI(H6%Nt{b`Fuk3DGb&#ZlTRYnZ-RtA zBe>RFXlV?sVi`!^2sQ{4sJ}@r*t1MYuS!gvhY`sVQ}iB%eABR^ORmrr{fM7C@-Xg| zpLW)IHft%hD5tP1BL<^V9C>q0{%6XtPUadT&RwyVMpI(vg2@TAC*#)78rqj~!UFwv zKhAr!YgvP_YMv7F5$149r*zsc(p2m$K;*X!y%91@mVXQiJY%~OI}He>IHNo5yh8&3 z^QaUAAH|-4387cl{aFo#Uj76DlALwFLXWJn29;^ayF+|J_d3s>Sl@Pr3-S+gdWO>M zPfjjV!lSmd?U&;*Zes=&cDox#taGwgaYpzE&#>*uxCk>&bz*(CD@SF5Ul;3hZvA=LS7{|Cxucq8AqM*2X{IC+=W8rWR7xfFm zlP#*h@xosmpj>+g%a{9lqj?&hlLNS&mh;=>c_C(?5!jbUquYO|`Xh<(VnCPN5)K^U z0{}CA(UtC?89E%weP)NDe2(|xbrkY;+XHwTLA#4WW9<-uHl99@YtDQcU|zq#^^U*m zTVu5Vp!mx>Ht(e`nB8@(FP&O?pQXdij8CD#Cr6`N4bI~+MYQhV7K6s=(X(jX-f$p5 z_`zhe#moPTEfTz6%@@JJ)ZvpFx=NbI@m>S zH2y@=UN;sWp2F?eYqXMzDhW$2-qXKhD{A&v+DT)lV6KUxaivnhEqho`VO=~%O}z^J0Kj0=TgK4n9b^u)O4-5M6t5F@viE-k zf*J?oxXq;e_)sC@3{fDfiyl%BCc5b7&1y^4!$&Ce1bTg#?doq{F9AmNcE^Njb@p{ww; z%0dVA@>UPt>Q&%8HACaNEKrbC-+yaWJO-}%JJgp7e|?VlQUG-b{13hkROHeqT+(rD zJRq-gJHoy?$C1Kmmaxd6*UZnsq|~6GEtp20O#L&Qci);E0l(Ht^|ahC5rm7W;u2l+ zBO3AWm87JU*l$rFWUCWynsiDn?iu^_d;ftFc^(aS@^lV+gr9jXYS;;x-pwF(Dr$LK zvAEun>?uTs7%O;12UNx2(}2X3!m6t)~z2Z^#4zNUBk%GRO;UkNo5_$8AL)PGIo1x z?6YRK11Y<(xz{iwLbY)P{lb;kgV=`;-M?nIKa_bKGQ-JIMre5}JfKJf5COrupzdmUoEe8D<>QQ#Pue`wYDLCca@UHHYA@EswVjt7*Cl2)~ z%X$K2S(9>qs%`!Z(xBr$Wr3Rj*`*BSS?iB}>i`?K)|sb)9SKuu)YCj>C zPp>9XpW`2H}?`^tg2ZvkXWZrNahy zv_ODO@UM?BEG#1UOYxK3aXkHi_nEJ$e_fogD941J@RV>e5E4Gp7ykteZTjr5dh)Mc z5{}6RQauSAGo_f^jjw;TzHQ6?|I6^+m&saAoH$@|TXh`xpuDW!|&t++N$ZYxSKbpwV&yMS#o)ZY9T0Q{D0X(hn71&Ba_Oz@Y#B1>S}tTi{}V=bc= zjSQbgUi~*e{9l3R-_$XjrY`>oCtm?X+DMVD@rwKcZ6BX~_^zs4)&$8-upi zAcr#;X^Qr{7XWYH?Z6d^e`CVWr+{v-JjyyQa}W#1xaGK!KA!#4dGwz~xbSlg?ty$Y z3N(=^pL)6~4wO1ispzM<0zcnrx10V&$Oi1&tnanw;xt>KoVR%d(}oVa4)7jH2~Qkr zcDv&IbawqqqdtWw~=8BU#8A^u;nA;MGDrI>ylQy7dc!P z`U14W2*i5LbK!bV4dAB~AGCfXdH*HU8D*N|;7#DS@RwNFGn6t(e8Kry7Z=M2QuEe& zzWH|!5EubI+I0<%{(fMDpY;#R8w95|fxmLXOT`M5m6G-X70Yc}IE8k9+O*m4oo{A(FYf-x^Qp$#ukHobdK1T}Ec|9>S}0;Is;4ddHhI@^)7kxb=d3XHb{w za-do>I^?!;vOeNvJ}~)xx|UDP51YMGq2HD(4U<=r^z9sRQpB|x(H4P=L(RWUt%G!e zl3%$Gne>yQrxNltSEhY99EK_j@JZlbi*aVhLlBD~Y25PKH+FRGX-u^$)!MnmiFu`3 zroL3ni52HP!tVG2Bfa{`{+*>rj;Ao|iF=${W+2Qxxv5cYtQ1wQQ#hbkAi$qMWdY@L z`SZz>a-mQ$Sf|p(FOYE{G%YY^dfqEf60a?NwP1Qpwb2>mS}wx z04Jz}0(Ea)CP!E!g>1*$*mMI43?etiqH+XQd2b578CLqUt-hJ{f{lo3KnZEy>@QGO zb>8m1Y8(jxzUCK z99c6)GkA1^ygG6KcY#}~eQoSoe>#vc@cv&+opo3g{Tr__Kmk$d5>UDp=?*29uBDff z?(SAXq-9x_2I&Tg1?leYM!LI1K;JWqzjLnRA6&Q&yR(Bk^L?Iq?)&5DBbDGg4*Dw^ zXg$<5uL)n{RH)8JSQTM0vCp$Sbs5Np!F6)xh6!;sTwD}LOiWacj*Zg@OQ&R}beIL zx`Ybxjo7wWWVuqrNI7R-?W;le2GUMGG$dX+H*C{f)f)eYR5SKKY5!eulnZbfc%rlV z7Cj2M9X2@b!?2AQT5_SH`1vL>nb-Y8-=CkYOBBMGG|7z8sv-$0irTtFfSssP!h(A%ELX{-NhmMcJpIEU*LKr zy2@A3%WGplLH#uDd|4T{Fxe<%&b7f(iHpEMgt^nqgDmRBe7jSTUd8t*n|;( zn=&tY5E7@$+QnUTE|QO4tzRxVj$|=aH`DKUX2Pns@O#F3-aq32b2cT!_u*J0btqOz zbqTT>smoo^9&f1$iz3mCT-?N7DR-m!ybH`{chsK9+W)xD(b%2yn)I%o=*w^^%_=*x z|MBP5N?1){V5_I(nNiYf`;k~;ulccWS3DeTse{+O)h)I!6in$mYg~&R9)xvgI%(SW zPNXjz7{^oENz()qys;j=x^aaj?9v$Wor`>fuWj1s9|^LHYb*T&v%EMweubFC>d$$d3Ns`rWF2d9#clNri% zPnpH@k4N!KBnU7WN5mZ)`uckx#LiX)r!uTQb45hNr}Jvh?M~df>9l*U3r0h;<*bjO zN44n=A;+JCXkXQF@DXwT6APK0G&*wqBK2H3_T&x4+WxIy9OtRakFHo(-#+2~Bf^l&VBxMk zUibp3p1K|FG}Y(2x;pK~t5#F(JQE|tQLFb6l-51Vs>wQ} zke-tW_d9!U!A0nqduh~5Z^UdulV+v=2W(}&n>?EqR6V8E@5GWbb?2;dHk5B z2#1-wjk=q(9s{K>-B0OTd4^M+O@4_sY~rV^kV;)EB;$U*hRd$9FWp%-n?m-AO?{2B zXyK!v<*9G%Q_wpD&%R1G%dQ~CYCNa7Jf?Xq#uUja-Y*}AHC>*3NjYFHeZjNE@FM8# z4fJ}(-HH|z@V4fJMnPwrZ8{P(S;OBauI1Y99Nqk--=ej;+;|v&mRWXor$bI>84^6n z;6A8QwCdV)U?yB8(qq|N@FcMRT`=Dl0W)-hYRhb1+LL1-7c*gA56tmWku3JjG7U%n zNv}|qKS#8^$)xI>;e<+&Ii;7)+%;AHzC3mXGp^s{-h1iJTqe(~VYBBwzO1FfTw_gz z#7mRKvUDqIsXqgs?X$GA>;-~!S?SB%RFTPwZ2o?3Qy&Zfj#wF8}++r-TlqflT!NFQvfKM&wXj{4- z-gMg$S{G?hwQOmRraGpYmNlcQ>lzgK-MT|ArGdx4PR##gsS@)nW?AA=`4xGm20tZa zfwf&-?5~bQ|4qk4+U1LJ`8`T%{TTlDua;hnw-mUxtb+Q<-t|wg2?g}i4`?f}o#EsS zavnhROn5rdjJO_BWIEFpgBsy-WVzFEyA=Xs;kX$?`k_=9dznq93C z-eK9%qmxa?l6JbOH~>583Gnv$gP&Eb&8>mxv2y@bwyZL1PV=cCIWk=iT{>>lr6Bcc4{r}I>w~kQ z><06agt2n*sG=x&5pTIBvi@yM7c(klBBxEf>RG0ld`J}3I+r;DTiI%{oJLuL#iD}$ z6(wZgbN?2mfsL!1>DHx94c`kBb~)AQLD&#wy#lZApO+>t<8@1uHS_)=Ya=-=Pl~=f zIe9>}D}G1E9|Rb1#Vg`lYFM@G?VXuXh6wYU{hoF6fLIJ)ggyejgy&}OGglll^uhKJ z1uf61LTIiyRag5~ic*(IMI5AmRiOo@c|u zO$SrV=F)xp%Bv_9ZdlL|f~r5JEezxAW(vbq=VAVkv#4(nXrsJrB;(?d|Jf8jnk7r;;tp!tME{ zop}UnY&g|mZuq5v&e|zGnCywXV)==Hl<4nnQTL>4oP_P7phSi_W235P!M0bXRa%}4 zDI0WG%cbnAw)ry*S}^OqrKWUQcD|VzS^L+v@*?xB|DnC~^)gLJ&LUX5?n`m?5y6@L zn??pdBr_u%s%)1vfHV0HhVu(qk)^sPp*?~Aqxux&f}3WK;th2x*D2p{-Gy3nnoNph za_MRaiHLRQ?1SN0%a_5epE#Nnb3cx(h<7^JoTRO1H zG6jB(RnqS^_a%bhTKdRz61mY?u8xinAQGw`9xux77cNB#3o8yf0Bt_5IO1k7xfO}d z6#^p)$?Yu9;u&wT5}KXsrmp$u%Hv5TvvP9X#x@q6pQDSCm&8;)?ETAOO#1G}f~`_O zxUT7?WxpScwwHDQ(+)Ff1!fabES;DGb#t=)k(KdU6`fbMf|J@Z#Hkn(ow#a<&Yhk- z9*dmKmE$&%d$~E(wVca06iHbIVa|teuf^HbjDSzhPU<%b+oenq*fblLFOUh0Ln%=1 z9v%g`Y8`PLP#qg75kjY(LhZR{$WSbyaFZuQBRwQD3GXdk(sj1Yr$w@H!RHgU#dh&b z;IXIO{PaJW-x4(djs6)3j|oZlU-^r(G@G33>}m}A_-u!q$;EFI1kahTK0lQQcke$B z7i?<8Ct$LoL#_ddH&K#ce>P|7reb12H>)y0Hqsq7?5Ok8SuC@5BcGqEg}?Hfs1FO= z2gL8I_FH6P=}*Q5>@Vqz`wa{KKxcDY!INjpP$IE}W?iSjOjdzqXV46T3yU|8c2kMQ+|#hLjEs@1@t(uZ8$#=@ zxy5?0^H;idQkJF6UzN79lYWclZ0&Y>a|6jY!@k+>`K6pRC<{nohl|j!jfK7JGu9w& z^r$w@Pl0An=NG+`h_mmLtlT`-y?9X`K5AE9NTIIpj2_c}yzr6t~3W!p$;|41u5*}gwh zl#Q#$rK5A}YBSOI#CSd-We0?iXQhUq3%z+p1yf zlc~)rsZwcg_~@j`p^9og$wZ`MK?#%3Y&x%;;_`3lNC4K|RAfkIN2UBcuKPnw_=5*g zRh@v5QDj=fnwT5r-c{KVPyZ~tBw5eZ1SwaWA} zoi}lXl2mV;=$UM@?MQr$`+~B?(sqx~=0KOs&}uW8SvwwzvmisOf?vhR37;cHpRQq{ zX&f==5Xl&_Yo4ix$-}0n@UPoQ&cUHsdVxfs^JJ=i3X$6Il^da_d5Ez5bgsp87-LHZ zyw<#2SZ&dCGvN!1dl)^=*K&+-VcKN6r^Ce_{(Re4(ddrRBP>nI>ob0Gj>#Su#%iZs zl!1t}v3RlFSGr65{i3>MXQ}hftII1%v8(%EB+mw7sjH2rvKa&fwW|wv|J09K$!WhC zSAk^^bQR5mXyfdtTSgwW)uL#Fbz=zt#kAJfn1c=eXB}Qdx1?d?vAfUv`N7s<2}}5t#$g z+=zv`Xh!&OqT1ab!TFqh9;it65N_SHZ(6p)`KuXT1&5(EryqCr^h?SwPM=1c_rq(3 zrl)+v#33@`vX5nzCwEk{&GVH)u&krVSg^u3x;dgdJ#XUDbcS^WTAFElO#%)HB4g^Xk zl};-l^cFvS$F`26W|Obc_9g6NUDAJ*ug%?ieY9!i@GK3u)KM2iGSgbR4F~Ay99Ax? zo!be_-i+9mYEEU@fV-gCojXH*g)N@zVI4(VHQk$iBKFa%JaPo<;3dWR*LBQJ+e^oB z8zZa65FZB%Q*!=G@mF{?(OU;o0&0RXWAq!XDXoXp!yvG_ucI}v(lH;}VqR9V!L*iL zOU9RK=+vz;_o~}hCK(aym|ii&v~2Pgi;BKh&wo4D6VV;J!*miPIXSbSP23zgGZe}e zmoeBVD2(r%l2C@LhqPTf3?VC+8*pR+r~Y)&J~b`BC1vP)J3^nmj-RZjp|x&qVa}X< zaZT3_0K_{*8L6u;Shoo`89*Xg)aCItAXl)%5Rt#AS?FHb0TConDt9oPHQ5%~x0FRL zBymVIow*;&+Dw3~G9)B&K~NZDCDNZsh|4k!?c%L^ZnR)SA+`y-7ZxTdX0qMh&YsLr67Kx9WFQw<5M9-$c*4kt?Oxt8)jUD)>^#u=}drd8(3s zb>9thK}iosm--Nhtn}GjL!HFxkX z!%afeig99n zi?{LX+Lq`n#@y#?BIM%onIWOne2tJ)x+afGAtQgexFDAEAm+ETd62)ZPlj9KmPCHe z{f8#|b~Sxu#y{-X##iccWV^*yO`X#RxuBM|66T{o=3E`NY#sdOH;hCS&S{jC<>cvY zNb;sivcj7|tDANV6AA=<%4u4ihR)koZ-PV8Q!nLGU*}H4jeUokWF||YIbKLQCh7K5 zZ&ykr(O0zRqp4(~h31RST8P|zlKye+s7;W``1uo0(^_Hvu34dlk~s7aK@$9GGO2F$ zdWV9~+mcB$hk{kts9t)=OL3~(Rb>-v@luIREIz8(#fk@cb7p;?x3+QYxJqjJB^@vO zYsNUHvH3S;zLaBGQ#41WT?A4k8q#uDBvc2@r@Z<_eEfY?+R}#kQhX5~k^REizA;bK ze9R-yQnwRnUE^g5D-kEFiJTr|{h4ilHnE74H4ttYcVgMlE-OpB?Rijjho1jQn6|1; zKfA#gyFQ;^R^%>KE`aRm<)o)-CX2pbRXAd|-RW%A=}-38dEyu4kGs zzU+x|4VpWMw~FhylgcF{qtF(4mor_)7Bv#Ce;gA%IPOYUicyVMoZY&Nr{y6HmP`IA zFdk?~=Gn|_x_6Qw4$*3GE|~5GJD;;O+OL-zK7CU3EqQzPvH#%NqpIFZL|vD5lLY1A z&1CFT2g_%v$(gLWd|zovOePLQH3C#KYjN?z#3UDTgT_FqoMd;wye5YiZ%yi5EtJOc zY*-{>Si!uP-1pucCXX-;Q}sTC?4p<3@m~#~2Xh6(l(j+M6l6j5W|taz5*&2945U%~Axi zR2~xP$IB5(Ln6-15ne}ED8*(S=@U=&W_6QE2?EdA6cC2Ms~miUE!!Sl=mrG^H!wcO z5i-`#(ZL_UgefGc>^?`@P$U{=kjU1=qPyuz38wU?g~@$Vw5LBg`JrwUL?5+?IGKvm zRQ|f1u>GWrEp3ztBxHW*qeWdR;<_iDff-=^)>f!2OiE5fkubLuNrv3~F@Kg%h2aP!L z`3j7<<(23*|FGwkeuZz>f48kP7L~PI0U9q8a7)#YW<;O3Q$)j0@$BI8U&X{a7ea5b zt3^C}fG{JZ&|JH67bDYKiX~}Lq=ULs+k5lx775p&hC%lxQsbk%qw!qCoJLlY6jc!- zRgG6QY~C>NJqc0`>{VBqRWcp91{sGl!rgR!V7JSiM_QOf!CurCLWn)TZHvvZmA5xx z%7MBk5Al|sDi5!d{8sutXXc&NpxM8-SfYfBj>x*gkL^m+MZ)H}4{6@5J=yZ|xy~rpa02Oo!>_4ZiLZz66JFmSvB0s`aDim?kxcSS+(O zU#23+)N}dyor#%#X~{XnyQ^v;-%{jwYCxB)s@mDzZP3ZSro!EZt??n7@{l7ZFt*0s zt~|{B!Cm|l42$jO>Qoha*>^iHNbl0Ej_s=aVFB$T(&ZrB<>~9#n{BCA^`IiG{>Oks=qM94$qt5qYyWdkA2c3>hN4 zE9VR_;XVS%|=8>DVInuD7bGR8Ds<>|vE1Pi_* ziL4GSkI<|Zc3k6^4r zvK|)ijjpmcdt9QisMIN7U|9hy?PVoWu!LO=jitLv-8e=!1C7ktT?dA5JhfW2zj?e$ z{&n!)N(-i2NDt``bNosOLIoizB$Yf}4nIlwc%vp~m7>wy#>}2+-FlR|Not}Jo>S!NqsRb)U>eTnM_w|i4s+x6f zB|6pf@K*eK&iECPQz>^IMVgzo!Ee_VMb}PNFY1m7QLXIG@-U#Ur} zu=IBConIFak_bjT&K-hu`JKi1x<9>xw_pTpQ>tZD*yi4CzrejqaSUBx{h5<-5~H>M zQ^ErXGy^x+UHf&Ecf5cZKAl!3k}#VSld$vZH;X+?OZ`J;W$EntT<Df=!)#!0Og7kuE^FGe^@y<^Ddyr&1 z?{3;((w-C8@&H9UgSo>ny9d1~seiDCO zz3+MmMNHu?^pg8?criI$WmU85b^swDc!xwYi8~+FaYk;It95Q3ald%R@F7>O$03*b z%G!EIN%&gY)HFBr6~MH1SGdNzbT$3h(+>>t;QSwp3EVp<|cK-^2}cJDU}p ztd0n_U)gp=j3+TJ>8(WY&7|LN+Wb29S#(5dHY*$!Usp7!q%kz+ z5PparS0jH5e-rEFt(st4p*d=|u_H{x#9K#D$|6uz&2JYLoU6n& za{=;VtCVpwTS3P*f1}0p_8U5u+GFFSF{LjU|3i~#h|d@B?fPq^R##PF0&o%l&Vae+QAhyB0TcV5kH7bKFGhwJChl5xIEL=H8e1LeW3M| zWOci^h5s}aG%-!Vx93yQo#Uew-4)H`a@|l?uiWSn{opx4WU?pEe`r~?H`K4}1a7y+ z&atm3HCNW>}hAM1PJ)xCm*edmyXnsFj zBc_JqvLe1$i zXuD^38$%f@s@~CTUeZ8>n!g@O2p?f~vap)wVV5$@{HhbYx|LI>fOnxW7ZG6WQrv)E zZQTD_DaJOrp_=zaw1bR93+~nr^zm}rU6qno_J(_N*CI_OlY8}! zF4F@5~iMK6VaNcZT>ArKxYW%svIt-f#>aXVAozJTd2J|p?_Yg ze9IYkM*br76{Xyzb!z&iT!66Z1pa3WRvW5;Y|vcvGAq{{B_{TR%~=QVRH2O`4ZZz%Qb6Bw4)EUfn5Tq?Yx;1r3Q3yvoZG@~vU z%&>r|mlCSQC&>*h#^ZgIcl;rLwnScCjj*=eb5M%H=^EwP1ydtV)b70giFI6^W zK*&1FqF%`3r?b|<)K|V2^KH)4Et7HX;3A*wy09JB_sdo`!EM#-e`v5TD>J}F+2INl zFP7R?eup?oSYU0*%{Ynp6R<;hHFiUHIgIe77XZ&)X_2~^p~E%ezbB?`kSitT&ZgFM z+kUQZr++LYo+As<^=5<%^iy9AO_i6iYoTs~6_Rs_7sWxoG%vO3lUk16Jd)noHz2mG z?6&r#^WM}*nPLJ9(f#L!&5XQ&+Q8~>5n?L^;uv2v=eP~6q!;A zdmGoRqRC=^LR(`+P>HP?dx#TJTtE6bmIzYPy-MsKR50(E*LB)9wK`R#u~wL}HeOB$ z=5|dBCzA*3Uiis>Utm(oXzRh0Cf*u=>wiG@ci2}hyh%gkFr1XZO=q@2(!R%i;wQHL z&So69#Qg!oAMXA(5IUx9LI!TE0-oN!I1BkEv>?5+e%Z5;>B%c5z?t|bVpD9J-QqXX zs&tKxnBv=2+`lT-#9o$v2m-<_&QyHK#Zq+?{&t;ZoF{TN5IAPuKh=L|PXidC*p1cx z;bL8a5XW#c$wP!YwC=qb6}F^KaD^p)Wh`}lk51+?^S;G+H76BAZ;3G*s{uLJ=T2gl zcSefo+ML!?DZ~kRz4GSETxNeJf}qsU7w;{Hh=tio(=!&>H}(|!-PjUbEBbQT_W0dc zV_>_7wAD3;+J(#jVyJJV&WarSXSQGJnvB1Cx(b0wwkO{NfDyU*X}!lII~u=%qON>c zI8V&@x7zOks+0hj0l}?V+{O4`+^e6PFW%j1QG6-e z>>f4v5-zE)U2C0Su@>5?-&e(rw1jgHQ$u@;%E!pqhBW)KUHxFCi*~ROGM5enqgo_g z=<-iW*;BtaP@)vKnlYtIr7_K%b$?F_0sf!IW&RSsT0XXX#%l8vX02H&$!4r&k@x$k zq;^qm>F%8(gm|OIQ5h*R5QDdP<>cDAW$E#8yG|a)5R@V+6t%Xned-Hw`Rg(FXcXmBs4y4BMns7Df z_>c;|i!C{wcllh`ZqEDC%H6>DlAJM;lM3J0cq@KHHLR}qq5Omiz-NQBxlpXGlp;GTYKKm8^2LU?h^S!d}qyMKjeKG;F+k z#N)g1AFWbTz+(I+3Zgp!44{7NrA5e~oYVJ?cFu9HEYrY=0Qwkyz+E&5jN8+F1O`ms z8KAW{AKG8p#L-fw1YY{h?4t+6SOvlFW8o1b0x zc+o(lvW;IKYExc3-TDKmmjs0Ccz9a+#WcjFJI`VPv;%`fx#^5k z2PH0VE%}1Lv`0^BQN1-v$!xmuL_IdYwNZDz%)weokoxa09c@6S*&id{|3Vg>Effw^ObXW@?d6|E{-p$1{>Uxo$)I-FV!Xl1&I;@FyfwsMy7& zPl=Oln4ktU@(=h2hz7qT;mHh!f7W*UU|c6*4OUY$sC<)bZVq)l*Y}f8)s*E;+vh|w z2q~eBdnb9JGiZ)?_CnSsX1=m;$F7f4W5MH;nQUIh&)971{X>^n?rDzFytKg)W(uZw zQc`1f?PTlA*n7cz@nxwZDHA7WXNa9~i^jOlH%XL$=jpvy9RN~X*IuuOZzWlw6S*lX z1#ONpW4xQ?8R92R;E1#iUyLOz<)PKQH^(!hBG?81ZM&2){kw-q&t=7n9n{Z)LPyimyNx_NqeFpJG^$Cl>M_qto@pHmH>(lbC|fhD zj@G^`>3fa-B+#ot;Q{(@hN_Zaiy^a&sT&7oR>Glqaaa|K_4pAfP(Zd;XnxZ+bjY$3 zV@YLRW%0B3V_E2Tl{@G;IsO&21|Igb_ z*#Bp6+ zlyLj}wOyNeA5A}~2@HTB4Zny1#Nz)N-OFs>8yqjn7{vF{7-RkNU%wxSH};*jZ8IOZ zrzUcmfrr;R36<*WyEXQqvxX$gH@HU2u4D37J0!fB6wNe%V;x0rd@InHnM6O)scc83 zS)kuz6EnEp>Lb;yvnUTZC&nZS&oEZaxgz%b=SvSn*}fA{w(oxmZY@!ldu2G?rj~SF zk95tlxN5Xw3Ok@>*OQ?W2}^kiO!>d1re-F3i1W{TzVC%c%_T@g1CR;;&|xmhHf7y1 ze@v>hmA-Dw(W2X%*j9xCA5gRUXaHoP+xvrJKo@um06S$7JD{KF&kmp%TKo0uv~iq8 z;eW{3=BjZLQTFh5fQqRw6wCVeH1}i-rgHMYI)GNuq8L6YX9Oq-pjP&vFa~erR)Sn~ zlR@ejuaVNh87tllalOoJBw!c+_pXdkPV#%7yHpVRX>_MW-?SXfMlRDdMkmvD36g1O z;tRkh+#qto9{dA9>QE2;kG|=YVV8Dt1vm_I*K6d)49eY4@oQ@U0z`S-6Ck!=e)laI zt!UkWOp5YWs0?-Y-%PxFr~4;>>_Fo+dV%}zh!X=Md@JCb4Os30q9<3N-s$0W_n`x) zr23DK_3S=wZvsHrZr&f~g4r*KU{5PrP-6Yd#;{0USkuNo-s9i95eE$V0FIMeTG>Vk zTqfQ|vUwwG&{GpH3~a&7BCP*50{>sl{)ZsDhGnw~fEtm!r!Uy`fGgX*kR2vZYl?01 z?DRE8CqVIF<3%xiZ)mOg2f`2omq!#Jg2t-iAR={7SKN~&z3qqcy5=_ieCI!R-@{N+ z`&M#Uxn)D$jfKE|KT0vcFX6iD3)XB zV%l}9aKf?8*QA0J5B19e4F8bnx%(&1jzyrcxV&gd3+F9N7-su2H%-78HMs`-4-Vb_(NEj!O;xd3bUZ`CN zKOOMmAv$BF#We{~0SLNDSRWp3><4i}Akri`$crU5_LcLptb`9kqW3_6Bf!I1CwtKd zB##)mlYW7z&-Xo)^HTN`oy07%JEWDA4wU;N3KDFsfb5(mwZx^LFPgrSg*1FKRPHwX zf(cypzcP^NQ*zw1ArE)}4o4XUFRpMF9-G{M!}ZDG!yN9Ksqd!2C~d)V)#M+(=Ztlt zlMSsSxD&f;99@(x3yfH|nt!wm1M<$8P0hXCDHd8IOZvK7fB`%Svdj=okHnafyma!0IO+Lzj>4*E5n7$LDV!mXZd}UJUT@r< z8q+cUbiDm6#qSwNP&_O@DiAL>Y-MSEk~Lhqy~}?NvSJT!iAenl>ELd5Al6ar3;!Doa(?KG#wXY z^VP^3f&MhjhDP4bR~M-VuO6E*t|B_VzkOK#7^m?aXJFh}dB6P#4X+x*oRM(P!JbrF zYCKjt{qA8yN~a(WLAaczk#A`#g01SQXLR{nX;_JEw^%x%H|UAGWL~LC+=;u5h`d==RC0K8t`%+7>E3LW z-;*`U=Q}ub?NI_**CJVr4dB=b!b~t+Q+DVqpQWyPw}TKG=bfp9ms%F7b60;BUL(-K zB;<$`^2{KTODu&WG>_N)`m7w9yW^v|nO>mI`>dbpg$tc$pWEjO;476w z#b~~9wz16cDVWqPr}L`d zV6|}(;Hj1vz$~e?wcij#td)DhtTu)<{D|G11}3(7)Q=3dLi_YLXj62!5_F~6E~a&H zw9eyi+$@htBflREZfcJ0Lpyf=bZ5<4Qs)2vzwscAKe2DEY z&7SeL27Mx;Q(*S|-MTS7_Ujj4a`6XmY@w9u&WZuA{^AcEa78l?kor`1hSb`i)3Qs^ zZ26I#dgrBn)bktHmqYvB0+*}?=Uh4pYDZR6`6>erd?hFwbu6PAjS}&V&7(BUzGFG{ zC^IEU?ivt&G+JoxpPnHrp18MgT}0RIO2)&w@XAlvjQRcaXN|dC1<8sYuWZOrv8EJ# zl$J{vnFi~jsC{J!C+D=@pAC%Eofb@;oB_Os92~2;tC!rkt4?Pg5Ap?dvD7nM^_GJ% za)1q>afL$iMSoO5+kPXm3*l-9`X@IwzhD3?$D{w2YukH9}Zux1zaZ%0!= zBXYT6L(@h>V@d9pDa-5lpsk69h9R?S0O8zy#OYBp(Ao-Y%rlr^IEwc1q2tgc8VJ4b z>ZhLHM>SCwT8>uTf_4RIsiA%PUZH&1)?Y$NIFzBNHq58uE zUuXSyFg3LeR`L7Nw&OJ#8a7Ow*)=LKNuF@N?8jGJv}duDf{}&&ZmrJ@%Ip7_t(XGw zM`d~`-}f3HXp?Gf)jay};c-486`ewjN`!|c5{d3^d%qOmpwzfVE*jBRO0{>qHsejU z;WnzS`tYHb2(?a4-hyZd+KCz^0;`8MCtO^W?|3*rOOw#hfFCXPV+2j1H{X}iW;v*0 zTR?5+eyK-Fg!_nz_edv*HcnU&te)Hpco*s}BYT<=GI&IZb@uOoR|Cu9Jv(j4p!^hv zlbZsfrf&ThVJ(|;Y}?yk|Hpnq0UNO61x+}TdKeb!MLb0T$t0X;m|!4Y3o{qPb27rS zitr}8G!_ngd|?nXuk{cN8geAEr2JKF96mMRyDQLsw&b$;8pYdo4J^`bY>Y!cac709 ziGH&BT&~4w%%N!L)7VQrDm6-rnJaijgz@3N?Qo8YCHn*eR??ulN9g+edvDC29PKTi|iX?uIN@QaMLe>Je>jE`EQZ0=Zk82-2;-|bo8zCM?8%A&XNTTKa zNBDKR)h%pSERriw=*xQaX|n%Dz4AIHNp~&Rz0;v%RQ2vzGv(-OMxU*y66+ z`H8M9UU?+`vomyEz^G{eRRw9?aZKFKqknpbx?kyzkKdt*1JJ5I-6Gn3x*OVkp8;63 zB;FVP(vLmx)&-y4TODxMZlp;^C8dE*0dN>mJ01jlO8}A@6@T4r?B*bP@)+m-yo7Q+ z&@lfAeiogOAgiy6DZ$$)nH^y+We%JRzi>~~Z9%1Zq_S%ZJ`g59J*A-$`AowIR5FZf zGr?h1oD<{fFX52Beb!JOTyD~t`2;b`Pt<^4fl$#sVV%T^$E6pS*VJ$JYhhOjup&k_ z_L8YXS%y5r=-k^eV8Y)2a?ak372No?6Y@SpGQ9siMR%Kfhi24GR?@OjZcbGgDT2AK0DTfL-^JJ4w%g2@&)X?l6$HO{>C!I!X20 z2~C?nujiOF1_45ABCyt;S9~&e-r2=Ojs_!;#zi}!Rr2L&5;H2j4J^x3uF(|>bSw>Y!^B^uXM8AoV2ajeN;%Xjt~xBQCiS^KZX@aZcYO$$Z~#_= z#;M}TkW$@Bf}6pUg7KrwcgyAz{s%OkPNSiBGlcSd)6X5O3?+R47j%l~UrBUVk-*Tk znZ((Q%BgF}dG;5~6qRl24KKRdlGfQ!0lY`n$#p`NAn=osS@HT5oF7s-h-qjHW6dSW zAg7;spJVXv!Dd`w!s5L{0TxeP5ip=C{q(Pf z?W2&Z-yhTc2qeNGbDde=tM3<=;Cw-q)?=jd&j;@->3;?U!hY=0qM@a@I3n^}~r2Jzis=4G>|E z5;*|v23nMr;@>N-u|BQ)^0vj`>>9{Aix7^69(0@ny9x9$V9d)Ndn^NdaRoTZP7P2k zYGdHy+I0$?D*vUjiKyzrfR4l@lJ;IG5uOXgkpVGl)LJE%v^BW6?xT|P!GsGi5Z+Ls zJg}Rns6>>`q61a*jzxFsvD<=$a8t&8o6P3l*@~xo_vMl)8+m-Hy0;~K$6lxS^8eNP zsI0rb$EY4j#eKxu(4MG4*1;PZbAt0}z59SVR581bQb52^1tbd_N>~A+jWucn+(NRh zs1^tpGbthy@4AN=@)$@-Bj*TOC`1{8mVv$ls16_XQ$YRSdH-xc>RLxF*K0#EkL}VV z)W2X1nuL}n-~wrMXl%jmEf1(seVltW(Y-DMRr%to1JR{`$N|-?cx)1&>TC1^)dvPm z5!TTdbIeBEw82**olYoK`?(l#uhkra(tk-JeRz z8N&x@z#aiOBL1~!qU%IqU5~4#wHf+?mIv@0XfgPQ1MeTW7jLkjwtPz{RMunn44X#j z?y^EcSeYA1>`4rMVV{FZtL;EK!_b6)kC&t2FLd`>2x=f$t~EJt zx+L~BT~}$z13E?F*n3sPimaLqtp)oZjvc`VJjy-bNBlLz+-@%ad<1eye(&)V zOZ~GgqNN3L`=m` z5+5(7ob&Ih{(g?ARO`kScdZV8Z0lk3ldjXy>;zaf>kOOiNYJNq3u<$!ELgXNW>OF({bcw&0ddAxVftJ-*_ zE@BV*W90`r-}9oj^;e^Hhpa5Gg? zg_APXq=XmU$~pc#|G@}S8YKMsTpqR{B=a>{K?NJ+;u_T&%P*f#8YJA%MaBQiG6%%* zT$FN&l4L*q^WbRCwY*?Lbm}pDx1Xm;qh=%w@k9jDeuOAZPopsG45;J^yra&Xi>pL0 zgFaj!$0?VQ9V?wjUMI)8u7*q$2R)wr4se;W!kmjE<#t*uk%_F}=eMtrHhz^>Oha8k z(un9&tL2AIwbgH)rI0f!)a=|%(@^;GD(Wz?9Vx}&OvcCNCdEekCAZljl{hlZ3RP>9 zBN|Ev)U`q~xPZHcCQ7}+EY%a0jvk+&^72zfN6l%`wfL0I&81%L+?MSZ6KT+|!G?k| zyCLo8?bH9EC1BsO;8#e3%~F%-z7&(Bba-ZCe65R~$>VpPR#M%$69Gl8!hEvT)U*{q zNmp$3hP><$MZwH(TUeh=(T;I`d?!+HXV0e=~ z_p}q+-kwpiW5b)flj>QV-8Z|(Bpv=g_Q5$jUx8axpJYp-bjH01nFuy%7D2!Vu9)95 zJQ6My?Ow^bz1e8;*n_Mp*Gn~)q7!WD&3#0w$m88RnZ|-Nzfa?pps)URWg}${gqjk{ z0TE(ozNAA)r9zT77-W3`fUatczuRyk@>Ya)4s_Ee5F|NkGyh)^N3rDN}%3SE>v3)v)&O+serLb$AyW8_#Vgv^ZW zQXwH2&>x8HvWXM4Zj_vd3gkKkFm759eQT3oZ2phUHIh*^NTL_4W)+x zRMt5kiCxEy%X0=?L__Hlk9iBEXIu9-8)%3}BovgAS#scdeqz3um7jYy;P=b@iMJ2K zPSpd4{VYpjNF18`tZ;F4dopy0;qtltJW1Z%w7EEp&uJIT-JZgqKGZuw9~3tQjnBs# zG}rRsRL60esZxGdX^7@uvL#ucNObHc^^sV=9XzDz@ICO63ED`TI=I#x3F8873Pxw9 z&ABlBSQ8Uy|FXKCkRZ3#T-tFyM`*(S=pzy_Lfrd=-CMrSr7vu{^eejTN3wt06GW}z z{|>@`7QQ!KW{wkr!Fts1w~c!BI{a0tTF%%)i71s`GvqwX8Sy&9##fynT_l zeiMqBoTGXMLuWZ9Iy;VeBO*P;x4$lq;Zv>yE#+#c$QRH!unjljrtb zx8r@+kZf!OiuVmx79S5;o!VqVJ~`WCkih04Xhzh$B-Xh>e^e;#F39J-+&u0UWbaAB z+fl17a9V`t-e7EuwDOQAmJT|_(xW4jfkEjelH{X&6WK$zk`o?yc9ss@|Lw!7&QyC# zCon-i#}&LC-F-ae@7Zc7ayC>udsyIj#Dc3DIrj`@n@mFD+KsPIjA|4($A2bB+8#VlS8afQfVDDe zS_C+o=AXW=H7E+`j*i*XgtK~hmDkZssXVAYQ4@vc*t2C+*kyE%ZdG-qFd@T$)vhR8 z{<9OjOfXoYX2-92F)C6IBiPG>K6 zVCI?Gl2>0XyL44r67G>*u$VBSe`!jsoS1KveK7rdcsVZ}r*Znat?p*HlS%>Q)(fsU z`NV1+lWbnGq(VR zckK>Gcr_B<-FHUWhMvs!4HazTc(}#Jx$k1UttVE9XKN7M=IFcR^t9@mSn7|S)25;; z%hX8d|6=j=z!X2-BtSa0nVcHYR%az)ffup)pK`v>7(qJr1v@5kZid$yDk=<=lG*j+ zEzVtSSpbE+pqPNQ;h@sMy^1*wI*^Hc1xY<$2{K%Co{cB{2wxXJsQz*;xMHT1DoVQym7vgO?eb znbV=F5PK=n^ZV1Ni24d|p2~=y-LK>)6w+_3cb|&ToR41+*mk3bw?67);$TF4sXO;7$fk~eu~;! zX_3P`7pzUjsH;-K>kok=w#Tdn>Q3THa*}AIA&FTZu%5)ceVYT;~GL^Q4rqo;5|EeuOF%hf&j@ z6#_>pH_Fdrlkzkc;~6|6_ON{{g#m>m{L$IwS{SNho9Ev}|MDH}abzyzVBo;WnD9t0 zw-yQ#{{T3Ua8B}L(wa1e#dn?^Q$k-2TSpF4gItZu#Go{rJK0;j>j(PZ8GhttvLOPuBTf%#$qk}N8I1e*lN z;)2?vp$B~kAd0g!C~~UE-wxtHfV^8tEy;I@Zw{W0vM>U0iT?rc^L&;Y!EM3DOQ6S# zZ<5eF#RyI;B(B-xjC&QUka>jGDJsXPFu}$4TR2j|WmIU5e_4(VUF7V@o+xkNM(+y_ z+r!S7(Psl|)i>F6<#V2{;X&(X!@h}z1qtCWDToz7QjxpF9JZq!J%Mz-`k;G(f{kl; zm})~jg543KOL1)q1^+&rtZX&W;XNXj&rk$w<|%wlyvYWp2vr7q>v6n}07(FwrZezQ zYv1DRX?j7EvakP4*3;3;O_6X#AkKJM5NaV=-IQPMlFRL9U%T>nT1)15-R&TU+n49g z8ylOKX$Dno2{ps4K{Dat9_+O1Q`Q@QCv~N3Lyr5O(z-3wx40|1d6nS#DF5N<$Qa%J z(AS~LGzK>g-;xR6q2~N`+neCIRNBzFb1GYMVa$_Sm-u=im|a9khR zO=l=A_pF#;8D#cV$8*1~Jj)HcYsNoXKWBQO{ccV+K4^N*eRyEmc!V`oiTm8i6V?e| zQl$;=)3Dq z-{-$KYPjL&;To00cJ@NxXlDG?h{vTmMj^+})*KI<+TWt0B01zbf4$wuY}K!|CcQf& zc=_n)b-LTWZt_0cImV)wvgxhRP54OgFivlWgb-cjePzEkZm^^&F3yA2pU7UQrjjIY zb?g9BOoLw5CV$UhguC0^steuF9sURB*q+z=)vqo#+3_^A$9cJwzO|B-rTRJ`451a<~1!{*D<|iYx&qLM#Grbf$)=>$yz2OUBjj->Vo%1 zLtY%n(@==5-?nord!r#KX=rfi57}OCBF!!>Ue{<^+<3nsBbRKh`D5z$EsB79vtm&O zSpZ*XZLEWy813^Uf!qRqVZO3@UhA|v=Lq*>g7~~skX6N9Fs9*mek!i zQIK4zKVPxkpL2R|_ipDJRg%j;+B{$2a!HdW501s6Dc}~0ONJAt$f*_$0d;2!uF`AQ zw>;wnQ_b@4d)@KGKP(@uy|?$eKuuFv{G*SC3ubisWbOmI_lTxk7){H=sZw!k{;s6u z1+Js2Gy(l1ov&c-Fxn=l0o~IWQsQXmh)%|>JDuPpBnwg#4kw}Wo+W8E*!=d;MZBZP z}aj*U=zPgRM-Q)GxSejMYSKGg=SahhSFG5oMAc$hQtR|=Wa4;h_i zA0D?jva=QZjNGC#R>BUd%{aDb?;Pb4%*in-5$8etFB9s6D7}%gfmjfL=Necl1&S)7To0KrOkSg`6L*fW4W%cnJh%F zjrPW?;w&PU7C+(}j2xW8%xITvNRxUXp7E2{Jyy8|(5zG&NvV6hnqMVlW{*u3wQ|vP z?YQ^ul5t|mW~G%hiDXdn8mCXiU+vA$$iVqV*IhKB;h20{o=v5p%(JUaYdCEwbkyg@() z#&CI(xp=}pYToOjb_+l0J1gdo+u+D7EH76HFKI5ch+8J319E#(Lh_{Zd;_Zv%lXht z@k}H=S2@&pPQEvQ^tV zzi&vV@|)~^xp_z}Ji-zk+i`O3Qf9NO|7)DaVD2robZyS+TRK0aILA)^XrH0R&NVN% zx2DaQkZwzd{p+7U8m)luWH>f~o&_r$3)6}3-&$Foo%qq+%7kbc+!1`4o4QL}Bh!Bg zKbM$`1dA7qoZjTE*M}~0VGi^T@8PTCOrNu9{Lpg>hbm!*D0J%K!_3+plGaK4;lKVV z+Gc_=6YE}hHV(??wE0dB+tSE{uc>0n>u0F*r$_UhS?KSFyOhCPb5F9oeF;RTSf-U+L*!lkTH1Eu)vx$eGYLDfmTS2j@BL1nA+I-Z!FM)8bbjU{g zd+&`>bK!U9Z-PlkLT%GW6F&Pvmk77g`*?dsrvB2|R90y-ILd&3Q>kl@v5v*I zFOx#RJ*RV(;kiAGTLCfk&x^8TuDV&~-(Y>5+wKd~s$`vlvS~9{*{8pz?h5Mmf-Fjx zV&Y~qKy>8aV$YP5{J>;3Xk^ly5tzS~3hM$+(dqW>6xTL~?E!n((?r&W&72~PHbocf zJI{mBWXOn6Eo$TN@WHwJOX33#7Yqc~^dpk3dkz`QFrO=i&0;M?V=#U1oM$fnW5Kp9 zCc}r0R_ORIl`C%zkLKkRfnEE+ZWhzLfSOtkb{+-W7rZ;$Y`mL@r}@%J1JRAQEy{HY zD{SWnz%$E!ddZgS;D=xu9d>T}FX)_`(u<_BN`~v$=wx%{ zbOP__nX7bckF9v~N53pItKF-n#d`OdXjVsK=@9`l`!&`Md}|k&TwHA)!|&o@n2s(6heRf&3^jp&O`Bbj_wsz{pEIku?(4e z-V?q&b8qZ*I3}6ro-?SC*zV8O)u7k#>F4|md7WGbA!^K0!&+Q99x*yS<52CMF_QMs zBBJeU$OZ01kJ3r7W`CJO2Ja5$A_=JQ7b`Z{J4uI_5HG=F6r8@#=Xy`Utt2GK0UG>& z>TR8H15+J0(-W`0YIm8I7Rv>q^OaFAWah?<-?VQja zfA`?BT@d^DkG#Tyr`66`-nt*i1W^`_J6DU!y7tK=wpn2!mS_r$MaDrseZmUXV?Ar9 zSn=Wa2jyQi*`uG)FLLV1+s)A^jesncg*%&Z55lZkkvqOQycC4PxDHvzK`0HrlJfe- z47GdK1&=&Sd-%_P1!&CkPjM)pEQU_`>oMrQhz~xSgs;dxzHNpVY~%e2YX{KH!U6+u za6`L~Oo&+wrppVi@CR|8J2%+_EROh@sNV8Vx7VnHy(=Yyhn`B;EO&_(gDu zQxFxb@gU`5v}lcFe{F~P&@B%MZ1se!HLdUCU|x(&~^{kCaJD`QNScz>lAD7*4>9_H*FTMjHh9lP}C+ zns)*Q*vS+~)CjZWnj6PI#Zn3>psHWw$R{t zIP0VndPC6VMO*zN5^&@}k;|kd^BLAB2insGhL655_@G0UhERj zs`uygUI~|`dhKh~KYE(ggQ{OTJ$wgG(CovK$JHET!JeBp(igdAo9~-l-u`twCR6g1 zq(@uayi4Op0FG)WTdn?pPYUx+*G8gOy3;x`b}oN;bN?r9EIXRHB}z0pc zf|G~iNHSJ znl9ckt9f?%f&3SjtXkKD{u}-KN1pGio%MOypuNes7w&K2qZMQJrBD^+9XDJTE;Tpm zZof;sj@Na2U$mZ9#vqXRZ93>{Vz=m&!N!C*IN9HSJbt)*ZqW6^)$xa^<7p}@vh{BU`DXqKduAU6|NWvG?CBu_zdL|XT}El0tN4muZV{D z+KVTAJ>n~7;qP}f+0xTU%{;k&gXv93Q~C>AkKHXBO@r%aJ>5fE6qeRwvob~no3b_U zlXFNFh3UJ_dI*|J8SN;%Ic7o_2zP(}0`~d5BKMUzT_$)Glb1w?hNzs6t{qGDyft6G zZtJ-@tzq56`b;w^ZPj2Eti~UO>Wj5icGz9f^gof}W}0j4$~U*LO08MI{3s{qR*DFj zBhFp6m6<1Hr-4v-nvy#PmF}mTipsP{e3my_4Z5Y|-NEWB*4>-%fCHLvD?&C?7g*kg z=0nD!Pc%hx*rS-IT*WS(fyb|4PE=NQ^)J0JBuKs?$FXF)YQ3JOt6BQC4&C51+XWPF$ptibH(OHJfygcjC&&&3JDiA@DCY_u$vk#_1~nD>F?(?6y6(RYU|wV)#z`Xv z+}nNh0%S(fm0-O2vOO4kaX7(L7Mmc)(|iIU^)*f?wb!to&P4#rukoeh8?i=NPl96b zK51t{hHzGZ5lTI0Ca-je6<31Z*qY!J{mXpX*po4gOLs2qt$kv?Rw<-1J>gcn4d%kQ zaMnz>EhM!_)*-$6_pU5xtNG23Y_Q<%aUe80spK+Jg<}`lDhNOJ=^{~B@;8c%n8|I&D z&Xz1spl9~OF@rjg`-FuB9jQ-vV5@JE2sZ_G`O+2{>})hD5_(~uUbTN1cT+H8=>D4F zP3$LJ_aaf#H_nnx*WLg4>6O61d*M($<4kl?iA_s@V=>W;&iJu0op!>Ds2KbpsELG5 z@wq35Q&LD?cH?+^l8N;v$x0D)byH6du`6s?c~hLa_asMP&cy-e_JGvv<l94 zZ)JlPoFN(@KapsQrLkZkrwwrv&ZTR_e%%AJ1Vs{!F?@XDQ;a)VxyAgZN>BIWi`c`D zK55?MHIo0;b?J7;9@@Jvr1Gg$vNFSHL%V;r!m2vL$s1Z%pK_bqRiJsQxUO&@_iY*f zgdXOfSury(U38Q=UeZ*g2b*VhKMb+a2HEqdKs_T9MxJ_@gvf|ezYGGR67p{b@!u}M zdEpWWkgAUR>&SRsBkJierrjYpm-r=|9!(&Y@jV}*6pqD>XH+p?Eza#EkV@TGNxqboe9j2Tx!Ns@}*M4HF6H_x`4B83qX4oXx+TIiL>uyofk~pB zcM$6p=vn%b`gwoT&u2VM&*%3)x-F6;{A*z2_QmjvNI}J&!X6nFc9Nz_z$Ud9ZiUWK z!pIs1ii%?8WdrO6VnM>BpDYqxz>|FyH4(hbLH+HhD zvL`33w{`b{M;D2Wm9eSAVh;o8!LBO{dSae{L%Dml5)F@syrJCqt7{Npz~TfbY}}c+ zE;?kUM6+K}R>NJVFr_xGtGG6&3VDLnL2Kn7Ha3_XIDsk#UsPu5_LaXDgw1c$7Tex?q!3dVp~F^} zZgR%iG7WF*(F&&rsoOb3Fa>kD|MD28y8*`IxHe37t?2R+GnP*qT-{p(PHQ{k8WxsG zb)sG9{%gR&H{E}m+EvxU!5GZK<-u$O-W*B&YKAvud*m}J9q43}i7S-UnlZk};r;db;Hf=S-}D+@b0=Wi=(+?rY-4w)B*uJ@a1 z*PH)xxi@=(`$QEs_G@!_;oQbivPEK1Jim84$yb^5deq+Y36P{szu}9QM{;Wwn{zT8 z3qz+`a9)FncCuI)xb+pn*Ox~e_q{oZ5dc_IGFd?6WaU_nThyF{8>B3pi!mMd67bdY zu`eBmv&767B>R9-7wLGsUQb0f3D|Wn=!v29&2jfMkV|;$W&D+tb&mhwInP4-FExM1hr=s4IDYf!v_rB3;}H?#&lPg74E1VEZLw9DnP<@15<%_1 zHsgQ=8v+)ZrEmhnxngYj9O(<}#dZ$~{w_uBEYonQN)1yZvzbC_xGHg6S zkplq*oIO6k(m0e?l|?39mZkSz7{jHmsOU&Us@vAEVgmzlieLz%$6hS4tB!P3vvX)a zUl6C7b1OW~m0*gm)e|8YWdq<9SS#4}zfvXe2e^4buzmE=96Y=IczB7>ePjMv{J56K zCvKobc+)VIcwQy;7Py`dTV4Vs+um~@3&gkI1XG|5{v!* z0z1%f#0fN>6x!TleDxs?UM8tt*8LnlqC1nH>?UZLKl<_3*sitgCv1eA>E(modb zCPf{s!NS=bMPQ^=5&BzT+Fl~T$Da>|5pRm!wXu7~1KMG43BDb4L2X9kmSrmp3UToH zdrij374L&)6Hy&jovn{##uLIrCtgorE8NcSnD4qm;+KvDE>)4s5q-j!&L?{KbLI{X?{k@PuH^pB`uF;Ee$7ct-XKAe=jE_(aVdw{3i&SC-R$iemsB&BkZx% z8mmVi6f>?LpxD;fB$zJ z(X?^d?|h{t0BVlI*puPUp%ro+wHMF+mQCw7I zUdwK#>58KyFX9XK(EUSA%n(?03@n(CmPzl~)%!x_GVNIN@ji{pxv>h(mXn>(JCdky znRcpgaoCz?lBm@`Z4tXaWK=MxEV_z3b}JA(R!XBTqGid`lO7Tzx2TDW%elSQMrKVf zysQPU+%P(HbJVr7``3w-Vpld}OFzq=3gWB4Ld)_$G9qB8i^tKFV!@mXv~Fdw`ER}$p_l2n=E+Ph1t11BuU7dz5qK;sC1JIja8n4T3Io6RfF!D zxYP=@VF7D3L0OwwG$msN>nNeiFP=)fck;KP$M(-wkM4{fDUoYB2UU1IUgYeLOGtRY zt1wSnZ6apo6MWRYZQE#%aEesOrrbd@#j&Bb@=pp*2IWKO+Na+HnE9~K>sjt99=7XsnF+VZ_5p3En_(Tov)yo1XoGLU!thV z%NRzLQsL%}vxl9*#34#@G-43u<-7zOx1qobTYJV8F}Z0I$STw5=<@N(q*91 z`k=lwu{%92gNr4zWvae&4~}t?b0ceOwcDn>gz(3QqG8W*n-tgHaI;{Y^$AL9Oj$b3Zg%nPus{GG|hD4wPJz@$f@I`DY0jP z9$43en%IPqE58)(Jb!8ruYs^!N4|B388lDanYvowD?yF3q@NdqJc=?s9Dm4er9H;# z8i55g39L9An=aGmVvf&_LBTS;kwAN!X$c+2bXGiz7{YL5R=sYe9@e&aHwQ?ul$EL0 zSi(Y6djy5F@+PG06nvJsdtyFz27zF6TD~Pl8rZqddC~i74*sO>kJ_ejulAbkE^bk` zXJ?p_kO!xkiAuQRcdmWh@_`>pwCNQi2RyO6CUffvZq}G0{-uc(EHzxU-lq93v(?|} zgfJ8No}5l8>pw}NurS4qqR$Q9+dvDvI`~|tCU9N+@waZ(Qyuqc%4vBfp^!mGo6hkS z2Wz%zvk;g4G{%JAUQcC_FrFgxscz#j9spuOfK%=JkV z^x~R4Vn&ogl|jNDY-E*%&Ej#bF?eV$qKZ%3oZqI(0Pm=b5Z80XAWHTWRW?1Bn8hHp zJ~r#wsP&Jizo9;Z8_h$XLE1IK5-Z2@--_>~!%k5-5PMBsd%R9!CE&PFCKX2k%HAsP57R*98bnjS_6weFGOQoa+u|lg; zU^+U-+&}b`a@)^22VD{tWw1C-BEtoND@|`i5)ovoJ0^ZPhE-?*@FH2$UOP7FAU~%7 zseTU@pghxFM{xJPP*pAAG-x}+dd<>9eP+n2*2c_rIP}DMYLUWZUN_mc@}ITCg}C3xre^3r5NlMI9Pu57E#3qt|D7MRBUqz{(dnl2Rn9eu+GVuS z`)I!-Q6Dyhb0kw7tl-RunmSoWS2c=Uu{X5CP!Jt|4DBTl*f-UUxF-~^>nRQ6HfM~|xd%?o?bkkd3j zsP65h@@o>?m|<3Z)jFw^NW3JsFcJjOfP{3G6z>&EH5NspG#;5qPbeS$B5aJVZDR|Q z#bnQr`M*C5cq={V{yypY8Cx0+Z}P#%`6MvOiiw`yFiu^l->##_$C;*Nxn4G6RY7f3 z#@K%Fs-<;H17Vj6!=A8SNXwrUo+={}bGxIRid4C99^t|(fu8mdx|dXF(>^6MYFzf0 zP5Be+G&n~Gq}VSDjUdlFpgLNwugAf|y~Tetb`6ukc` zF6Kxu6@cS!Uy&B`b~!(5PFr6LU<@VnN%uOi8T*oh_rCwgsI=!vK%-l?N=aH@r`k^+ zu?NLe5M?DVI3aaQ6>}w$Q3?@+OAl+I&CJU(6LiBOO>fj>;qV9tt4x{bnPDNF4{NMa zkw+vvEB{REuz}%t0{cp^l=pV|0GoRjXG}eWC_Fphv;KcM($AQ(8I3N_CA`QjLOr9l z`H;h{_7KE`E_fslkPL-%jaxxb!~@!f$(1f<^)WPoQ zRS$cf`7sY~5A5ZoApzR%RGzR6shl5xU?`eFNT&?0KQCgAEFax`sLw=35mtivJ8wqu z1i7|Y4C`XjC=OLa^xAfEK=T#_Y;_b#ln)p!2HoXGB40hsgP!Ru#7>pJFG_Szoj)KF zec&35pHW*ExRy>=;&slIEo*mjwDZ?`H2=93;{V;s*qayY98}T@T`+a&-IEv0gV;<{szxqiqgOg0!@b+7Ay@P1yRU^zJRZuuE^;?hnC8HaI`hIa zST^QxTTk#cT_cTS<@h>H+jnd(McbEKjV zsDjuz#cVmP{>rw{%{21C^I+@hg4=~D;nhmTCa(=&!?i-HZvWbajn6la5G_)V#O~GY z;jCa@Vi$=sQu7@vpP@D@h=Mx8(}ljG4%XVO110tie%{~v{FTV2OWA#~ABsrHmixCG zkISz5^YjGpJz+1GFL1S)ph?-v%e2;9zLFjP!o6%P<-yP^y+tJMrCMv0tUe1a8tGFU z5qe>(snLt7gl@PFu%u2VKY!@MSD@RtaaHQ*17uX)XBH8^YQ!^f=tg{}1;@dw503UI zi?5qK+AZa=v9Y~-@5G_&Y>hwq&q>!MSf82qYCd4ZIq^$HPAkr9S4UJpquae^Cd^P9 zEapx3y-#as=ta=IRXV%TUxB_JSk#jA@YB^Z&qI}NaEx?z*9F>khR}9{bN0*E76ySy z5J(H836BbFcKy@e*NmLA2YpBGO15SBA5;OoQfB_dW8K)CkfFO1j~2H>kdUB0g-R8EqOE+#&x;)Q;6ej(oLg!8`V=03Slw-rkOd%l z-KnZ<{{7;hY^LERxx0e+W?$dgDk;x%3AMuy*oAqii&x$0lx?tMsM3>1L3qvf>g{7E2Xa?cc68EZEqRK_%0AbA>NW?Oq**WdOy1ea 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򡣭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

V8PN&x;LmR)Tt6IVIF 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
%CRbE&}O*m!S-zFMV|$mfiKfExx2ql8P0-N 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/(N-`#R1N+gAX6i=m&uW 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�$k{(Q4$S;HykODkGB`Ym&s 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

    dB-8nmGBC&X}w*zBj^QCQZzsH#fD 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%0DC_H>DZ;L8CzrZC42!3wTK{NHb-M7cPzu`B? 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 z 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 Date: Tue, 2 Dec 2025 11:16:35 -0800 Subject: [PATCH 064/162] docs: add comprehensive index to Stylus Rust SDK overview Add a well-organized documentation index to the Stylus Rust SDK overview page, making it easier for developers to navigate the reference section. The index includes: - Fundamentals: contract structure, global variables, contracts, testing - Data types: primitives, compound types, storage, type conversions - Advanced topics: Solidity differences, recommended packages, hostio - CLI usage: verification, ABI export, debugging, optimization - WASM concepts: WebAssembly, EVM differences, activation, caching - Troubleshooting and external references Each section includes brief descriptions to help users understand what they will find in each article. --- docs/stylus/reference/overview.md | 80 ++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/docs/stylus/reference/overview.md b/docs/stylus/reference/overview.md index 10443bde20..aa6c9400b7 100644 --- a/docs/stylus/reference/overview.md +++ b/docs/stylus/reference/overview.md @@ -4,6 +4,9 @@ description: 'An overview of the features provided by the Stylus Rust SDK' author: jose-franco sme: jose-franco sidebar_position: 1 +sidebar_label: 'Overview' +user_story: 'As a developer, I want to understand the Stylus Rust SDK structure so I can navigate the documentation effectively.' +content_type: 'reference' target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. --- @@ -13,6 +16,79 @@ The Stylus Rust SDK is built on top of [Alloy](https://www.paradigm.xyz/2023/06/ The Stylus Rust SDK has been audited in August 2024 at [commit #62bd831](https://github.com/OffchainLabs/stylus-sdk-rs/tree/62bd8318c7f3ab5be954cbc264f85bf2ba3f4b06) by Open Zeppelin which can be viewed [on our audits page](audit-reports.mdx). -This section contains a set of pages that describe a certain aspect of the Stylus Rust SDK, like how to work with [variables](https://stylus-by-example.org/basic_examples/variables), or what ways are there to [send ether](https://stylus-by-example.org/basic_examples/sending_ether). Additionally, there's also a page that compiles a set of [advanced features](/stylus/reference/rust-sdk-guide.md) that the Stylus Rust SDK provides. +## Documentation index -Finally, there's also a [Stylus by example](https://stylus-by-example.org) portal available that provides most of the information included in this section, as well as many different example contracts. +Use this index to navigate the Stylus Rust SDK reference documentation. + +### Fundamentals + +Learn the core concepts of writing smart contracts with the Stylus Rust SDK. + +| Article | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| [Structure of a contract](/stylus/reference/project-structure) | Understand how Rust contracts are organized, including project layout, the entrypoint macro, and public methods. | +| [Global variables and functions](/stylus/reference/global-variables-and-functions) | Access blockchain context through the VM interface, including message sender, block info, and cryptographic functions. | +| [Contracts](/stylus/reference/contracts) | Learn about contract basics, storage definition, method declarations, and the contract lifecycle. | +| [Writing tests](/stylus/how-tos/testing-contracts) | Write and run tests for your contracts using the built-in testing framework without deploying to a blockchain. | + +### Data types + +Understand how to work with different data types in Stylus contracts. + +| Article | Description | +| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| [Primitives](/stylus/reference/data-types/primitives) | Use Rust primitive types (bool, integers, addresses) with automatic ABI encoding and Solidity type mappings. | +| [Compound types](/stylus/reference/data-types/compound-types) | Work with complex data structures including arrays, vectors, tuples, and custom structs. | +| [Storage](/stylus/reference/data-types/storage) | Define and manage persistent contract state using storage types and the storage macro. | +| [Conversions between types](/stylus/reference/data-types/conversions-between-types) | Convert between Rust types and Solidity-compatible types for cross-contract communication. | + +### Advanced topics + +Explore advanced features and optimization techniques for Stylus development. + +| Article | Description | +| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [Solidity differences](/stylus/advanced/solidity-differences) | Understand key differences between writing smart contracts in Solidity versus Stylus Rust. | +| [Recommended packages](/stylus/advanced/recommended-libraries) | Discover third-party Rust crates that work well with Stylus for extended functionality. | +| [Minimal entrypoint contracts](/stylus/advanced/minimal-entrypoint-contracts) | Build lightweight contracts with custom entrypoints for maximum gas efficiency. | +| [Hostio exports](/stylus/advanced/hostio-exports) | Access low-level host I/O functions for advanced contract behavior. | + +### Using the CLI + +Master the `cargo stylus` command-line tool for contract development and deployment. + +| Article | Description | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| [Verify contracts](/stylus/how-tos/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | +| [Exporting ABI](/stylus/how-tos/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | +| [Debugging with replay](/stylus/how-tos/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | +| [Optimizing WASM binary size](/stylus/how-tos/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | +| [Deploying non-Rust WASM contracts](/stylus/how-tos/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | + +### WASM concepts + +Understand how WebAssembly works within Arbitrum Nitro and its implications for Stylus development. + +| Article | Description | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | +| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | +| [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | +| [Caching strategy](/stylus/how-tos/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | + +### Troubleshooting + +| Article | Description | +| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| [Troubleshooting](/stylus/troubleshooting-building-stylus) | Find solutions to common issues encountered when building and deploying Stylus contracts. | + +### External references + +Additional resources for Stylus development. + +| Resource | Description | +| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| [Stylus by Example](https://stylus-by-example.org/) | Learn Stylus through practical, annotated code examples covering common patterns. | +| [Cargo Stylus CLI GitHub](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) | Source code and documentation for the `cargo stylus` command-line tool. | +| [Rust SDK Crate](https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html) | Official API documentation for the Stylus SDK on docs.rs. | +| [Source Code Repository](https://github.com/OffchainLabs/stylus-sdk-rs) | Browse the complete source code for the Stylus Rust SDK. | From 56b938083d6ff1f3ff02c27baf6370ab5550e5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 10:23:20 -0800 Subject: [PATCH 065/162] change extension from .md to .mdx for stylus overview doc --- docs/stylus/reference/{overview.md => overview.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/stylus/reference/{overview.md => overview.mdx} (100%) diff --git a/docs/stylus/reference/overview.md b/docs/stylus/reference/overview.mdx similarity index 100% rename from docs/stylus/reference/overview.md rename to docs/stylus/reference/overview.mdx From b040478c7f3f350a07ffbe7527382b5e952fc848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 10:56:18 -0800 Subject: [PATCH 066/162] docs: enrich Stylus contracts reference with delegate calls, sending ether, factory patterns, modifiers, and struct inheritance --- docs/stylus/reference/contracts.mdx | 720 ++++++++++++++++++++++++++++ 1 file changed, 720 insertions(+) diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx index 0b23a35abb..6f6ba7befe 100644 --- a/docs/stylus/reference/contracts.mdx +++ b/docs/stylus/reference/contracts.mdx @@ -1106,6 +1106,726 @@ pub fn raw_call(&mut self, token: Address, to: Address, amount: U256) -> Vec } ``` +## Delegate calls + +Delegate calls allow a contract to execute code from another contract while maintaining its own context. When Contract A executes a delegate call to Contract B, B's code runs using Contract A's storage, `msg.sender`, and `msg.value`. This means any state changes affect Contract A, and the original sender and value of the transaction are preserved. + +This pattern is essential for building upgradeable contracts, proxy patterns, and modular smart contract systems. + +### Using the low-level `delegate_call` function + +The `delegate_call` function is a low-level operation similar to `call` and `static_call`. It is considered unsafe because it requires trusting the external contract to maintain safety. + +```rust +pub unsafe fn delegate_call( + context: impl MutatingCallContext, + to: Address, + data: &[u8], +) -> Result, Error> +``` + +**Example usage:** + +```rust +use stylus_sdk::call::delegate_call; + +pub fn low_level_delegate_call( + &mut self, + calldata: Vec, + target: Address, +) -> Result, DelegateCallErrors> { + unsafe { + let result = delegate_call(self, target, &calldata) + .map_err(|_| DelegateCallErrors::DelegateCallFailed(DelegateCallFailed {}))?; + Ok(result) + } +} +``` + +### Using `RawCall` with `new_delegate()` + +For scenarios requiring untyped calls with more configuration options, `RawCall` offers a fluent interface. You can set up a delegate call by chaining optional configuration methods. + +```rust +use stylus_sdk::call::RawCall; + +pub fn raw_delegate_call( + &mut self, + calldata: Vec, + target: Address, +) -> Result, Vec> { + let data = RawCall::new_delegate() // Configure a delegate call + .gas(2100) // Supply 2100 gas + .limit_return_data(0, 32) // Only read the first 32 bytes back + .call(target, &calldata)?; + + Ok(data) +} +``` + +### Safety considerations + +:::caution +Delegate calls are inherently unsafe and require careful consideration before use. +::: + +- **Trust requirement**: The calling contract must trust the external contract to uphold safety requirements +- **Storage modification**: The external contract can arbitrarily change the calling contract's storage +- **Ether spending**: The external contract may spend ether or perform other critical operations on behalf of the caller +- **Cache clearing**: While the `delegate_call` function clears any cached values, it cannot prevent unsafe actions by the external contract + +### Complete delegate call example + +```rust +#![cfg_attr(not(feature = "export-abi"), no_main)] +extern crate alloc; + +use alloy_sol_types::sol; +use stylus_sdk::{ + alloy_primitives::Address, + call::{delegate_call, RawCall}, + prelude::*, +}; + +#[storage] +#[entrypoint] +pub struct DelegateExample; + +sol! { + error DelegateCallFailed(); +} + +#[derive(SolidityError)] +pub enum DelegateCallErrors { + DelegateCallFailed(DelegateCallFailed), +} + +#[public] +impl DelegateExample { + // Low-level delegate call + pub fn low_level_delegate_call( + &mut self, + calldata: Vec, + target: Address, + ) -> Result, DelegateCallErrors> { + unsafe { + let result = delegate_call(self, target, &calldata) + .map_err(|_| DelegateCallErrors::DelegateCallFailed(DelegateCallFailed {}))?; + + Ok(result) + } + } + + // RawCall delegate call with configuration + pub fn raw_delegate_call( + &mut self, + calldata: Vec, + target: Address, + ) -> Result, Vec> { + let data = RawCall::new_delegate() + .gas(2100) + .limit_return_data(0, 32) + .call(target, &calldata)?; + + Ok(data) + } +} +``` + +## Sending ether + +Stylus provides multiple ways to send ether from a contract. Unlike Solidity's `transfer` method which is capped at 2300 gas, Stylus's `transfer_eth` forwards all gas to the recipient. You can cap gas using the low-level `call` method if needed. + +### Methods for sending ether + +| Method | Description | Gas behavior | +| ------------------------ | --------------------------------------- | ------------------------------- | +| `transfer_eth()` | Simple ether transfer | Forwards all gas | +| `call()` with `.value()` | Low-level call with value | Forwards all gas (configurable) | +| Payable external calls | Call payable methods on other contracts | Forwards all gas (configurable) | + +### Using `transfer_eth()` + +The simplest way to send ether: + +```rust +use stylus_sdk::call::transfer_eth; + +#[public] +impl SendEther { + #[payable] + pub fn send_via_transfer(to: Address) -> Result<(), Vec> { + transfer_eth(to, msg::value())?; + Ok(()) + } +} +``` + +### Using low-level `call()` with value + +For more control over the transfer: + +```rust +use stylus_sdk::call::{call, Call}; + +#[public] +impl SendEther { + #[payable] + pub fn send_via_call(&mut self, to: Address) -> Result<(), Vec> { + call(Call::new_in(self).value(msg::value()), to, &[])?; + Ok(()) + } +} +``` + +These two approaches are equivalent under the hood: + +```rust +// These are equivalent: +transfer_eth(recipient, value)?; +call(Call::new_in(self).value(value), recipient, &[])?; +``` + +### Sending with a gas limit + +To cap the gas forwarded to the recipient (similar to Solidity's `transfer`): + +```rust +#[payable] +pub fn send_via_call_gas_limit(&mut self, to: Address, gas_amount: u64) -> Result<(), Vec> { + call( + Call::new_in(self).value(msg::value()).gas(gas_amount), + to, + &[], + )?; + Ok(()) +} +``` + +### Sending with calldata + +To trigger a fallback function on the receiving contract: + +```rust +use stylus_sdk::abi::Bytes; + +#[payable] +pub fn send_via_call_with_calldata( + &mut self, + to: Address, + data: Bytes, +) -> Result<(), Vec> { + call(Call::new_in(self).value(msg::value()), to, data.as_slice())?; + Ok(()) +} +``` + +### Sending to payable contract methods + +Use typed interfaces to call payable methods on other contracts: + +```rust +sol_interface! { + interface ITarget { + function receiveEther() external payable; + } +} + +#[public] +impl SendEther { + #[payable] + pub fn send_to_contract(&mut self, to: Address) -> Result<(), Vec> { + let target = ITarget::new(to); + let config = Call::new_in(self).value(msg::value()); + target.receive_ether(config)?; + Ok(()) + } +} +``` + +### Where you can send ether + +1. **Externally owned account (EOA) addresses**: Directly send ether to any EOA address +2. **Solidity contracts with `receive()` function**: Send ether without calldata to contracts implementing `receive()` +3. **Solidity contracts with `fallback()` function**: Send ether with calldata to contracts implementing `fallback()` +4. **Contracts with payable methods**: Call any payable method on Solidity or Stylus contracts + +### Complete sending ether example + +```rust +#![cfg_attr(not(any(feature = "export-abi", test)), no_main)] +extern crate alloc; + +use alloy_primitives::Address; +use stylus_sdk::{ + abi::Bytes, + call::{call, transfer_eth, Call}, + msg, + prelude::*, +}; + +sol_interface! { + interface ITarget { + function receiveEther() external payable; + } +} + +#[storage] +#[entrypoint] +pub struct SendEther; + +#[public] +impl SendEther { + // Simple transfer + #[payable] + pub fn send_via_transfer(to: Address) -> Result<(), Vec> { + transfer_eth(to, msg::value())?; + Ok(()) + } + + // Low-level call + #[payable] + pub fn send_via_call(&mut self, to: Address) -> Result<(), Vec> { + call(Call::new_in(self).value(msg::value()), to, &[])?; + Ok(()) + } + + // With gas limit + #[payable] + pub fn send_via_call_gas_limit(&mut self, to: Address, gas_amount: u64) -> Result<(), Vec> { + call( + Call::new_in(self).value(msg::value()).gas(gas_amount), + to, + &[], + )?; + Ok(()) + } + + // With calldata (triggers fallback) + #[payable] + pub fn send_via_call_with_calldata( + &mut self, + to: Address, + data: Bytes, + ) -> Result<(), Vec> { + call(Call::new_in(self).value(msg::value()), to, data.as_slice())?; + Ok(()) + } + + // To payable contract method + #[payable] + pub fn send_to_contract(&mut self, to: Address) -> Result<(), Vec> { + let target = ITarget::new(to); + let config = Call::new_in(self).value(msg::value()); + target.receive_ether(config)?; + Ok(()) + } +} +``` + +## Factory contract deployment (coming soon) + +The factory pattern allows a contract to deploy other contracts programmatically. This is useful for creating contract instances on-demand, such as deploying new token contracts or creating user-specific vaults. + +:::note +Advanced deployment patterns documentation is in development. This section will cover: + +- Deploying contracts from within a contract +- Passing constructor arguments +- Deterministic deployment with CREATE2 +- Handling deployment failures + ::: + +**Constructor considerations for factory-deployed contracts:** + +When a contract is deployed via a factory contract (rather than directly by an EOA), the `msg_sender()` in the constructor will be the factory contract's address, not the original deployer. If you need the original deployer's address, use `tx_origin()` instead: + +```rust +#[public] +impl FactoryDeployedContract { + #[constructor] + pub fn constructor(&mut self) { + // msg_sender() = factory contract address + // tx_origin() = original transaction sender (EOA) + let original_deployer = self.vm().tx_origin(); + self.owner.set(original_deployer); + } +} +``` + +## Function modifiers and access control patterns + +Unlike Solidity, Rust does not have built-in modifier syntax. However, you can achieve similar functionality using helper functions that return `Result<(), Error>` combined with the `?` operator. + +### Basic modifier pattern + +Create helper functions that perform checks and return early on failure: + +```rust +sol! { + error Unauthorized(); + error Paused(); +} + +#[derive(SolidityError)] +pub enum ContractError { + Unauthorized(Unauthorized), + Paused(Paused), +} + +#[public] +impl MyContract { + // Modifier-like helper function + fn only_owner(&self) -> Result<(), ContractError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(ContractError::Unauthorized(Unauthorized {})); + } + Ok(()) + } + + // Using the "modifier" with the ? operator + pub fn admin_function(&mut self) -> Result<(), ContractError> { + self.only_owner()?; // Returns early if check fails + + // Admin logic here... + Ok(()) + } +} +``` + +### Multiple guard functions + +You can combine multiple checks by chaining helper functions: + +```rust +#[public] +impl MyContract { + fn only_owner(&self) -> Result<(), ContractError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(ContractError::Unauthorized(Unauthorized {})); + } + Ok(()) + } + + fn when_not_paused(&self) -> Result<(), ContractError> { + if self.paused.get() { + return Err(ContractError::Paused(Paused {})); + } + Ok(()) + } + + fn only_after(&self, timestamp: u64) -> Result<(), ContractError> { + if self.vm().block_timestamp() < timestamp { + return Err(ContractError::TooEarly(TooEarly {})); + } + Ok(()) + } + + // Combining multiple "modifiers" + pub fn protected_action(&mut self) -> Result<(), ContractError> { + self.only_owner()?; + self.when_not_paused()?; + self.only_after(self.unlock_time.get())?; + + // Protected logic here... + Ok(()) + } +} +``` + +### Reusable access control module + +For larger projects, encapsulate access control in a reusable module: + +```rust +// Access control helpers +impl MyContract { + fn require_role(&self, role: FixedBytes<32>, account: Address) -> Result<(), ContractError> { + if !self.has_role(role, account) { + return Err(ContractError::MissingRole(MissingRole { role, account })); + } + Ok(()) + } + + fn has_role(&self, role: FixedBytes<32>, account: Address) -> bool { + self.roles.getter(role).get(account) + } + + // Grant role (admin only) + pub fn grant_role( + &mut self, + role: FixedBytes<32>, + account: Address, + ) -> Result<(), ContractError> { + self.require_role(self.admin_role(), self.vm().msg_sender())?; + self.roles.setter(role).setter(account).set(true); + Ok(()) + } +} +``` + +### Complete access control example + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::prelude::*; + +sol! { + error Unauthorized(); + error Paused(); + error InvalidAmount(); +} + +#[derive(SolidityError)] +pub enum VaultError { + Unauthorized(Unauthorized), + Paused(Paused), + InvalidAmount(InvalidAmount), +} + +sol_storage! { + #[entrypoint] + pub struct Vault { + address owner; + bool paused; + mapping(address => uint256) balances; + } +} + +#[public] +impl Vault { + // Modifier-like helpers + fn only_owner(&self) -> Result<(), VaultError> { + if self.vm().msg_sender() != self.owner.get() { + return Err(VaultError::Unauthorized(Unauthorized {})); + } + Ok(()) + } + + fn when_not_paused(&self) -> Result<(), VaultError> { + if self.paused.get() { + return Err(VaultError::Paused(Paused {})); + } + Ok(()) + } + + fn valid_amount(&self, amount: U256) -> Result<(), VaultError> { + if amount == U256::ZERO { + return Err(VaultError::InvalidAmount(InvalidAmount {})); + } + Ok(()) + } + + // Public functions using modifiers + #[payable] + pub fn deposit(&mut self) -> Result<(), VaultError> { + self.when_not_paused()?; + + let sender = self.vm().msg_sender(); + let amount = self.vm().msg_value(); + self.valid_amount(amount)?; + + let current = self.balances.get(sender); + self.balances.setter(sender).set(current + amount); + Ok(()) + } + + pub fn pause(&mut self) -> Result<(), VaultError> { + self.only_owner()?; + self.paused.set(true); + Ok(()) + } + + pub fn unpause(&mut self) -> Result<(), VaultError> { + self.only_owner()?; + self.paused.set(false); + Ok(()) + } +} +``` + +## Struct inheritance with `#[inherit]` (legacy pattern - subject to change) + +:::note +This section covers the legacy `#[inherit]` pattern. The trait-based composition pattern described in the [Contract composition and inheritance](#contract-composition-and-inheritance) section is the preferred approach for new contracts. +::: + +The Stylus Rust SDK provides an `#[inherit]` macro that replicates Solidity's composition pattern. The `#[public]` macro provides the `Router` trait, which can be used to connect types via inheritance. + +### Basic inheritance + +Use `#[inherit]` to include methods from another type: + +```rust +#[public] +#[inherit(Erc20)] +impl Token { + pub fn mint(&mut self, amount: U256) -> Result<(), Vec> { + // Token-specific logic + Ok(()) + } +} + +#[public] +impl Erc20 { + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } +} +``` + +In this example, `Token` inherits the public methods from `Erc20`. If someone calls the `Token` contract with the `balanceOf` selector, the function `Erc20::balance_of()` executes. + +### Using `#[borrow]` for storage access + +The inheriting type must implement the `Borrow` trait for borrowing data from the inherited type. The `#[borrow]` annotation simplifies this: + +```rust +sol_storage! { + #[entrypoint] + pub struct Token { + #[borrow] + Erc20 erc20; + uint256 cap; + } + + pub struct Erc20 { + mapping(address => uint256) balances; + uint256 total_supply; + } +} +``` + +### Method resolution order + +When a method is called, Stylus searches for it in this order: + +1. The entrypoint struct itself +2. Inherited types, in order of declaration +3. Types inherited by those types (depth-first search) + +```rust +#[public] +#[inherit(B, C)] +impl A { + pub fn foo() -> Result<(), Vec> { /* ... */ } +} + +#[public] +impl B { + pub fn bar() -> Result<(), Vec> { /* ... */ } +} + +#[public] +impl C { + pub fn bar() -> Result<(), Vec> { /* ... */ } + pub fn baz() -> Result<(), Vec> { /* ... */ } +} +``` + +In this example: + +- Calling `foo()` executes `A::foo()` (found in A) +- Calling `bar()` executes `B::bar()` (found in B first, C's version is never reached) +- Calling `baz()` executes `C::baz()` (not found in A or B, found in C) + +### Method overriding + +Because methods are checked in inheritance order, a method in the higher-level type overrides methods with the same name in lower levels: + +```rust +#[public] +#[inherit(B)] +impl A { + pub fn foo() -> Result<(), Vec> { + // This version will be called + Ok(()) + } +} + +#[public] +impl B { + pub fn foo() -> Result<(), Vec> { + // This version is never reached + Ok(()) + } +} +``` + +:::caution +The Stylus Rust SDK does not currently contain explicit `override` or `virtual` keywords. Carefully ensure your contracts only override the intended functions. Unintentional method shadowing can lead to unexpected behavior. +::: + +### Limitations + +- **No multi-inheritance**: A single contract cannot inherit from multiple unrelated types that both need storage access +- **No explicit override/virtual**: Method overriding is implicit based on declaration order +- **Subject to change**: This pattern may evolve in future SDK versions + +### Complete inheritance example + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloy_primitives::{Address, U256}; +use stylus_sdk::prelude::*; + +sol_storage! { + #[entrypoint] + pub struct Token { + #[borrow] + Erc20 erc20; + address owner; + } + + pub struct Erc20 { + mapping(address => uint256) balances; + uint256 total_supply; + } +} + +#[public] +#[inherit(Erc20)] +impl Token { + pub fn mint(&mut self, to: Address, amount: U256) -> Result<(), Vec> { + // Token adds minting capability + let current = self.erc20.balances.get(to); + self.erc20.balances.setter(to).set(current + amount); + let supply = self.erc20.total_supply.get(); + self.erc20.total_supply.set(supply + amount); + Ok(()) + } +} + +#[public] +impl Erc20 { + pub fn balance_of(&self, account: Address) -> U256 { + self.balances.get(account) + } + + pub fn total_supply(&self) -> U256 { + self.total_supply.get() + } + + pub fn transfer(&mut self, to: Address, amount: U256) -> Result> { + let from = self.vm().msg_sender(); + let from_balance = self.balances.get(from); + if from_balance < amount { + return Ok(false); + } + self.balances.setter(from).set(from_balance - amount); + let to_balance = self.balances.get(to); + self.balances.setter(to).set(to_balance + amount); + Ok(true) + } +} +``` + ## See Also - [Primitives](./data-types/primitives.mdx) - Basic data types From 21bc1e178c00247f004d38325dfd38c401c638af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 13:05:09 -0800 Subject: [PATCH 067/162] fix broken link --- docs/stylus/gentle-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index f4e9b8b3d4..78e760cdde 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -45,7 +45,7 @@ While many developers will be drawn to new use cases, rebuilding existing applic ### Getting Started -1. Utilize our [quickstart](/stylus/quickstart.mdx), [Rust SDK](/stylus/reference/overview.md), to help you start building. +1. Utilize our [quickstart](/stylus/quickstart.mdx), [Rust SDK](/stylus/reference/overview.mdx), to help you start building. 2. Join our Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for support as well as the official Arbitrum ([@Arbitrum](https://twitter.com/arbitrum)) and Arbitrum Developers ([@ArbitrumDevs](https://twitter.com/ArbitrumDevs)) X accounts for announcements. 3. Check out the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for various community contributed Stylus projects and tools. If you build something useful, we'd be happy to add it there. 4. Stay updated with the latest from the Stylus community through tutorials, builder interviews, technical deep dives, and more with the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter. From 0097162ba3fafb4245a183eecd18bb6a77c037f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 13:05:25 -0800 Subject: [PATCH 068/162] remove unneeded cli-tools-overview.md --- docs/stylus/cli-tools-overview.md | 43 ------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 docs/stylus/cli-tools-overview.md diff --git a/docs/stylus/cli-tools-overview.md b/docs/stylus/cli-tools-overview.md deleted file mode 100644 index ba9675b99d..0000000000 --- a/docs/stylus/cli-tools-overview.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: cli-tools-overview -title: CLI Tools (cargo-stylus) -sidebar_label: CLI tools overview ---- - -The CLI tools provided for Stylus, specifically the `cargo-stylus` tool, are designed to help developers manage, compile, and optimize their Stylus contracts efficiently. This overview provides a summary of the tools available and how to use them effectively. - -## Available tools - -### 1. Optimize WASM binaries - -The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. - -- **[Optimize WASM binaries](/stylus/how-tos/optimizing-binaries.mdx):** Learn how to optimize your WASM binaries for performance and size. - -### 2. Debug Stylus transactions - -Gain insights into your Stylus contracts by debugging transactions. - -- **[Debug Stylus transactions](/stylus/how-tos/debugging-tx.mdx):** A guide to debugging transactions, helping you identify and fix issues. - -### 3. Verify contracts - -Ensure that your Stylus contracts are correctly verified. - -- **[Verify contracts](/stylus/how-tos/verifying-contracts.mdx):** Step-by-step instructions on how to verify your contracts using `cargo-stylus`. - -## Source code repository - -The source code for `cargo-stylus` is available on GitHub. Explore the code, contribute, or use it as a reference. - -- **[cargo-stylus repository](https://github.com/OffchainLabs/stylus):** Visit the GitHub repository for more information. - -## Additional resources - -For more advanced usage and detailed guides, refer to the following resources: - -- **[Optimize WASM binaries](/stylus/how-tos/optimizing-binaries.mdx)** -- **[Troubleshooting](/stylus/troubleshooting-building-stylus.md)** -- **[Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx)** - -This overview page serves as the starting point for mastering the CLI tools available for Stylus development. From optimizing your contracts to debugging and verifying them, the `cargo-stylus` toolset is integral to a smooth development experience. From 8170119be050c77bba2138777fe6bd0cbd77a9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 13:16:43 -0800 Subject: [PATCH 069/162] change gentle introduction tone --- docs/stylus/gentle-introduction.mdx | 79 +++++++++++++++++++---------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 78e760cdde..a4bb3621ad 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -1,51 +1,78 @@ --- id: gentle-introduction title: 'A gentle introduction to Stylus' -description: 'An educational introduction that provides a high-level understanding of Stylus, a new way to write EVM-compatible smart contracts using your favorite programming languages.' +description: 'An introduction to Stylus, which enables writing EVM-compatible smart contracts in programming languages that compile to WASM, such as Rust, C, and C++.' author: amarrazza sme: amarrazza target_audience: 'Developers who want to build on Arbitrum using popular programming languages, like Rust' sidebar_position: 1 -displayed_sidebar: buildStylusSidebar +displayed_sidebar: buildAppsSidebar --- import ImageZoom from '@site/src/components/ImageZoom'; ### In a nutshell: -- Stylus lets you write smart contracts in programming languages that compile to WASM, such as **Rust, C, C++, and many others**, allowing you to tap into their ecosystem of libraries and tools. Rich language and tooling support already exist for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). -- Solidity contracts and Stylus contracts are **fully interoperable**. In Solidity, you can call a Rust program and vice versa. -- Stylus contracts offer **faster execution and lower gas fees** for memory and compute-intensive operations, they also enable complex computation Solidity doesn't support. +- Stylus lets you write smart contracts in programming languages that compile to WASM, such as Rust, C, C++, and others, allowing you to use their ecosystem of libraries and tools. Language and tooling support exists for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). +- Solidity contracts and Stylus contracts are interoperable. In Solidity, you can call a Rust program and vice versa, thanks to a second, coequal WASM virtual machine. +- Stylus contracts offer reduced gas costs for memory and compute-intensive operations because WASM programs execute more efficiently than EVM bytecode for these workloads. ### What's Stylus? -Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. We call this paradigm MultiVM. +Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. This paradigm is called MultiVM because it is additive to existing functionality. -This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a modern binary format popularized by its use in major web standards, browsers, and companies to speed up computation. WASM is built to be fast, portable, and human-readable. It has sandboxed execution environments for security and simplicity. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fully functioning fraud proofs. +This second virtual machine executes WebAssembly (WASM) rather than EVM bytecode. WASM is a binary format used in web standards and browsers for efficient computation. Its design is to be portable and human-readable, with sandboxed execution environments for security. Working with WASM is nothing new for Arbitrum chains. Ever since the [Nitro upgrade](https://medium.com/offchainlabs/arbitrum-nitro-one-small-step-for-l2-one-giant-leap-for-ethereum-bc9108047450), WASM has been a fundamental component of Arbitrum's fraud proofs. -With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile into WASM, some compilers are more suitable for smart contract development than others, like Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and Javascript, are more complex for Stylus to support, although not impossible. Compared to Solidity, WASM programs are more efficient for memory-intensive applications. There are many reasons for this, including the decades of compiler development for Rust and C. WASM also has a faster runtime than the EVM, resulting in faster execution. Third-party contributions in the form of libraries for new and existing languages are welcomed! +With a WASM VM, any programming language compilable to WASM is within Stylus's scope. While many popular programming languages can compile to WASM, some compilers are better suited to smart contract development than others, such as Rust, C, and C++. Other languages like Go, Sway, Move, and Cairo are also supported. Languages that include their own runtimes, like Python and JavaScript, are more complex for Stylus to support, although not impossible. WASM programs tend to be more efficient than EVM bytecode for memory-intensive applications. This efficiency comes from mature compiler toolchains for languages like Rust and C, which have benefited from decades of optimization work. The WASM runtime also executes faster than the EVM interpreter. Third-party contributions in the form of libraries for new and existing languages are welcome. -### Use Cases +### How Stylus works -While many developers will be drawn to new use cases, rebuilding existing applications in Stylus will also open the door to innovation and optimization. dApps have never been faster, cheaper, or safer. Stylus can integrate easily into existing Solidity projects by calling a Stylus contract to optimize specific parts of your dApp or building the entire dApp with Stylus. It's impossible to list all of the use cases Stylus enables; think about the properties of all WASM-compatible languages! That said, here are some particularly exciting ideas: +Bringing a Stylus program to life involves four stages: coding, activation, execution, and proving. The following sections describe each step. -- **Efficient Onchain Verification with ZK-Proofs**: Enable cost-effective onchain verification - using zero-knowledge proving systems for privacy, interoperability, and more (see [case - study](https://blog.arbitrum.io/renegade-stylus-case-study/)). -- **Advanced DeFi Instruments**: Power complex financial instruments and processes like custom - pricing curves for AMMs, synthetic assets, options, and futures with onchain computation via - extending current protocols (i.e., Uniswap V4 hooks) or building your own. -- **High-Performance Onchain Logic**: Support memory and compute-intensive applications like - onchain games and generative art either by writing all of the application in Stylus or enhance - performance of existing Solidity contracts by optimizing specific parts. -- **Innovations**: generative art, compute-heavy - AI models, onchain games, advanced cryptography. +#### Coding -### Getting Started +You write your smart contract in any programming language that compiles to WASM. Rust has the most developed support with an open-source SDK for smart contract development. C and C++ are also supported, so that you can deploy existing contracts in those languages onchain with minimal modifications. -1. Utilize our [quickstart](/stylus/quickstart.mdx), [Rust SDK](/stylus/reference/overview.mdx), to help you start building. -2. Join our Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for support as well as the official Arbitrum ([@Arbitrum](https://twitter.com/arbitrum)) and Arbitrum Developers ([@ArbitrumDevs](https://twitter.com/ArbitrumDevs)) X accounts for announcements. -3. Check out the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for various community contributed Stylus projects and tools. If you build something useful, we'd be happy to add it there. -4. Stay updated with the latest from the Stylus community through tutorials, builder interviews, technical deep dives, and more with the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter. +The [Stylus SDK for Rust](/stylus/reference/rust-sdk-guide.md) provides the development framework and language features for smart contract development. It also provides access to EVM-specific functionality used by smart contract developers. + +#### Activation + +Once you've written your contract, compile it to WASM using the Stylus CLI (or another compiler, like Clang for C/C++). Then you post the compiled WASM onchain. + +To make your contract callable, it must undergo an activation process. During activation, the WASM compiles down to a node's native machine code (e.g., ARM or x86). This step also includes safety checks, such as gas metering, depth-checking, and memory charging, to ensure your program runs safely and can be fraud-proven. + +Stylus measures computational costs using ink instead of gas. Ink works like gas but is thousands of times smaller. WASM executes faster than the EVM, so a single EVM operation takes as long as thousands of WASM operations. A finer-grained unit makes pricing more precise. + +:::note +Stylus contracts need to be reactivated once per year (365 days) or after any Stylus upgrade. You can do this using [`cargo-stylus`](/stylus/using-cli.mdx#cargo-stylus-commands-reference) or the [ArbWasm precompile](/build-decentralized-apps/precompiles/reference#common-precompiles). If a contract isn't reactivated, it becomes uncallable. +::: + +#### Execution + +When your Stylus program runs, it executes in a fork of [Wasmer](https://wasmer.io/), a WebAssembly runtime. Because Wasmer compiles to native machine code, it executes faster than Geth's EVM bytecode interpreter. This performance difference reduces gas costs for compute-intensive operations. + +EVM contracts continue to work exactly as before. When a contract is called, the system checks whether it's an EVM contract or a WASM program and routes it to the appropriate runtime. Solidity and WASM contracts can call each other, so the language a contract was written in doesn't affect interoperability. + +#### Proving + +Stylus builds on Nitro's fraud-proving technology. In normal operation, execution compiles to native code for speed. But if there's a dispute, the execution history compiles to WASM so validators can run interactive fraud proofs on Ethereum. + +What makes Stylus possible: Nitro can already replay and verify disputes using WASM. Stylus extends this capability to verify not just execution history, but also the WASM programs you deploy. The result is a system where any program compiled to WASM can be deterministically fraud-proven. For more details, see the [Nitro architecture documentation](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx). + +### Use cases + +Stylus can integrate into existing Solidity projects by calling a Stylus contract to optimize specific parts of your app, or you can build an entire app with Stylus. Developers can also port existing applications written in Rust, C, or C++ to run onchain with minimal modifications. Here are some use cases where Stylus may be a good fit: + +- Onchain verification with zero-knowledge proofs: Reduce gas costs for onchain verification using zero-knowledge proving systems. See [case study](https://blog.arbitrum.io/renegade-stylus-case-study/) for an example implementation. +- DeFi instruments: Implement custom pricing curves for AMMs, synthetic assets, options, and futures with onchain computation. You can extend existing protocols (such as Uniswap V4 hooks) or build your own. +- Memory and compute-intensive applications: Build onchain games, generative art, or other applications that benefit from reduced memory costs. You can write the entire application in Stylus or optimize specific parts of existing Solidity contracts. +- Cryptographic applications: Implement applications that require advanced cryptography or other compute-heavy operations that would be cost-prohibitive in Solidity. + +### Getting started + +1. Follow the [quickstart](/stylus/quickstart.mdx) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview.md) documentation. +2. Join the Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for community support. +3. Browse the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for community-contributed projects, examples, and tools. +4. Subscribe to the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter for tutorials and technical content. From 24dbf97f309ab710cbb580b8cd64414bdba7f5e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 13:18:48 -0800 Subject: [PATCH 070/162] fix broken link --- docs/stylus/gentle-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index a4bb3621ad..794474bb18 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -72,7 +72,7 @@ Stylus can integrate into existing Solidity projects by calling a Stylus contrac ### Getting started -1. Follow the [quickstart](/stylus/quickstart.mdx) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview.md) documentation. +1. Follow the [quickstart](/stylus/quickstart.mdx) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview.mdx) documentation. 2. Join the Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for community support. 3. Browse the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for community-contributed projects, examples, and tools. 4. Subscribe to the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter for tutorials and technical content. From cd7045e47006478fe702cf6ddce4e5350620892a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 14:01:42 -0800 Subject: [PATCH 071/162] edit frontmatter to buildStylusSidebar --- docs/stylus/gentle-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 794474bb18..18338666d4 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -6,7 +6,7 @@ author: amarrazza sme: amarrazza target_audience: 'Developers who want to build on Arbitrum using popular programming languages, like Rust' sidebar_position: 1 -displayed_sidebar: buildAppsSidebar +displayed_sidebar: buildStylusSidebar --- import ImageZoom from '@site/src/components/ImageZoom'; From 2af1cf272fad7743216b080ad9bec5788cb66232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 14:21:48 -0800 Subject: [PATCH 072/162] docs: update Rust SDK guide to version 0.10.0 - Update SDK version from 0.6.0 to 0.10.0 - Replace deprecated inheritance model (#[inherit]/#[borrow]) with trait-based composition - Update Call API from Call::new_in() to new constructors (Call::new(), Call::new_mutating(), Call::new_payable()) - Update storage layout warning for trait composition - Add info boxes documenting SDK 0.10.0 breaking changes --- ...ons.md => public-preview-expectations.mdx} | 0 ...o-pricing.md => opcode-hostio-pricing.mdx} | 0 docs/stylus/reference/rust-sdk-guide.md | 132 ++++++++++++------ 3 files changed, 86 insertions(+), 46 deletions(-) rename docs/stylus/concepts/{public-preview-expectations.md => public-preview-expectations.mdx} (100%) rename docs/stylus/reference/{opcode-hostio-pricing.md => opcode-hostio-pricing.mdx} (100%) diff --git a/docs/stylus/concepts/public-preview-expectations.md b/docs/stylus/concepts/public-preview-expectations.mdx similarity index 100% rename from docs/stylus/concepts/public-preview-expectations.md rename to docs/stylus/concepts/public-preview-expectations.mdx diff --git a/docs/stylus/reference/opcode-hostio-pricing.md b/docs/stylus/reference/opcode-hostio-pricing.mdx similarity index 100% rename from docs/stylus/reference/opcode-hostio-pricing.md rename to docs/stylus/reference/opcode-hostio-pricing.mdx diff --git a/docs/stylus/reference/rust-sdk-guide.md b/docs/stylus/reference/rust-sdk-guide.md index 18b05e009c..2d94fbb04f 100644 --- a/docs/stylus/reference/rust-sdk-guide.md +++ b/docs/stylus/reference/rust-sdk-guide.md @@ -85,9 +85,9 @@ The above will expand to the equivalent definitions in Rust, each structure impl Because the layout is identical to [Solidityโ€™s](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html), existing Solidity smart contracts can upgrade to Rust without fear of storage slots not lining up. You simply copy-paste your type definitions. -:::warning Storage layout in contracts using inheritance +:::warning Storage layout in contracts using trait composition -One exception to this storage layout guarantee is contracts which utilize inheritance. The current solution in Stylus using `#[borrow]` and `#[inherits(...)]` packs nested (inherited) structs into their own slots. This is consistent with regular struct nesting in solidity, but not inherited structs. We plan to revisit this behavior in an upcoming release. +When using trait-based composition (the pattern recommended in SDK 0.10.0+), storage is organized by embedding structs as fields. Each embedded struct occupies its own storage slots based on field order. This is consistent with regular struct nesting in Solidity, but differs from Solidity's inheritance model where parent contract storage is flattened. Plan your storage layout carefully when migrating from Solidity contracts that use inheritance. ::: @@ -268,7 +268,7 @@ The above will make the public methods of `Contract` the first to consider durin If a contract calls another that then calls the first, it is said to be reentrant. By default, all Stylus contracts revert when this happens. However, you can opt out of this behavior by enabling the `reentrant` feature flag. ```rust -stylus-sdk = { version = "0.6.0", features = ["reentrant"] } +stylus-sdk = { version = "0.10.0", features = ["reentrant"] } ``` This is dangerous, and should be done only after careful reviewโ€“โ€“ideally by third-party auditors. Numerous exploits and hacks have in Web3 are attributable to developers misusing or not fully understanding reentrant patterns. @@ -279,57 +279,86 @@ If enabled, the Stylus SDK will flush the storage cache in between reentrant cal The [`#[entrypoint]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.entrypoint.html) macro will automatically implement the [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) trait for the annotated `struct`. The single type implementing [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) is special in that mutable access to it represents mutable access to the entire programโ€™s state. This idea will become important when discussing calls to other programs in later sections. -### Inheritance, `#[inherit]`, and `#[borrow]`. +### Trait-based composition -Composition in Rust follows that of Solidity. Types that implement [`Router`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html), the trait that [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) provides, can be connected via inheritance. +:::info SDK 0.10.0 changes + +Starting with SDK version 0.10.0, the inheritance model has been replaced with a trait-based composition pattern. The `#[inherit]` and `#[borrow]` attributes are no longer used. Instead, you implement traits on your contract type and use the `#[public]` macro's `impl` parameter to expose methods from embedded structs. + +::: + +Composition in Rust uses a trait-based model that provides explicit control over method routing. Types that implement [`Router`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html), the trait that [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) provides, can be composed together. ```rust +#[storage] +#[entrypoint] +pub struct Token { + erc20: Erc20, +} + +// Expose Erc20 methods through Token by implementing the trait #[public] -#[inherit(Erc20)] +#[implements(IErc20)] impl Token { pub fn mint(&mut self, amount: U256) -> Result<(), Vec> { - ... + // Custom mint logic + self.erc20.balance_of(msg::sender())?; + Ok(()) } } +// The Erc20 implementation provides the IErc20 trait #[public] impl Erc20 { - pub fn balance_of() -> Result { - ... + pub fn balance_of(&self, account: Address) -> Result> { + Ok(self.balances.get(account)) } } ``` -Because `Token` inherits `Erc20` in the above, if `Token` has the [`#[entrypoint]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.entrypoint.html), calls to the contract will first check if the requested method exists within `Token`. If a matching function is not found, it will then try the `Erc20`. Only after trying everything `Token` inherits will the call revert. +With the trait-based model, you explicitly define which methods are exposed at the contract's public interface. The `#[implements(...)]` attribute declares which interfaces your contract supports, making the ABI generation explicit and predictable. -Note that because methods are checked in that order, if both implement the same method, the one in `Token` will override the one in `Erc20`, which wonโ€™t be callable. This allows for patterns where the developer imports a crate implementing a standard, like the `ERC-20`, and then adds or overrides just the methods they want to without modifying the imported `Erc20` type. +To delegate method calls to an embedded struct, use the `impl` parameter of the `#[public]` macro: -::::warning +```rust +#[storage] +#[entrypoint] +pub struct Token { + erc20: Erc20, + erc721: Erc721, +} -Stylus does not currently contain explicit `override` or `virtual` keywords for explicitly marking override functions. It is important, therefore, to carefully ensure that contracts are only overriding the functions. +// Delegate Erc20 methods to the embedded erc20 field +#[public] +impl Token { + // Token-specific methods + pub fn custom_method(&mut self) -> Result<(), Vec> { + Ok(()) + } +} -:::: +// Expose Erc20 methods from the embedded struct +#[public(impl = "erc20")] +impl Token { + // Methods here delegate to self.erc20 +} -Inheritance can also be chained. `#[inherit(Erc20, Erc721)]` will inherit both `Erc20` and `Erc721`, checking for methods in that order. `Erc20` and `Erc721` may also inherit other types themselves. Method resolution finds the first matching method by [Depth First Search](https://en.wikipedia.org/wiki/Depth-first_search). +// Expose Erc721 methods from the embedded struct +#[public(impl = "erc721")] +impl Token { + // Methods here delegate to self.erc721 +} +``` -For the above to work, `Token` must implement [`Borrow`](https://doc.rust-lang.org/core/borrow/trait.Borrow.html). You can implement this yourself, but for simplicity, [`#[storage]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.storage.html) and [`sol_storage!`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/macro.sol_storage.html) provide a `#[borrow]` annotation. +This explicit delegation model provides clearer control over which methods are exposed and from which implementation they originate. -```rust -sol_storage! { - #[entrypoint] - pub struct Token { - #[borrow] - Erc20 erc20; - ... - } +::::warning - pub struct Erc20 { - ... - } -} -``` +Unlike Solidity, Stylus does not have explicit `override` or `virtual` keywords. When composing multiple implementations, ensure method names are unique across all exposed interfaces to avoid conflicts. If the same method signature appears in multiple `#[public]` blocks, only the first one encountered will be callable. + +:::: ### Fallback and receive functions @@ -411,9 +440,21 @@ Observe the casing change. [`sol_interface!`](https://docs.rs/stylus-sdk/latest/ [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) lets you configure a call via optional configuration methods. This is similar to how one would configure opening a [`File`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#examples) in Rust. +:::info SDK 0.10.0 changes + +Starting with SDK version 0.10.0, the `Call` API uses new constructors that make the intent of each call explicit: + +- `Call::new()` - For pure/view calls that do not modify state +- `Call::new_mutating()` - For calls that may modify state (requires `&mut self`) +- `Call::new_payable()` - For calls that send value (requires `&mut self` and the method must be `#[payable]`) + +The previous `Call::new_in()` pattern is deprecated. + +::: + ```rust -pub fn do_call(account: IService, user: Address) -> Result { - let config = Call::new_in() +pub fn do_call(&mut self, account: IService, user: Address) -> Result { + let config = Call::new_payable() .gas(evm::gas_left() / 2) // limit to half the gas left .value(msg::value()); // set the callvalue @@ -421,7 +462,7 @@ pub fn do_call(account: IService, user: Address) -> Result { } ``` -By default [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) supplies all gas remaining and zero value, which often means [`Call::new_in()`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html#method.new_in) may be passed to the method directly. Additional configuration options are available in cases of reentrancy. +By default [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) supplies all gas remaining and zero value. Choose the appropriate constructor based on whether your call modifies state or sends value. Additional configuration options are available in cases of reentrancy. ### Reentrant calls @@ -440,38 +481,37 @@ sol_interface! { #[public] impl Contract { pub fn call_pure(&self, methods: IMethods) -> Result<(), Vec> { - Ok(methods.pure_foo(self)?) // `pure` methods might lie about not being `view` + Ok(methods.pure_foo(Call::new())?) // pure calls use Call::new() } pub fn call_view(&self, methods: IMethods) -> Result<(), Vec> { - Ok(methods.view_foo(self)?) + Ok(methods.view_foo(Call::new())?) // view calls also use Call::new() } pub fn call_write(&mut self, methods: IMethods) -> Result<(), Vec> { - methods.view_foo(self)?; // allows `pure` and `view` methods too - Ok(methods.write_foo(self)?) + methods.view_foo(Call::new())?; // view calls within mutating context + Ok(methods.write_foo(Call::new_mutating())?) // state-modifying calls use Call::new_mutating() } #[payable] pub fn call_payable(&mut self, methods: IMethods) -> Result<(), Vec> { - methods.write_foo(Call::new_in(self))?; // these are the same - Ok(methods.payable_foo(self)?) // ------------------ + methods.write_foo(Call::new_mutating())?; // non-payable mutating call + Ok(methods.payable_foo(Call::new_payable())?) // payable calls use Call::new_payable() } } ``` -In the above, weโ€™re able to pass `&self` and `&mut self` because `Contract` implements [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html), which means that a reference to it entails access to the entirety of the contractโ€™s state. This is the reason it is sound to make a call, since it ensures all cached values are invalidated and/or persisted to state at the right time. +In the above, we use the new `Call` constructors (`new()`, `new_mutating()`, `new_payable()`) which make the intent explicit. The contract still implements [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html), which means that access to it entails access to the entirety of the contract's state. This ensures all cached values are invalidated and/or persisted to state at the right time. -When writing Stylus libraries, a type might not be [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) and therefore `&self` or `&mut self` wonโ€™t work. Building a [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) from a generic parameter via [`new_in`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html#method.new_in) is the usual solution. +When writing Stylus libraries, the new `Call` constructors make it explicit what type of call you're making: ```rust pub fn do_call( - storage: &mut impl TopLevelStorage, // can be generic, but often just &mut self account: IService, // serializes as an Address user: Address, ) -> Result { - let config = Call::new_in(storage) // take exclusive access to all contract storage + let config = Call::new_payable() // explicitly a payable call .gas(evm::gas_left() / 2) // limit to half the gas left .value(msg::value()); // set the callvalue @@ -479,7 +519,7 @@ pub fn do_call( } ``` -In the context of a [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) call, the `&mut impl` argument will correctly distinguish the method as being `write` or [`payable`](https://docs.alchemy.com/docs/solidity-payable-functions). This means you can write library code that will work regardless of whether the reentrant feature flag is enabled. +The choice of constructor (`new()`, `new_mutating()`, or `new_payable()`) makes the intent clear and helps the compiler enforce correct usage. In the context of a [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) call, using `new_mutating()` or `new_payable()` will correctly distinguish the method as being `write` or [`payable`](https://docs.alchemy.com/docs/solidity-payable-functions). Also, that code that previously compiled with reentrancy disabled may require modification in order to type-check. This is done to ensure storage changes are persisted and that the storage cache is properly managed before calls. @@ -488,7 +528,7 @@ Also, that code that previously compiled with reentrancy disabled may require mo Though [`sol_interface!`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/macro.sol_interface.html) and [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) form the most common idiom to invoke other contracts, their underlying [`call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/fn.call.html) and [`static_call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/fn.static_call.html) are exposed for direct access. ```rust -let return_data = call(Call::new_in(self), contract, call_data)?; +let return_data = call(Call::new_mutating(), contract, call_data)?; ``` In each case the calldata is supplied as a [`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html). The return result is either the raw return data on success, or a call [`Error`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/enum.Error.html) on failure. @@ -504,9 +544,9 @@ This method invokes the other contract, which may in turn call others. All gas i ::: ```rust -transfer_eth(recipient, value)?; // these two are equivalent +transfer_eth(recipient, value)?; // these two are equivalent -call(Call::new_in().value(value), recipient, &[])?; // these two are equivalent +call(Call::new_payable().value(value), recipient, &[])?; // these two are equivalent ``` ### [`RawCall`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.RawCall.html) and `unsafe` calls From 11d2e13cc8dc17567fbf4276b7ee03a0f8a78b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 14:41:46 -0800 Subject: [PATCH 073/162] remove redundant sidebar entries for stylus --- sidebars.js | 267 ++++++++-------------------------------------------- 1 file changed, 39 insertions(+), 228 deletions(-) diff --git a/sidebars.js b/sidebars.js index bff9cf567a..727c5fc91a 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1185,195 +1185,6 @@ const sidebars = { }, ], }, - { - type: 'category', - label: 'Build apps with Stylus', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/gentle-introduction', - label: 'A gentle introduction', - }, - { - type: 'category', - label: 'Rust SDK', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/reference/overview', - label: 'Overview', - }, - { - type: 'doc', - id: 'stylus/reference/project-structure', - label: 'Structure of a Contract', - }, - { - type: 'category', - label: 'Data types', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/reference/data-types/primitives', - label: 'Primitives', - }, - { - type: 'doc', - id: 'stylus/reference/data-types/compound-types', - label: 'Compound types', - }, - { - type: 'doc', - id: 'stylus/reference/data-types/storage', - label: 'Storage', - }, - { - type: 'doc', - id: 'stylus/reference/data-types/conversions-between-types', - label: 'Conversions Between Types', - }, - ], - }, - { - type: 'doc', - id: 'stylus/reference/global-variables-and-functions', - label: 'Global variables and functions', - }, - { - type: 'doc', - id: 'stylus/reference/contracts', - label: 'Contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/testing-contracts', - label: 'Writing Tests', - }, - { - type: 'category', - label: 'Advanced', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/advanced/solidity-differences', - label: 'Solidity differences', - }, - { - type: 'doc', - id: 'stylus/advanced/recommended-libraries', - label: 'Recommended packages', - }, - { - type: 'doc', - id: 'stylus/advanced/minimal-entrypoint-contracts', - label: 'Minimal entrypoint contracts', - }, - { - type: 'doc', - id: 'stylus/advanced/hostio-exports', - label: 'Hostio exports', - }, - ], - }, - { - type: 'doc', - id: 'stylus/troubleshooting-building-stylus', - label: 'Troubleshooting', - }, - { - type: 'category', - label: 'Using the CLI', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/how-tos/verifying-contracts', - label: 'Verify contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/exporting-abi', - label: 'Exporting ABI', - }, - { - type: 'doc', - id: 'stylus/how-tos/debugging-tx', - label: 'Debugging with replay', - }, - { - type: 'doc', - id: 'stylus/how-tos/optimizing-binaries', - label: 'Optimizing WASM binary size', - }, - { - type: 'doc', - id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', - label: 'Deploying non-Rust WASM contracts', - }, - ], - }, - { - type: 'category', - label: 'WM Concepts', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/concepts/webassembly', - label: 'Webassembly', - }, - { - type: 'doc', - id: 'stylus/concepts/evm-differences', - label: 'EVM differences', - }, - { - type: 'doc', - id: 'stylus/concepts/activation', - label: 'Activation', - }, - { - type: 'doc', - id: 'stylus/how-tos/caching-contracts', - label: 'Caching Strategy', - }, - ], - }, - { - type: 'category', - label: 'Reference', - collapsed: true, - items: [ - { - type: 'link', - label: 'Stylus by Example', - href: 'https://stylus-by-example.org/', - }, - { - type: 'link', - label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', - }, - { - type: 'link', - label: 'Rust SDK Crate', - href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', - }, - { - type: 'link', - label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus-sdk-rs', - }, - ], - }, - ], - }, - ], - }, { type: 'html', value: @@ -1631,7 +1442,44 @@ const sidebars = { }, { type: 'category', - label: 'Rust SDK', + label: 'Using the CLI', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-binaries', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], + }, + { + type: 'category', + label: 'Stylus Rust SDK', collapsed: true, items: [ { @@ -1720,44 +1568,7 @@ const sidebars = { }, { type: 'category', - label: 'Using the CLI', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/how-tos/check-and-deploy', - label: 'Check and deploy', - }, - { - type: 'doc', - id: 'stylus/how-tos/verifying-contracts', - label: 'Verify contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/exporting-abi', - label: 'Exporting ABI', - }, - { - type: 'doc', - id: 'stylus/how-tos/debugging-tx', - label: 'Debugging with replay', - }, - { - type: 'doc', - id: 'stylus/how-tos/optimizing-binaries', - label: 'Optimizing WASM binary size', - }, - { - type: 'doc', - id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', - label: 'Deploying non-Rust WASM contracts', - }, - ], - }, - { - type: 'category', - label: 'WM Concepts', + label: 'VM Concepts', collapsed: true, items: [ { From ac01a769119f0b92208e420350fedf19254a7d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 15:07:33 -0800 Subject: [PATCH 074/162] shuffled sections for better clarity --- sidebars.js | 84 ++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/sidebars.js b/sidebars.js index 727c5fc91a..24d83b75e2 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1440,43 +1440,6 @@ const sidebars = { id: 'stylus/gentle-introduction', label: 'A gentle introduction', }, - { - type: 'category', - label: 'Using the CLI', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/how-tos/check-and-deploy', - label: 'Check and deploy', - }, - { - type: 'doc', - id: 'stylus/how-tos/verifying-contracts', - label: 'Verify contracts', - }, - { - type: 'doc', - id: 'stylus/how-tos/exporting-abi', - label: 'Exporting ABI', - }, - { - type: 'doc', - id: 'stylus/how-tos/debugging-tx', - label: 'Debugging with replay', - }, - { - type: 'doc', - id: 'stylus/how-tos/optimizing-binaries', - label: 'Optimizing WASM binary size', - }, - { - type: 'doc', - id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', - label: 'Deploying non-Rust WASM contracts', - }, - ], - }, { type: 'category', label: 'Stylus Rust SDK', @@ -1561,11 +1524,6 @@ const sidebars = { }, ], }, - { - type: 'doc', - id: 'stylus/troubleshooting-building-stylus', - label: 'Troubleshooting', - }, { type: 'category', label: 'VM Concepts', @@ -1622,6 +1580,48 @@ const sidebars = { }, ], }, + { + type: 'category', + label: 'Using the CLI', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-binaries', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], + }, + { + type: 'doc', + id: 'stylus/troubleshooting-building-stylus', + label: 'Troubleshooting', + }, ], }, { From 4674f9ac42116fe8bff94e3779a2955db3e0f1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 15:23:17 -0800 Subject: [PATCH 075/162] docs: enforce sentence case in all Stylus documentation headings - Update titles to sentence case in recommended-libraries.mdx - Update title to sentence case in testing-contracts.mdx - Update heading to sentence case in contracts.mdx - Update heading to sentence case in storage.mdx - Update author/sme metadata in storage.mdx --- docs/stylus/advanced/recommended-libraries.mdx | 4 ++-- docs/stylus/how-tos/testing-contracts.mdx | 2 +- docs/stylus/reference/contracts.mdx | 2 +- docs/stylus/reference/data-types/storage.mdx | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/stylus/advanced/recommended-libraries.mdx b/docs/stylus/advanced/recommended-libraries.mdx index 213c1b47e3..0d7886f509 100644 --- a/docs/stylus/advanced/recommended-libraries.mdx +++ b/docs/stylus/advanced/recommended-libraries.mdx @@ -1,7 +1,7 @@ --- id: recommended-libraries -title: Recommended Libraries (Rust crates) -sidebar_label: Recommended Libraries +title: Recommended libraries (Rust crates) +sidebar_label: Recommended libraries --- ## Using public Rust crates diff --git a/docs/stylus/how-tos/testing-contracts.mdx b/docs/stylus/how-tos/testing-contracts.mdx index c960961ba2..17ddda113a 100644 --- a/docs/stylus/how-tos/testing-contracts.mdx +++ b/docs/stylus/how-tos/testing-contracts.mdx @@ -1,6 +1,6 @@ --- id: 'testing-contracts' -title: 'Testing Smart Contracts with Stylus' +title: 'Testing smart contracts with Stylus' description: 'A comprehensive guide to writing and running tests for Stylus smart contracts.' sme: anegg0 target_audience: 'Developers writing smart contracts using Stylus.' diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/reference/contracts.mdx index 6f6ba7befe..f644c2f3fb 100644 --- a/docs/stylus/reference/contracts.mdx +++ b/docs/stylus/reference/contracts.mdx @@ -10,7 +10,7 @@ displayed_sidebar: buildStylusSidebar Stylus smart contracts are fully compatible with Solidity contracts on Arbitrum chains. They compile to WebAssembly and share the same EVM state trie as Solidity contracts, enabling seamless interoperability. -## Contract Basics +## Contract basics A Stylus contract consists of three main components: diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 8f353542fe..9870268ca1 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -1,8 +1,8 @@ --- title: 'Stylus Rust SDK storage' description: 'Stylus Rust SDK storage types' -author: chrisco -sme: chrisco +author: anegg0 +sme: anegg0 sidebar_position: 3 target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. displayed_sidebar: buildStylusSidebar @@ -87,7 +87,7 @@ impl Contract { } ``` -### Integer Storage +### Integer storage Store unsigned and signed integers with various bit sizes: From 0a7d6e14005cbd2d80166b4166190140bb5dacb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 15:42:30 -0800 Subject: [PATCH 076/162] docs: add importing interfaces how-to guide for Stylus Add comprehensive guide for importing and calling external contract interfaces - Declare interfaces with sol_interface! macro - Create interface instances and call methods - Configure calls with SDK 0.10.0 Call API (new(), new_mutating(), new_payable()) - CamelCase to snake_case conversion table - Complete working examples with proper error handling - Best practices and common pitfalls - Based on stylus-by-example content --- docs/stylus/how-tos/importing-interfaces.mdx | 630 +++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 docs/stylus/how-tos/importing-interfaces.mdx diff --git a/docs/stylus/how-tos/importing-interfaces.mdx b/docs/stylus/how-tos/importing-interfaces.mdx new file mode 100644 index 0000000000..d9cb3dcdd8 --- /dev/null +++ b/docs/stylus/how-tos/importing-interfaces.mdx @@ -0,0 +1,630 @@ +--- +id: 'importing-interfaces' +title: 'Import and call external contract interfaces' +sidebar_label: 'Importing interfaces' +description: 'Learn how to import Solidity interfaces and call external contracts from your Stylus smart contracts' +author: 'anegg0' +sme: 'anegg0' +user_story: 'As a Rust developer building Stylus smart contracts, I want to interact with other contracts on the blockchain' +content_type: 'how-to' +target_audience: 'Developers building Stylus smart contracts that need to interact with other contracts' +sidebar_position: 8 +displayed_sidebar: buildStylusSidebar +--- + +import CustomDetails from '@site/src/components/CustomDetails'; +import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition/'; + +Interfaces enable your Stylus contract to interact with other contracts on the blockchain, regardless of whether they're written in Solidity, Rust, or another language. This guide shows you how to import and use external contract interfaces in your Stylus smart contracts. + +## Why use interfaces + +Contract interfaces provide a type-safe way to communicate with other contracts on the blockchain. Common use cases include: + +- **Interacting with existing protocols**: Call methods on deployed Solidity contracts like ERC-20 tokens, oracles, or DeFi protocols +- **Composing functionality**: Build contracts that leverage other contracts' capabilities +- **Cross-language interoperability**: Stylus contracts can call Solidity contracts and vice versa +- **Upgradeability patterns**: Use interfaces to interact with proxy contracts + + + Since interfaces operate at the ABI level, they work identically whether the target contract is + written in Solidity, Rust, or any other language that compiles to EVM bytecode. + + +## Prerequisites + +Before implementing interfaces, ensure you have: + + + +Follow the instructions on [Rust Lang's installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain (v1.88 or newer) on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. + + + + + +In your terminal, run: + +```shell +cargo install --force cargo-stylus +``` + +Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.88 as well as adding the WASM build target: + +```shell +rustup default 1.88 +rustup target add wasm32-unknown-unknown --toolchain 1.88 +``` + +You can verify that cargo stylus is installed by running `cargo stylus --help` in your terminal, which will return a list of helpful commands. + + + +## Declaring interfaces with `sol_interface!` + +The [`sol_interface!`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/macro.sol_interface.html) macro allows you to declare interfaces using Solidity syntax. It generates Rust structs that represent external contracts and provides type-safe methods for calling them. + +### Basic interface declaration + +```rust +use stylus_sdk::prelude::*; + +sol_interface! { + interface IToken { + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + function approve(address spender, uint256 amount) external returns (bool); + } +} +``` + +This macro generates an `IToken` struct that you can use to call methods on any deployed contract that implements this interface. + +### Declaring multiple interfaces + +You can declare multiple interfaces in a single `sol_interface!` block: + +```rust +sol_interface! { + interface IPaymentService { + function makePayment(address user) payable returns (string); + function getBalance(address user) view returns (uint256); + } + + interface IOracle { + function getPrice(bytes32 feedId) external view returns (uint256); + function getLastUpdate() external view returns (uint256); + } + + interface IVault { + function deposit() external payable; + function withdraw(uint256 amount) external; + } +} +``` + + + Interface declarations use standard Solidity syntax. The SDK computes the correct 4-byte function + selectors based on the exact names and parameter types you provide. + + +## Calling external contract methods + +Once you've declared an interface, you can call methods on external contracts using instances of the generated struct. + +### Creating interface instances + +Use the `::new(address)` constructor to create an interface instance pointing to a deployed contract: + +```rust +use alloy_primitives::Address; + +// Create an instance pointing to a deployed token contract +let token_address = Address::from([0x12; 20]); // Replace with actual address +let token = IToken::new(token_address); +``` + +### CamelCase to snake_case conversion + +The `sol_interface!` macro converts Solidity's CamelCase method names to Rust's snake_case convention: + +| Solidity method | Rust method | +| --------------- | --------------- | +| `balanceOf` | `balance_of` | +| `makePayment` | `make_payment` | +| `getPrice` | `get_price` | +| `transferFrom` | `transfer_from` | + +The macro preserves the original CamelCase name for computing the correct function selector, so your calls reach the right method on the target contract. + +### Basic method calls + +Here's how to call methods on an external contract: + +```rust +use stylus_sdk::{call::Call, prelude::*}; +use alloy_primitives::{Address, U256}; + +sol_interface! { + interface IToken { + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + } +} + +#[public] +impl MyContract { + pub fn check_balance(&self, token_address: Address, account: Address) -> U256 { + let token = IToken::new(token_address); + let config = Call::new(); + + token.balance_of(self.vm(), config, account).unwrap() + } +} +``` + +## Configuring your calls + +The Stylus SDK provides three `Call` constructors for different types of external calls. Choosing the correct one is essential for your contract to work properly. + +### View calls with `Call::new()` + +Use `Call::new()` for read-only calls that don't modify state: + +```rust +use stylus_sdk::call::Call; + +#[public] +impl MyContract { + pub fn get_token_balance(&self, token: Address, account: Address) -> U256 { + let token_contract = IToken::new(token); + let config = Call::new(); + + token_contract.balance_of(self.vm(), config, account).unwrap() + } + + pub fn get_oracle_price(&self, oracle: Address, feed_id: [u8; 32]) -> U256 { + let oracle_contract = IOracle::new(oracle); + let config = Call::new(); + + oracle_contract.get_price(self.vm(), config, feed_id.into()).unwrap() + } +} +``` + +### State-changing calls with `Call::new_mutating(self)` + +Use `Call::new_mutating(self)` for calls that modify state on the target contract: + +```rust +#[public] +impl MyContract { + pub fn transfer_tokens( + &mut self, + token: Address, + to: Address, + amount: U256, + ) -> bool { + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + + token_contract.transfer(self.vm(), config, to, amount).unwrap() + } + + pub fn approve_spender( + &mut self, + token: Address, + spender: Address, + amount: U256, + ) -> bool { + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + + token_contract.approve(self.vm(), config, spender, amount).unwrap() + } +} +``` + + + When using `Call::new_mutating(self)`, your method must take `&mut self` as its first parameter. + This ensures the Stylus runtime properly handles state changes and reentrancy protection. + + +### Payable calls with `Call::new_payable(self, value)` + +Use `Call::new_payable(self, value)` to send ETH along with your call: + +```rust +use alloy_primitives::U256; + +sol_interface! { + interface IVault { + function deposit() external payable; + } +} + +#[public] +impl MyContract { + #[payable] + pub fn deposit_to_vault(&mut self, vault: Address) -> Result<(), Vec> { + let vault_contract = IVault::new(vault); + let value = self.vm().msg_value(); + let config = Call::new_payable(self, value); + + vault_contract.deposit(self.vm(), config)?; + Ok(()) + } + + pub fn deposit_specific_amount( + &mut self, + vault: Address, + amount: U256, + ) -> Result<(), Vec> { + let vault_contract = IVault::new(vault); + let config = Call::new_payable(self, amount); + + vault_contract.deposit(self.vm(), config)?; + Ok(()) + } +} +``` + +### Configuring gas limits + +You can limit the gas forwarded to external calls using the `.gas()` method: + +```rust +#[public] +impl MyContract { + pub fn safe_transfer( + &mut self, + token: Address, + to: Address, + amount: U256, + ) -> bool { + let token_contract = IToken::new(token); + + // Use half of remaining gas + let gas_limit = self.vm().evm_gas_left() / 2; + let config = Call::new_mutating(self).gas(gas_limit); + + token_contract.transfer(self.vm(), config, to, amount).unwrap() + } +} +``` + +### Call configuration summary + +| Constructor | Use case | State access | ETH transfer | +| -------------------------------- | --------------- | ------------ | ------------ | +| `Call::new()` | View/pure calls | Read-only | No | +| `Call::new_mutating(self)` | Write calls | Read/write | No | +| `Call::new_payable(self, value)` | Payable calls | Read/write | Yes | + +## Complete example + +Here's a complete contract that demonstrates all aspects of interface usage: + +```rust +#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] +extern crate alloc; + +use alloy_primitives::{Address, U256}; +use alloy_sol_types::sol; +use stylus_sdk::{call::Call, prelude::*}; + +// Declare interfaces for external contracts +sol_interface! { + interface IToken { + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address from, address to, uint256 amount) external returns (bool); + } + + interface IOracle { + function getPrice(bytes32 feedId) external view returns (uint256); + } + + interface IVault { + function deposit() external payable; + function withdraw(uint256 amount) external; + } +} + +// Define events +sol! { + event TokensTransferred(address indexed token, address indexed to, uint256 amount); + event DepositMade(address indexed vault, uint256 amount); +} + +// Define errors +sol! { + error TransferFailed(address token, address to, uint256 amount); + error InsufficientBalance(uint256 have, uint256 want); +} + +#[derive(SolidityError)] +pub enum InterfaceError { + TransferFailed(TransferFailed), + InsufficientBalance(InsufficientBalance), +} + +// Contract storage +sol_storage! { + #[entrypoint] + pub struct InterfaceExample { + address owner; + address default_token; + address default_vault; + } +} + +#[public] +impl InterfaceExample { + #[constructor] + pub fn constructor(&mut self, token: Address, vault: Address) { + self.owner.set(self.vm().tx_origin()); + self.default_token.set(token); + self.default_vault.set(vault); + } + + // View call example + pub fn get_token_balance(&self, token: Address, account: Address) -> U256 { + let token_contract = IToken::new(token); + let config = Call::new(); + + token_contract.balance_of(self.vm(), config, account).unwrap() + } + + // View call with oracle + pub fn get_price(&self, oracle: Address, feed_id: [u8; 32]) -> U256 { + let oracle_contract = IOracle::new(oracle); + let config = Call::new(); + + oracle_contract.get_price(self.vm(), config, feed_id.into()).unwrap() + } + + // Mutating call example + pub fn transfer_tokens( + &mut self, + token: Address, + to: Address, + amount: U256, + ) -> Result { + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + + let success = token_contract + .transfer(self.vm(), config, to, amount) + .map_err(|_| InterfaceError::TransferFailed(TransferFailed { + token, + to, + amount, + }))?; + + if success { + self.vm().log(TokensTransferred { token, to, amount }); + } + + Ok(success) + } + + // Payable call example + #[payable] + pub fn deposit_to_vault(&mut self, vault: Address) -> Result<(), Vec> { + let vault_contract = IVault::new(vault); + let value = self.vm().msg_value(); + let config = Call::new_payable(self, value); + + vault_contract.deposit(self.vm(), config)?; + + self.vm().log(DepositMade { vault, amount: value }); + Ok(()) + } + + // Using gas limits + pub fn safe_withdraw(&mut self, vault: Address, amount: U256) -> Result<(), Vec> { + let vault_contract = IVault::new(vault); + + // Limit gas to prevent reentrancy issues + let gas_limit = self.vm().evm_gas_left() / 2; + let config = Call::new_mutating(self).gas(gas_limit); + + vault_contract.withdraw(self.vm(), config, amount)?; + Ok(()) + } + + // Complex multi-call example + pub fn swap_and_deposit( + &mut self, + token: Address, + vault: Address, + amount: U256, + ) -> Result<(), InterfaceError> { + let token_contract = IToken::new(token); + + // First, check balance + let balance = token_contract + .balance_of(self.vm(), Call::new(), self.vm().contract_address()) + .unwrap(); + + if balance < amount { + return Err(InterfaceError::InsufficientBalance(InsufficientBalance { + have: balance, + want: amount, + })); + } + + // Approve vault to spend tokens + let config = Call::new_mutating(self); + token_contract + .approve(self.vm(), config, vault, amount) + .map_err(|_| InterfaceError::TransferFailed(TransferFailed { + token, + to: vault, + amount, + }))?; + + Ok(()) + } +} +``` + +## Best practices + +### Validate addresses before calls + +Always verify that contract addresses are valid before making external calls: + +```rust +pub fn safe_transfer( + &mut self, + token: Address, + to: Address, + amount: U256, +) -> Result { + // Validate addresses + if token == Address::ZERO || to == Address::ZERO { + return Err(InterfaceError::InvalidAddress); + } + + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + + Ok(token_contract.transfer(self.vm(), config, to, amount).unwrap()) +} +``` + +### Handle call failures gracefully + +External calls can fail for various reasons. Always handle errors appropriately: + +```rust +pub fn try_transfer( + &mut self, + token: Address, + to: Address, + amount: U256, +) -> Result { + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + + match token_contract.transfer(self.vm(), config, to, amount) { + Ok(success) => Ok(success), + Err(_) => Err(InterfaceError::TransferFailed(TransferFailed { + token, + to, + amount, + })), + } +} +``` + +### Follow the checks-effects-interactions pattern + +When making external calls, update your contract's state before calling external contracts to prevent reentrancy attacks: + +```rust +pub fn withdraw_tokens( + &mut self, + token: Address, + amount: U256, +) -> Result<(), InterfaceError> { + let caller = self.vm().msg_sender(); + + // Checks + let balance = self.balances.get(caller); + if balance < amount { + return Err(InterfaceError::InsufficientBalance(InsufficientBalance { + have: balance, + want: amount, + })); + } + + // Effects - update state BEFORE external call + self.balances.setter(caller).set(balance - amount); + + // Interactions - external call last + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + token_contract.transfer(self.vm(), config, caller, amount) + .map_err(|_| InterfaceError::TransferFailed(TransferFailed { + token, + to: caller, + amount, + }))?; + + Ok(()) +} +``` + +### Use gas limits for untrusted contracts + +When calling untrusted contracts, limit the gas to prevent malicious behavior: + +```rust +pub fn call_untrusted( + &mut self, + target: Address, +) -> Result> { + let contract = IToken::new(target); + + // Limit gas to prevent griefing attacks + let config = Call::new().gas(100_000); + + Ok(contract.balance_of(self.vm(), config, self.vm().msg_sender()).unwrap()) +} +``` + +## Common pitfalls + +### Using the wrong call constructor + +Using `Call::new()` for state-changing calls will cause the transaction to fail: + +```rust +// Wrong - using Call::new() for a write operation +pub fn bad_transfer(&mut self, token: Address, to: Address, amount: U256) -> bool { + let token_contract = IToken::new(token); + let config = Call::new(); // This will fail! + token_contract.transfer(self.vm(), config, to, amount).unwrap() +} + +// Correct - using Call::new_mutating(self) +pub fn good_transfer(&mut self, token: Address, to: Address, amount: U256) -> bool { + let token_contract = IToken::new(token); + let config = Call::new_mutating(self); + token_contract.transfer(self.vm(), config, to, amount).unwrap() +} +``` + +### Forgetting to pass the VM context + +All interface method calls require `self.vm()` as the first argument: + +```rust +// Wrong - missing self.vm() +let balance = token_contract.balance_of(config, account).unwrap(); + +// Correct +let balance = token_contract.balance_of(self.vm(), config, account).unwrap(); +``` + +### Incorrect method naming + +Remember that Solidity method names are converted to snake_case in Rust: + +```rust +// Wrong - using Solidity naming +let balance = token.balanceOf(self.vm(), config, account); + +// Correct - using Rust snake_case +let balance = token.balance_of(self.vm(), config, account); +``` + +## See also + +- [Stylus contracts reference](../reference/contracts.mdx#external-contract-calls): Detailed reference for external contract calls +- [Stylus by Example: Import interfaces](https://stylus-by-example.org/basic_examples/import_interfaces): Interactive examples +- [Stylus SDK documentation](https://docs.rs/stylus-sdk/latest/stylus_sdk/): Complete API reference From 68ff418865d7724234c5aa9eb4eaeeac6bb53853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 15:57:35 -0800 Subject: [PATCH 077/162] add importing interfaces article to sidebars.js --- sidebars.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sidebars.js b/sidebars.js index 24d83b75e2..4c7fcf021d 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1491,8 +1491,6 @@ const sidebars = { type: 'doc', id: 'stylus/reference/contracts', label: 'Contracts', - }, - { type: 'doc', id: 'stylus/how-tos/testing-contracts', label: 'Writing Tests', @@ -1600,6 +1598,11 @@ const sidebars = { id: 'stylus/how-tos/exporting-abi', label: 'Exporting ABI', }, + { + type: 'doc', + id: 'stylus/how-tos/importing-interfaces', + label: 'Importing interfaces', + }, { type: 'doc', id: 'stylus/how-tos/debugging-tx', From 88d299b5b97d53e723dcdf35ae1ffa5d6c2fdac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 16:15:19 -0800 Subject: [PATCH 078/162] rename troubleshooting to FAQ in sidebar --- sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sidebars.js b/sidebars.js index 4c7fcf021d..58ac165850 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1623,7 +1623,7 @@ const sidebars = { { type: 'doc', id: 'stylus/troubleshooting-building-stylus', - label: 'Troubleshooting', + label: 'FAQ', }, ], }, From 87e44600e58cc9430a36581b5bc379928d79c7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 18:17:23 -0800 Subject: [PATCH 079/162] remove unused Stylus documentation files --- docs/stylus/using-cli.mdx | 131 -------------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 docs/stylus/using-cli.mdx diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx deleted file mode 100644 index da6b73b4fa..0000000000 --- a/docs/stylus/using-cli.mdx +++ /dev/null @@ -1,131 +0,0 @@ ---- -id: using-cli -title: 'Using Stylus CLI' -description: 'Get started with Stylus CLI, a Rust toolkit for developing Stylus contracts' -author: 'anegg0' -sme: 'anegg0' -sidebar_position: 2 -target_audience: Developers writing Stylus contracts in Rust using Stylus -displayed_sidebar: buildStylusSidebar ---- - -This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. - -This overview will help you discover and learn how to uses cargo stylus tools. - -### Installing cargo stylus - -Cargo stylus is a plugin to the standard cargo tool for developing Rust programs. - -#### Prerequisites - -

    -Rust toolchain - -Follow the instructions on [Rust Lang's installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain (v1.81 or newer) on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. - -
    - -
    -Docker - -We will use the testnet, and some `cargo stylus` commands will require Docker to operate. - -You can download Docker from [Docker's website](https://www.docker.com/products/docker-desktop). - -
    - -
    -Foundry's Cast - -[Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool for interacting with your EVM contracts. - -
    - -
    -Nitro devnode - -Stylus is available on Arbitrum Sepolia, but we'll use Nitro devnode, which has a pre-funded wallet, saving us the effort of wallet provisioning or running out of tokens to send transactions. - -```shell title="Install your devnode" -git clone https://github.com/OffchainLabs/nitro-devnode.git -cd nitro-devnode -``` - -```shell title="Launch your devnode" -./run-dev-node.sh -``` - -
    - -#### Installation - -In your terminal, run: - -```shell -cargo install --force cargo-stylus -``` - -Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: - -```shell -rustup default 1.80 -rustup target add wasm32-unknown-unknown --toolchain 1.80 -``` - -You can verify the cargo stylus installation by running `cargo stylus -V` in your terminal, returning something like:`stylus 0.5.6` - -### Using cargo stylus - -#### Cargo Stylus Commands Reference - -| Command | Description | Arguments | Options | Example Usage | -| ------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | -| `new` | Create a new Stylus project | โ€ข `name`: Project name (required) | โ€ข `--minimal`: Create a minimal contract | `cargo stylus new ` | -| `init` | Initialize a Stylus project in current directory | | โ€ข `--minimal`: Create a minimal contract | `cargo stylus init --minimal` | -| `export-abi` | Export a Solidity ABI | | โ€ข `--output`: Output file (defaults to stdout)
    โ€ข `--json`: Write JSON ABI using `solc` | `cargo stylus export-abi --json` | -| `activate` | Activate an already deployed contract | โ€ข `--address`: Contract address to activate | โ€ข `--data-fee-bump-percent`: Percent to bump estimated fee (default 20%)
    โ€ข `--estimate-gas`: Only estimate gas without sending transaction | `cargo stylus activate --address ` | -| `cache` | Cache contract using Stylus CacheManager | โ€ข `bid`: Place bid on contract
    โ€ข `status`: Check contract status
    โ€ข `suggest-bid`: Get suggested minimum bid | | `cargo stylus cache bid --address ` | -| `check` | Check a contract | | โ€ข `--wasm-file`: WASM file to check
    โ€ข `--contract-address`: Deployment address | | -| `deploy` | Deploy a contract | โ€ข `--contract-address `: Where to deploy and activate the contract (defaults to a random address) | โ€ข `--estimate-gas`: Only perform estimation
    โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image
    โ€ข `--source-files-for-project-hash `: Path to source files to include in the project hash
    โ€ข `--max-fee-per-gas-gwei `: Optional max fee per gas in `gwei` units
    โ€ข `--wasm-file `: The WASM file to check (defaults to any found in the current directory) | `cargo stylus deploy --endpoint='http://localhost:8547' --private-key="" --estimate-gas` | -| `verify` | Verify contract deployment | โ€ข `--deployment-tx`: Hash of deployment transaction | โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image | | -| `cgen` | Generate C code bindings | โ€ข `--input`: Input file path
    โ€ข `--out_dir`: Output directory path | | | -| `replay` | Replay transaction in GDB | โ€ข `-t, --tx `: Transaction to replay | โ€ข `-p, --project `: Project path (default: `.`)
    โ€ข `-u, --use-native-tracer`: Use the native tracer instead of the JavaScript one (may not be available in the node)
    โ€ข `-s, --stable-rust`: Use stable Rust (note that nightly is needed to expand macros) | `cargo stylus replay --tx ` | -| `trace` | Trace a transaction | โ€ข `--tx`: Transaction hash | โ€ข `--endpoint`: RPC endpoint
    โ€ข `--project`: Project path
    โ€ข `--use-native-tracer`: Use native tracer | | - -##### Common options - -These options are available across multiple commands: - -| Option | Description | -| ------------------------------- | ------------------------------------------------------ | -| --endpoint | Arbitrum RPC endpoint (default: http://localhost:8547) | -| --verbose | Print debug info | -| --source-files-for-project-hash | Paths to source files for project hash | -| --max-fee-per-gas-gwei | Optional max fee per gas in `gwei` | - -##### Authentication options - -Available for commands involving transactions: - -| Option | Description | -| ------------------------ | ---------------------------------------------------- | -| --private-key-path | Path to file containing hex-encoded private key | -| --private-key | Private key as hex string (exposes to shell history) | -| --keystore-path | Path to Ethereum wallet keystore file | -| --keystore-password-path | Keystore password file path | - -#### How-tos - -| Topic | Description | -| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/how-tos/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/how-tos/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/how-tos/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | -| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | - -#### Additional resources - -#### [Troubleshooting](/stylus/troubleshooting-building-stylus.md): solve the most common issues. - -#### [cargo-stylus repository](https://github.com/OffchainLabs/stylus): consult cargo stylus' source code. From a27a78b1756ab383ddbf96badc9c902aba2d8bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 18:31:19 -0800 Subject: [PATCH 080/162] remove obsolete Stylus testnets documentation --- docs/stylus/reference/testnet-information.md | 33 -------------------- 1 file changed, 33 deletions(-) delete mode 100644 docs/stylus/reference/testnet-information.md diff --git a/docs/stylus/reference/testnet-information.md b/docs/stylus/reference/testnet-information.md deleted file mode 100644 index 1226e32078..0000000000 --- a/docs/stylus/reference/testnet-information.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: 'Stylus testnet information' -description: A reference providing details about the Stylus testnet and faucets for obtaining testnet ETH -author: amarrazza -sme: amarrazza -target_audience: Developers building on the Stylus testnet -sidebar_position: 9 ---- - -import StylusFaucets from './partials/_stylus-faucets.mdx'; - -import ArbitrumContractAddresses from '../../partials/_reference-arbitrum-contract-addresses-partial.mdx'; - -## Arbitrum public RPC endpoints - -:::caution - -- Unlike the RPC Urls, the Sequencer endpoints only support `eth_sendRawTransaction` and `eth_sendRawTransactionConditional` calls. -- Arbitrum public RPCs do not provide Websocket support. -- Stylus testnets v1 and v2 have been spun down and are not accessible anymore. -- Visit [Quicknode's Arbitrum Sepolia faucet](https://faucet.quicknode.com/arbitrum/sepolia), [Alchemy's Arbitrum sepolia faucet](https://www.alchemy.com/faucets/arbitrum-sepolia), or [Getblock's Arbitrum Sepolia faucet](https://getblock.io/faucet/arb-sepolia) for testnet Sepolia tokens on L2. - -::: - -This section provides an overview of the available public RPC endpoints for different Arbitrum chains that have Stylus enabled, and the necessary details to interact with them. - -| Name | RPC Url(s) | Chain ID | Block explorer | Underlying chain | Tech stack | Sequencer feed URL | Sequencer endpointโš ๏ธ | -| -------------------------- | -------------------------------------- | -------- | --------------------------- | ---------------- | -------------- | ------------------------------------- | ------------------------------------------------ | -| Arbitrum Sepolia (Testnet) | https://sepolia-rollup.arbitrum.io/rpc | 421614 | https://sepolia.arbiscan.io | Sepolia | Nitro (Rollup) | wss://sepolia-rollup.arbitrum.io/feed | https://sepolia-rollup-sequencer.arbitrum.io/rpc | - - - - From 38d929c8537b6a256b97b7d53c3a0fc80ced842f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 18:47:08 -0800 Subject: [PATCH 081/162] fix broken link --- docs/partials/_reference-arbitrum-rpc-endpoints-partial.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/partials/_reference-arbitrum-rpc-endpoints-partial.mdx b/docs/partials/_reference-arbitrum-rpc-endpoints-partial.mdx index 4be212eb7c..c9ea9fd096 100644 --- a/docs/partials/_reference-arbitrum-rpc-endpoints-partial.mdx +++ b/docs/partials/_reference-arbitrum-rpc-endpoints-partial.mdx @@ -12,7 +12,7 @@ last_reviewed: 2025-01-15 - Unlike the RPC Urls, the Sequencer endpoints only support `eth_sendRawTransaction` and `eth_sendRawTransactionConditional` calls. - Arbitrum public RPCs do not provide Websocket support. -- View the [faucets](/stylus/reference/testnet-information.md#faucets) for testnet Sepolia tokens on L2. +- View the [faucets](docs/for-devs/dev-tools-and-resources/chain-info.mdx) for testnet Sepolia tokens on L2. ::: From 8875a8792ff8f80ebf7e60a5252b4b5499e34d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 18:47:49 -0800 Subject: [PATCH 082/162] rename Stylus contract > project + re-add CLI overview --- docs/stylus/reference/project-structure.mdx | 4 +- docs/stylus/using-cli.mdx | 131 ++++++++++++++++++++ sidebars.js | 11 +- 3 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 docs/stylus/using-cli.mdx diff --git a/docs/stylus/reference/project-structure.mdx b/docs/stylus/reference/project-structure.mdx index e6f6cd19c8..5fe01e06cc 100644 --- a/docs/stylus/reference/project-structure.mdx +++ b/docs/stylus/reference/project-structure.mdx @@ -1,5 +1,5 @@ --- -title: 'Structure of a Rust Contract' +title: 'Structure of a Stylus Rust project' description: 'A quick overview of how contracts are structured with the Stylus Rust SDK' author: chrisco sme: chrisco @@ -24,7 +24,7 @@ In the most basic example, this is how a Rust contract will be organized. The si `src/lib.rs` is the root module of your contract's code. Here, you can import utilities or methods from internal or external modules, define the data layout of your contract's state variables, and define your contract's public API. This module must define a root data struct with the `#[entrypoint]` macro and provide an impl block annotated with `#[public]` to define public or external methods. See [First App](https://stylus-by-example.org/basic_examples/first_app) for an example of this. These macros are used to maintain [Solidity ABI](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#basic-design) compatibility to ensure that Rust contracts work with existing Solidity libraries and tooling. -`src/main.rs` is typically auto-generated by [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) and does not usually need to be modified. Its purpose is to assist with the generation of [JSON describing](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#json) your contract's public interface, for use with automated tooling and frontend frameworks. +`src/main.rs` is typically auto-generated by [cargo-stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) and does not usually need to be modified. Its purpose is to assist with the generation of [JSON describing](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#json) your contract's public interface, for use with automated tooling and frontend frameworks. `Cargo.toml` is a standard file that Rust projects use to define a package's name, repository location, etc, as well as import dependencies and define feature and build flags. From here, you can define required dependencies such as the [Stylus SDK](https://crates.io/crates/stylus-sdk) itself or import third-party packages from [crates.io](https://crates.io). See [First Steps with Cargo](https://doc.rust-lang.org/cargo/getting-started/first-steps.html) if you are new to Rust. diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx new file mode 100644 index 0000000000..da6b73b4fa --- /dev/null +++ b/docs/stylus/using-cli.mdx @@ -0,0 +1,131 @@ +--- +id: using-cli +title: 'Using Stylus CLI' +description: 'Get started with Stylus CLI, a Rust toolkit for developing Stylus contracts' +author: 'anegg0' +sme: 'anegg0' +sidebar_position: 2 +target_audience: Developers writing Stylus contracts in Rust using Stylus +displayed_sidebar: buildStylusSidebar +--- + +This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. + +This overview will help you discover and learn how to uses cargo stylus tools. + +### Installing cargo stylus + +Cargo stylus is a plugin to the standard cargo tool for developing Rust programs. + +#### Prerequisites + +
    +Rust toolchain + +Follow the instructions on [Rust Lang's installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain (v1.81 or newer) on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. + +
    + +
    +Docker + +We will use the testnet, and some `cargo stylus` commands will require Docker to operate. + +You can download Docker from [Docker's website](https://www.docker.com/products/docker-desktop). + +
    + +
    +Foundry's Cast + +[Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool for interacting with your EVM contracts. + +
    + +
    +Nitro devnode + +Stylus is available on Arbitrum Sepolia, but we'll use Nitro devnode, which has a pre-funded wallet, saving us the effort of wallet provisioning or running out of tokens to send transactions. + +```shell title="Install your devnode" +git clone https://github.com/OffchainLabs/nitro-devnode.git +cd nitro-devnode +``` + +```shell title="Launch your devnode" +./run-dev-node.sh +``` + +
    + +#### Installation + +In your terminal, run: + +```shell +cargo install --force cargo-stylus +``` + +Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: + +```shell +rustup default 1.80 +rustup target add wasm32-unknown-unknown --toolchain 1.80 +``` + +You can verify the cargo stylus installation by running `cargo stylus -V` in your terminal, returning something like:`stylus 0.5.6` + +### Using cargo stylus + +#### Cargo Stylus Commands Reference + +| Command | Description | Arguments | Options | Example Usage | +| ------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `new` | Create a new Stylus project | โ€ข `name`: Project name (required) | โ€ข `--minimal`: Create a minimal contract | `cargo stylus new ` | +| `init` | Initialize a Stylus project in current directory | | โ€ข `--minimal`: Create a minimal contract | `cargo stylus init --minimal` | +| `export-abi` | Export a Solidity ABI | | โ€ข `--output`: Output file (defaults to stdout)
    โ€ข `--json`: Write JSON ABI using `solc` | `cargo stylus export-abi --json` | +| `activate` | Activate an already deployed contract | โ€ข `--address`: Contract address to activate | โ€ข `--data-fee-bump-percent`: Percent to bump estimated fee (default 20%)
    โ€ข `--estimate-gas`: Only estimate gas without sending transaction | `cargo stylus activate --address ` | +| `cache` | Cache contract using Stylus CacheManager | โ€ข `bid`: Place bid on contract
    โ€ข `status`: Check contract status
    โ€ข `suggest-bid`: Get suggested minimum bid | | `cargo stylus cache bid --address ` | +| `check` | Check a contract | | โ€ข `--wasm-file`: WASM file to check
    โ€ข `--contract-address`: Deployment address | | +| `deploy` | Deploy a contract | โ€ข `--contract-address `: Where to deploy and activate the contract (defaults to a random address) | โ€ข `--estimate-gas`: Only perform estimation
    โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image
    โ€ข `--source-files-for-project-hash `: Path to source files to include in the project hash
    โ€ข `--max-fee-per-gas-gwei `: Optional max fee per gas in `gwei` units
    โ€ข `--wasm-file `: The WASM file to check (defaults to any found in the current directory) | `cargo stylus deploy --endpoint='http://localhost:8547' --private-key="" --estimate-gas` | +| `verify` | Verify contract deployment | โ€ข `--deployment-tx`: Hash of deployment transaction | โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image | | +| `cgen` | Generate C code bindings | โ€ข `--input`: Input file path
    โ€ข `--out_dir`: Output directory path | | | +| `replay` | Replay transaction in GDB | โ€ข `-t, --tx `: Transaction to replay | โ€ข `-p, --project `: Project path (default: `.`)
    โ€ข `-u, --use-native-tracer`: Use the native tracer instead of the JavaScript one (may not be available in the node)
    โ€ข `-s, --stable-rust`: Use stable Rust (note that nightly is needed to expand macros) | `cargo stylus replay --tx ` | +| `trace` | Trace a transaction | โ€ข `--tx`: Transaction hash | โ€ข `--endpoint`: RPC endpoint
    โ€ข `--project`: Project path
    โ€ข `--use-native-tracer`: Use native tracer | | + +##### Common options + +These options are available across multiple commands: + +| Option | Description | +| ------------------------------- | ------------------------------------------------------ | +| --endpoint | Arbitrum RPC endpoint (default: http://localhost:8547) | +| --verbose | Print debug info | +| --source-files-for-project-hash | Paths to source files for project hash | +| --max-fee-per-gas-gwei | Optional max fee per gas in `gwei` | + +##### Authentication options + +Available for commands involving transactions: + +| Option | Description | +| ------------------------ | ---------------------------------------------------- | +| --private-key-path | Path to file containing hex-encoded private key | +| --private-key | Private key as hex string (exposes to shell history) | +| --keystore-path | Path to Ethereum wallet keystore file | +| --keystore-password-path | Keystore password file path | + +#### How-tos + +| Topic | Description | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/how-tos/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/how-tos/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/how-tos/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | + +#### Additional resources + +#### [Troubleshooting](/stylus/troubleshooting-building-stylus.md): solve the most common issues. + +#### [cargo-stylus repository](https://github.com/OffchainLabs/stylus): consult cargo stylus' source code. diff --git a/sidebars.js b/sidebars.js index 58ac165850..287e57c5d0 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1453,7 +1453,7 @@ const sidebars = { { type: 'doc', id: 'stylus/reference/project-structure', - label: 'Structure of a Contract', + label: 'Structure of a project', }, { type: 'category', @@ -1491,6 +1491,8 @@ const sidebars = { type: 'doc', id: 'stylus/reference/contracts', label: 'Contracts', + }, + { type: 'doc', id: 'stylus/how-tos/testing-contracts', label: 'Writing Tests', @@ -1580,9 +1582,14 @@ const sidebars = { }, { type: 'category', - label: 'Using the CLI', + label: 'Using Stylus CLI', collapsed: true, items: [ + { + type: 'doc', + id: 'stylus/using-cli', + label: 'Overview', + }, { type: 'doc', id: 'stylus/how-tos/check-and-deploy', From 1f69649d2999fcfc10095589f844dc0cece31ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Dec 2025 18:56:09 -0800 Subject: [PATCH 083/162] rename contracts > structure of a contract --- sidebars.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sidebars.js b/sidebars.js index 287e57c5d0..af03827c8c 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1455,6 +1455,11 @@ const sidebars = { id: 'stylus/reference/project-structure', label: 'Structure of a project', }, + { + type: 'doc', + id: 'stylus/reference/contracts', + label: 'Structure of a contracts', + }, { type: 'category', label: 'Data types', @@ -1487,11 +1492,6 @@ const sidebars = { id: 'stylus/reference/global-variables-and-functions', label: 'Global variables and functions', }, - { - type: 'doc', - id: 'stylus/reference/contracts', - label: 'Contracts', - }, { type: 'doc', id: 'stylus/how-tos/testing-contracts', From c11a17a991b481948d06a80ea2695e4b91adc729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:12:12 -0800 Subject: [PATCH 084/162] reformat --- .../_troubleshooting-stylus-partial.mdx | 4 +- docs/stylus/concepts/webassembly.mdx | 2 +- .../adding-support-for-new-languages.mdx | 4 +- docs/stylus/how-tos/check-and-deploy.mdx | 4 +- .../deploying-non-rust-wasm-contracts.mdx | 2 +- docs/stylus/how-tos/optimizing-binaries.mdx | 2 +- docs/stylus/quickstart.mdx | 4 +- docs/stylus/reference/data-types/storage.mdx | 2 +- docs/stylus/reference/overview.md | 94 ++++++++++++ docs/stylus/reference/rust-sdk-guide.md | 136 +++++++----------- docs/stylus/using-cli.mdx | 2 +- static/building-stylus-faqs.json | 2 +- 12 files changed, 156 insertions(+), 102 deletions(-) create mode 100644 docs/stylus/reference/overview.md diff --git a/docs/partials/_troubleshooting-stylus-partial.mdx b/docs/partials/_troubleshooting-stylus-partial.mdx index 28cdc3f141..050d317a02 100644 --- a/docs/partials/_troubleshooting-stylus-partial.mdx +++ b/docs/partials/_troubleshooting-stylus-partial.mdx @@ -54,7 +54,7 @@ As an alternative solution, you can use [entrypoint-style contracts](https://doc ### Why do I get an error "no library targets found in package" when trying to compile and old example? -Some of the first Stylus examples were built and deployed using a previous version of [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) (`0.1.x`). In that version, Stylus projects were structured as regular Rust binaries. +Some of the first Stylus examples were built and deployed using a previous version of [cargo-stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) (`0.1.x`). In that version, Stylus projects were structured as regular Rust binaries. Since [cargo-stylus v0.2.1](https://github.com/OffchainLabs/cargo-stylus/releases/tag/v0.2.1), Stylus projects are structured as libraries, so when trying to compile old projects you might get an error `no library targets found in package`. @@ -62,7 +62,7 @@ To solve this, it's usually enough to rename the `main.rs` file to a `lib.rs` fi ### How can I generate the ABI of my Stylus contract? -The [cargo-stylus tool](https://github.com/OffchainLabs/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`. +The [cargo-stylus tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`. If you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so: diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 07d296b3ae..7ae24d0827 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -395,6 +395,6 @@ pub extern "C" fn pay_for_memory_grow(pages: u16) { - [WebAssembly specification](https://webassembly.github.io/spec/) - [Rust WASM target documentation](https://doc.rust-lang.org/rustc/platform-support/wasm32-unknown-unknown.html) - [Stylus SDK repository](https://github.com/OffchainLabs/stylus-sdk-rs) -- [Cargo Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus) +- [Cargo Stylus CLI tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) - [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) - [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) diff --git a/docs/stylus/how-tos/adding-support-for-new-languages.mdx b/docs/stylus/how-tos/adding-support-for-new-languages.mdx index 527e09fd95..346d42abfe 100644 --- a/docs/stylus/how-tos/adding-support-for-new-languages.mdx +++ b/docs/stylus/how-tos/adding-support-for-new-languages.mdx @@ -30,7 +30,7 @@ Programs written in Zig and deployed to Stylus have a tiny footprint and will ha ## Requirements - Download and install [Zig 0.11.0](https://ziglang.org/downloads) -- Install [Rust](https://www.rust-lang.org/tools/install), which we'll need for the [Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus) to deploy our program to the Stylus testnet +- Install [Rust](https://www.rust-lang.org/tools/install), which we'll need for the [Stylus CLI tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) to deploy our program to the Stylus testnet We'll also be using Rust to run an example script that can call our Zig contract on the Stylus testnet using the popular [ethers-rs](https://github.com/gakonst/ethers-rs) library. @@ -79,7 +79,7 @@ Next, we can build our Zig library to a freestanding WASM file for our onchain d zig build-lib ./src/main.zig -target wasm32-freestanding -dynamic --export=user_entrypoint -OReleaseSmall --export=mark_unused ``` -This is enough for us to deploy on the Stylus testnet! We'll use the [Stylus CLI tool](https://github.com/OffchainLabs/cargo-stylus), which you installed earlier using `cargo install`: +This is enough for us to deploy on the Stylus testnet! We'll use the [Stylus CLI tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus), which you installed earlier using `cargo install`: ``` cargo stylus deploy --private-key= --wasm-file=main.wasm diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/how-tos/check-and-deploy.mdx index 855667b2a6..aa60343b78 100644 --- a/docs/stylus/how-tos/check-and-deploy.mdx +++ b/docs/stylus/how-tos/check-and-deploy.mdx @@ -775,5 +775,5 @@ cargo stylus activate --address=
    [OPTIONS] - [Cargo Stylus repository](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) - [Testnet information](https://docs.arbitrum.io/stylus/reference/testnet-information) - [Contract verification guide](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts) -- [Optimizing WASM size](https://github.com/OffchainLabs/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md) -- [Valid WASM requirements](https://github.com/OffchainLabs/cargo-stylus/blob/main/VALID_WASM.md) +- [Optimizing WASM size](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md) +- [Valid WASM requirements](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/VALID_WASM.md) diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx index bf17673f71..25d39fe3f2 100644 --- a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -793,7 +793,7 @@ To support a new language: - [Stylus C SDK](https://github.com/OffchainLabs/stylus-sdk-c) - [WebAssembly specification](https://webassembly.github.io/spec/) - [WAT format reference](https://webassembly.github.io/spec/core/text/) -- [Cargo Stylus CLI](https://github.com/OffchainLabs/cargo-stylus) +- [Cargo Stylus CLI](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) - [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) - [WASM binary toolkit (wabt)](https://github.com/WebAssembly/wabt) - [Binaryen optimization tools](https://github.com/WebAssembly/binaryen) diff --git a/docs/stylus/how-tos/optimizing-binaries.mdx b/docs/stylus/how-tos/optimizing-binaries.mdx index c8de5e1323..7524a28812 100644 --- a/docs/stylus/how-tos/optimizing-binaries.mdx +++ b/docs/stylus/how-tos/optimizing-binaries.mdx @@ -11,7 +11,7 @@ displayed_sidebar: buildStylusSidebar To be deployed onchain, the size of your **uncompressed WebAssembly (WASM) file** must not exceed 128Kb, while the **compressed binary** must not exceed 24KB. Stylus conforms with the same contract size limit as the EVM to remain fully interoperable with all smart contracts on Arbitrum chains. -[cargo-stylus](https://github.com/OffchainLabs/cargo-stylus), the Stylus CLI tool, automatically compresses your WASM programs, but there are additional steps that you can take to further reduce the size of your binaries. +[cargo-stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus), the Stylus CLI tool, automatically compresses your WASM programs, but there are additional steps that you can take to further reduce the size of your binaries. Your options fall into two categories: Rust compiler flags, and third-party optimization tools. diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 7651067793..e74b73644a 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -82,7 +82,7 @@ cd nitro-devnode ## Creating a Stylus project with cargo stylus -[cargo stylus](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) is a CLI toolkit built to facilitate the development of Stylus contracts. +[cargo stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/main/VALID_WASM.md) is a CLI toolkit built to facilitate the development of Stylus contracts. It is available as a plugin to the standard cargo tool used for developing Rust programs. @@ -186,7 +186,7 @@ Location: prover/src/binary.rs:493:9, data: None ``` -The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. +The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/main/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. If your contract succeeds, you'll see something like this: diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 9870268ca1..27af6493d1 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -87,7 +87,7 @@ impl Contract { } ``` -### Integer storage +### Integer Storage Store unsigned and signed integers with various bit sizes: diff --git a/docs/stylus/reference/overview.md b/docs/stylus/reference/overview.md new file mode 100644 index 0000000000..4a0ef3998e --- /dev/null +++ b/docs/stylus/reference/overview.md @@ -0,0 +1,94 @@ +--- +title: 'Stylus Rust SDK overview' +description: 'An overview of the features provided by the Stylus Rust SDK' +author: jose-franco +sme: jose-franco +sidebar_position: 1 +sidebar_label: 'Overview' +user_story: 'As a developer, I want to understand the Stylus Rust SDK structure so I can navigate the documentation effectively.' +content_type: 'reference' +target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. +--- + +This section provides an in-depth overview of the features provided by the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs). For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../gentle-introduction.mdx). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../quickstart.mdx). + +The Stylus Rust SDK is built on top of [Alloy](https://www.paradigm.xyz/2023/06/alloy), a collection of crates empowering the Rust Ethereum ecosystem. Because the SDK uses the same [Rust primitives for Ethereum types](https://docs.rs/alloy-primitives/latest/alloy_primitives/), Stylus is compatible with existing Rust libraries. + +The Stylus Rust SDK has been audited in August 2024 at [commit #62bd831](https://github.com/OffchainLabs/stylus-sdk-rs/tree/62bd8318c7f3ab5be954cbc264f85bf2ba3f4b06) by Open Zeppelin which can be viewed [on our audits page](audit-reports.mdx). + +## Documentation index + +Use this index to navigate the Stylus Rust SDK reference documentation. + +### Fundamentals + +Learn the core concepts of writing smart contracts with the Stylus Rust SDK. + +| Article | Description | +| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| [Structure of a contract](/stylus/reference/project-structure) | Understand how Rust contracts are organized, including project layout, the entrypoint macro, and public methods. | +| [Global variables and functions](/stylus/reference/global-variables-and-functions) | Access blockchain context through the VM interface, including message sender, block info, and cryptographic functions. | +| [Contracts](/stylus/reference/contracts) | Learn about contract basics, storage definition, method declarations, and the contract lifecycle. | +| [Writing tests](/stylus/how-tos/testing-contracts) | Write and run tests for your contracts using the built-in testing framework without deploying to a blockchain. | + +### Data types + +Understand how to work with different data types in Stylus contracts. + +| Article | Description | +| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| [Primitives](/stylus/reference/data-types/primitives) | Use Rust primitive types (bool, integers, addresses) with automatic ABI encoding and Solidity type mappings. | +| [Compound types](/stylus/reference/data-types/compound-types) | Work with complex data structures including arrays, vectors, tuples, and custom structs. | +| [Storage](/stylus/reference/data-types/storage) | Define and manage persistent contract state using storage types and the storage macro. | +| [Conversions between types](/stylus/reference/data-types/conversions-between-types) | Convert between Rust types and Solidity-compatible types for cross-contract communication. | + +### Advanced topics + +Explore advanced features and optimization techniques for Stylus development. + +| Article | Description | +| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [Solidity differences](/stylus/advanced/solidity-differences) | Understand key differences between writing smart contracts in Solidity versus Stylus Rust. | +| [Recommended packages](/stylus/advanced/recommended-libraries) | Discover third-party Rust crates that work well with Stylus for extended functionality. | +| [Minimal entrypoint contracts](/stylus/advanced/minimal-entrypoint-contracts) | Build lightweight contracts with custom entrypoints for maximum gas efficiency. | +| [Hostio exports](/stylus/advanced/hostio-exports) | Access low-level host I/O functions for advanced contract behavior. | + +### Using the CLI + +Master the `cargo stylus` command-line tool for contract development and deployment. + +| Article | Description | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| [Verify contracts](/stylus/how-tos/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | +| [Exporting ABI](/stylus/how-tos/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | +| [Debugging with replay](/stylus/how-tos/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | +| [Optimizing WASM binary size](/stylus/how-tos/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | +| [Deploying non-Rust WASM contracts](/stylus/how-tos/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | + +### WASM concepts + +Understand how WebAssembly works within Arbitrum Nitro and its implications for Stylus development. + +| Article | Description | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | +| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | +| [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | +| [Caching strategy](/stylus/how-tos/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | + +### Troubleshooting + +| Article | Description | +| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| [Troubleshooting](/stylus/troubleshooting-building-stylus) | Find solutions to common issues encountered when building and deploying Stylus contracts. | + +### External references + +Additional resources for Stylus development. + +| Resource | Description | +| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | +| [Stylus by Example](https://stylus-by-example.org/) | Learn Stylus through practical, annotated code examples covering common patterns. | +| [Cargo Stylus CLI GitHub](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) | Source code and documentation for the `cargo stylus` command-line tool. | +| [Rust SDK Crate](https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html) | Official API documentation for the Stylus SDK on docs.rs. | +| [Source Code Repository](https://github.com/OffchainLabs/stylus-sdk-rs) | Browse the complete source code for the Stylus Rust SDK. | diff --git a/docs/stylus/reference/rust-sdk-guide.md b/docs/stylus/reference/rust-sdk-guide.md index 2d94fbb04f..48b5d16e7b 100644 --- a/docs/stylus/reference/rust-sdk-guide.md +++ b/docs/stylus/reference/rust-sdk-guide.md @@ -9,7 +9,7 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart import StylusNoMultiInheritanceBannerPartial from '../partials/_stylus-no-multi-inheritance-banner-partial.mdx'; -This document provides information about advanced features included in the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs), that are not described in the previous pages. For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../gentle-introduction.mdx). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../quickstart.mdx). +This document provides information about advanced features included in the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs), that are not described in the previous pages. For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../gentle-introduction.mdx). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../quickstart.mdx). :::info @@ -85,9 +85,9 @@ The above will expand to the equivalent definitions in Rust, each structure impl Because the layout is identical to [Solidityโ€™s](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html), existing Solidity smart contracts can upgrade to Rust without fear of storage slots not lining up. You simply copy-paste your type definitions. -:::warning Storage layout in contracts using trait composition +:::warning Storage layout in contracts using inheritance -When using trait-based composition (the pattern recommended in SDK 0.10.0+), storage is organized by embedding structs as fields. Each embedded struct occupies its own storage slots based on field order. This is consistent with regular struct nesting in Solidity, but differs from Solidity's inheritance model where parent contract storage is flattened. Plan your storage layout carefully when migrating from Solidity contracts that use inheritance. +One exception to this storage layout guarantee is contracts which utilize inheritance. The current solution in Stylus using `#[borrow]` and `#[inherits(...)]` packs nested (inherited) structs into their own slots. This is consistent with regular struct nesting in solidity, but not inherited structs. We plan to revisit this behavior in an upcoming release. ::: @@ -268,7 +268,7 @@ The above will make the public methods of `Contract` the first to consider durin If a contract calls another that then calls the first, it is said to be reentrant. By default, all Stylus contracts revert when this happens. However, you can opt out of this behavior by enabling the `reentrant` feature flag. ```rust -stylus-sdk = { version = "0.10.0", features = ["reentrant"] } +stylus-sdk = { version = "0.6.0", features = ["reentrant"] } ``` This is dangerous, and should be done only after careful reviewโ€“โ€“ideally by third-party auditors. Numerous exploits and hacks have in Web3 are attributable to developers misusing or not fully understanding reentrant patterns. @@ -279,86 +279,57 @@ If enabled, the Stylus SDK will flush the storage cache in between reentrant cal The [`#[entrypoint]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.entrypoint.html) macro will automatically implement the [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) trait for the annotated `struct`. The single type implementing [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) is special in that mutable access to it represents mutable access to the entire programโ€™s state. This idea will become important when discussing calls to other programs in later sections. -### Trait-based composition +### Inheritance, `#[inherit]`, and `#[borrow]`. -:::info SDK 0.10.0 changes - -Starting with SDK version 0.10.0, the inheritance model has been replaced with a trait-based composition pattern. The `#[inherit]` and `#[borrow]` attributes are no longer used. Instead, you implement traits on your contract type and use the `#[public]` macro's `impl` parameter to expose methods from embedded structs. - -::: - -Composition in Rust uses a trait-based model that provides explicit control over method routing. Types that implement [`Router`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html), the trait that [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) provides, can be composed together. +Composition in Rust follows that of Solidity. Types that implement [`Router`](https://docs.rs/stylus-sdk/latest/stylus_sdk/abi/trait.Router.html), the trait that [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) provides, can be connected via inheritance. ```rust -#[storage] -#[entrypoint] -pub struct Token { - erc20: Erc20, -} - -// Expose Erc20 methods through Token by implementing the trait #[public] -#[implements(IErc20)] +#[inherit(Erc20)] impl Token { pub fn mint(&mut self, amount: U256) -> Result<(), Vec> { - // Custom mint logic - self.erc20.balance_of(msg::sender())?; - Ok(()) + ... } } -// The Erc20 implementation provides the IErc20 trait #[public] impl Erc20 { - pub fn balance_of(&self, account: Address) -> Result> { - Ok(self.balances.get(account)) + pub fn balance_of() -> Result { + ... } } ``` -With the trait-based model, you explicitly define which methods are exposed at the contract's public interface. The `#[implements(...)]` attribute declares which interfaces your contract supports, making the ABI generation explicit and predictable. - -To delegate method calls to an embedded struct, use the `impl` parameter of the `#[public]` macro: +Because `Token` inherits `Erc20` in the above, if `Token` has the [`#[entrypoint]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.entrypoint.html), calls to the contract will first check if the requested method exists within `Token`. If a matching function is not found, it will then try the `Erc20`. Only after trying everything `Token` inherits will the call revert. -```rust -#[storage] -#[entrypoint] -pub struct Token { - erc20: Erc20, - erc721: Erc721, -} +Note that because methods are checked in that order, if both implement the same method, the one in `Token` will override the one in `Erc20`, which wonโ€™t be callable. This allows for patterns where the developer imports a crate implementing a standard, like the `ERC-20`, and then adds or overrides just the methods they want to without modifying the imported `Erc20` type. -// Delegate Erc20 methods to the embedded erc20 field -#[public] -impl Token { - // Token-specific methods - pub fn custom_method(&mut self) -> Result<(), Vec> { - Ok(()) - } -} +::::warning -// Expose Erc20 methods from the embedded struct -#[public(impl = "erc20")] -impl Token { - // Methods here delegate to self.erc20 -} +Stylus does not currently contain explicit `override` or `virtual` keywords for explicitly marking override functions. It is important, therefore, to carefully ensure that contracts are only overriding the functions. -// Expose Erc721 methods from the embedded struct -#[public(impl = "erc721")] -impl Token { - // Methods here delegate to self.erc721 -} -``` +:::: -This explicit delegation model provides clearer control over which methods are exposed and from which implementation they originate. +Inheritance can also be chained. `#[inherit(Erc20, Erc721)]` will inherit both `Erc20` and `Erc721`, checking for methods in that order. `Erc20` and `Erc721` may also inherit other types themselves. Method resolution finds the first matching method by [Depth First Search](https://en.wikipedia.org/wiki/Depth-first_search). -::::warning +For the above to work, `Token` must implement [`Borrow`](https://doc.rust-lang.org/core/borrow/trait.Borrow.html). You can implement this yourself, but for simplicity, [`#[storage]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.storage.html) and [`sol_storage!`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/macro.sol_storage.html) provide a `#[borrow]` annotation. -Unlike Solidity, Stylus does not have explicit `override` or `virtual` keywords. When composing multiple implementations, ensure method names are unique across all exposed interfaces to avoid conflicts. If the same method signature appears in multiple `#[public]` blocks, only the first one encountered will be callable. +```rust +sol_storage! { + #[entrypoint] + pub struct Token { + #[borrow] + Erc20 erc20; + ... + } -:::: + pub struct Erc20 { + ... + } +} +``` ### Fallback and receive functions @@ -393,7 +364,7 @@ Both methods can be annotated with `#[payable]` to accept ETH along with the tra ## Calls -Just as with storage and functions, Stylus SDK calls are Solidity ABI equivalent. This means you never have to know the implementation details of other contracts to invoke them. You simply import the Solidity interface of the target contract, which can be auto-generated via the `cargo stylus` [CLI tool](https://github.com/OffchainLabs/cargo-stylus#exporting-solidity-abis). +Just as with storage and functions, Stylus SDK calls are Solidity ABI equivalent. This means you never have to know the implementation details of other contracts to invoke them. You simply import the Solidity interface of the target contract, which can be auto-generated via the `cargo stylus` [CLI tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus#exporting-solidity-abis). :::tip @@ -440,21 +411,9 @@ Observe the casing change. [`sol_interface!`](https://docs.rs/stylus-sdk/latest/ [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) lets you configure a call via optional configuration methods. This is similar to how one would configure opening a [`File`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html#examples) in Rust. -:::info SDK 0.10.0 changes - -Starting with SDK version 0.10.0, the `Call` API uses new constructors that make the intent of each call explicit: - -- `Call::new()` - For pure/view calls that do not modify state -- `Call::new_mutating()` - For calls that may modify state (requires `&mut self`) -- `Call::new_payable()` - For calls that send value (requires `&mut self` and the method must be `#[payable]`) - -The previous `Call::new_in()` pattern is deprecated. - -::: - ```rust -pub fn do_call(&mut self, account: IService, user: Address) -> Result { - let config = Call::new_payable() +pub fn do_call(account: IService, user: Address) -> Result { + let config = Call::new_in() .gas(evm::gas_left() / 2) // limit to half the gas left .value(msg::value()); // set the callvalue @@ -462,7 +421,7 @@ pub fn do_call(&mut self, account: IService, user: Address) -> Result Result<(), Vec> { - Ok(methods.pure_foo(Call::new())?) // pure calls use Call::new() + Ok(methods.pure_foo(self)?) // `pure` methods might lie about not being `view` } pub fn call_view(&self, methods: IMethods) -> Result<(), Vec> { - Ok(methods.view_foo(Call::new())?) // view calls also use Call::new() + Ok(methods.view_foo(self)?) } pub fn call_write(&mut self, methods: IMethods) -> Result<(), Vec> { - methods.view_foo(Call::new())?; // view calls within mutating context - Ok(methods.write_foo(Call::new_mutating())?) // state-modifying calls use Call::new_mutating() + methods.view_foo(self)?; // allows `pure` and `view` methods too + Ok(methods.write_foo(self)?) } #[payable] pub fn call_payable(&mut self, methods: IMethods) -> Result<(), Vec> { - methods.write_foo(Call::new_mutating())?; // non-payable mutating call - Ok(methods.payable_foo(Call::new_payable())?) // payable calls use Call::new_payable() + methods.write_foo(Call::new_in(self))?; // these are the same + Ok(methods.payable_foo(self)?) // ------------------ } } ``` -In the above, we use the new `Call` constructors (`new()`, `new_mutating()`, `new_payable()`) which make the intent explicit. The contract still implements [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html), which means that access to it entails access to the entirety of the contract's state. This ensures all cached values are invalidated and/or persisted to state at the right time. +In the above, weโ€™re able to pass `&self` and `&mut self` because `Contract` implements [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html), which means that a reference to it entails access to the entirety of the contractโ€™s state. This is the reason it is sound to make a call, since it ensures all cached values are invalidated and/or persisted to state at the right time. -When writing Stylus libraries, the new `Call` constructors make it explicit what type of call you're making: +When writing Stylus libraries, a type might not be [`TopLevelStorage`](https://docs.rs/stylus-sdk/latest/stylus_sdk/storage/trait.TopLevelStorage.html) and therefore `&self` or `&mut self` wonโ€™t work. Building a [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) from a generic parameter via [`new_in`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html#method.new_in) is the usual solution. ```rust pub fn do_call( + storage: &mut impl TopLevelStorage, // can be generic, but often just &mut self account: IService, // serializes as an Address user: Address, ) -> Result { - let config = Call::new_payable() // explicitly a payable call + let config = Call::new_in(storage) // take exclusive access to all contract storage .gas(evm::gas_left() / 2) // limit to half the gas left .value(msg::value()); // set the callvalue @@ -519,7 +479,7 @@ pub fn do_call( } ``` -The choice of constructor (`new()`, `new_mutating()`, or `new_payable()`) makes the intent clear and helps the compiler enforce correct usage. In the context of a [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) call, using `new_mutating()` or `new_payable()` will correctly distinguish the method as being `write` or [`payable`](https://docs.alchemy.com/docs/solidity-payable-functions). +In the context of a [`#[public]`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/attr.public.html) call, the `&mut impl` argument will correctly distinguish the method as being `write` or [`payable`](https://docs.alchemy.com/docs/solidity-payable-functions). This means you can write library code that will work regardless of whether the reentrant feature flag is enabled. Also, that code that previously compiled with reentrancy disabled may require modification in order to type-check. This is done to ensure storage changes are persisted and that the storage cache is properly managed before calls. @@ -528,7 +488,7 @@ Also, that code that previously compiled with reentrancy disabled may require mo Though [`sol_interface!`](https://docs.rs/stylus-sdk/latest/stylus_sdk/prelude/macro.sol_interface.html) and [`Call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.Call.html) form the most common idiom to invoke other contracts, their underlying [`call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/fn.call.html) and [`static_call`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/fn.static_call.html) are exposed for direct access. ```rust -let return_data = call(Call::new_mutating(), contract, call_data)?; +let return_data = call(Call::new_in(self), contract, call_data)?; ``` In each case the calldata is supplied as a [`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html). The return result is either the raw return data on success, or a call [`Error`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/enum.Error.html) on failure. @@ -544,9 +504,9 @@ This method invokes the other contract, which may in turn call others. All gas i ::: ```rust -transfer_eth(recipient, value)?; // these two are equivalent +transfer_eth(recipient, value)?; // these two are equivalent -call(Call::new_payable().value(value), recipient, &[])?; // these two are equivalent +call(Call::new_in().value(value), recipient, &[])?; // these two are equivalent ``` ### [`RawCall`](https://docs.rs/stylus-sdk/latest/stylus_sdk/call/struct.RawCall.html) and `unsafe` calls diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index da6b73b4fa..249ab2822f 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -9,7 +9,7 @@ target_audience: Developers writing Stylus contracts in Rust using Stylus displayed_sidebar: buildStylusSidebar --- -This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. +This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. This overview will help you discover and learn how to uses cargo stylus tools. diff --git a/static/building-stylus-faqs.json b/static/building-stylus-faqs.json index e348130405..4b295e0a6e 100644 --- a/static/building-stylus-faqs.json +++ b/static/building-stylus-faqs.json @@ -46,7 +46,7 @@ }, { "question": "How can I generate the ABI of my Stylus contract?", - "answer": "The [cargo-stylus tool](https://github.com/OffchainLabs/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`.\n\nIf you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so:\n\n```rust\n[features]\nexport-abi = [\"stylus-sdk/export-abi\"]\n```\nYou'll also need to have a `main.rs` file that selects that feature.\n\nThis is an example of a `main.rs` file that allows you to export the ABI of the [stylus-hello-world](https://github.com/OffchainLabs/stylus-hello-world) example project:\n\n```rust\n#![cfg_attr(not(feature = \"export-abi\"), no_main)]\n\n#[cfg(feature = \"export-abi\")]\nfn main() {\n stylus_hello_world::main();\n}\n```\n\n\n", + "answer": "The [cargo-stylus tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`.\n\nIf you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so:\n\n```rust\n[features]\nexport-abi = [\"stylus-sdk/export-abi\"]\n```\nYou'll also need to have a `main.rs` file that selects that feature.\n\nThis is an example of a `main.rs` file that allows you to export the ABI of the [stylus-hello-world](https://github.com/OffchainLabs/stylus-hello-world) example project:\n\n```rust\n#![cfg_attr(not(feature = \"export-abi\"), no_main)]\n\n#[cfg(feature = \"export-abi\")]\nfn main() {\n stylus_hello_world::main();\n}\n```\n\n\n", "key": "how-can-i-generate-the-abi-of-my-stylus-contract" } ] From f57c6fe81140c03df4da8f8cf25aefd9aa64685a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:12:57 -0800 Subject: [PATCH 085/162] fix Arbos version to 51 --- docs/notices/fusaka-upgrade-notice.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/notices/fusaka-upgrade-notice.mdx b/docs/notices/fusaka-upgrade-notice.mdx index e1b0b6c44f..3caf89e14f 100644 --- a/docs/notices/fusaka-upgrade-notice.mdx +++ b/docs/notices/fusaka-upgrade-notice.mdx @@ -7,7 +7,7 @@ content_type: notice :::danger ๐Ÿ›‘ IMPORTANT ๐Ÿ›‘ -Arbitrum chain operators must ensure that their nodes are properly configured before or shortly after the parent chain upgrades to Fusaka or the child chain upgrades to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx). +Arbitrum chain operators must ensure that their nodes are properly configured before or shortly after the parent chain upgrades to Fusaka or the child chain upgrades to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx). ::: From a1dda5040d1e0ce50f9e24474f0058131e8c9ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:15:48 -0800 Subject: [PATCH 086/162] delete deprecated oracle references --- docs/for-devs/oracles/dia/dia.mdx | 67 -------------------- docs/for-devs/oracles/pyth/pyth.mdx | 77 ----------------------- docs/for-devs/oracles/quex/quex.mdx | 97 ----------------------------- 3 files changed, 241 deletions(-) delete mode 100644 docs/for-devs/oracles/dia/dia.mdx delete mode 100644 docs/for-devs/oracles/pyth/pyth.mdx delete mode 100644 docs/for-devs/oracles/quex/quex.mdx diff --git a/docs/for-devs/oracles/dia/dia.mdx b/docs/for-devs/oracles/dia/dia.mdx deleted file mode 100644 index 7366ea1761..0000000000 --- a/docs/for-devs/oracles/dia/dia.mdx +++ /dev/null @@ -1,67 +0,0 @@ ---- -id: 'dia' -title: 'DIA' -description: Learn how to integrate oracles into your Arbitrum app -user_story: As a developer, I want to understand how to use oracles in Arbitrum to get offchain data onchain. -content_type: how-to ---- - -[DIA](https://www.diadata.org/) is a cross-chain oracle provider that enhances data transparency, customization, and accessibility. With a novel architecture aggregating raw trade data directly from first-party sources, namely centralized and decentralized exchanges, DIA offers 100% source transparency, bespoke customization, and chain-native asset price feeds. - -You can find an example on how to use DIA in your project on this [page](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle). - -### How to use DIA oracles on Arbitrum - -**Requesting a custom oracle**: DIA deploys oracles tailored to each appโ€™s needs. Each oracle is customizable, including data sources, cleansing filters, pricing, computational methodologies, update mechanisms, and more. This flexibility ensures that the data and oracle remain robust and resilient to the market conditions and provide a global market price and specific individual or cross-chain market prices. -โ†’ [Request a Custom Oracle for your dApp | DIA Documentation](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle) - -### Token Price Feeds - -DIA token price feeds provide smart contracts with real-time price information for [3,000+ cryptocurrencies](https://diadata.org/app/price), sourced from [80+ trusted, high-volume DEXs and CEXs](https://diadata.org/app/source/defi). - -### How to access DIA oracles? - -Here is an example of how to access a price value on DIA oracles: - -1. Access your custom oracle smart contract on Arbitrum. -2. Call `getValue(pair_name)` with `pair_name` being the full pair name such as `BTC/USD`. You can use the "Read" section on the explorer to execute this call. -3. The response of the call contains two values: - -- The current asset price in `USD` with a fix-comma notation of 8 decimals. -- The UNIX timestamp of the last oracle update. - -You can find DIA's oracle integration samples in Solidity and Vyper languages by visiting: -โ†’ [Access the Oracle | DIA Documentation](https://docs.diadata.org/products/token-price-feeds/access-the-oracle) - -### Arbitrum demo price oracles - -DIA has deployed the following demo oracles for the Arbitrum community. It provides a limited selection of cryptocurrency price feeds with predefined configuration settings. - -:::note - -DIA demo oracles are not intended for use in production environments. Developers can request a dedicated, production-ready oracle with custom price feeds and configuration settings. Start the request process: [Request a Custom Oracle | DIA Documentation](https://docs.diadata.org/introduction/intro-to-dia-oracles/request-an-oracle) - -::: - -### Demo Oracle Smart Contracts - -| Network | Contract address | -| ------------- | --------------------------------------------------------------------------------------------------------------------------- | -| Arbitrum | [`0xd041478644048d9281f88558e6088e9da97df624`](https://arbiscan.io/address/0xd041478644048d9281f88558e6088e9da97df624) | -| Arbitrum Nova | [`0xa707a5c6a180da0ae2ef17ebff54f1f3589d9670`](https://nova.arbiscan.io/address/0xa707a5c6a180da0ae2ef17ebff54f1f3589d9670) | - -### Included Price Feeds - -[DIA/USD](https://diadata.org/app/price/asset/Ethereum/0x84cA8bc7997272c7CfB4D0Cd3D55cd942B3c9419/), [BTC/USD](https://diadata.org/app/price/asset/Bitcoin/0x0000000000000000000000000000000000000000/), [USDC/USD](https://diadata.org/app/price/asset/Ethereum/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/) - -### Supported token API endpoints - -DIA supports API and GraphQL endpoints to return cryptocurrency price data. You can [visit the DIA Documentation](https://docs.diadata.org/products/token-price-feeds/access-api-endpoints) to see all API endpoints. - -### NFT Price Feeds - -DIA NFT floor price feeds provide smart contracts with real-time price information of [18,000+ NFT collections](https://diadata.org/app/floor-price), sourced onchain with 100% transparency from [multiple, cross-chain NFT marketplaces](https://diadata.org/app/source/nft). - -### Supported NFT API endpoints - -DIA supports API endpoints to return cryptocurrency price data. Developers can directly access the example endpoints listed below or [visit the DIA Documentation](https://docs.diadata.org/use-nexus-product/readme/token-price-feeds/access-api-endpoints) to see all API endpoints. diff --git a/docs/for-devs/oracles/pyth/pyth.mdx b/docs/for-devs/oracles/pyth/pyth.mdx deleted file mode 100644 index 0b63b878b6..0000000000 --- a/docs/for-devs/oracles/pyth/pyth.mdx +++ /dev/null @@ -1,77 +0,0 @@ ---- -id: 'pyth' -title: 'Pyth' -description: 'Learn how to use Pyth Oracle' -author: pete-vielhaber -sme: pete-vielhaber -sidebar_label: 'pyth' -content_type: how-to ---- - -The [Pyth network](https://pyth.network/) a first-party oracle network, securely and transparently delivering real-time market data to [multiple chains](https://docs.pyth.network/price-feeds/contract-addresses). - -The network comprises some of the worldโ€™s [largest exchanges, market makers, and financial services providers](https://pyth.network/publishers). These publish proprietary data onchain for aggregation and distribution to smart contract applications. - -## Pyth price feeds - -The Pyth network introduces an innovative low-latency [pull oracle design](https://docs.pyth.network/price-feeds/pull-updates), where users can pull price updates onchain when needed, enabling everyone in the blockchain environment to access that data point. Pyth network updates the prices every 400ms, making Pyth the fastest onchain oracle. - -Here is a working example of a contract that fetches the latest price of `ARB/USD` on the Arbitrum network. - -You have to pass Pyth's contract address for Arbitrum mainnet/testnet and the desired price feed ID to fetch the latest price. - -Install the Pyth SDK Solidity package in your project: - -```tsx -npm install @pythnetwork/pyth-sdk-solidity -``` - -And then, in a few lines of code you can fetch the latest price on the Arbitrum network. - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; -import "@pythnetwork/pyth-sdk-solidity/IPyth.sol"; -import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol"; -contract MyFirstPythContract { - IPyth pyth; - // Pass the address of Pyth's contract for Arbitrum mainnet(0xff1a0f4744e8582DF1aE09D5611b887B6a12925C) - constructor(address _pyth) { - pyth = IPyth(_pyth); - } - function fetchPrice( - bytes[] calldata updateData, - bytes32 priceFeed - ) public payable returns (int64) { - // Fetch the priceUpdate from hermes. - uint updateFee = pyth.getUpdateFee(updateData); - pyth.updatePriceFeeds{value: updateFee}(updateData); - // Fetch the latest price - PythStructs.Price memory price = pyth.getPrice(priceFeed); - return price.price; - } -} -``` - -Here you can fetch the `updateData` from Pyth's [Hermes](https://hermes.pyth.network/docs/) feed, which listens to Pythnet and Wormhole for price updates; or you can use the [pyth-evm-js](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/ethereum/sdk/js/src/EvmPriceServiceConnection.ts#L15) SDK. Check [How to Fetch Price Updates](https://docs.pyth.network/price-feeds/fetch-price-updates) to pull the latest data. - -## Pyth Entropy - -Pyth Entropy allows developers to quickly and easily generate secure **random numbers** on the blockchain. - -Check [how to generate random numbers in EVM contracts](https://docs.pyth.network/entropy/generate-random-numbers/evm) for a detailed walkthrough. - -### Supported networks for Arbitrum(Pyth Entropy): - -- Arbitrum: [`0x7698E925FfC29655576D0b361D75Af579e20AdAc`](https://arbiscan.io/address/0x7698E925FfC29655576D0b361D75Af579e20AdAc) -- Arbitrum Sepolia: [`0x549Ebba8036Ab746611B4fFA1423eb0A4Df61440`](https://sepolia.arbiscan.io/address/0x549Ebba8036Ab746611B4fFA1423eb0A4Df61440) - -## Additional resources - -Check out the following links to get started with Pyth: - -- [Pyth EVM Integration Guide](https://docs.pyth.network/price-feeds/use-real-time-data/evm) -- [Pyth Docs](https://docs.pyth.network/home) -- [Pyth API Reference](https://api-reference.pyth.network/price-feeds/evm/getPrice) -- [Pyth Examples](https://github.com/pyth-network/pyth-examples) -- [Pyth Price Feed Ids](https://pyth.network/developers/price-feed-ids) diff --git a/docs/for-devs/oracles/quex/quex.mdx b/docs/for-devs/oracles/quex/quex.mdx deleted file mode 100644 index 7b85efa0dd..0000000000 --- a/docs/for-devs/oracles/quex/quex.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -id: 'quex' -title: 'Quex' -sidebar_label: 'Quex' -description: 'Learn how to make verifiable HTTP requests from your Arbitrum dApp' -author: catena2w -sme: catena2w -user_story: As an Arbitrum developer, I want to learn how to use oracles in my dApp. -content_type: get-started ---- - -:::warning - -Quex contracts are currently undergoing security audits and infrastructure security improvements. Before using Quex oracles in production dApps, please reach out via [on Discord](https://discord.com/invite/NsuE32xHvj). Quex will be happy to assist you with the integration and, if needed, set up a dedicated data oracle pools if there is a need. - -::: - -[Quex](https://quex.tech/) is an oracle protocol designed to securely deliver verifiable offchain data to onchain smart contracts using confidential computing proofs. Quex oracles enable dApps on Arbitrum to reliably and securely access real-world data, empowering developers to build advanced financial applications, parametric tokens, prediction markets, and more. - -Unlike traditional oracles, Quex allows developers to securely make verifiable API calls to virtually any offchain data source โ€”โ€“ including private APIs protected by credentials. This means you're not limited to predefined data feeds and can securely access the entire internet. - -### Querying the API endpoint through Quex - -Here's an example of how to use Quex to securely fetch the TVL data for the AAVE protocol from DefiLlama's [API endpoint](https://api.llama.fi/tvl/aave). This example will also include basic post-processing to showcase Quex's capabilities for verifiable offchain computations. We'll build our example using [Foundry](https://book.getfoundry.sh) (Forge), but feel free to use your preferred tools. - -Quex provides a package with convenient libraries that simplify making requests and verifying responses. First, install this package in your project: - -```bash -forge install quex-tech/quex-v1-interfaces -``` - -Here's a complete Solidity example demonstrating how to use Quex for verifiable API calls within an Arbitrum smart contract: - -```solidity -import "quex-v1-interfaces/src/libraries/QuexRequestManager.sol"; - -contract ApiCallConsumer is QuexRequestManager { - /** - * Network: Arbitrum One - * Quex Core: 0xD8a37e96117816D43949e72B90F73061A868b387 - * Request Oracle Pool: 0x957E16D5bfa78799d79b86bBb84b3Ca34D986439 - */ - constructor(address _coreAddress, address _poolAddress) QuexRequestManager(_coreAddress){ - setUpFlow(quexCore, oraclePool); - } - - /** - * @notice Creates a new flow to fetch TVL data from the DeFi Llama API for Aave, multiplies it by 1e18, - * and rounds to the nearest integer. - */ - function setUpFlow(address quexCore, address oraclePool) private onlyOwner { - FlowBuilder.FlowConfig memory config = FlowBuilder.create(quexCore, oraclePool, "api.llama.fi", "/tvl/aave"); - config = config.withFilter(". * 1000000000000000000 | round"); - config = config.withSchema("uint256"); - config = config.withCallback(address(this), this.processResponse.selector); - registerFlow(config); - } - - /** - * Verify proofs and processes a response from Request Oracle Pool - */ - function processResponse(uint256 receivedRequestId, DataItem memory response, IdType idType) - external verifyResponse(receivedRequestId, idType) - { - uint256 lastTVL = abi.decode(response.value, (uint256)); - } -} -``` - -The most interesting part here is the `setUpFlow` function. It relies on two contracts, Core and the HTTP oracle pool, that are already [deployed on Arbitrum](https://docs.quex.tech/general-information/addresses). This function specifies the host (`api.llama.fi`) and path (`/tvl/aave`) for future requests that the oracle will perform upon request. - -Most APIs return JSON responses, which aren't very convenient to process directly in Solidity. To extract necessary data, Quex oracles support response post-processing: a script written in the [JQ language](https://docs.quex.tech/developers/https_pool/jq_subset) which is applied before passing the data onchain. Our example script defined in `config.withFilter(". * 1000000000000000000 | round");` multiplies the response by `1e18` and rounds it to the nearest integer. Since Quex supports operations with complex response structures, we must define a schema for the returned result. In our example, `config.withSchema("uint256");` specifies the return type as a simple numeric value. - -As we've mentioned, Quex is a pull oracle operating in a request-response model. Thanks to the efficient confidential computing security model, proof generation is extremely fast, and you can expect responses with proofs delivered in the next block. However, because this is still an asynchronous operation, we must define a callback, a function called once the response is delivered. This is done in the line `config.withCallback(address(this), this.processResponse.selector);`, specifying that the contract's own `processResponse` function will be invoked. - -### Making requests - -Quex supports both offchain and onchain initiated data [delivery modes](https://docs.quex.tech/general-information/data_delivery). This example relies on the on-chain mechanism, meaning that data requests must be initiated directly from your smart contract. To request data, simply call the built-in `request()` method, which triggers the entire process. Note that this method is payable, as you need to attach enough funds to cover the callback gas fees. - -Once the response is generated, it is passed to the `processResponse` method we've specified as a callback. The response arrives with confidential computing proofs, preventing any data manipulation. However, by the time the data reaches your contract, these proofs are already verified within the Quex core. Still, calling `verifyResponse(receivedRequestId, idType)` remains essential to ensure that the response originates from the correct Quex core address and corresponds exactly to the original request. After that, you only need to unpack the data according to the schema you've defined: - -```solidity -uint256 lastTVL = abi.decode(response.value, (uint256)); -``` - -Tada! You now have your response to the defined API call โ€“โ€“ with complete certainty about its authenticity and security! - -## Connect with us! - -Still looking for answers? We got them! Check out all the ways you can reach us: - -- Visit us at [quex.tech](https://quex.tech) -- Read our [Docs](https://docs.quex.tech) -- Explore our [examples repository](https://github.com/quex-tech/quex-v1-examples) -- Chat with us on [Telegram](https://t.me/quex_tech) -- Follow us on [X](https://x.com/quex_tech) -- Join our [Discord](https://discord.com/invite/NsuE32xHvj) From 8b743f65dd38d9e8a820cc6a1508c11f253c7bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:38:01 -0800 Subject: [PATCH 087/162] fix missig arbos51 file + add overview of stylus cli on click --- .../arbos-releases/arbos51.mdx | 152 ++++++++++++++++++ sidebars.js | 9 +- 2 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 docs/run-arbitrum-node/arbos-releases/arbos51.mdx diff --git a/docs/run-arbitrum-node/arbos-releases/arbos51.mdx b/docs/run-arbitrum-node/arbos-releases/arbos51.mdx new file mode 100644 index 0000000000..7d17633b02 --- /dev/null +++ b/docs/run-arbitrum-node/arbos-releases/arbos51.mdx @@ -0,0 +1,152 @@ +--- +title: 'ArbOS 51 Dia' +sidebar_label: 'ArbOS 51 Dia' +sidebar_position: 2 +description: 'Learn about ArbOS 51 Dia release, including Fusaka upgrade support, new EIPs, bug fixes, and upgrade requirements for Arbitrum chain owners and node operators.' +user_story: As an Arbitrum chain owner or node operator, I want to know what ArbOS 51 implements. +author: zk-Lumi +sme: zk-Lumi +content_type: release note +--- + +import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition'; + + + +ArbOS 51 Dia is still pre-release. This document may change. + + + +This page is intended for all Arbitrum node operators and Arbitrum chain owners chains. This page summarizes the changes brought by ArbOS 51 Dia, and what you should do to ensure a seamless upgrade. + + + +Before Ethereum Parent chain Sepolia and Mainnet upgrade to Fusaka: ensure that your Nitro node version is upgraded and consensus layer client is configured as per the [Fusaka upgrade notice](../../notices/fusaka-upgrade-notice.mdx). + + +The minimum Nitro version that supports ArbOS 51 "Dia" is [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3), which is available on Docker Hub with the image tag `Noffchainlabs/nitro-node:v3.9.3-8bc5554`. This release of Nitro is a mandatory upgrade for Arbitrum One and Nova node operators if adopted. For Arbitrum One and Nova, the ArbOS 51 "Dia" upgrade will require a governance vote to activate. + +As a refresher, ArbOS upgrades get treated as Arbitrum's equivalent of a hard fork. To learn more, refer to the [Arbitrum ArbOS upgrades forum post](https://forum.arbitrum.foundation/t/arbitrum-arbos-upgrades/19695). Note that ArbOS 51 Dia is an upgrade that builds upon [ArbOS 40 Callisto](./arbos40.mdx). + +### Requirements + +- Having read and understood the [ArbOS Software Releases Overview page](./01-overview.mdx). +- Running [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) or higher, which is available on Docker Hub with the image tag `offchainlabs/nitro-node:v3.9.3-8bc5554`. + - Note that it's important to run Nitro v3.9.3 only against trusted databases. If you want to use an untrusted database, you can first remove the `wasm` directory if it exists (potentially inside the `nitro` folder). Otherwise, the database may have malicious, unvalidated code that can result in remote code execution. Avoiding unvalidated code is also mitigated by ensuring you run the Arbitrum Nitro node inside Docker. +- Running [nitro-contracts v3.1.0](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.0) or higher + - If your chain isn't ready to activate BoLD, use [nitro-contracts v2.1.3](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v2.1.3) instead; v3.0.0 or higher can't be used without activating BoLD. + - If you want to enable [Native Token Mint/Burn capabilities](#native-token-mint-and-burn) for your chain, you must use [nitro-contracts v3.1.1](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.1) or higher. +- WASM module root: `0x8a7513bf7bb3e3db04b0d982d0e973bcf57bf8b88aef7c6d03dba3a81a56a499` +- If the Arbitrum chain posts blobs to a Fusaka-enabled parent chain, ensure that the consensus layer client is configured correctly as per the [Fusaka upgrade notice](../../notices/fusaka-upgrade-notice.mdx). + +### High-level description of ArbOS 51 changes + +ArbOS 51 Dia is an upgrade to support the relevant EVM changes that are a part of Ethereum's [Fusaka upgrade](https://ethereum.org/en/roadmap/fusaka/). Ethereum's mainnet upgrade to Fusaka is tentatively scheduled for [December 3, 2025 at epoch `411392`](https://notes.ethereum.org/@bbusa/fusaka-bpo-timeline). As a result, the majority of the ArbOS-specific changes revolve around implementing the relevant [Fusaka EIPs](https://eips.ethereum.org/EIPS/eip-7607) on Arbitrum Chains. + +Here's the list of all changes included in ArbOS 51 Dia: + +#### [EIP-7951: Precompile for secp256r1 curve support](https://eips.ethereum.org/EIPS/eip-7951) + +This EIP implements the same functionality and interface as [RIP-7212](https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md), which was activated as part of [ArbOS 31 Bianca](https://forum.arbitrum.foundation/t/aip-arbos-31-bianca-activation-of-arbitrum-stylus-rip-7212-support-nova-fee-router-proposal/25904). The main difference here is to add a point-at-infinity check and to update the comparison step in the signature verification algorithm. Developers should expect the same behavior as the EIP being proposed on Ethereum after Fusaka is activated. + +#### [EIP-7825: Transaction gas limit cap](https://eips.ethereum.org/EIPS/eip-7825) + +This EIP introduces a gas cap for individual transactions. The goal is to ensure fairer access to block space and improve network stability. For Arbitrum One and Arbitrum Nova we're proposing a 32 million gas limit (Child chain execution gas, not including parent chain gas) per transaction, which is the same as the current block gas limit. This 32 million gas limit diverges from the EIP's proposed limit of 16 million gas per transaction for Ethereum parent chain. Orbit chains can customize this value according to their chains' needs. + +#### [EIP-7642: eth/69 - history expiry and simpler receipts](https://eips.ethereum.org/EIPS/eip-7642) + +This networking upgrade removes deprecated fields used prior to Ethereum's Proof of Stake (PoS) transition. We're including this EIP as part of Geth upstream. This is a networking change that impacts mainly parent chain nodes. As Arbitrum nodes don't have a P2P layer, we don't expect this to have any impact on Arbitrum node operators. + +#### [EIP-7939: Count leading zeros (CLZ) opcode](https://eips.ethereum.org/EIPS/eip-7939) + +This EIP adds a new CLZ (Count Leading Zeros) opcode to efficiently count the number of zero bits at the start of a 256-bit number. This is a fundamental mathematical operation used in many algorithms, especially for mathematical computations, data compression, and cryptographic operations. Currently, implementing this operation in Solidity requires complex and expensive code - this opcode makes it much cheaper and faster. + +#### [EIP-7823: Set upper bounds for ModExp](https://eips.ethereum.org/EIPS/eip-7823) + +This EIP introduces an 8192-bit (1024 byte) limit on each input to the ModExp cryptographic precompile. ModExp has been a source of consensus bugs due to unbounded inputs. By setting practical limits that cover real-world use cases (like RSA verification), this reduces the testing surface area and paves the way for future replacement with more efficient EVM code. + +#### [EIP-7883: ModExp gas cost increase](https://eips.ethereum.org/EIPS/eip-7883) + +This EIP increases the gas cost of the ModExp cryptographic precompile to address underpriced operations. It raises the minimum cost from 200 to 500 gas and doubles the costs for large inputs over 32 bytes. + +#### [EIP-7910: eth_config JSON-RPC method](https://eips.ethereum.org/EIPS/eip-7910) + +This EIP provides a new RPC method that allows the Arbitrum Nitro node to respond with key configuration variables, offering node operators the ability to gain greater confidence that their Nitro nodes are correctly configured and prepared for upcoming forks. In future Nitro releases, we expect to include additional fields specific to Arbitrum chains. This update is at the RPC level and may be enabled later than the ArbOS 51 Dia upgrade. + +#### [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) + +As [disclosed previously](https://forum.arbitrum.foundation/t/disclosure-of-support-for-eip-2537-on-arbitrum-one-and-nova/29720), the precompiled contracts for performing various operations over the BLS12-381 elliptic curve, including BLS Signature verification, were added but not properly enabled in [ArbOS 40 Callisto](./arbos40.mdx) as originally expected. ArbOS 51 Dia will now enable `EIP-2537`. + +#### ArbOS block limit change: Effective block gas limit + +Since ArbOS 51 introduces a `MaxTxGasLimit`, the State Transition Function (STF) will be relaxed in ArbOS 51 to allow the final transaction in a block to use up to the `MaxTxGasLimit` even if it would cause the block to exceed `MaxBlockGasLimit`. This means that the "Effective Block Gas Limit" is really `MaxBlockGasLimit + MaxTxGasLimit`. In previous versions of ArbOS, the Sequencer would skip transactions if the transaction request's `GasLimit` minus the parent chain data posting gas exceeded the gas remaining in the block. + +The new algorithm is more efficient because the sequencer doesn't need to keep searching through the queue of transactions to find one that fits in the remaining block gas, and can continue to add transactions until the unused block gas is 0. + +This change doesn't affect the `GasTarget`, and therefore doesn't affect how much overall gas per second the chain will use - only how transactions using that gas could be divided between different blocks. + +#### A few bug fixes + +- ArbOS didn't get updated for parent chain calldata price increase + - This change standardizes the calculation of gas units for compressed Batch calldata across the codebase by replacing hard-coded values with a method call (tokenGasUnits). +- `EIP-7702` precompile delegation behavior divergence + - Previously, calls to precompiles could execute an INVALID opcode instead of succeeding with no execution. ArbOS 51 Dia will update code to align with `EIP-7702` spec to treat precompile code as empty during delegation. +- ARM and x86 divergence + - This change adds a map to store transaction hash along with its gas used to bypass transaction execution for a problematic transaction execution which diverged between ARM and x86 architectures. This was added in to hardcode one transaction that caused the divergence on Arbitrum Sepolia, as disclosed in the [security council emergency Action report](https://forum.arbitrum.foundation/t/security-council-emergency-action-10-13-2025/30093). + - The default WASM Stack Depth value in ArbOS is now set to 22,000, preventing new chains from encountering the same divergence issue. + +#### Raising the gas target, increasing the min L2 base fee, & improving the pricing algorithm + +As part of our strategy for scaling Arbitrum technology, the ArbOS 51 release includes a slight change to improve the pricing algorithm for Arbitrum One and Nova. This improvement is aimed at reducing the severity, frequency, and duration of high L2 gas prices during periods of elevated demand on the network. Concretely, the changes are to: + +- Replace the current single gas target and single adjustment window, with a new model that employs multiple (higher) gas targets, measured over multiple adjustment windows. +- Increase the default minimum L2 base fee from 0.01 gwei per gas to 0.02 gwei per gas. + +To read more about this change, see the [AIP for raising the gas target & improvements to the pricing algorithm](https://forum.arbitrum.foundation/t/aip-raise-the-gas-target-implement-improvements-to-the-pricing-algorithm/30182). + +#### A constraint-based pricing change: STF instrumentation to track multi-gas + +We've instrumented Arbitrum's State Transition Function (STF) to track gas usage across multiple resource types including computation, storage access, storage growth, and history growth, rather than only a single total based on opcodes. This work lays the foundation for dynamic, constraint-based pricing where gas fees can adjust based on the most constrained resource at the network level. The goal is to create more stable prices, improve responsiveness to spikes, and allow the network to safely increase throughput without overloading node hardware. In this release, none of the constraints are enabled, so there won't be any impact on current gas prices. This update simply adds the ability to measure and record per-resource usage, with actual pricing changes coming in a later version once constraints are configured, benchmarked and tested. + +To read more about this feature, see the [dynamic pricing explainer](https://blog.arbitrum.io/dynamic-pricing-explainer/). + +#### Native token mint and burn + +Native token mint and burn is a feature that allows Arbitrum chains to use interoperability-enabled token standards (e.g., LayerZero OFTs, xERC20s, native USDC) as native gas tokens on their chains. Currently, Arbitrum chains are designed to "lock and mint" native gas tokens on the chain's canonical Bridge. However, doing so means that these "locked and minted" native gas tokens can't interact with third-party cross-chain adapter contracts. This new feature lets an Arbitrum chain delegate minting and burning of its native gas token to a trusted bridge provider (e.g., LayerZero OFT). + +Native token mint and burn is included in ArbOS 51 Dia for the benefit of Arbitrum Orbit chains (reducing the need for forks) and to streamline development and testing into a single codebase. There are no plans to enable this feature on Arbitrum One or Arbitrum Nova, consequently this feature will be explicitly left disabled for Arbitrum One and Arbitrum Nova. + +To read more about this feature, see the [Native Token Mint/Burn enablement guide](https://arbitrum.notion.site/Enable-Native-Mint-Burn-for-your-chain-s-gas-token-22601a3f59f880be9b99d3d55f982a17). + + + +If you want to enable Native Token Mint/Burn capabilities for your chain, you must use [nitro-contracts v3.1.1](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.1) or higher. + + + +### Fusaka EIPs that aren't proposed to be in ArbOS 51 Dia + +Support and implementation for the following EIPs aren't planned to be part of ArbOS 51 Dia: + +- [EIP-7594](https://eips.ethereum.org/EIPS/eip-7594), [EIP-7918](https://eips.ethereum.org/EIPS/eip-7918), and [EIP-7892](https://eips.ethereum.org/EIPS/eip-7892), since Arbitrum chains don't have blob data markets (though they do support posting blob data to a non-Arbitrum parent chain) +- [EIP-7917](https://eips.ethereum.org/EIPS/eip-7917), since Arbitrum chains don't have a beacon chain and therefore don't have a peer-to-peer layer like Ethereum does +- [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934), this EIP is to help propagating blocks between nodes. Arbitrum doesn't do that - it sends messages (which are limited) and each node builds every block by itself +- [EIP-7907](https://eips.ethereum.org/EIPS/eip-7907), this EIP is no longer Scheduled For Inclusion (SFI) for Fusaka, as agreed upon by Client teams during [ACDE 216](https://ethereum-magicians.org/t/allcoredevs-execution-acde-216-july-17-2025/24770/2) on July 17, 2025. We're currently exploring alternative ways to increase the Smart Contract size limit that don't interfere with the ability for Arbitrum chains to support `EIP-7907` in the future. See this [forum post reply](https://forum.arbitrum.foundation/t/non-constitutional-proposal-to-direct-the-arbitrum-foundation-to-implement-an-extended-version-of-eip-7907-and-for-the-dao-to-ratify-its-deployment-on-arbitrum-one/29375/3) for more details about this. +- [EIP-7935](https://eips.ethereum.org/EIPS/eip-7935), since Arbitrum chains already have a default gas target of 28Mgas/s and we have separate, alternative plans for increasing the gas limit through other means, as mentioned in [Scaling Arbitrum everywhere](https://blog.arbitrum.io/scaling-arbitrum-everywhere/). + +### Special note about ArbOS 51 Dia for chains that haven't yet upgraded to use Arbitrum BoLD + +While ArbOS 51 Dia will be compatible with both `nitro-contracts 3.1.X` and `nitro-contracts 2.1.3`, only chains that have Arbitrum BoLD enabled can use `nitro-contracts 3.x`. This requirement means that if your chain hasn't yet upgraded to use BoLD, only use `nitro-contracts 2.1.3` for your ArbOS 51 Dia upgrade. + +### Reference links for ArbOS 51 Dia + +- [Guide for how to upgrade ArbOS on your Arbitrum chain](../../launch-arbitrum-chain/02-configure-your-chain/common-configurations/13-arbos-upgrade.mdx) +- [README for how to upgrade your rollup contracts to support ArbOS 51 on your chain](https://github.com/OffchainLabs/orbit-actions?tab=readme-ov-file#nitro-contracts-upgrades) +- [Nitro v3.9.3](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) +- [nitro-contracts v3.1.1](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v3.1.1) +- [nitro-contracts v2.1.3](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v2.1.3) (only relevant for Arbitrum chains that don't have BoLD enabled yet) +- [AIP: ArbOS Version 50 Dia Forum Post](https://forum.arbitrum.foundation/t/constitutional-aip-arbos-version-50-dia/) +- [Temperature check vote on Snapshot for ArbOS 50 Dia](https://snapshot.box/#/s:arbitrumfoundation.eth/proposal/0x33754da4006d0ef38666ec5d5e85fd0966a891a594ab9dc21f23beedea2d330b) +- [AIP: ArbOS Version 51 Raising the gas target & improvements to pricing algorithm Forum Post](https://forum.arbitrum.foundation/t/aip-raise-the-gas-target-implement-improvements-to-the-pricing-algorithm/30182) +- [Temperature check vote on Snapshot for ArbOS 51 Raising the gas target & improvements to pricing algorithm](https://snapshot.box/#/s:arbitrumfoundation.eth/proposal/0x4a96a91d162975de0d402b83ca8b8a24e808ca357150120fc0d44ae0bf1cc4a5) +- Coming Soon - ArbOS 50 & ArbOS 51 Audit Report, from Trail of Bits diff --git a/sidebars.js b/sidebars.js index af03827c8c..ba2ed7291a 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1584,12 +1584,11 @@ const sidebars = { type: 'category', label: 'Using Stylus CLI', collapsed: true, + link: { + type: 'doc', + id: 'stylus/using-cli', + }, items: [ - { - type: 'doc', - id: 'stylus/using-cli', - label: 'Overview', - }, { type: 'doc', id: 'stylus/how-tos/check-and-deploy', From 9e81cfb00ce451e2bc04ab4351544db7a1fb1638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:43:47 -0800 Subject: [PATCH 088/162] add overview of stylus SDK on click --- sidebars.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sidebars.js b/sidebars.js index ba2ed7291a..4edc5c726e 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1444,12 +1444,12 @@ const sidebars = { type: 'category', label: 'Stylus Rust SDK', collapsed: true, + link: { + type: 'doc', + id: 'stylus/reference/overview', + }, + items: [ - { - type: 'doc', - id: 'stylus/reference/overview', - label: 'Overview', - }, { type: 'doc', id: 'stylus/reference/project-structure', From 8ec849c0751c67af770be03a53329a3d6407af84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:47:47 -0800 Subject: [PATCH 089/162] remove obsolete content maps --- .../node-running/node-running-content-map.mdx | 98 ------------------- docs/node-running/sequencer-content-map.mdx | 38 ------- sidebars.js | 8 -- 3 files changed, 144 deletions(-) delete mode 100644 docs/node-running/node-running-content-map.mdx delete mode 100644 docs/node-running/sequencer-content-map.mdx diff --git a/docs/node-running/node-running-content-map.mdx b/docs/node-running/node-running-content-map.mdx deleted file mode 100644 index 01e0c38fb9..0000000000 --- a/docs/node-running/node-running-content-map.mdx +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: node-running-content-map -title: Run an Arbitrum node -sidebar_label: Run an Arbitrum node ---- - -import Card from '@site/src/components/Cards/Card'; - -# Run an Arbitrum node - -Learn how to run an Arbitrum node. - -
    - - - - - - - - - - - - - -
    diff --git a/docs/node-running/sequencer-content-map.mdx b/docs/node-running/sequencer-content-map.mdx deleted file mode 100644 index cd4465ec67..0000000000 --- a/docs/node-running/sequencer-content-map.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -id: sequencer-content-map -title: Sequencer -sidebar_label: Sequencer ---- - -import Card from '@site/src/components/Cards/Card'; - -# Sequencer - -Keep your node in sync with the sequencer. - -
    - - - -
    diff --git a/sidebars.js b/sidebars.js index 4edc5c726e..a64b74e1ae 100644 --- a/sidebars.js +++ b/sidebars.js @@ -106,10 +106,6 @@ const sidebars = { type: 'category', label: 'Oracles', collapsed: true, - link: { - type: 'doc', - id: 'for-devs/oracles/oracles-content-map', - }, items: [ { type: 'doc', @@ -669,10 +665,6 @@ const sidebars = { type: 'category', label: 'Sequencer', collapsed: true, - link: { - type: 'doc', - id: 'node-running/sequencer-content-map', - }, items: [ { type: 'doc', From 4daf01cffc9b3efd7faf5ddd6f2a74c0d1b7361a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:49:23 -0800 Subject: [PATCH 090/162] delete obsolete Stylus how it works --- docs/stylus/concepts/how-it-works.md | 82 ---------------------------- 1 file changed, 82 deletions(-) delete mode 100644 docs/stylus/concepts/how-it-works.md diff --git a/docs/stylus/concepts/how-it-works.md b/docs/stylus/concepts/how-it-works.md deleted file mode 100644 index f9bfda604c..0000000000 --- a/docs/stylus/concepts/how-it-works.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: how-it-works -title: 'Architecture overview' -sidebar_label: 'Architecture overview' -description: 'Learn what powers Stylus' -author: srinjoyc -SME: srinjoyc -user_story: As an Ethereum developer/project owner, I need to vet the Stylus. -content_type: concept ---- - -import { VanillaAdmonition } from '@site/src/components/VanillaAdmonition/'; - -There are four main steps for bringing a Stylus program to life: **coding, activation, execution, and proving**. - -## Coding - -Developers can now write smart contracts in any programming language that compiles to WASM. - -:::note -Some high-level languages generate far more performant WASMs than others. -::: - -Currently, there is support for Rust, C, and C++. However, the levels of support vary. Rust has rich language support from day one, with an open-source SDK that makes writing smart contracts in Rust as easy as possible. C and C++ are supported off the bat, enabling the deployment of existing contracts in those languages onchain with minimal modifications. - -The Stylus SDK for Rust contains the smart contract development framework and language features most developers will need to use in Stylus. The SDK also makes it possible to perform all EVM-specific functionalities that smart contract developers use. Check out the [Rust SDK Guide](/stylus/reference/rust-sdk-guide.md) and the [Crate Docs](https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html). - -## Activation - -Starting from a high-level language (such as Rust, C, or C++), the first compilation stage happens using the CLI provided in the Stylus SDK for Rust or any other compiler, such as Clang for C and C++. Once compiled, the WASM is posted onchain. Then, in an activation process, WASM gets lowered to a node's native machine code (such as ARM or x86). - -Activating a Stylus program requires a new precompile, ArbWasm. This precompile produces efficient binary code tailored to a node's native assembly. During this step, a series of middlewares ensure that user programs execute safely and are deterministically fraud-proven. Instrumentation includes gas metering, depth-checking, memory charging, and more to guarantee all WASM programs are safe for the chain to execute. Stylus contracts can be called only after activation. - -Gas metering is essential for certifying that computational resources are paid for. In Stylus, the unit for measuring cost is called **ink**, which is similar to Ethereum's gas but thousands of times smaller. There are two reasons why a new measurement is used: First, WASM execution is so much faster than the EVM that executing thousands of WASM opcodes could be done in the same amount of time it takes the EVM to execute one. Second, the conversion rate of ink to gas can change based on future hardware or VM improvements. For a conceptual introduction to Stylus gas and ink, see [gas and ink (Stylus)](/stylus/concepts/gas-metering.mdx). - - - Stylus smart contracts will need to be reactivated once per year (365 days) or whenever an upgrade - to Stylus (which will always involve an ArbOS upgrade), even if they are in the cache. To complete - this reactivation, you can use - [`cargo-stylus`](https://docs.arbitrum.io/stylus/using-cli#cargo-stylus-commands-reference) or - directly through the [ArbWasm - precompile](https://docs.arbitrum.io/build-decentralized-apps/precompiles/reference#arbwasm). If - contracts do not get reactivated, they will no longer be callable. - - -## Execution - -Stylus programs execute in a fork of [Wasmer](https://wasmer.io/), the leading WebAssembly runtime, with minimal changes to optimize their codebase for blockchain-specific use cases. Wasmer executes native code much faster than Geth executes EVM bytecode, contributing to the significant gas savings that Stylus provides. - -EVM contracts continue to execute the same way they were before Stylus. When calling a contract, the difference between an EVM contract and a WASM program is visible via an [EOF](https://notes.ethereum.org/@ipsilon/evm-object-format-overview)-inspired contract header. From there, the contract executes using its corresponding runtime. Contracts written in Solidity and WASM languages can make cross-contract calls to each other, meaning a developer never has to consider which language the contract is in. Everything is interoperable. - -## Proving - -Nitro operates in two modes: a "happy case" where it compiles execution history to native code, and a "sad case" during validator disputes, where it compiles execution history to WASM for interactive fraud proofs on Ethereum. Stylus builds on Nitro's fraud-proving technology, allowing it to verify both execution history and WASM programs deployed by developers. - -Stylus is made possible by Nitroโ€™s ability to replay and verify disputes using WASM. Validators bisect disputes until an invalid step is identified and proven onchain through a [โ€œone-step proof.โ€](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx#step-5-ensuring-correctness-validation-and-dispute-resolution). This deterministic fraud-proving capability ensures the correctness of any arbitrary program compiled to WASM. The combination of WASM's and Nitro's properties enables this technological leap we call Stylus. - -For more details on Nitroโ€™s architecture, refer to the [documentation](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx) or the Arbitrum whitepaper. - -## Why does this matter? - -Stylus innovates on many levels, with the key ones described here: - -### One chain, many languages - -There are roughly 20k Solidity developers, compared to three million Rust developers or 12 million C developers [[1](https://slashdatahq.medium.com/state-of-the-developer-nation-23rd-edition-the-fall-of-web-frameworks-coding-languages-711525e3df3a)]. Developers can now use their preferred programming language, which is interoperable on any Arbitrum chain with Stylus. By onboarding the next million developers, scaling to the next billion users becomes possible. - -### A better EVM - -Stylus' MultiVM brings the best of both worlds. Developers still get all of the benefits of the EVM, including the ecosystem and liquidity, while getting efficiency improvements and access to existing libraries in Rust, C, and C++, all without changing anything about how the EVM works. EVM equivalence is no longer the ceiling; it's the floor. - -### Cheaper execution - -Stylus is a more efficient execution environment than the EVM, leading directly to gas savings for complex smart contracts. Computation and memory can be significantly cheaper. Deploying cryptography libraries can be done permissionlessly as custom application layer precompiles. Use cases that are impractical in the EVM are now possible in Stylus. - -### Opt-in reentrancy - -Stylus doesn't just improve on cost and speed. WASM programs are also safer. Reentrancy is a common vulnerability developers can only attempt to mitigate in Solidity. Stylus provides cheap reentrancy detection, and using the Rust SDK, reentrancy is disabled by default unless intentionally overridden. - -### Fully interoperable - -Solidity programs and WASM programs are completely composable. If working in Solidity, a developer can call a Rust program or rely on another dependency in a different language. If working in Rust, all Solidity functionalities are accessible out of the box. From 6d40cb5a0d98d164532c21932cb7134b79203792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:52:15 -0800 Subject: [PATCH 091/162] remove unused node running contribute --- docs/node-running/contribute.mdx | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 docs/node-running/contribute.mdx diff --git a/docs/node-running/contribute.mdx b/docs/node-running/contribute.mdx deleted file mode 100644 index 4f7c3501cf..0000000000 --- a/docs/node-running/contribute.mdx +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: 'Contribute docs' -description: "Learn how to contribute to Arbitrum's documentation" ---- - -import ContributeDocsPartial from '../partials/_contribute-docs-partial.mdx'; - - From 2e9eeb7ff539d19ece6d83fa51cd9d337c2d4cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:54:20 -0800 Subject: [PATCH 092/162] fix link fusaka arbos version --- docs/notices/fusaka-upgrade-notice.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/notices/fusaka-upgrade-notice.mdx b/docs/notices/fusaka-upgrade-notice.mdx index 3caf89e14f..0a0a35f449 100644 --- a/docs/notices/fusaka-upgrade-notice.mdx +++ b/docs/notices/fusaka-upgrade-notice.mdx @@ -23,8 +23,8 @@ The following dates are relevant for Arbitrum chain operators. | Date | Network upgrade | Affected audience | | ---------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx) | Node operators for Arbitrum Sepolia | -| `Jan 8th, 2026, 17:00:00 UTC (proposed)` | Arbitrum One/Nova upgrade to [ArbOS 50](docs/run-arbitrum-node/arbos-releases/arbos50.mdx) | Node operators for Arbitrum One/Nova | +| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum Sepolia | +| `Jan 8th, 2026, 17:00:00 UTC (proposed)` | Arbitrum One/Nova upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum One/Nova | | `Oct 14th 2025, 07:36:00 UTC` | Ethereum Sepolia Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Sepolia (Orbit L2s, Arbitrum Sepolia) | | `Dec 3rd 2025, 21:49:11 UTC` | Ethereum Mainnet Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Mainnet (Orbit L2s, Arbitrum One/Nova) | From ea4428f118e36bcaaa16de10a8b2ab2cb1354058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 08:56:13 -0800 Subject: [PATCH 093/162] fix link fusaka arbos version --- docs/notices/fusaka-upgrade-notice.mdx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docs/notices/fusaka-upgrade-notice.mdx b/docs/notices/fusaka-upgrade-notice.mdx index 0a0a35f449..3a99ceabde 100644 --- a/docs/notices/fusaka-upgrade-notice.mdx +++ b/docs/notices/fusaka-upgrade-notice.mdx @@ -23,7 +23,8 @@ The following dates are relevant for Arbitrum chain operators. | Date | Network upgrade | Affected audience | | ---------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum Sepolia | +| `Nov 20th 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to ArbOS 50 | Node operators for Arbitrum Sepolia | +| `Dec 1st 2025, 17:00:00 UTC` | Arbitrum Sepolia upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum Sepolia | | `Jan 8th, 2026, 17:00:00 UTC (proposed)` | Arbitrum One/Nova upgrade to [ArbOS 51](docs/run-arbitrum-node/arbos-releases/arbos51.mdx) | Node operators for Arbitrum One/Nova | | `Oct 14th 2025, 07:36:00 UTC` | Ethereum Sepolia Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Sepolia (Orbit L2s, Arbitrum Sepolia) | | `Dec 3rd 2025, 21:49:11 UTC` | Ethereum Mainnet Fusaka hard fork | Node operators for Arbitrum chains settling on Ethereum Mainnet (Orbit L2s, Arbitrum One/Nova) | @@ -34,12 +35,18 @@ Outlined below are different types of Arbitrum chains, along with node software | Layer | Data Availability | Fallback to blobs enabled? | Required Nitro node version | Configurations for the Ethereum Consensus Layer client | | ------ | -------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **L2** | **Rollup** | N/A | Update to [`3.9.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) (ArbOS 50); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | -| **L2** | **AnyTrust / AltDA** | Enabled | Update to [`3.9.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.0) (ArbOS 50); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | +| **L2** | **Rollup** | N/A | Update to [`3.9.3`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) (ArbOS 51); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | +| **L2** | **AnyTrust / AltDA** | Enabled | Update to [`3.9.3`](https://github.com/OffchainLabs/nitro/releases/tag/v3.9.3) (ArbOS 51); [`3.8.0`](https://github.com/OffchainLabs/nitro/releases/tag/v3.8.0) or [`3.7.6`](https://github.com/OffchainLabs/nitro/releases/tag/v3.7.6) (ArbOS 40 or older) | Requires all [historical blob data](#how-to-ensure-your-node-has-access-to-all-historical-blob-data-and-blob-data-from-all-subnets) | | **L2** | **AnyTrust / AltDA** | Disabled | No nitro update required | Doesn't require historical blob data | | **L3** | **Rollup** | N/A | No nitro update required | Doesn't require historical blob data | | **L3** | **AnyTrust / AltDA** | Enabled or Disabled | No nitro update required | Doesn't require historical blob data | +:::warning Exceptions + +For batch posters settling to mainnet Ethereum, Nitro >=3.8.0 is required. + +::: + ### How to ensure your node has access to all historical blob data and blob data from all subnets #### If you run a Nitro node and use an external L1 Ethereum beacon chain RPC: From 9f97c60e22a84a49bf6d81b68277fb38bc968726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 09:43:29 -0800 Subject: [PATCH 094/162] revert irrelevant edit --- docs/run-arbitrum-node/02-run-full-node.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run-arbitrum-node/02-run-full-node.mdx b/docs/run-arbitrum-node/02-run-full-node.mdx index 5338cc996c..1311ac7e15 100644 --- a/docs/run-arbitrum-node/02-run-full-node.mdx +++ b/docs/run-arbitrum-node/02-run-full-node.mdx @@ -150,7 +150,7 @@ If you are running more than on node, you should [run a feed relay](/run-arbitru ### Pruning - Pruning a full node refers to removing older, unnecessary data from the local copy of the blockchain that the node maintains, thereby saving disk space and slightly improving the node's efficiency. Pruning will remove all states from blocks older than the latest 128. -- You can activate pruning by using the parameter `--init.prune` and using "full" or "validator" as the value (depending on the type of node you are running). Note that this process occurs when the node starts and will not serve RPC requests during pruning. +- If you are using the default setting `--execution.caching.state-scheme=hash` then you can activate pruning by using the parameter: ### Transaction prechecker From 62fe951542c03c4abd84b853b55ad3fc01b8a811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 10:19:53 -0800 Subject: [PATCH 095/162] update notion content --- ...troubleshooting-arbitrum-chain-partial.mdx | 62 +++++++--------- .../_troubleshooting-bridging-partial.mdx | 8 --- .../_troubleshooting-building-partial.mdx | 14 +--- .../_troubleshooting-nodes-partial.mdx | 14 +--- .../_troubleshooting-stylus-partial.mdx | 44 +++++++++--- .../_troubleshooting-users-partial.mdx | 14 +--- static/building-faqs.json | 4 +- static/building-orbit-faqs.json | 72 +++++++++---------- static/building-stylus-faqs.json | 27 ++++++- static/get-started-faqs.json | 7 +- static/node-running-faqs.json | 6 +- 11 files changed, 136 insertions(+), 136 deletions(-) diff --git a/docs/partials/_troubleshooting-arbitrum-chain-partial.mdx b/docs/partials/_troubleshooting-arbitrum-chain-partial.mdx index b67ef7407b..7b61754aa8 100644 --- a/docs/partials/_troubleshooting-arbitrum-chain-partial.mdx +++ b/docs/partials/_troubleshooting-arbitrum-chain-partial.mdx @@ -1,67 +1,59 @@ ---- -partial_type: troubleshooting -title: 'Arbitrum Chain Troubleshooting Guide' -description: 'Common issues and solutions for Arbitrum chain operations' -author: anegg0 -last_reviewed: 2025-11-06 ---- +### Can I use the Chain SDK to deploy a mainnet chain? -### Can I use Orbit to deploy a mainnet chain? +Yes! The Arbitrum Chain SDK's core technology has undergone a comprehensive audit and is now capable of supporting deployments to mainnet. You can read more about it in our [preview expectations notice](https://docs.arbitrum.io/launch-orbit-chain/concepts/public-preview-expectations#arbitrum-orbit-is-mainnet-ready-but-deploy-to-testnet-first). -Yes! Arbitrum Orbit's core technology has undergone a comprehensive audit and is now capable of supporting deployments to mainnet. You can read more about it [in our public preview annoucement](https://docs.arbitrum.io/launch-orbit-chain/concepts/public-preview-expectations#arbitrum-orbit-is-mainnet-ready-but-deploy-to-testnet-first). +### Do I need permission/license to launch an Arbitrum chain? -### Do I need permission/license to launch an Orbit chain? - -You can launch any Arbitrum Orbit chain permissionlessly. +You can launch any Arbitrum chain permissionlessly. Nitro's license is under a [Business Source license](https://github.com/OffchainLabs/nitro?tab=License-1-ov-file), similar to DeFi protocols like Uniswap and Aave, among others. This license contains an Additional Use Grant that permits the permissionless deployment of Nitro software on blockchains that settle to Arbitrum One or Nova. -However, Arbitrum Orbit chains that settle to a parent chain other than Arbitrum One or Nova are subject to additional licensing guidelines under the [AEP](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf). +However, Arbitrum chains that settle to a parent chain other than Arbitrum One or Nova are subject to additional licensing guidelines under the [AEP](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf). ### Does Arbitrum officially deploy and/or maintain L3s for external teams? -No. Teams are required to deploy and maintain their Arbitrum Orbit chains. There are, however, several RaaS (Rollup as a Service) providers that can deploy and maintain your Arbitrum Orbit chain on your behalf. +No. Teams are required to deploy and maintain their Arbitrum chains. There are, however, several RaaS (Rollup as a Service) providers that can deploy and maintain your Arbitrum chain on your behalf. -### Can I modify Orbit's underlying technology to customize my chain? +### Can I modify the underlying technology to customize my Arbitrum chain? Yes, you can make any changes you require to the underlying Nitro code base. -### What Data Availability (DA) solutions are currently available for Orbit chains? +### What Data Availability (DA) solutions are currently available for Arbitrum chains? -Arbitrum Orbit currently supports three different DA solutions: +Arbitrum chains currently support three different DA solutions: - Rollup, posting data to the parent chain, which ultimately posts the data to Ethereum. - AnyTrust, posting data to a Data Availability Committee, selected by the chain owner. - Celestia, posting data to the [Celestia network](https://blog.celestia.org/celestia-is-first-modular-data-availability-network-to-integrate-with-arbitrum-orbit/). Note that using AnyTrust provides the chain owner with the most flexibility and the most cost-effective fees. -### What token is used to pay gas fees on Orbit chains? +### What token is used to pay gas fees on Arbitrum chains? -By default, Arbitrum Orbit chains pay gas in `ETH`. However, Arbitrum Orbit chains that use AnyTrust are configurable to use any `ERC-20` token for the gas fee token of the chain. +By default, Arbitrum chains pay gas in `ETH`. However, Arbitrum chains that use AnyTrust are configurable to use any `ERC-20` token for the gas fee token of the chain. -### Can I use Ethereum toolkits to develop on my Orbit chain? +### Can I use Ethereum toolkits to develop on my Arbitrum chain? -Arbitrum Orbit chains are fully EVM-compatible. Most tools that support Ethereum should be able to support an Arbitrum Orbit chain. There are, however, specific differences that developers need to consider when building on an Orbit chain. You can find them [in our Arbitrum vs. Ethereum overview](https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/overview). +Arbitrum chains are fully EVM-compatible. Most tools that support Ethereum should be able to support an Arbitrum chain. There are, however, specific differences that developers need to consider when building on an Arbitrum chain. You can find them in our [overview of the differences between Arbitrum and Ethereum](https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/overview). -### Do Orbit chains have any built-in AA solution? +### Do Arbitrum chains have any built-in AA solution? Not by default, but they can be customized to have native AA. -### Is there any cross-chain bridging solution between two Orbit chains? +### Is there any cross-chain bridging solution between two Arbitrum chains? -There is currently no native Orbit-to-Orbit chain bridging solution, except for going through the parent chain (even if they share the same parent chain). However, many third-party bridges have expressed interest in supporting Arbitrum Orbit chains. +There is currently no native Arbitrum-to-Arbitrum chain bridging solution, except for going through the parent chain (even if they share the same parent chain). However, many third-party bridges have expressed interest in supporting Arbitrum chains. -### Is there an official block explorer for Orbit chains? +### Is there an official block explorer for Arbitrum chains? -Arbitrum Orbit chains deployments usually come with an open-source Blockscout explorer by default, but there are many third-party solutions that have expressed interest in supporting Arbitrum Orbit chains. +Arbitrum chains deployments usually come with an open-source Blockscout explorer by default, but there are many third-party solutions that have expressed interest in supporting Arbitrum chains. -### Is there any indexing solution that supports Orbit chains? +### Is there any indexing solution that supports Arbitrum chains? -Similar to bridges and block explorers, there are many third-party indexing solutions that have expressed interest in supporting Arbitrum Orbit chains. +Similar to bridges and block explorers, there are many third-party indexing solutions that have expressed interest in supporting Arbitrum chains. -### Can I increase the maximum contract size for my Orbit chain? +### Can I increase the maximum contract size for my Arbitrum chain? -Yes, Arbitrum Orbit chains support an increased smart contract size limit of up to 96kB. You can use our [Orbit SDK](https://github.com/OffchainLabs/arbitrum-orbit-sdk) and configure the parameters `[MaxCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[ and ](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[MaxInitCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)` when calling `[prepareNodeConfig](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/examples/prepare-node-config/index.ts#L43)`. Once deployed, you cannot change the parameters for the smart contract size limit through an upgrade. +Yes, Arbitrum chains support an increased smart contract size limit of up to 96kB. You can use our [Chain SDK](https://github.com/OffchainLabs/arbitrum-orbit-sdk) and configure the parameters `[MaxCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[ and ](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[MaxInitCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)` when calling `[prepareNodeConfig](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/examples/prepare-node-config/index.ts#L43)`. Once deployed, you cannot change the parameters for the smart contract size limit through an upgrade. ### How can I modify Nitro to force posting an invalid assertion and test the fraud proof mechanism? @@ -74,9 +66,9 @@ go test ./system_tests/ -tags=challengetest -run=TestChallenge ### What fee collectors can be configured on my chain? -Four fee types are configurable on an Orbit chain: +Four fee types are configurable on an Arbitrum chain: -- **L2 base fee**: L2 execution fees corresponding to the minimum base price of the chain. This fee is deposited into the infraFeeAccount, which can be set by calling `ArbOwner.setInfraFeeAccount().` +- **L2 base fee**: L2 execution fees corresponding to the minimum base price of the chain. This fee is deposited into the `infraFeeAccount`, which can be set by calling `ArbOwner.setInfraFeeAccount().` - **L2 surplus fee**: L2 execution fees above the minimum base price (in the case of congestion). This fee goes to the `networkFeeAccount`, which can be set by calling `ArbOwner.setNetworkFeeAccount().` - **L1 base fee**: Relative fees for posting a transaction on the parent chain. This fee is paid ultimately to the fee collector of the active batch poster. A call to `SequencerInbox.setIsBatchPoster()` on the parent chain will set the batch poster. Delegating a different fee collector for that batch poster can be specified by calling `ArbAggregator.setFeeCollector()`. - **L1 surplus fee**: Any extra fees rewarded to the batch poster. This is paid to a specific `L1RewardRecipient`, which can be set by calling `ArbOwner.setL1PricingRewardRecipient()`. @@ -86,7 +78,7 @@ To learn more about precompiles, refer to the [Precompiles reference page](https ### What is the lowest you can set the base fee to? -You can set the base fee to any amount to charge users less. You can even set it to `0` (however, this would open the chain to DOS attacks). If the Orbit base fee is `0`, users are then only paying for the cost of DA. +You can set the base fee to any amount to charge users less. You can even set it to `0` (however, this would open the chain to DOS attacks). If the Arbitrum chain base fee is `0`, users are then only paying for the cost of DA. ### How does fee collection work in Nitro? @@ -134,7 +126,7 @@ Test this thoroughly on a testnet first. ### What is the max theoretical TPS for an Arbitrum Chain? -Max TPS is a challenging metric to measure, as it relies on network activity and the type of submitted transactions. We can, however, calculate the max throughput using default orbit chain parameters. +Max TPS is a challenging metric to measure, as it relies on network activity and the type of submitted transactions. We can, however, calculate the max throughput using default Arbitrum chain parameters. The actual maximum throughput depends on the configurable execution parameters: @@ -152,7 +144,7 @@ The actual maximum throughput depends on the configurable execution parameters: ### Why is the WETH Gateway not necessary for custom gas token chains? -The `WETH` gateway used in the token bridge is a special, custom gateway that unwraps the `WETH` deposits and sends them to the Arbitrum chain, then wraps them again on the Arbitrum chain. Since `ETH` is the gas token in the Arbitrum (Orbit) chain, there's no need to perform this operation, so you can use a standard `ERC-20` for `WETH` (this is the default case of the token bridge so that you wouldn't need a special `WETH` gateway). +The `WETH` gateway used in the token bridge is a special, custom gateway that unwraps the `WETH` deposits and sends them to the Arbitrum chain, then wraps them again on the Arbitrum chain. Since `ETH` is the gas token in the Arbitrum chain, there's no need to perform this operation, so you can use a standard `ERC-20` for `WETH` (this is the default case of the token bridge so that you wouldn't need a special `WETH` gateway). If you want to enable extra custom operations with `WETH`, you can create a custom token and a custom gateway to handle this case. diff --git a/docs/partials/_troubleshooting-bridging-partial.mdx b/docs/partials/_troubleshooting-bridging-partial.mdx index 43cc06fbfc..7172a50dd8 100644 --- a/docs/partials/_troubleshooting-bridging-partial.mdx +++ b/docs/partials/_troubleshooting-bridging-partial.mdx @@ -1,11 +1,3 @@ ---- -partial_type: troubleshooting -title: 'Bridging Troubleshooting Guide' -description: 'Common issues and solutions for bridging assets to/from Arbitrum' -author: anegg0 -last_reviewed: 2025-11-06 ---- - ### How do I move assets between One and Nova? Both Arbitrum One and Arbitrum Nova run as layers on top of Ethereum. Thus, you can always move assets between the two chains in two steps by going "through" Ethereum. In other words: withdraw your assets from Arbitrum One to Ethereum and then deposit them onto Nova, or conversely, withdraw your assets from Nova to Ethereum and then deposit them to Arbitrum One. You can complete these steps using the [Arbitrum Bridge](https://bridge.arbitrum.io/). diff --git a/docs/partials/_troubleshooting-building-partial.mdx b/docs/partials/_troubleshooting-building-partial.mdx index f1496f7d10..c6dc5e4687 100644 --- a/docs/partials/_troubleshooting-building-partial.mdx +++ b/docs/partials/_troubleshooting-building-partial.mdx @@ -1,11 +1,3 @@ ---- -partial_type: troubleshooting -title: 'Building Troubleshooting Guide' -description: 'Common issues and solutions for building on Arbitrum' -author: anegg0 -last_reviewed: 2025-11-06 ---- - ### How does gas work on Arbitrum? Fees on Arbitrum chains are collected on L2 in the chains' native currency (ETH on both Arbitrum One and Nova). @@ -62,9 +54,9 @@ There are two differences betweenย `createRetryableTicket`ย andย `unsafeCreateRe ### Why do I get "custom tx type" errors when I use hardhat? -In Arbitrum, we use a number of non-standardย [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)ย typed transactions. Seeย [here](https://developer.arbitrum.io/arbos/geth#transaction-types)ย for the full list and the rationale. +In Arbitrum, we use a number of non-standardย [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)ย typed transactions. Feel free to consult the [full list of transaction types](https://developer.arbitrum.io/arbos/geth#transaction-types) and the rationale. -Note that if you're using Hardhat, [v2.12.2](https://github.com/NomicFoundation/hardhat/releases/tag/hardhat%402.12.2)ย added support for forking networks like Arbitrum with custom transaction types (find more information [here](https://github.com/NomicFoundation/hardhat/issues/2995)). +Note that if you're using Hardhat, [v2.12.2](https://github.com/NomicFoundation/hardhat/releases/tag/hardhat%402.12.2)ย added support for forking networks like Arbitrum with custom transaction types (find more information [in this HardHat GitHub issue](https://github.com/NomicFoundation/hardhat/issues/2995)). ### Why does it look like two identical transactions consume a different amount of gas? @@ -156,7 +148,7 @@ The WASM module root is a 32-byte hash, which is a Merkelization of the Go repla The replay binary is much too large to post on-chain, so this hash is set in the L1 rollup contract to determine the correct replay binary during fraud proofs. -You can find more information in [How to Customize your Orbit chain's behavior](https://docs.arbitrum.io/launch-orbit-chain/how-tos/customize-stf#step-4-enable-fraud-proofs). +You can find more information in [How to Customize your Arbitrum chain's behavior](https://docs.arbitrum.io/launch-orbit-chain/how-tos/customize-stf#step-4-enable-fraud-proofs). ### Why do I get a "gas required exceeds allowance" when trying to estimate the gas costs of a request? diff --git a/docs/partials/_troubleshooting-nodes-partial.mdx b/docs/partials/_troubleshooting-nodes-partial.mdx index 767479be47..f9b857ea34 100644 --- a/docs/partials/_troubleshooting-nodes-partial.mdx +++ b/docs/partials/_troubleshooting-nodes-partial.mdx @@ -1,14 +1,6 @@ ---- -partial_type: troubleshooting -title: 'Node Running Troubleshooting Guide' -description: 'Common issues and solutions for running Arbitrum nodes' -author: anegg0 -last_reviewed: 2025-11-06 ---- - ### How do I run a node? -See instructions in the tutorial explaining how to [run a full node](https://developer.arbitrum.io/node-running/how-tos/running-a-full-node)! +See instructions [in our guide about running a full node](https://developer.arbitrum.io/node-running/how-tos/running-a-full-node)! ### How to verify the integrity of the Nitro database I currently have? @@ -36,7 +28,7 @@ Running an Arbitrum relay locally as a [Feed Relay](https://docs.arbitrum.io/nod ### How do I run a node locally for development? -See instructionsย on [how to set up a local dev node](https://developer.arbitrum.io/node-running/how-tos/local-dev-node). +See instructions in our ย [our guide about running a local devnet node](https://developer.arbitrum.io/node-running/how-tos/local-dev-node). We recommend running Nitro nodes via Docker; to compile directly / run without Docker, you can follow the steps in [How to build Nitro locally](https://docs.arbitrum.io/node-running/how-tos/build-nitro-locally). @@ -44,7 +36,7 @@ We recommend running Nitro nodes via Docker; to compile directly / run without D The pre-Nitro stack is also called the "classic" stack. Full Nitro nodes start with a database that contains the information from the "classic" era. -However, a Nitro node can't query archive information contained in "classic" blocks right away. To do that, you also need to run a classic node. You can find detailed instructions [in this detailed How To](https://developer.arbitrum.io/node-running/how-tos/running-a-classic-node) and set the parameter `โ€”node.rpc.classic-redirect=your-classic-node-RPC`. +However, a Nitro node can't query archive information contained in "classic" blocks right away. To do that, you also need to run a classic node ([instructions in our guide about running a classic node](https://developer.arbitrum.io/node-running/how-tos/running-a-classic-node)) and set the parameter `โ€”node.rpc.classic-redirect=your-classic-node-RPC`. Please note that this information only applies to Arbitrum One nodes. Arbitrum Nova and Sepolia nodes started with a Nitro stack, so they don't have "classic" data. diff --git a/docs/partials/_troubleshooting-stylus-partial.mdx b/docs/partials/_troubleshooting-stylus-partial.mdx index 050d317a02..8716e431a0 100644 --- a/docs/partials/_troubleshooting-stylus-partial.mdx +++ b/docs/partials/_troubleshooting-stylus-partial.mdx @@ -1,11 +1,3 @@ ---- -partial_type: troubleshooting -title: 'Stylus Troubleshooting Guide' -description: 'Common issues and solutions for Stylus smart contract development' -author: anegg0 -last_reviewed: 2025-11-06 ---- - ### How does Stylus manage security issues in smart contracts when interacting with so many different languages? All languages are compiled to WASM for them to be able to work with Stylus. So it just needs to verify that the produced WASM programs behave as they should inside the new virtual machine. @@ -54,7 +46,7 @@ As an alternative solution, you can use [entrypoint-style contracts](https://doc ### Why do I get an error "no library targets found in package" when trying to compile and old example? -Some of the first Stylus examples were built and deployed using a previous version of [cargo-stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) (`0.1.x`). In that version, Stylus projects were structured as regular Rust binaries. +Some of the first Stylus examples were built and deployed using a previous version of [cargo-stylus](https://github.com/OffchainLabs/cargo-stylus) (`0.1.x`). In that version, Stylus projects were structured as regular Rust binaries. Since [cargo-stylus v0.2.1](https://github.com/OffchainLabs/cargo-stylus/releases/tag/v0.2.1), Stylus projects are structured as libraries, so when trying to compile old projects you might get an error `no library targets found in package`. @@ -62,7 +54,9 @@ To solve this, it's usually enough to rename the `main.rs` file to a `lib.rs` fi ### How can I generate the ABI of my Stylus contract? -The [cargo-stylus tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`. +The + +has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`. If you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so: @@ -83,3 +77,33 @@ fn main() { stylus_hello_world::main(); } ``` + +### How can I find out if the smart contract bytecode is from a Stylus contract or Solidity contract? + +You can check the first three bytes of the code at the contract address. If they read `0xEFF000`, it's a Stylus program. Otherwise, it will be from a Solidity contract. + +### I'm trying to work with cargo stylus on Windows and got error: failed to resolve: could not find unix in os + +Cargo Stylus is just compatible with Unix operating systems and not Windows. You should install `WSL` (Windows Subsystem for Linux) before using that and then use `WSL terminal` to install and use cargo stylus. + +### How can I return a struct from a function? + +Currently, the SDK doesn't support external structs directly, but support is in progress. For now, you can use tuples as output instead of structs. + +Keep in mind that structs are mapped to tuples by the Solidity ABI. You can read more about this mapping here: [Solidity ABI Specification](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#mapping-solidity-to-abi-types). + +Since the current SDK macro doesn't automatically handle struct-to-tuple conversions, you'll need to manually convert your struct into a tuple in the return type. + +### How can I get the WASM opcodes of the compiled Stylus contracts? + +To view the WASM opcodes, you can convert the WebAssembly binary (WASM) to WebAssembly Text (WAT). This conversion is possible using the WebAssembly Binary Toolkit (wabt). An easy way to do this is to use the online tool [Wasm-to-Wat converter](https://webassembly.github.io/wabt/demo/wasm2wat/), which is part of wabt. + +For more information or if you'd like to use the toolkit locally, you can find wabt on [GitHub](https://github.com/WebAssembly/wabt). + +### What is the difference between .set and .setter? + +--- + +- **`.set`\*\***:\*\* This method is used directly to set a value in storage. It's a straightforward way to assign a value if you only need to perform a one-time set operation. +- **`.setter`\*\***:\*\* This method provides a handle to a storage slot. It allows you to both `set` and `get` the value of the storage slot, making it more versatile if you need to access the current value and also update it. + If you plan to both retrieve and modify a value frequently, it's more efficient to use `.setter`, assign it to a variable, and then use the `.get` and `.set` methods on that variable. However, if you only need to set a value, you can use `.set` directly. diff --git a/docs/partials/_troubleshooting-users-partial.mdx b/docs/partials/_troubleshooting-users-partial.mdx index 6b23b50681..b571e8f493 100644 --- a/docs/partials/_troubleshooting-users-partial.mdx +++ b/docs/partials/_troubleshooting-users-partial.mdx @@ -1,11 +1,3 @@ ---- -partial_type: troubleshooting -title: 'User Troubleshooting Guide' -description: 'Common issues and solutions for Arbitrum users' -author: anegg0 -last_reviewed: 2025-11-06 ---- - ### Why do I need ETH to use the Arbitrum network? `ETH` is the currency used to pay gas fees on Arbitrum, and it powers all transactions on Arbitrum. You can bridge `ETH` (and other tokens) from Ethereum to Arbitrum through [Arbitrum's bridge](https://bridge.arbitrum.io/). @@ -105,13 +97,9 @@ Although we currently don't maintain any stats dashboard for Arbitrum, you can f There is no notion of a mempool on Arbitrum; transactions are processed on a first-come, first-served basis by the Sequencer. Thus, the gas price bid parameter does not affect the order in which transactions get processed. -### Where can I find a list of the current validators of the Arbitrum chains? - -Validation on both Arbitrum One and Arbitrum Nova is currently allow-listed to a committee of public entities. You can see the list of validatorsย **[here](https://docs.arbitrum.foundation/state-of-progressive-decentralization#allowlisted-validators)**. Governance currently has the power to change this status. - ### Where can I find the current Data Availability Committee members? -The Arbitrum Nova chain has a 7-party DAC, whose members can be seenย **[here](https://docs.arbitrum.foundation/state-of-progressive-decentralization#data-availability-committee-members)**. Governance has the ability to remove or add members to the committee. +The Arbitrum Nova chain has a 7-party DAC, whose members can be seen in theย [Arbitrum Foundation's state of progressive decentralization status document](https://docs.arbitrum.foundation/state-of-progressive-decentralization#data-availability-committee-members). Governance has the ability to remove or add members to the committee. ### Can I withdraw my funds from Arbitrum back to Ethereum without going through the Sequencer? What about funds that are in a contract? diff --git a/static/building-faqs.json b/static/building-faqs.json index 9c38dd6373..ceef1f7ac5 100644 --- a/static/building-faqs.json +++ b/static/building-faqs.json @@ -26,7 +26,7 @@ }, { "question": "Why do I get \"custom tx type\" errors when I use hardhat?", - "answer": "In Arbitrum, we use a number of non-standardย [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)ย typed transactions. Seeย [here](https://developer.arbitrum.io/arbos/geth#transaction-types)ย for the full list and the rationale.\n\nNote that if you're using Hardhat, [v2.12.2](https://github.com/NomicFoundation/hardhat/releases/tag/hardhat%402.12.2)ย added support for forking networks like Arbitrum with custom transaction types (find more information [here](https://github.com/NomicFoundation/hardhat/issues/2995)).\n\n\n\n", + "answer": "In Arbitrum, we use a number of non-standardย [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)ย typed transactions. Feel free to consult the [full list of transaction types](https://developer.arbitrum.io/arbos/geth#transaction-types) and the rationale.\n\nNote that if you're using Hardhat, [v2.12.2](https://github.com/NomicFoundation/hardhat/releases/tag/hardhat%402.12.2)ย added support for forking networks like Arbitrum with custom transaction types (find more information [in this HardHat GitHub issue](https://github.com/NomicFoundation/hardhat/issues/2995)).\n\n\n\n", "key": "why-do-i-get-custom-tx-type-errors-when-i-use-hardhat" }, { @@ -96,7 +96,7 @@ }, { "question": "What is the WASM module root?", - "answer": "The WASM module root is a 32-byte hash, which is a Merkelization of the Go replay binary and its dependencies.\n\nThe replay binary is much too large to post on-chain, so this hash is set in the L1 rollup contract to determine the correct replay binary during fraud proofs.\n\nYou can find more information in [How to Customize your Orbit chain's behavior](https://docs.arbitrum.io/launch-orbit-chain/how-tos/customize-stf#step-4-enable-fraud-proofs).\n\n\n\n", + "answer": "The WASM module root is a 32-byte hash, which is a Merkelization of the Go replay binary and its dependencies.\n\nThe replay binary is much too large to post on-chain, so this hash is set in the L1 rollup contract to determine the correct replay binary during fraud proofs.\n\nYou can find more information in [How to Customize your Arbitrum chain's behavior](https://docs.arbitrum.io/launch-orbit-chain/how-tos/customize-stf#step-4-enable-fraud-proofs).\n\n\n\n", "key": "what-is-the-wasm-module-root" }, { diff --git a/static/building-orbit-faqs.json b/static/building-orbit-faqs.json index e096404e32..2aa9374480 100644 --- a/static/building-orbit-faqs.json +++ b/static/building-orbit-faqs.json @@ -1,63 +1,63 @@ [ { - "question": "Can I use Orbit to deploy a mainnet chain?", - "answer": "Yes! Arbitrum Orbit's core technology has undergone a comprehensive audit and is now capable of supporting deployments to mainnet. You can read more about it [here](https://docs.arbitrum.io/launch-orbit-chain/concepts/public-preview-expectations#arbitrum-orbit-is-mainnet-ready-but-deploy-to-testnet-first).\n\n\n\n", - "key": "can-i-use-orbit-to-deploy-a-mainnet-chain" + "question": "Can I use the Chain SDK to deploy a mainnet chain?", + "answer": "Yes! The Arbitrum Chain SDK's core technology has undergone a comprehensive audit and is now capable of supporting deployments to mainnet. You can read more about it in our [preview expectations notice](https://docs.arbitrum.io/launch-orbit-chain/concepts/public-preview-expectations#arbitrum-orbit-is-mainnet-ready-but-deploy-to-testnet-first).\n\n\n\n", + "key": "can-i-use-the-chain-sdk-to-deploy-a-mainnet-chain" }, { - "question": "Do I need permission/license to launch an Orbit chain?", - "answer": "You can launch any Arbitrum Orbit chain permissionlessly.\n\nNitro's license is under a [Business Source license](https://github.com/OffchainLabs/nitro?tab=License-1-ov-file), similar to DeFi protocols like Uniswap and Aave, among others. This license contains an Additional Use Grant that permits the permissionless deployment of Nitro software on blockchains that settle to Arbitrum One or Nova.\n\nHowever, Arbitrum Orbit chains that settle to a parent chain other than Arbitrum One or Nova are subject to additional licensing guidelines under the [AEP](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf).\n\n", - "key": "do-i-need-permissionlicense-to-launch-an-orbit-chain" + "question": "Do I need permission/license to launch an Arbitrum chain?", + "answer": "You can launch any Arbitrum chain permissionlessly.\n\nNitro's license is under a [Business Source license](https://github.com/OffchainLabs/nitro?tab=License-1-ov-file), similar to DeFi protocols like Uniswap and Aave, among others. This license contains an Additional Use Grant that permits the permissionless deployment of Nitro software on blockchains that settle to Arbitrum One or Nova.\n\nHowever, Arbitrum chains that settle to a parent chain other than Arbitrum One or Nova are subject to additional licensing guidelines under the [AEP](https://docs.arbitrum.foundation/aep/ArbitrumExpansionProgramTerms.pdf).\n\n", + "key": "do-i-need-permissionlicense-to-launch-an-arbitrum-chain" }, { "question": "Does Arbitrum officially deploy and/or maintain L3s for external teams?", - "answer": "No. Teams are required to deploy and maintain their Arbitrum Orbit chains. There are, however, several RaaS (Rollup as a Service) providers that can deploy and maintain your Arbitrum Orbit chain on your behalf.\n\n\n\n", + "answer": "No. Teams are required to deploy and maintain their Arbitrum chains. There are, however, several RaaS (Rollup as a Service) providers that can deploy and maintain your Arbitrum chain on your behalf.\n\n\n\n", "key": "does-arbitrum-officially-deploy-andor-maintain-l3s-for-external-teams" }, { - "question": "Can I modify Orbit's underlying technology to customize my chain?", + "question": "Can I modify the underlying technology to customize my Arbitrum chain?", "answer": "Yes, you can make any changes you require to the underlying Nitro code base.\n\n\n\n", - "key": "can-i-modify-orbits-underlying-technology-to-customize-my-chain" + "key": "can-i-modify-the-underlying-technology-to-customize-my-arbitrum-chain" }, { - "question": "What Data Availability (DA) solutions are currently available for Orbit chains?", - "answer": "Arbitrum Orbit currently supports three different DA solutions:\n\n- Rollup, posting data to the parent chain, which ultimately posts the data to Ethereum.\n- AnyTrust, posting data to a Data Availability Committee, selected by the chain owner.\n- Celestia, posting data to the [Celestia network](https://blog.celestia.org/celestia-is-first-modular-data-availability-network-to-integrate-with-arbitrum-orbit/).\nNote that using AnyTrust provides the chain owner with the most flexibility and the most cost-effective fees.\n\n", - "key": "what-data-availability-da-solutions-are-currently-available-for-orbit-chains" + "question": "What Data Availability (DA) solutions are currently available for Arbitrum chains?", + "answer": "Arbitrum chains currently support three different DA solutions:\n\n- Rollup, posting data to the parent chain, which ultimately posts the data to Ethereum.\n- AnyTrust, posting data to a Data Availability Committee, selected by the chain owner.\n- Celestia, posting data to the [Celestia network](https://blog.celestia.org/celestia-is-first-modular-data-availability-network-to-integrate-with-arbitrum-orbit/).\nNote that using AnyTrust provides the chain owner with the most flexibility and the most cost-effective fees.\n\n", + "key": "what-data-availability-da-solutions-are-currently-available-for-arbitrum-chains" }, { - "question": "What token is used to pay gas fees on Orbit chains?", - "answer": "By default, Arbitrum Orbit chains pay gas in `ETH`. However, Arbitrum Orbit chains that use AnyTrust are configurable to use any `ERC-20` token for the gas fee token of the chain.\n\n\n\n", - "key": "what-token-is-used-to-pay-gas-fees-on-orbit-chains" + "question": "What token is used to pay gas fees on Arbitrum chains?", + "answer": "By default, Arbitrum chains pay gas in `ETH`. However, Arbitrum chains that use AnyTrust are configurable to use any `ERC-20` token for the gas fee token of the chain.\n\n\n\n", + "key": "what-token-is-used-to-pay-gas-fees-on-arbitrum-chains" }, { - "question": "Can I use Ethereum toolkits to develop on my Orbit chain?", - "answer": "Arbitrum Orbit chains are fully EVM-compatible. Most tools that support Ethereum should be able to support an Arbitrum Orbit chain. There are, however, specific differences that developers need to consider when building on an Orbit chain. You can find them [here](https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/overview).\n\n\n\n", - "key": "can-i-use-ethereum-toolkits-to-develop-on-my-orbit-chain" + "question": "Can I use Ethereum toolkits to develop on my Arbitrum chain?", + "answer": "Arbitrum chains are fully EVM-compatible. Most tools that support Ethereum should be able to support an Arbitrum chain. There are, however, specific differences that developers need to consider when building on an Arbitrum chain. You can find them in our [overview of the differences between Arbitrum and Ethereum](https://docs.arbitrum.io/for-devs/concepts/differences-between-arbitrum-ethereum/overview).\n\n\n\n", + "key": "can-i-use-ethereum-toolkits-to-develop-on-my-arbitrum-chain" }, { - "question": "Do Orbit chains have any built-in AA solution?", + "question": "Do Arbitrum chains have any built-in AA solution?", "answer": "Not by default, but they can be customized to have native AA.\n\n", - "key": "do-orbit-chains-have-any-builtin-aa-solution" + "key": "do-arbitrum-chains-have-any-builtin-aa-solution" }, { - "question": "Is there any cross-chain bridging solution between two Orbit chains?", - "answer": "There is currently no native Orbit-to-Orbit chain bridging solution, except for going through the parent chain (even if they share the same parent chain). However, many third-party bridges have expressed interest in supporting Arbitrum Orbit chains.\n\n\n\n", - "key": "is-there-any-crosschain-bridging-solution-between-two-orbit-chains" + "question": "Is there any cross-chain bridging solution between two Arbitrum chains?", + "answer": "There is currently no native Arbitrum-to-Arbitrum chain bridging solution, except for going through the parent chain (even if they share the same parent chain). However, many third-party bridges have expressed interest in supporting Arbitrum chains.\n\n\n\n", + "key": "is-there-any-crosschain-bridging-solution-between-two-arbitrum-chains" }, { - "question": "Is there an official block explorer for Orbit chains?", - "answer": "Arbitrum Orbit chains deployments usually come with an open-source Blockscout explorer by default, but there are many third-party solutions that have expressed interest in supporting Arbitrum Orbit chains.\n\n\n\n", - "key": "is-there-an-official-block-explorer-for-orbit-chains" + "question": "Is there an official block explorer for Arbitrum chains?", + "answer": "Arbitrum chains deployments usually come with an open-source Blockscout explorer by default, but there are many third-party solutions that have expressed interest in supporting Arbitrum chains.\n\n\n\n", + "key": "is-there-an-official-block-explorer-for-arbitrum-chains" }, { - "question": "Is there any indexing solution that supports Orbit chains?", - "answer": "Similar to bridges and block explorers, there are many third-party indexing solutions that have expressed interest in supporting Arbitrum Orbit chains.\n\n\n\n", - "key": "is-there-any-indexing-solution-that-supports-orbit-chains" + "question": "Is there any indexing solution that supports Arbitrum chains?", + "answer": "Similar to bridges and block explorers, there are many third-party indexing solutions that have expressed interest in supporting Arbitrum chains.\n\n\n\n", + "key": "is-there-any-indexing-solution-that-supports-arbitrum-chains" }, { - "question": "Can I increase the maximum contract size for my Orbit chain?", - "answer": "Yes, Arbitrum Orbit chains support an increased smart contract size limit of up to 96kB. You can use our [Orbit SDK](https://github.com/OffchainLabs/arbitrum-orbit-sdk) and configure the parameters `[MaxCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[ and ](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[MaxInitCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)` when calling `[prepareNodeConfig](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/examples/prepare-node-config/index.ts#L43)`. Once deployed, you cannot change the parameters for the smart contract size limit through an upgrade.\n\n\n\n", - "key": "can-i-increase-the-maximum-contract-size-for-my-orbit-chain" + "question": "Can I increase the maximum contract size for my Arbitrum chain?", + "answer": "Yes, Arbitrum chains support an increased smart contract size limit of up to 96kB. You can use our [Chain SDK](https://github.com/OffchainLabs/arbitrum-orbit-sdk) and configure the parameters `[MaxCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[ and ](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)`[MaxInitCodeSize](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/src/prepareChainConfig.ts#L29)` when calling `[prepareNodeConfig](https://github.com/OffchainLabs/arbitrum-orbit-sdk/blob/main/examples/prepare-node-config/index.ts#L43)`. Once deployed, you cannot change the parameters for the smart contract size limit through an upgrade.\n\n\n\n", + "key": "can-i-increase-the-maximum-contract-size-for-my-arbitrum-chain" }, { "question": "How can I modify Nitro to force posting an invalid assertion and test the fraud proof mechanism?", @@ -66,12 +66,12 @@ }, { "question": "What fee collectors can be configured on my chain?", - "answer": "Four fee types are configurable on an Orbit chain:\n\n- **L2 base fee**: L2 execution fees corresponding to the minimum base price of the chain. This fee is deposited into the infraFeeAccount, which can be set by calling `ArbOwner.setInfraFeeAccount().`\n- **L2 surplus fee**: L2 execution fees above the minimum base price (in the case of congestion). This fee goes to the `networkFeeAccount`, which can be set by calling `ArbOwner.setNetworkFeeAccount().`\n- **L1 base fee**: Relative fees for posting a transaction on the parent chain. This fee is paid ultimately to the fee collector of the active batch poster. A call to `SequencerInbox.setIsBatchPoster()` on the parent chain will set the batch poster. Delegating a different fee collector for that batch poster can be specified by calling `ArbAggregator.setFeeCollector()`.\n- **L1 surplus fee**: Any extra fees rewarded to the batch poster. This is paid to a specific `L1RewardRecipient`, which can be set by calling `ArbOwner.setL1PricingRewardRecipient()`.\nFor more detailed information about fees, please refer to the [L1 Fees](https://docs.arbitrum.io/arbos/l1-pricing) and [L2 Fees](https://docs.arbitrum.io/arbos/gas) pages.\n\nTo learn more about precompiles, refer to the [Precompiles reference page](https://docs.arbitrum.io/build-decentralized-apps/precompiles/reference).\n\n", + "answer": "Four fee types are configurable on an Arbitrum chain:\n\n- **L2 base fee**: L2 execution fees corresponding to the minimum base price of the chain. This fee is deposited into the `infraFeeAccount`, which can be set by calling `ArbOwner.setInfraFeeAccount().`\n- **L2 surplus fee**: L2 execution fees above the minimum base price (in the case of congestion). This fee goes to the `networkFeeAccount`, which can be set by calling `ArbOwner.setNetworkFeeAccount().`\n- **L1 base fee**: Relative fees for posting a transaction on the parent chain. This fee is paid ultimately to the fee collector of the active batch poster. A call to `SequencerInbox.setIsBatchPoster()` on the parent chain will set the batch poster. Delegating a different fee collector for that batch poster can be specified by calling `ArbAggregator.setFeeCollector()`.\n- **L1 surplus fee**: Any extra fees rewarded to the batch poster. This is paid to a specific `L1RewardRecipient`, which can be set by calling `ArbOwner.setL1PricingRewardRecipient()`.\nFor more detailed information about fees, please refer to the [L1 Fees](https://docs.arbitrum.io/arbos/l1-pricing) and [L2 Fees](https://docs.arbitrum.io/arbos/gas) pages.\n\nTo learn more about precompiles, refer to the [Precompiles reference page](https://docs.arbitrum.io/build-decentralized-apps/precompiles/reference).\n\n", "key": "what-fee-collectors-can-be-configured-on-my-chain" }, { "question": "What is the lowest you can set the base fee to?", - "answer": "You can set the base fee to any amount to charge users less. You can even set it to `0` (however, this would open the chain to DOS attacks). If the Orbit base fee is `0`, users are then only paying for the cost of DA.\n\n", + "answer": "You can set the base fee to any amount to charge users less. You can even set it to `0` (however, this would open the chain to DOS attacks). If the Arbitrum chain base fee is `0`, users are then only paying for the cost of DA.\n\n", "key": "what-is-the-lowest-you-can-set-the-base-fee-to" }, { @@ -101,12 +101,12 @@ }, { "question": "What is the max theoretical TPS for an Arbitrum Chain?", - "answer": "Max TPS is a challenging metric to measure, as it relies on network activity and the type of submitted transactions. We can, however, calculate the max throughput using default orbit chain parameters.\n\nThe actual maximum throughput depends on the configurable execution parameters:\n\n**Using standard Arbitrum chain defaults**\n\n- Block time: 250ms\n- Block gas limit: 32M L2 gas\n- Max L2 gas per second: 128M gas/sec\n- These parameters are entirely configurable, for example, by dropping the block time to 100ms or by increasing the block gas limit (which comes at the cost of faster state bloat).\n- Dropping to 100ms and doubling the block gas limit to 64m L2 gas would achieve 640m L2 gas per second.\n**The actual TPS varies depending on the gas cost per transaction:**\n\n- A simple transfer (~21,000 gas) could approximately achieve around 6,000 TPS.\n- A more complex transaction (~200,000 gas) would enable approximately 640 TPS.\n", + "answer": "Max TPS is a challenging metric to measure, as it relies on network activity and the type of submitted transactions. We can, however, calculate the max throughput using default Arbitrum chain parameters.\n\nThe actual maximum throughput depends on the configurable execution parameters:\n\n**Using standard Arbitrum chain defaults**\n\n- Block time: 250ms\n- Block gas limit: 32M L2 gas\n- Max L2 gas per second: 128M gas/sec\n- These parameters are entirely configurable, for example, by dropping the block time to 100ms or by increasing the block gas limit (which comes at the cost of faster state bloat).\n- Dropping to 100ms and doubling the block gas limit to 64m L2 gas would achieve 640m L2 gas per second.\n**The actual TPS varies depending on the gas cost per transaction:**\n\n- A simple transfer (~21,000 gas) could approximately achieve around 6,000 TPS.\n- A more complex transaction (~200,000 gas) would enable approximately 640 TPS.\n", "key": "what-is-the-max-theoretical-tps-for-an-arbitrum-chain" }, { "question": "Why is the WETH Gateway not necessary for custom gas token chains?", - "answer": "The `WETH` gateway used in the token bridge is a special, custom gateway that unwraps the `WETH` deposits and sends them to the Arbitrum chain, then wraps them again on the Arbitrum chain. Since `ETH` is the gas token in the Arbitrum (Orbit) chain, there's no need to perform this operation, so you can use a standard `ERC-20` for `WETH` (this is the default case of the token bridge so that you wouldn't need a special `WETH` gateway).\n\nIf you want to enable extra custom operations with `WETH`, you can create a custom token and a custom gateway to handle this case.\n\n", + "answer": "The `WETH` gateway used in the token bridge is a special, custom gateway that unwraps the `WETH` deposits and sends them to the Arbitrum chain, then wraps them again on the Arbitrum chain. Since `ETH` is the gas token in the Arbitrum chain, there's no need to perform this operation, so you can use a standard `ERC-20` for `WETH` (this is the default case of the token bridge so that you wouldn't need a special `WETH` gateway).\n\nIf you want to enable extra custom operations with `WETH`, you can create a custom token and a custom gateway to handle this case.\n\n", "key": "why-is-the-weth-gateway-not-necessary-for-custom-gas-token-chains" }, { diff --git a/static/building-stylus-faqs.json b/static/building-stylus-faqs.json index 4b295e0a6e..8201436850 100644 --- a/static/building-stylus-faqs.json +++ b/static/building-stylus-faqs.json @@ -46,7 +46,32 @@ }, { "question": "How can I generate the ABI of my Stylus contract?", - "answer": "The [cargo-stylus tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/tree/main#exporting-solidity-abis) has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`.\n\nIf you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so:\n\n```rust\n[features]\nexport-abi = [\"stylus-sdk/export-abi\"]\n```\nYou'll also need to have a `main.rs` file that selects that feature.\n\nThis is an example of a `main.rs` file that allows you to export the ABI of the [stylus-hello-world](https://github.com/OffchainLabs/stylus-hello-world) example project:\n\n```rust\n#![cfg_attr(not(feature = \"export-abi\"), no_main)]\n\n#[cfg(feature = \"export-abi\")]\nfn main() {\n stylus_hello_world::main();\n}\n```\n\n\n", + "answer": "The \n\n has a command that allows you to export the ABI of your Stylus contract: `cargo stylus export-abi`.\n\nIf you're using the Stylus Rust SDK, you'll need to enable the `export-abi` feature in your `Cargo.toml` file like so:\n\n```rust\n[features]\nexport-abi = [\"stylus-sdk/export-abi\"]\n```\nYou'll also need to have a `main.rs` file that selects that feature.\n\nThis is an example of a `main.rs` file that allows you to export the ABI of the [stylus-hello-world](https://github.com/OffchainLabs/stylus-hello-world) example project:\n\n```rust\n#![cfg_attr(not(feature = \"export-abi\"), no_main)]\n\n#[cfg(feature = \"export-abi\")]\nfn main() {\n stylus_hello_world::main();\n}\n```\n\n\n\n\n", "key": "how-can-i-generate-the-abi-of-my-stylus-contract" + }, + { + "question": "How can I find out if the smart contract bytecode is from a Stylus contract or Solidity contract?", + "answer": "You can check the first three bytes of the code at the contract address. If they read `0xEFF000`, it's a Stylus program. Otherwise, it will be from a Solidity contract.\n\n", + "key": "how-can-i-find-out-if-the-smart-contract-bytecode-is-from-a-stylus-contract-or-solidity-contract" + }, + { + "question": "I'm trying to work with cargo stylus on Windows and got error: failed to resolve: could not find unix in os", + "answer": "Cargo Stylus is just compatible with Unix operating systems and not Windows. You should install `WSL` (Windows Subsystem for Linux) before using that and then use `WSL terminal` to install and use cargo stylus.\n\n\n\n", + "key": "im-trying-to-work-with-cargo-stylus-on-windows-and-got-error-failed-to-resolve-could-not-find-unix-in-os" + }, + { + "question": "How can I return a struct from a function?", + "answer": "Currently, the SDK doesn't support external structs directly, but support is in progress. For now, you can use tuples as output instead of structs.\n\nKeep in mind that structs are mapped to tuples by the Solidity ABI. You can read more about this mapping here: [Solidity ABI Specification](https://docs.soliditylang.org/en/v0.8.19/abi-spec.html#mapping-solidity-to-abi-types).\n\nSince the current SDK macro doesn't automatically handle struct-to-tuple conversions, you'll need to manually convert your struct into a tuple in the return type.\n\n", + "key": "how-can-i-return-a-struct-from-a-function" + }, + { + "question": "How can I get the WASM opcodes of the compiled Stylus contracts?", + "answer": "To view the WASM opcodes, you can convert the WebAssembly binary (WASM) to WebAssembly Text (WAT). This conversion is possible using the WebAssembly Binary Toolkit (wabt). An easy way to do this is to use the online tool [Wasm-to-Wat converter](https://webassembly.github.io/wabt/demo/wasm2wat/), which is part of wabt.\n\nFor more information or if you'd like to use the toolkit locally, you can find wabt on [GitHub](https://github.com/WebAssembly/wabt).\n\n", + "key": "how-can-i-get-the-wasm-opcodes-of-the-compiled-stylus-contracts" + }, + { + "question": "What is the difference between .set and .setter?", + "answer": "---\n\n- **`.set`****:** This method is used directly to set a value in storage. It's a straightforward way to assign a value if you only need to perform a one-time set operation.\n- **`.setter`****:** This method provides a handle to a storage slot. It allows you to both `set` and `get` the value of the storage slot, making it more versatile if you need to access the current value and also update it.\nIf you plan to both retrieve and modify a value frequently, it's more efficient to use `.setter`, assign it to a variable, and then use the `.get` and `.set` methods on that variable. However, if you only need to set a value, you can use `.set` directly.\n\n\n\n", + "key": "what-is-the-difference-between-set-and-setter" } ] diff --git a/static/get-started-faqs.json b/static/get-started-faqs.json index b3229e30ec..4f095c33dd 100644 --- a/static/get-started-faqs.json +++ b/static/get-started-faqs.json @@ -79,14 +79,9 @@ "answer": "There is no notion of a mempool on Arbitrum; transactions are processed on a first-come, first-served basis by the Sequencer. Thus, the gas price bid parameter does not affect the order in which transactions get processed.\n\n\n\n", "key": "will-transactions-with-a-higher-gas-price-bid-be-confirmed-first" }, - { - "question": "Where can I find a list of the current validators of the Arbitrum chains?", - "answer": "Validation on both Arbitrum One and Arbitrum Nova is currently allow-listed to a committee of public entities. You can see the list of validatorsย **[here](https://docs.arbitrum.foundation/state-of-progressive-decentralization#allowlisted-validators)**. Governance currently has the power to change this status.\n\n\n\n", - "key": "where-can-i-find-a-list-of-the-current-validators-of-the-arbitrum-chains" - }, { "question": "Where can I find the current Data Availability Committee members?", - "answer": "The Arbitrum Nova chain has a 7-party DAC, whose members can be seenย **[here](https://docs.arbitrum.foundation/state-of-progressive-decentralization#data-availability-committee-members)**. Governance has the ability to remove or add members to the committee.\n\n\n\n", + "answer": "The Arbitrum Nova chain has a 7-party DAC, whose members can be seen in theย [Arbitrum Foundation's state of progressive decentralization status document](https://docs.arbitrum.foundation/state-of-progressive-decentralization#data-availability-committee-members). Governance has the ability to remove or add members to the committee.\n\n\n\n", "key": "where-can-i-find-the-current-data-availability-committee-members" }, { diff --git a/static/node-running-faqs.json b/static/node-running-faqs.json index 2daefd9a41..f359da16ac 100644 --- a/static/node-running-faqs.json +++ b/static/node-running-faqs.json @@ -1,7 +1,7 @@ [ { "question": "How do I run a node?", - "answer": "See instructions [here](https://developer.arbitrum.io/node-running/how-tos/running-a-full-node)! \n\n\n\n", + "answer": "See instructions [in our guide about running a full node](https://developer.arbitrum.io/node-running/how-tos/running-a-full-node)!\n\n\n\n", "key": "how-do-i-run-a-node" }, { @@ -31,12 +31,12 @@ }, { "question": "How do I run a node locally for development?", - "answer": "See instructionsย [here](https://developer.arbitrum.io/node-running/how-tos/local-dev-node).\n\nWe recommend running Nitro nodes via Docker; to compile directly / run without Docker, you can follow the steps in [How to build Nitro locally](https://docs.arbitrum.io/node-running/how-tos/build-nitro-locally).\n\n\n\n\n\n\n\n", + "answer": "See instructions in our ย [our guide about running a local devnet node](https://developer.arbitrum.io/node-running/how-tos/local-dev-node).\n\nWe recommend running Nitro nodes via Docker; to compile directly / run without Docker, you can follow the steps in [How to build Nitro locally](https://docs.arbitrum.io/node-running/how-tos/build-nitro-locally).\n\n\n\n\n\n\n\n", "key": "how-do-i-run-a-node-locally-for-development" }, { "question": "Is there any way to retrieve pre-Nitro archive data from a Nitro node?", - "answer": "The pre-Nitro stack is also called the \"classic\" stack. Full Nitro nodes start with a database that contains the information from the \"classic\" era.\n\nHowever, a Nitro node can't query archive information contained in \"classic\" blocks right away. To do that, you also need to run a classic node ([instructions here](https://developer.arbitrum.io/node-running/how-tos/running-a-classic-node)) and set the parameter `โ€”node.rpc.classic-redirect=your-classic-node-RPC`.\n\nPlease note that this information only applies to Arbitrum One nodes. Arbitrum Nova and Sepolia nodes started with a Nitro stack, so they don't have \"classic\" data.\n\n", + "answer": "The pre-Nitro stack is also called the \"classic\" stack. Full Nitro nodes start with a database that contains the information from the \"classic\" era.\n\nHowever, a Nitro node can't query archive information contained in \"classic\" blocks right away. To do that, you also need to run a classic node ([instructions in our guide about running a classic node](https://developer.arbitrum.io/node-running/how-tos/running-a-classic-node)) and set the parameter `โ€”node.rpc.classic-redirect=your-classic-node-RPC`.\n\nPlease note that this information only applies to Arbitrum One nodes. Arbitrum Nova and Sepolia nodes started with a Nitro stack, so they don't have \"classic\" data.\n\n\n\n", "key": "is-there-any-way-to-retrieve-prenitro-archive-data-from-a-nitro-node" }, { From 4cc5b0cc00a60d13b1ed825c0683f148e7093075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 10:21:56 -0800 Subject: [PATCH 096/162] revert changes to run full nodes article --- docs/run-arbitrum-node/02-run-full-node.mdx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/run-arbitrum-node/02-run-full-node.mdx b/docs/run-arbitrum-node/02-run-full-node.mdx index 1311ac7e15..6890c0ff22 100644 --- a/docs/run-arbitrum-node/02-run-full-node.mdx +++ b/docs/run-arbitrum-node/02-run-full-node.mdx @@ -42,7 +42,7 @@ Although there are beta and release candidate versions of the Arbitrum Nitro sof ::: -Latest [Docker image](https://hub.docker.com/r/offchainlabs/nitro-node/tags): @@latestNitroNodeImage=offchainlabs/nitro-node:v3.9.3-8bc5554@@ +Latest [Docker image](https://hub.docker.com/r/offchainlabs/nitro-node/tags): @@latestNitroNodeImage=offchainlabs/nitro-node:v3.8.0-62c0aa7@@ ### Database snapshots @@ -151,6 +151,16 @@ If you are running more than on node, you should [run a feed relay](/run-arbitru - Pruning a full node refers to removing older, unnecessary data from the local copy of the blockchain that the node maintains, thereby saving disk space and slightly improving the node's efficiency. Pruning will remove all states from blocks older than the latest 128. - If you are using the default setting `--execution.caching.state-scheme=hash` then you can activate pruning by using the parameter: +- `--init.prune ` + - `minimal`: Only genesis + latest head state is left, takes the least amount of time (several house for Arbitrum One-sized database) + - `full` : Genesis + head state + state for latest confirmed block (will take a long time ~50 hours or more) + - `validator`: All of above + state of latest validated block (will take a little less than twice what `full` will take) + +:::note + +This process occurs when the node starts and will not serve RPC requests during pruning. + +::: ### Transaction prechecker From c692673cd7b093d30b10049d08aecd1fdae7dd7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 4 Dec 2025 10:25:46 -0800 Subject: [PATCH 097/162] correct arbos release arbos version --- docs/run-arbitrum-node/arbos-releases/01-overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run-arbitrum-node/arbos-releases/01-overview.mdx b/docs/run-arbitrum-node/arbos-releases/01-overview.mdx index 5d1dbc91ad..46c762998b 100644 --- a/docs/run-arbitrum-node/arbos-releases/01-overview.mdx +++ b/docs/run-arbitrum-node/arbos-releases/01-overview.mdx @@ -31,7 +31,7 @@ Visit [How Arbitrum works](/how-arbitrum-works/01-inside-arbitrum-nitro.mdx) to ## List of available ArbOS releases -- [Dia (ArbOS 50)](/run-arbitrum-node/arbos-releases/arbos50.mdx) +- [Dia (ArbOS 51)](/run-arbitrum-node/arbos-releases/arbos51.mdx) - [Callisto (ArbOS 40)](/run-arbitrum-node/arbos-releases/arbos40.mdx) - [Bianca (ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx) - [Atlas (ArbOS 20)](/run-arbitrum-node/arbos-releases/arbos20.mdx) From 5f52159afae3a093515a64cd27bdc49314fdc10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 8 Dec 2025 12:09:12 -0800 Subject: [PATCH 098/162] rephrase sentence --- docs/stylus/how-tos/debugging-tx.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/how-tos/debugging-tx.mdx b/docs/stylus/how-tos/debugging-tx.mdx index 2cba8db919..aac7157564 100644 --- a/docs/stylus/how-tos/debugging-tx.mdx +++ b/docs/stylus/how-tos/debugging-tx.mdx @@ -14,7 +14,7 @@ Debugging smart contracts can be challenging, especially when dealing with compl ### Overview -Cargo Stylus is a tool designed to simplify the development and debugging process for smart contracts written in Rust for the Stylus execution environment. One of its powerful features is the `cargo stylus` subcommand, which provides essential functionalities for developers: +Cargo Stylus simplifies the development and debugging of Rust smart contracts for the Stylus execution environment. One of its powerful features is the `cargo stylus` subcommand, which provides essential functionalities for developers: 1. **Trace transactions**: Perform trace calls against Stylus transactions using Ethereum nodes' `debug_traceTransaction` RPC. This feature enables developers to analyze the execution flow and state changes of their transactions in a detailed manner. 2. **Debugging with GDB or LLDB**: Replay and debug the execution of a Stylus transaction using a debugger. This allows developers to set breakpoints, inspect variables, and step through the transaction execution line by line, providing an in-depth understanding of the transaction's behavior. From ab2300de3f2a052a89568e135fa749ee6ab9ad9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 8 Dec 2025 12:10:39 -0800 Subject: [PATCH 099/162] Update docs/build-decentralized-apps/reference/04-development-frameworks.mdx Co-authored-by: Pete --- .../reference/04-development-frameworks.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx index f67a2ade1f..9d59cbec03 100644 --- a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx +++ b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx @@ -22,7 +22,7 @@ The following tools will help you develop and test your decentralized apps (dApp ## Truffle -[Truffle](https://trufflesuite.com/) is a comprehensive suite of tools for smart contract development, providing an end-to-end solution for building, testing, debugging, and deploying on Ethereum, Arbitrum and other EVM compatible chains. It features advanced debugging capabilities, fast EVM simulation with Ganache, a user-centered design with a VS Code extension, and robust parent and child chain support. Truffle prioritizes security and partners with ConsenSys Diligence to bring continuous security to projects, providing a seamless and secure developer experience. +[Truffle](https://trufflesuite.com/) is a comprehensive suite of tools for smart contract development, providing an end-to-end solution for building, testing, debugging, and deploying on Ethereum, Arbitrum and other EVM-compatible chains. It features advanced debugging capabilities, fast EVM simulation with Ganache, a user-centric design with a VS Code extension, and robust parent and child chain support. Truffle prioritizes security and partners with ConsenSys Diligence to bring continuous security to projects, providing a seamless and secure developer experience. ## thirdweb From 8ae2954a77fd2b28d7188d0dfa271d0048f14d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 8 Dec 2025 12:17:43 -0800 Subject: [PATCH 100/162] add missing redirect --- vercel.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vercel.json b/vercel.json index 20d4603e39..3eeba02b88 100644 --- a/vercel.json +++ b/vercel.json @@ -245,6 +245,11 @@ "destination": "/how-arbitrum-works/bold/gentle-introduction", "permanent": false }, + { + "source": "/(docs/stylus/recommended-libraries/?)", + "destination": "/(docs/stylus/advanced/recommended-libraries/?)", + "permanent": false + }, { "source": "/(faqs/anytrust-vs-rollup/?)", "destination": "/faqs/protocol-faqs#q-rollup-vs-anytrust", From 906550365a25416778364634be95e17c5eea0ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 11 Dec 2025 22:26:56 -0800 Subject: [PATCH 101/162] add links to sdk files --- .../reference/data-types/conversions-between-types.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/stylus/reference/data-types/conversions-between-types.mdx b/docs/stylus/reference/data-types/conversions-between-types.mdx index e2f77358e8..d86fd64494 100644 --- a/docs/stylus/reference/data-types/conversions-between-types.mdx +++ b/docs/stylus/reference/data-types/conversions-between-types.mdx @@ -371,7 +371,7 @@ impl Counter { For complete implementation details, see: -- `/stylus-sdk/src/abi/mod.rs` - AbiType trait and encoding functions -- `/stylus-sdk/src/abi/ints.rs` - Integer type conversions -- `/stylus-sdk/src/abi/impls.rs` - Implementations for standard types -- `/stylus-sdk/src/storage/traits.rs` - Storage type conversion traits +- `[/stylus-sdk/src/abi/mod.rs](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/stylus-sdk/src/abi/mod.rs)` - AbiType trait and encoding functions +- `[/stylus-sdk/src/abi/ints.rs](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/stylus-sdk/src/abi/ints.rs)` - Integer type conversions +- `[/stylus-sdk/src/abi/impls.rs](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/stylus-sdk/src/abi/impls.rs)` - Implementations for standard types +- `[/stylus-sdk/src/storage/traits.rs](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/stylus-sdk/src/abi/traits.rs)` - Storage type conversion traits From 1b06052711cc7e07453ea6c9abc46cc655518b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 11 Dec 2025 22:39:57 -0800 Subject: [PATCH 102/162] docs: ensure all Stylus titles/headers are sentence cased MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed titles and headers in Stylus documentation to follow sentence case style guide (first letter capitalized, rest lowercase except proper nouns and acronyms). Changes: - Fixed frontmatter title: "Public preview: What to expect" โ†’ "Public preview: what to expect" - Fixed 9 headers in webassembly.mdx (e.g., "WASM Compilation Target" โ†’ "WASM compilation target") - Fixed 9 headers in deploying-non-rust-wasm-contracts.mdx (e.g., "Why Use Non-Rust Languages?" โ†’ "Why use non-Rust languages?") Proper nouns (Stylus, Rust, WebAssembly, Nitro, etc.) and acronyms (WASM, SDK, ABI, etc.) remain capitalized as appropriate. --- .../concepts/public-preview-expectations.mdx | 2 +- docs/stylus/concepts/webassembly.mdx | 18 +++++++++--------- .../deploying-non-rust-wasm-contracts.mdx | 18 +++++++++--------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docs/stylus/concepts/public-preview-expectations.mdx b/docs/stylus/concepts/public-preview-expectations.mdx index 89a7854c02..3ff00bc060 100644 --- a/docs/stylus/concepts/public-preview-expectations.mdx +++ b/docs/stylus/concepts/public-preview-expectations.mdx @@ -1,5 +1,5 @@ --- -title: 'Public preview: What to expect' +title: 'Public preview: what to expect' description: 'Stylus is currently tagged as a `release-candidate` supported by *public preview* documentation. This concept document explains what this means, and what to expect.' author: symbolpunk sidebar_position: 10 diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 7ae24d0827..456055c36e 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -29,7 +29,7 @@ Nitro uses WebAssembly as its execution environment for several reasons: 4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM 5. **Determinism**: Guaranteed identical execution across all validators -## WASM Compilation Target +## WASM compilation target Stylus contracts are compiled to the `wasm32-unknown-unknown` target, which means: @@ -54,7 +54,7 @@ rustflags = [ - **Bulk memory**: Enables efficient `memory.copy` and `memory.fill` operations - **No reference types**: Keeps the WASM simpler and more compatible -## WASM Binary Structure +## WASM binary structure A Stylus WASM module consists of several sections: @@ -126,7 +126,7 @@ Custom sections can store: - Compiler metadata - ABI information -## Compression and Deployment +## Compression and deployment Before deployment, Stylus contracts undergo compression: @@ -158,7 +158,7 @@ pub fn add_prefix(compressed_wasm: impl IntoIterator, prefix: &str) - This prefix allows the Nitro VM to distinguish Stylus contracts from EVM bytecode. -## Contract Activation +## Contract activation After deployment, contracts must be **activated** before execution: @@ -194,7 +194,7 @@ if !wasm::has_entrypoint(&wasm)? { } ``` -## Development Workflow +## Development workflow ### 1. Write Rust code @@ -253,7 +253,7 @@ cargo stylus deploy --private-key=$PRIVATE_KEY # Activation happens automatically ``` -## Size Limitations +## Size limitations Nitro imposes limits on WASM contract size: @@ -271,7 +271,7 @@ To stay within limits: - Minimize dependencies - Use compact data structures -## Memory Model +## Memory model ### Linear memory layout @@ -301,7 +301,7 @@ unsafe { The `bulk-memory` feature flag enables efficient WASM instructions like `memory.copy` and `memory.fill`. -## Advanced: WASM Instructions +## Advanced: WASM instructions Stylus uses WASM MVP (Minimum Viable Product) instructions plus bulk-memory operations: @@ -332,7 +332,7 @@ Stylus uses WASM MVP (Minimum Viable Product) instructions plus bulk-memory oper - โŒ Multiple memories - โŒ Threads -## Best Practices +## Best practices ### 1. Minimize binary size diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx index 25d39fe3f2..a3e111bbba 100644 --- a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx @@ -25,7 +25,7 @@ Stylus accepts any valid WebAssembly module that meets its requirements. You can The key is using the `--wasm-file` flag with `cargo stylus` commands to bypass Rust compilation. -## Why Use Non-Rust Languages? +## Why use non-Rust languages? Different languages excel at different tasks: @@ -50,7 +50,7 @@ Different languages excel at different tasks: - **Ecosystem**: Rich library support and examples - **Productivity**: Higher-level abstractions and macros -## WASM Requirements +## WASM requirements All WASM modules deployed to Stylus must meet these requirements: @@ -195,7 +195,7 @@ Compressed WASM size: 142 B Contract succeeded Stylus onchain activation checks with Stylus version: 1 ``` -## C/C++ Development +## C/C++ development The [Stylus C SDK](https://github.com/OffchainLabs/stylus-sdk-c) enables C/C++ smart contract development. @@ -384,7 +384,7 @@ int main(int argc, char *argv[]) { } ``` -## AssemblyScript Contracts +## AssemblyScript contracts AssemblyScript is TypeScript-like language that compiles to WebAssembly. @@ -453,7 +453,7 @@ cargo stylus deploy \ --private-key-path=./key.txt ``` -## Deployment Workflow +## Deployment workflow ### 1. Prepare your WASM @@ -511,7 +511,7 @@ Activating contract at address 0x... Confirmed tx 0x... ``` -## Best Practices +## Best practices ### 1. Minimize binary size @@ -738,7 +738,7 @@ LDFLAGS = -no-entry --export=user_entrypoint --export=memory cast call $CONTRACT "0x" ``` -## Examples Repository +## Examples repository Official examples for different languages: @@ -746,7 +746,7 @@ Official examples for different languages: - [**Stylus Bf SDK**](https://github.com/OffchainLabs/stylus-sdk-bf) - Brainfuck educational examples - [**Awesome Stylus**](https://github.com/OffchainLabs/awesome-stylus) - Community examples -## Language Support Matrix +## Language support matrix | Language | Status | SDK | Best Use Case | | ------------------ | --------------- | -------------------------------------------------------------- | --------------------------- | @@ -757,7 +757,7 @@ Official examples for different languages: | **Go** | ๐Ÿ”ถ Experimental | TinyGo | Custom applications | | **Zig** | ๐Ÿ”ถ Experimental | Custom | Systems programming | -## Advanced: Custom Languages +## Advanced: custom languages To support a new language: From b19d7660a90bd52865502f3a7db1f7a5fcf2e5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 11 Dec 2025 22:53:07 -0800 Subject: [PATCH 103/162] docs: fix headers to sentence case in primitives.mdx --- .../reference/data-types/primitives.mdx | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/reference/data-types/primitives.mdx index d46d8c6f1b..0ec5f86ddc 100644 --- a/docs/stylus/reference/data-types/primitives.mdx +++ b/docs/stylus/reference/data-types/primitives.mdx @@ -14,7 +14,7 @@ The Stylus SDK provides full support for Rust primitive types with automatic ABI Booleans in Rust map directly to Solidity's `bool` type. -### Usage in Contract Methods +### Usage in contract methods ```rust use stylus_sdk::prelude::*; @@ -34,7 +34,7 @@ impl MyContract { } ``` -### Solidity Mapping +### Solidity mapping - **Rust type**: `bool` - **Solidity type**: `bool` @@ -45,9 +45,9 @@ impl MyContract { The Stylus SDK supports both signed and unsigned integers with various bit sizes. All integer types from Rust's standard library and alloy-primitives are supported. -### Unsigned Integers +### Unsigned integers -#### Standard Rust Unsigned Integers +#### Standard Rust unsigned integers ```rust use stylus_sdk::prelude::*; @@ -81,7 +81,7 @@ impl MyContract { } ``` -#### Alloy Unsigned Integers +#### Alloy unsigned integers For larger integers and full compatibility with Solidity's uint types, use `alloy_primitives::Uint`: @@ -107,9 +107,9 @@ impl MyContract { } ``` -### Signed Integers +### Signed integers -#### Standard Rust Signed Integers +#### Standard Rust signed integers ```rust use stylus_sdk::prelude::*; @@ -143,7 +143,7 @@ impl MyContract { } ``` -#### Alloy Signed Integers +#### Alloy signed integers ```rust use alloy_primitives::{Signed, I256}; @@ -163,7 +163,7 @@ impl MyContract { } ``` -### Integer Type Mappings +### Integer type mappings | Rust Type | Solidity Type | Bit Size | ABI Signature | | ------------------------- | ------------- | -------- | ------------- | @@ -188,7 +188,7 @@ impl MyContract { Ethereum addresses are represented by the `Address` type from `alloy_primitives`. -### Basic Usage +### Basic usage ```rust use alloy_primitives::Address; @@ -213,7 +213,7 @@ impl MyContract { } ``` -### Address Constants +### Address constants ```rust use alloy_primitives::Address; @@ -229,7 +229,7 @@ let bytes: [u8; 20] = [0; 20]; let addr = Address::from(bytes); ``` -### Solidity Mapping +### Solidity mapping - **Rust type**: `Address` (from `alloy_primitives`) - **Solidity type**: `address` @@ -240,7 +240,7 @@ let addr = Address::from(bytes); Rust `String` types map to Solidity `string` type. -### String Literals +### String literals ```rust use stylus_sdk::prelude::*; @@ -258,7 +258,7 @@ impl MyContract { } ``` -### Solidity Mapping +### Solidity mapping - **Rust type**: `String` (from `alloc::string`) - **Solidity type**: `string` @@ -278,7 +278,7 @@ impl MyContract { The SDK provides two types for working with byte data: -### 1. Dynamic Bytes (`Bytes`) +### 1. Dynamic bytes (`Bytes`) For variable-length byte arrays (Solidity `bytes`): @@ -298,7 +298,7 @@ impl MyContract { } ``` -### 2. Fixed Bytes (`FixedBytes`) +### 2. Fixed bytes (`FixedBytes`) For fixed-length byte arrays (Solidity `bytesN`): @@ -325,7 +325,7 @@ impl MyContract { } ``` -### Common FixedBytes Aliases +### Common FixedBytes aliases ```rust use alloy_primitives::{B256, B160, B128}; @@ -340,7 +340,7 @@ let data: B160 = B160::ZERO; let value: B128 = B128::ZERO; ``` -### Bytes Type Mappings +### Bytes type mappings | Rust Type | Solidity Type | Description | | ------------------------- | ------------- | -------------------------------- | @@ -357,7 +357,7 @@ let value: B128 = B128::ZERO; - `Bytes` maps to Solidity `bytes` (dynamic byte array) - For Solidity `bytes`, always use `alloy_primitives::Bytes` -### Bytes ABI Encoding +### Bytes ABI encoding ```rust // Bytes type @@ -370,7 +370,7 @@ let value: B128 = B128::ZERO; // Example: FixedBytes<32> -> "bytes32" ``` -## Hex String Literals +## Hex string literals When working with hex data, you can use hex literals: @@ -392,7 +392,7 @@ let hash = FixedBytes::<32>::from(hex!( let bytes = Bytes::from(hex!("aabbccdd")); ``` -## Complete Example +## Complete example Here's a comprehensive example showing all primitive types: @@ -472,7 +472,7 @@ impl PrimitiveExample { } ``` -## Best Practices +## Best practices 1. **Use U256 for token amounts**: Solidity commonly uses `uint256` for token balances and amounts. @@ -527,9 +527,9 @@ impl PrimitiveExample { } ``` -## Type Conversion +## Type conversion -### Between Integer Types +### Between integer types ```rust use alloy_primitives::U256; @@ -543,7 +543,7 @@ let big_value = U256::from(1000); let small_value: u64 = big_value.to::(); ``` -### Address Conversions +### Address conversions ```rust use alloy_primitives::Address; @@ -557,7 +557,7 @@ let addr = Address::ZERO; let bytes: [u8; 20] = addr.into(); ``` -## See Also +## See also - [Compound Types](./compound-types.mdx) - Arrays, tuples, structs - [Storage Types](./storage.mdx) - Persistent storage for primitives From c5b870891f315a6d88433c851420ebb885dc47eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 11 Dec 2025 22:53:17 -0800 Subject: [PATCH 104/162] docs: fix headers to sentence case in compound-types.mdx --- .../reference/data-types/compound-types.mdx | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/reference/data-types/compound-types.mdx index 00b7e89b2b..6cef7b8c79 100644 --- a/docs/stylus/reference/data-types/compound-types.mdx +++ b/docs/stylus/reference/data-types/compound-types.mdx @@ -14,7 +14,7 @@ Compound types allow you to group multiple values together in Stylus contracts. Tuples group multiple values of different types together. They map directly to Solidity tuples. -### Basic Tuples +### Basic tuples ```rust use alloy_primitives::{Address, U256, Bytes}; @@ -40,7 +40,7 @@ impl MyContract { } ``` -### Tuple Destructuring +### Tuple destructuring ```rust use alloy_primitives::U256; @@ -68,7 +68,7 @@ impl MyContract { } ``` -### Tuple Type Mappings +### Tuple type mappings | Rust Type | Solidity Type | ABI Signature | | ---------------------- | ---------------------------- | ---------------------------- | @@ -87,7 +87,7 @@ impl MyContract { Structs define custom data types with named fields. Use the `sol!` macro to define Solidity-compatible structs. -### Defining Structs with `sol!` +### Defining structs with `sol!` ```rust use alloy_primitives::{Address, U256}; @@ -135,7 +135,7 @@ impl MyContract { } ``` -### Nested Structs +### Nested structs Structs can contain other structs, enabling complex data structures: @@ -186,7 +186,7 @@ impl MyContract { } ``` -### Struct Best Practices +### Struct best practices 1. **Always use `#[derive(AbiType)]`** for structs that will be used in contract interfaces: @@ -229,7 +229,7 @@ impl MyContract { Arrays are fixed-size collections of elements. Stylus supports both Rust arrays and Solidity-style arrays. -### Fixed-Size Arrays +### Fixed-size arrays ```rust use alloy_primitives::U256; @@ -260,7 +260,7 @@ impl MyContract { } ``` -### Array Operations +### Array operations ```rust use alloy_primitives::{Address, U256}; @@ -286,7 +286,7 @@ impl MyContract { } ``` -### Array Type Mappings +### Array type mappings | Rust Type | Solidity Type | Description | | --------------------- | -------------- | ------------------------- | @@ -300,7 +300,7 @@ impl MyContract { Vectors are dynamic arrays that can grow or shrink at runtime. They map to Solidity dynamic arrays. -### Basic Vector Usage +### Basic vector usage ```rust use alloy_primitives::{Address, U256, Bytes}; @@ -333,7 +333,7 @@ impl MyContract { } ``` -### Vector Operations +### Vector operations ```rust use alloy_primitives::U256; @@ -369,7 +369,7 @@ impl MyContract { } ``` -### Vectors of Structs +### Vectors of structs ```rust use alloy_primitives::Address; @@ -409,7 +409,7 @@ impl MyContract { } ``` -### Vector Type Mappings +### Vector type mappings | Rust Type | Solidity Type | ABI Signature | Storage | | --------------- | ------------- | --------------------- | ------- | @@ -429,7 +429,7 @@ impl MyContract { The SDK provides `Bytes` for dynamic byte arrays and `FixedBytes` for fixed-size byte arrays. -### Dynamic Bytes (`Bytes`) +### Dynamic bytes (`Bytes`) ```rust use alloy_primitives::Bytes; @@ -456,7 +456,7 @@ impl MyContract { } ``` -### Fixed Bytes (`FixedBytes`) +### Fixed bytes (`FixedBytes`) ```rust use alloy_primitives::FixedBytes; @@ -484,9 +484,9 @@ impl MyContract { } ``` -## Complete Examples +## Complete examples -### Example 1: Complex Data Structures +### Example 1: Complex data structures ```rust #![cfg_attr(not(any(test, feature = "export-abi")), no_main)] @@ -563,7 +563,7 @@ impl CompoundExample { } ``` -### Example 2: Nested Data Structures +### Example 2: Nested data structures ```rust #![cfg_attr(not(any(test, feature = "export-abi")), no_main)] @@ -624,9 +624,9 @@ impl NestedExample { } ``` -## Best Practices +## Best practices -### 1. Choose the Right Type +### 1. Choose the right type ```rust // Use tuples for simple groupings @@ -650,7 +650,7 @@ pub fn get_top_five(&self) -> [U256; 5] { /* ... */ } pub fn get_all_users(&self) -> Vec
    { /* ... */ } ``` -### 2. Memory Efficiency +### 2. Memory efficiency ```rust use alloy_primitives::U256; @@ -667,7 +667,7 @@ pub fn dynamic_data(&self, count: usize) -> Vec { } ``` -### 3. Struct Naming +### 3. Struct naming ```rust use alloy_sol_types::sol; @@ -690,7 +690,7 @@ sol! { } ``` -### 4. Vector vs Array +### 4. Vector vs array ```rust use alloy_primitives::{Address, U256}; @@ -708,7 +708,7 @@ pub fn get_users(&self) -> Vec
    { } ``` -### 5. Nested Structures +### 5. Nested structures ```rust use alloy_sol_types::sol; @@ -750,9 +750,9 @@ sol! { } ``` -## Type Conversion and Helpers +## Type conversion and helpers -### Converting Between Types +### Converting between types ```rust use alloy_primitives::{U256, Bytes}; @@ -774,7 +774,7 @@ let vec = vec![U256::from(1), U256::from(2), U256::from(3)]; let arr: [U256; 3] = vec.try_into().unwrap(); ``` -### Working with Iterators +### Working with iterators ```rust use alloy_primitives::U256; @@ -790,9 +790,9 @@ let evens: Vec = numbers.into_iter().filter(|n| n.byte(0) % 2 == 0).collec let sum = numbers.iter().fold(U256::ZERO, |acc, n| acc + n); ``` -## Common Patterns +## Common patterns -### Batch Operations +### Batch operations ```rust use alloy_primitives::{Address, U256}; @@ -838,7 +838,7 @@ impl MyContract { } ``` -## See Also +## See also - [Primitives](./primitives.mdx) - Basic types (bool, integers, address, strings) - [Storage Types](./storage.mdx) - Persistent storage for compound types From 6fad28597e6690eedd5c34f994fbf1d7b882a858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 11 Dec 2025 22:53:24 -0800 Subject: [PATCH 105/162] docs: fix headers to sentence case in storage.mdx --- docs/stylus/reference/data-types/storage.mdx | 66 ++++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 27af6493d1..1de74c4d0b 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -19,7 +19,7 @@ Stylus contracts share the same persistent storage as Solidity contracts: - Stylus provides compile-time safety through Rust's type system - Storage operations are cached for gas efficiency -### Storage Declaration +### Storage declaration Use the `sol_storage!` macro to define contract storage with Solidity-compatible layout: @@ -51,11 +51,11 @@ pub struct MyContract { } ``` -## Storage Primitives +## Storage primitives Storage primitives are persistent versions of basic types. -### Boolean Storage (`StorageBool`) +### Boolean storage (`StorageBool`) Store boolean values in persistent storage: @@ -87,7 +87,7 @@ impl Contract { } ``` -### Integer Storage +### Integer storage Store unsigned and signed integers with various bit sizes: @@ -128,7 +128,7 @@ impl Counter { } ``` -#### Available Storage Integer Types +#### Available storage integer types | Storage Type | Primitive Type | Bit Size | Solidity Type | | ------------- | -------------- | -------- | ------------- | @@ -145,7 +145,7 @@ impl Counter { | `StorageI128` | `I128` | 128 bits | `int128` | | `StorageI256` | `I256` | 256 bits | `int256` | -#### Integer Update Operations +#### Integer update operations `StorageUint` types provide convenient update methods: @@ -186,7 +186,7 @@ impl Contract { } ``` -### Address Storage (`StorageAddress`) +### Address storage (`StorageAddress`) Store Ethereum addresses: @@ -236,7 +236,7 @@ impl Ownership { } ``` -### Fixed Bytes Storage +### Fixed bytes storage Store fixed-size byte arrays: @@ -269,7 +269,7 @@ impl Hashes { } ``` -#### Available Fixed Bytes Storage Types +#### Available fixed bytes storage types | Storage Type | Bytes | Bits | Solidity Type | | ------------- | ----- | -------- | ------------- | @@ -282,11 +282,11 @@ impl Hashes { | `StorageB224` | 28 | 224 bits | `bytes28` | | `StorageB256` | 32 | 256 bits | `bytes32` | -## Storage Collections +## Storage collections Storage collections provide persistent arrays, vectors, and maps. -### StorageVec (Dynamic Array) +### StorageVec (dynamic array) Dynamic arrays that can grow and shrink: @@ -345,7 +345,7 @@ impl TokenList { } ``` -#### StorageVec Methods +#### StorageVec methods ```rust // Length operations @@ -363,7 +363,7 @@ fn grow(&mut self) -> StorageGuardMut<'_, T> // Add new element and return muta fn erase(&mut self) // Clear all elements ``` -### StorageArray (Fixed Array) +### StorageArray (fixed array) Fixed-size arrays with compile-time known length: @@ -407,7 +407,7 @@ impl FixedData { } ``` -### StorageMap (Mapping) +### StorageMap (mapping) Key-value storage, equivalent to Solidity `mapping`: @@ -464,7 +464,7 @@ impl Token { } ``` -#### StorageMap Methods +#### StorageMap methods ```rust // Read operations @@ -479,7 +479,7 @@ fn take(&mut self, key: K) -> V // Returns value and deletes fn delete(&mut self, key: K) // Erases entry ``` -#### Supported Map Key Types +#### Supported map key types Any type implementing `StorageKey` can be used as a map key: @@ -555,7 +555,7 @@ impl Metadata { } ``` -## Storage Structs +## Storage structs Define custom storage types with nested structures: @@ -605,7 +605,7 @@ impl UserRegistry { } ``` -### Nested Storage Structs +### Nested storage structs ```rust use stylus_sdk::prelude::*; @@ -655,9 +655,9 @@ impl Registry { } ``` -## Storage Patterns +## Storage patterns -### Initialization Pattern +### Initialization pattern ```rust use stylus_sdk::prelude::*; @@ -694,7 +694,7 @@ impl Contract { } ``` -### Counter Pattern +### Counter pattern ```rust use stylus_sdk::prelude::*; @@ -736,7 +736,7 @@ impl Counter { } ``` -### Access Control Pattern +### Access control pattern ```rust use stylus_sdk::prelude::*; @@ -798,7 +798,7 @@ impl AccessControl { } ``` -### Registry Pattern +### Registry pattern ```rust use stylus_sdk::prelude::*; @@ -861,9 +861,9 @@ impl Registry { } ``` -## Best Practices +## Best practices -### 1. Use Appropriate Storage Types +### 1. Use appropriate storage types ```rust // Good: Use StorageU256 for counters @@ -888,7 +888,7 @@ sol_storage! { } ``` -### 2. Minimize Storage Operations +### 2. Minimize storage operations ```rust // Bad: Multiple storage reads @@ -905,7 +905,7 @@ pub fn good_example(&self) -> U256 { } ``` -### 3. Use Batch Operations +### 3. Use batch operations ```rust // Good: Batch updates in a single transaction @@ -916,7 +916,7 @@ pub fn update_multiple(&mut self, values: Vec) { } ``` -### 4. Check Before Delete +### 4. Check before delete ```rust // Good: Verify before deletion @@ -928,7 +928,7 @@ pub fn remove_user(&mut self, user: Address) { } ``` -### 5. Use Erase for Gas Refunds +### 5. Use erase for gas refunds ```rust // Good: Clear storage for gas refunds @@ -937,7 +937,7 @@ pub fn clear_data(&mut self) { } ``` -## Storage Slots and Layout +## Storage slots and layout Stylus uses the same storage layout as Solidity: @@ -957,7 +957,7 @@ sol_storage! { } ``` -### Custom Storage Slots +### Custom storage slots You can specify custom storage slots for specific use cases: @@ -976,7 +976,7 @@ pub struct CustomSlots { } ``` -## Complete Example +## Complete example Here's a comprehensive example demonstrating various storage types: @@ -1090,7 +1090,7 @@ impl Token { } ``` -## See Also +## See also - [Primitives](./primitives.mdx) - Basic types used in storage - [Compound Types](./compound-types.mdx) - Complex types in storage From 1f905d0ed7b3629ab4cc3ce52fda5651b5874cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 16:23:22 -0800 Subject: [PATCH 106/162] docs(stylus): add comprehensive restructure implementation guides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add master implementation guide with Phases 1-2 details - Add Phase 3 guide (content consolidation) - Add Phase 4 guide (new content creation) - Add Phase 5 guide (expansion & validation) - Add RESTRUCTURE_README with overview and quick start - Include all automation scripts and validation checklists - Provide rollback procedures for each phase Guides cover: - 5-phase restructure plan (58 hours total) - 13 Mermaid diagram implementations - 100+ file modifications - CLAUDE.md compliance enforcement - Accessibility validation (โ‰ฅ95% target) - Complete rollback procedures Ready for execution with full safety measures. --- docs/stylus/IMPLEMENTATION_GUIDE.md | 1090 +++++++++++++++++++ docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md | 618 +++++++++++ docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md | 1095 ++++++++++++++++++++ docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md | 872 ++++++++++++++++ docs/stylus/RESTRUCTURE_README.md | 348 +++++++ 5 files changed, 4023 insertions(+) create mode 100644 docs/stylus/IMPLEMENTATION_GUIDE.md create mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md create mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md create mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md create mode 100644 docs/stylus/RESTRUCTURE_README.md diff --git a/docs/stylus/IMPLEMENTATION_GUIDE.md b/docs/stylus/IMPLEMENTATION_GUIDE.md new file mode 100644 index 0000000000..9069375c0a --- /dev/null +++ b/docs/stylus/IMPLEMENTATION_GUIDE.md @@ -0,0 +1,1090 @@ +# Stylus Documentation Restructure - Implementation Guide + +**Status:** Ready for execution +**Total Duration:** 5 weeks (5 phases) +**Files Affected:** ~100+ files +**Plan Source:** `~/.claude/plans/hashed-scribbling-finch.md` + +## Overview + +This guide provides step-by-step instructions, scripts, and checklists for implementing the Stylus documentation restructure. Each phase can be executed independently with built-in validation and rollback capabilities. + +## Quick Start + +```bash +# Navigate to project root +cd /Users/allup/OCL/stylus-V10 + +# Create backup before starting +git checkout -b stylus-docs-restructure +git add -A +git commit -m "checkpoint: before restructure" + +# Execute phases in order +./scripts/restructure/phase1.sh +./scripts/restructure/phase2.sh +./scripts/restructure/phase3.sh +./scripts/restructure/phase4.sh +./scripts/restructure/phase5.sh +``` + +## Pre-Flight Checklist + +Before starting any phase: + +- [ ] All changes committed to git +- [ ] Working on feature branch `stylus-docs-restructure` +- [ ] Backup created +- [ ] Build passing (`yarn build`) +- [ ] No uncommitted changes + +## Phase Execution Order + +**IMPORTANT:** Phases must be executed in order due to dependencies: + +1. **Phase 1** โ†’ Clean foundation (delete duplicates, fix compliance) +2. **Phase 2** โ†’ Directory structure (depends on Phase 1 cleanup) +3. **Phase 3** โ†’ Content consolidation (depends on Phase 2 structure) +4. **Phase 4** โ†’ New content (depends on Phase 3 structure) +5. **Phase 5** โ†’ Expansion & validation (depends on all previous phases) + +## Validation Between Phases + +After each phase: + +```bash +# Check build +yarn build + +# Check for broken links +yarn build 2>&1 | grep -i "broken" + +# Verify no uncommitted files +git status + +# Test dev server +yarn start --no-open +# Visit http://localhost:3000/stylus and verify navigation +``` + +## Rollback Procedures + +If issues arise during any phase: + +```bash +# Rollback to pre-phase state +git reset --hard HEAD~1 + +# Or rollback specific files +git checkout HEAD~1 -- docs/stylus/path/to/file.mdx + +# Or rollback entire phase using tag +git reset --hard phase-1-start +``` + +## Success Metrics + +Track these metrics after each phase: + +| Metric | Target | Command | +|--------|--------|---------| +| Build success | Pass | `yarn build` | +| Broken links | 0 | `yarn build 2>&1 \| grep broken` | +| Terminology violations | 0 | See Phase 1 audit scripts | +| Missing frontmatter | 0 | See Phase 1 validation | +| Diagram rendering | 100% | Visual inspection | +| Accessibility score | โ‰ฅ95% | Lighthouse audit | + +--- + +## Phase 1: Foundation & Compliance (Week 1) + +**Goal:** Fix critical issues, ensure CLAUDE.md compliance, complete frontmatter + +**Duration:** ~8 hours +**Files Modified:** ~28 files +**New Files:** 2 +**Deleted Files:** 3 +**Diagrams Added:** 3 + +### Phase 1 Checklist + +- [ ] Delete duplicate overview.md file +- [ ] Create missing advanced/_category_.yml +- [ ] Run terminology audit and fix all violations +- [ ] Complete missing frontmatter +- [ ] Merge verification docs +- [ ] Move faucets partial +- [ ] Add 3 quick-win diagrams +- [ ] Validate build +- [ ] Commit changes + +### Phase 1 Tasks + +#### Task 1.1: Delete Duplicate Files + +```bash +# Verify files are identical +diff docs/stylus/reference/overview.md docs/stylus/reference/overview.mdx + +# Delete the .md version (keep .mdx) +rm docs/stylus/reference/overview.md + +# Verify +git status +``` + +**Expected output:** 1 file deleted + +#### Task 1.2: Create Missing Configuration + +```bash +# Create advanced/_category_.yml +cat > docs/stylus/advanced/_category_.yml << 'EOF' +label: 'Advanced' +position: 8 +link: + type: generated-index + description: Deep dives into Stylus internals, advanced patterns, and optimization techniques. +EOF + +# Verify +cat docs/stylus/advanced/_category_.yml +``` + +**Expected output:** New _category_.yml file created + +#### Task 1.3: Terminology Audit & Fixes + +Create audit script: + +```bash +# Create audit script +mkdir -p scripts/restructure +cat > scripts/restructure/terminology-audit.sh << 'EOF' +#!/bin/bash + +echo "=== Stylus Terminology Audit ===" +echo "" + +violations=0 + +# Check for "js" instead of "JavaScript" +echo "Checking for 'js' (should be 'JavaScript')..." +results=$(grep -rn '\bjs\b' docs/stylus/ --include="*.mdx" --include="*.md" | grep -v "ts.js" | grep -v ".js" | grep -v "js/") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "smartcontract" instead of "smart contract" +echo "" +echo "Checking for 'smartcontract' (should be 'smart contract')..." +results=$(grep -rin 'smartcontract' docs/stylus/ --include="*.mdx" --include="*.md") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "whitelist/blacklist" instead of "allowlist/denylist" +echo "" +echo "Checking for 'whitelist/blacklist' (should be 'allowlist/denylist')..." +results=$(grep -rin 'whitelist\|blacklist' docs/stylus/ --include="*.mdx" --include="*.md") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "on-chain" instead of "onchain" +echo "" +echo "Checking for 'on-chain/on chain' (should be 'onchain')..." +results=$(grep -rn 'on-chain\|on chain' docs/stylus/ --include="*.mdx" --include="*.md") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "ERC20" instead of "ERC-20" +echo "" +echo "Checking for 'ERC20/ERC721' (should be 'ERC-20/ERC-721')..." +results=$(grep -rn 'ERC20\|ERC721\|ERC1155' docs/stylus/ --include="*.mdx" --include="*.md" | grep -v "ERC-") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "Layer-1/L1" instead of "Parent chain" +echo "" +echo "Checking for 'Layer-1/L1/layer 1' (should be 'Parent chain')..." +results=$(grep -rin 'Layer-1\|Layer 1\|\bL1\b' docs/stylus/ --include="*.mdx" --include="*.md") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "Layer-2/L2" instead of "Child chain" +echo "" +echo "Checking for 'Layer-2/L2/layer 2' (should be 'Child chain')..." +results=$(grep -rin 'Layer-2\|Layer 2\|\bL2\b' docs/stylus/ --include="*.mdx" --include="*.md") +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +echo "" +echo "=== Audit Complete ===" +echo "Total violation types found: $violations" +echo "" + +if [ $violations -eq 0 ]; then + echo "โœ… No terminology violations found!" + exit 0 +else + echo "โŒ Terminology violations found. Please fix manually." + exit 1 +fi +EOF + +chmod +x scripts/restructure/terminology-audit.sh +``` + +Run the audit: + +```bash +# Run audit +./scripts/restructure/terminology-audit.sh + +# Fix violations manually based on output +# For each file flagged, open and fix the terminology +``` + +**Manual fixes required:** Review each flagged file and update terminology according to CLAUDE.md standards. + +#### Task 1.4: Frontmatter Audit & Completion + +Create frontmatter audit script: + +```bash +cat > scripts/restructure/frontmatter-audit.sh << 'EOF' +#!/bin/bash + +echo "=== Frontmatter Audit ===" +echo "" + +missing_user_story=() +missing_content_type=() + +# Check all .mdx and .md files +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md" | grep -v "partials"); do + # Check for user_story + if ! grep -q "user_story:" "$file"; then + missing_user_story+=("$file") + fi + + # Check for content_type + if ! grep -q "content_type:" "$file"; then + missing_content_type+=("$file") + fi +done + +echo "Files missing user_story:" +printf '%s\n' "${missing_user_story[@]}" +echo "" +echo "Total: ${#missing_user_story[@]}" +echo "" + +echo "Files missing content_type:" +printf '%s\n' "${missing_content_type[@]}" +echo "" +echo "Total: ${#missing_content_type[@]}" +echo "" + +if [ ${#missing_user_story[@]} -eq 0 ] && [ ${#missing_content_type[@]} -eq 0 ]; then + echo "โœ… All files have complete frontmatter!" + exit 0 +else + echo "โŒ Some files missing frontmatter fields" + exit 1 +fi +EOF + +chmod +x scripts/restructure/frontmatter-audit.sh +``` + +Run and fix: + +```bash +# Run audit +./scripts/restructure/frontmatter-audit.sh + +# For each file missing fields, add: +# user_story: 'As a , I want to ' +# content_type: 'how-to' # or: concept, reference, quickstart, tutorial, faq +``` + +#### Task 1.5: Merge Verification Docs + +**Manual task:** Combine two verification files into one. + +```bash +# Read both files +cat docs/stylus/how-tos/verifying-contracts.mdx +cat docs/stylus/how-tos/verifying-contracts-arbiscan.mdx + +# Create merged version (do this manually by combining content) +# The merged file should have: +# - Overview (what/why verification) +# - Local verification section (from verifying-contracts.mdx) +# - Arbiscan verification section (from verifying-contracts-arbiscan.mdx) +# - Troubleshooting section + +# After creating merged version, delete originals +rm docs/stylus/how-tos/verifying-contracts-arbiscan.mdx +``` + +**Note:** The merged file will be moved to `cli-tools/` in Phase 2. + +#### Task 1.6: Move Partials + +```bash +# Move faucets partial +mv docs/stylus/reference/partials/_stylus-faucets.mdx docs/stylus/partials/ + +# Update all imports (search and replace) +# Old: import StylusFaucets from '../reference/partials/_stylus-faucets.mdx'; +# New: import StylusFaucets from '../partials/_stylus-faucets.mdx'; + +# Find files that import this partial +grep -r "reference/partials/_stylus-faucets" docs/stylus/ + +# Update each file found +``` + +#### Task 1.7: Add Quick-Win Diagrams + +**Diagram #3: WASM Processing Pipeline** (docs/stylus/concepts/activation.mdx) + +Find the existing ASCII art (around lines 74-90) and replace with: + +```mdx +The following diagram shows the complete WASM processing pipeline: + +```mermaid +flowchart LR + A[Raw WASM Binary] --> B[Remove dangling references] + B --> C[Add project_hash metadata] + C --> D[Strip user custom sections] + D --> E[Brotli compress
    level 11] + E --> F[Add EOF prefix] + F --> G[Final compressed code
    โ‰ค 24KB] + + style G fill:#90EE90 + style A fill:#FFE4B5 +``` + +*Figure 1: WASM binary processing pipeline showing transformation from raw binary to deployment-ready compressed code.* + +The deployment process ensures... +``` + +**Diagram #8: Call Configuration Decision Tree** (docs/stylus/how-tos/importing-interfaces.mdx) + +Add after the "Configuring your calls" section introduction: + +```mdx +Use this decision tree to choose the correct Call constructor: + +```mermaid +flowchart TD + Start[Need to call external contract?] --> Modify{Does it modify state?} + Modify -->|No| View[Call::new
    view calls only] + Modify -->|Yes| ETH{Requires ETH payment?} + ETH -->|No| Mutating[Call::new_mutating self
    state changes, no value] + ETH -->|Yes| Payable[Call::new_payable self, value
    state changes + ETH] + + View --> Gas{Need custom gas limit?} + Mutating --> Gas + Payable --> Gas + + Gas -->|Yes| AddGas[Add .gas limit] + Gas -->|No| Done[Ready to call] + AddGas --> Done + + style View fill:#E3F2FD + style Mutating fill:#FFF3E0 + style Payable fill:#FFEBEE + style Done fill:#90EE90 +``` + +*Figure 2: Decision tree for selecting the appropriate Call constructor based on state modification and payment requirements.* +``` + +**Diagram #12: Storage Type Hierarchy** (docs/stylus/reference/data-types/storage.mdx) + +Add at the beginning of the document after the introduction: + +```mdx +The Stylus SDK provides a comprehensive hierarchy of storage types: + +```mermaid +graph TB + Root[Storage Types] --> Primitives + Root --> Collections + Root --> Custom[Custom Structs] + + Primitives --> Bool[StorageBool] + Primitives --> Uint[StorageU256, U128, U64, etc.] + Primitives --> Int[StorageI256, I128, I64, etc.] + Primitives --> Addr[StorageAddress] + Primitives --> Bytes[StorageB256, B32, etc.] + + Collections --> Vec[StorageVec T] + Collections --> Array[StorageArray T, N] + Collections --> Map[StorageMap K, V] + Collections --> Str[StorageString] + Collections --> BytesCol[StorageBytes] + + Custom --> Struct[#[storage] annotated structs] + + style Root fill:#E1BEE7 + style Primitives fill:#BBDEFB + style Collections fill:#C8E6C9 + style Custom fill:#FFE0B2 +``` + +*Figure 3: Storage type hierarchy showing primitives, collections, and custom struct options.* +``` + +#### Task 1.8: Validate Phase 1 + +```bash +# Run build +yarn build + +# Run terminology audit +./scripts/restructure/terminology-audit.sh + +# Run frontmatter audit +./scripts/restructure/frontmatter-audit.sh + +# Check git status +git status + +# Verify diagrams render +yarn start --no-open +# Visit the 3 pages with diagrams and verify they render correctly +``` + +#### Task 1.9: Commit Phase 1 + +```bash +# Stage all changes +git add -A + +# Commit with descriptive message +git commit -m "docs(stylus): Phase 1 - Foundation & Compliance + +- Delete duplicate reference/overview.md +- Create missing advanced/_category_.yml +- Fix all terminology violations per CLAUDE.md +- Complete missing frontmatter (user_story, content_type) +- Merge verification docs into single file +- Move faucets partial to partials/ directory +- Add 3 quick-win Mermaid diagrams (#3, #8, #12) + +Files modified: ~28 +Diagrams added: 3 +Compliance: 100% terminology, 100% frontmatter" + +# Tag for rollback point +git tag phase-1-complete +``` + +### Phase 1 Success Criteria + +- [ ] โœ… Build passes without errors +- [ ] โœ… Zero terminology violations +- [ ] โœ… All files have complete frontmatter +- [ ] โœ… 3 diagrams render correctly +- [ ] โœ… No broken links +- [ ] โœ… Changes committed and tagged + +--- + +## Phase 2: Directory Restructure (Week 2) + +**Goal:** Create flatter, clearer directory structure with better categorization + +**Duration:** ~10 hours +**Files Modified:** ~20 files +**New Files:** 8 +**Directories Created:** 5 + +### Phase 2 Checklist + +- [ ] Create new directory structure +- [ ] Move files to fundamentals/ +- [ ] Move files to guides/ +- [ ] Create cli-tools/ section +- [ ] Update sidebars.js +- [ ] Update all imports +- [ ] Validate build +- [ ] Commit changes + +### Phase 2 Tasks + +#### Task 2.1: Create New Directory Structure + +```bash +# Create new top-level directories +mkdir -p docs/stylus/fundamentals +mkdir -p docs/stylus/guides +mkdir -p docs/stylus/cli-tools +mkdir -p docs/stylus/best-practices +mkdir -p docs/stylus/troubleshooting + +# Create _category_.yml for each +cat > docs/stylus/fundamentals/_category_.yml << 'EOF' +label: 'Fundamentals' +position: 2 +collapsed: false +link: + type: generated-index + description: Essential Stylus SDK concepts, prerequisites, and core development skills. +EOF + +cat > docs/stylus/guides/_category_.yml << 'EOF' +label: 'Guides' +position: 3 +link: + type: generated-index + description: Practical guides for common Stylus development tasks. +EOF + +cat > docs/stylus/cli-tools/_category_.yml << 'EOF' +label: 'CLI tools' +position: 4 +link: + type: generated-index + description: cargo-stylus command-line tools for building, deploying, and verifying contracts. +EOF + +cat > docs/stylus/best-practices/_category_.yml << 'EOF' +label: 'Best practices' +position: 6 +link: + type: generated-index + description: Security, performance, and gas optimization patterns for production Stylus contracts. +EOF + +cat > docs/stylus/troubleshooting/_category_.yml << 'EOF' +label: 'Troubleshooting' +position: 8 +link: + type: generated-index + description: Common issues, error messages, and debugging strategies. +EOF +``` + +#### Task 2.2: Move Files to fundamentals/ + +```bash +# Move SDK basics to fundamentals +mv docs/stylus/reference/project-structure.mdx docs/stylus/fundamentals/ +mv docs/stylus/reference/contracts.mdx docs/stylus/fundamentals/ +mv docs/stylus/reference/global-variables-and-functions.mdx docs/stylus/fundamentals/ +mv docs/stylus/reference/data-types docs/stylus/fundamentals/ + +# Move testing (core skill) +mv docs/stylus/how-tos/testing-contracts.mdx docs/stylus/fundamentals/ + +# Update frontmatter in each moved file to fix sidebar_position +# This needs to be done manually for each file +``` + +#### Task 2.3: Move Files to guides/ + +```bash +# Rename how-tos to guides +# First, move all files from how-tos to guides (except those already moved) +for file in docs/stylus/how-tos/*.mdx; do + mv "$file" docs/stylus/guides/$(basename "$file") +done + +# Remove empty how-tos directory (after Phase 2 complete) +``` + +#### Task 2.4: Create cli-tools/ Section + +```bash +# Transform using-cli.mdx into cli-tools/overview.mdx +cp docs/stylus/using-cli.mdx docs/stylus/cli-tools/overview.mdx + +# Move CLI-related files +mv docs/stylus/guides/check-and-deploy.mdx docs/stylus/cli-tools/ +mv docs/stylus/guides/verifying-contracts.mdx docs/stylus/cli-tools/verify-contracts.mdx +mv docs/stylus/guides/debugging-tx.mdx docs/stylus/cli-tools/ +``` + +Create cli-tools/commands-reference.mdx: + +```mdx +--- +title: 'cargo-stylus command reference' +description: 'Complete reference for all cargo-stylus CLI commands' +user_story: 'As a Stylus developer, I want a complete reference of all CLI commands' +content_type: reference +author: offchainlabs +sidebar_position: 5 +--- + +# cargo-stylus command reference + +Complete reference for all `cargo-stylus` commands. + +## new + +Create a new Stylus project. + +**Usage:** +```shell +cargo stylus new +``` + +**Options:** +- `--minimal` - Create minimal project structure + +**Example:** +```shell +cargo stylus new my-stylus-contract +``` + +## check + +Verify a contract compiles to valid WASM. + +**Usage:** +```shell +cargo stylus check +``` + +**Options:** +- `--endpoint ` - RPC endpoint (default: http://localhost:8547) + +## deploy + +Deploy a Stylus contract. + +**Usage:** +```shell +cargo stylus deploy \\ + --endpoint \\ + --private-key +``` + +**Options:** +- `--endpoint ` - RPC endpoint +- `--private-key ` - Private key for deployment +- `--estimate-gas` - Estimate gas only, don't deploy + +## activate + +Activate a deployed contract. + +**Usage:** +```shell +cargo stylus activate \\ + --endpoint \\ + --private-key \\ + --address +``` + +## verify + +Verify contract source code. + +**Usage:** +```shell +cargo stylus verify \\ + --deployment-tx +``` + +**Options:** +- `--endpoint ` - RPC endpoint + +## cache + +Manage contract caching. + +**Usage:** +```shell +cargo stylus cache bid
    +cargo stylus cache status
    +``` + +## export-abi + +Export contract ABI. + +**Usage:** +```shell +cargo stylus export-abi +``` + +**Output:** +Generates Solidity interface compatible ABI. + +--- + +For detailed usage examples, see the [CLI tools guides](/stylus/cli-tools/overview). +``` + +#### Task 2.5: Update sidebars.js + +This is a critical file that needs careful updating. Create a backup first: + +```bash +cp sidebars.js sidebars.js.backup +``` + +Then update the Stylus section (around lines 1572-1791) to reflect the new flatter structure: + +```javascript +// In sidebars.js, find the buildStylusSidebar section and update: + +{ + type: 'category', + label: 'Build apps with Stylus', + link: { + type: 'generated-index', + title: 'Build apps with Stylus', + description: 'Learn how to build decentralized applications using Stylus, Arbitrum\'s next-generation smart contract platform supporting Rust, C, and C++.', + slug: '/stylus', + }, + collapsed: false, + items: [ + 'stylus/gentle-introduction', + 'stylus/quickstart', + { + type: 'category', + label: 'Fundamentals', + collapsed: false, + link: { + type: 'generated-index', + }, + items: [ + 'stylus/fundamentals/project-structure', + 'stylus/fundamentals/contracts', + 'stylus/fundamentals/global-variables-and-functions', + { + type: 'category', + label: 'Data types', + items: [ + 'stylus/fundamentals/data-types/primitives', + 'stylus/fundamentals/data-types/compound-types', + 'stylus/fundamentals/data-types/storage', + 'stylus/fundamentals/data-types/conversions-between-types', + ], + }, + 'stylus/fundamentals/testing-contracts', + ], + }, + { + type: 'category', + label: 'Guides', + items: [ + 'stylus/guides/using-constructors', + 'stylus/guides/using-inheritance', + 'stylus/guides/importing-interfaces', + 'stylus/guides/exporting-abi', + 'stylus/guides/optimizing-binaries', + 'stylus/guides/caching-contracts', + 'stylus/guides/deploy-non-rust-contracts', + 'stylus/guides/add-language-support', + ], + }, + { + type: 'category', + label: 'CLI tools', + items: [ + 'stylus/cli-tools/overview', + 'stylus/cli-tools/check-and-deploy', + 'stylus/cli-tools/verify-contracts', + 'stylus/cli-tools/debugging-tx', + 'stylus/cli-tools/commands-reference', + ], + }, + { + type: 'category', + label: 'Concepts', + items: [ + 'stylus/concepts/webassembly', + 'stylus/concepts/activation', + 'stylus/concepts/gas-metering', + 'stylus/concepts/evm-differences', + 'stylus/concepts/public-preview-expectations', + ], + }, + { + type: 'category', + label: 'Best practices', + items: [ + // Phase 4 will add files here + ], + }, + { + type: 'category', + label: 'Advanced', + items: [ + 'stylus/advanced/solidity-differences', + 'stylus/advanced/minimal-entrypoint-contracts', + 'stylus/advanced/hostio-exports', + 'stylus/advanced/recommended-libraries', + ], + }, + { + type: 'category', + label: 'Troubleshooting', + items: [ + // Phase 4 will add files here + ], + }, + { + type: 'category', + label: 'Reference', + items: [ + 'stylus/reference/overview', + 'stylus/reference/opcode-hostio-pricing', + // Phase 3 will add rust-sdk/* here + ], + }, + ], +}, +``` + +#### Task 2.6: Update Imports + +After moving files, all imports need updating. Create a script: + +```bash +cat > scripts/restructure/update-imports.sh << 'EOF' +#!/bin/bash + +echo "Updating imports for moved files..." + +# Update imports for files moved to fundamentals/ +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|../reference/project-structure|../fundamentals/project-structure|g' \ + -e 's|../reference/contracts|../fundamentals/contracts|g' \ + -e 's|../reference/global-variables-and-functions|../fundamentals/global-variables-and-functions|g' \ + -e 's|../reference/data-types|../fundamentals/data-types|g' \ + {} \; + +# Update imports for CLI tools +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|../using-cli|../cli-tools/overview|g' \ + -e 's|how-tos/check-and-deploy|cli-tools/check-and-deploy|g' \ + -e 's|how-tos/debugging-tx|cli-tools/debugging-tx|g' \ + {} \; + +# Update imports for guides (how-tos โ†’ guides) +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|/how-tos/|/guides/|g' \ + {} \; + +echo "โœ… Imports updated" +EOF + +chmod +x scripts/restructure/update-imports.sh +./scripts/restructure/update-imports.sh +``` + +**Note:** On Linux, remove the `''` after `-i` in sed commands. + +#### Task 2.7: Validate Phase 2 + +```bash +# Run build +yarn build + +# Check for broken links +yarn build 2>&1 | grep -i "broken\|error" + +# Start dev server +yarn start --no-open + +# Manual verification: +# - Navigate to /stylus +# - Verify new sidebar structure +# - Click through all sections +# - Verify no 404s +``` + +#### Task 2.8: Commit Phase 2 + +```bash +git add -A +git commit -m "docs(stylus): Phase 2 - Directory Restructure + +- Create 5 new top-level directories (fundamentals, guides, cli-tools, best-practices, troubleshooting) +- Move SDK basics to fundamentals/ (project-structure, contracts, data-types, testing) +- Rename how-tos/ to guides/ and flatten structure +- Create cli-tools/ section with overview and commands reference +- Update sidebars.js to max 3-level depth +- Update all imports for moved files + +Files modified: ~20 +New directories: 5 +Sidebar depth: Reduced from 4+ to 3 levels" + +git tag phase-2-complete +``` + +### Phase 2 Success Criteria + +- [ ] โœ… Build passes +- [ ] โœ… All sections appear in sidebar +- [ ] โœ… No broken internal links +- [ ] โœ… Max 3 sidebar levels +- [ ] โœ… Changes committed and tagged + +--- + +## Phase 3: Content Consolidation (Week 3) + +**Goal:** Merge overlapping content and break up large files + +**Duration:** ~12 hours +**Files Modified:** 4 +**New Files:** 12 +**Deleted Files:** 2 +**Diagrams Added:** 1 + +See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE3.md` (to be created). + +--- + +## Phase 4: Create New Content (Week 4) + +**Goal:** Fill identified gaps with new documentation + +**Duration:** ~16 hours +**New Files:** 15 +**Diagrams Added:** 6 + +See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE4.md` (to be created). + +--- + +## Phase 5: Expansion & Validation (Week 5) + +**Goal:** Expand stub files, final reviews, and comprehensive validation + +**Duration:** ~12 hours +**Files Modified:** ~18 +**Diagrams Added:** 3 + +See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE5.md` (to be created). + +--- + +## Rollback Scripts + +### Rollback Phase 1 + +```bash +git reset --hard phase-1-start +# or +git revert phase-1-complete +``` + +### Rollback Phase 2 + +```bash +git reset --hard phase-1-complete +# or +git revert phase-2-complete +``` + +### Full Rollback + +```bash +git reset --hard HEAD~5 # Rollback last 5 commits +# or +git checkout stylus-docs-restructure-backup +``` + +--- + +## Testing & Validation + +### Automated Tests + +```bash +# Run all validation scripts +./scripts/restructure/terminology-audit.sh +./scripts/restructure/frontmatter-audit.sh +./scripts/restructure/broken-links-check.sh + +# Build test +yarn build + +# Lighthouse accessibility audit +lighthouse http://localhost:3000/stylus --only-categories=accessibility +``` + +### Manual Testing + +1. **Navigation Testing** + - [ ] All sidebar items clickable + - [ ] No 404 pages + - [ ] Breadcrumbs work correctly + +2. **Content Testing** + - [ ] All diagrams render + - [ ] Code blocks formatted correctly + - [ ] Images load properly + +3. **Mobile Testing** + - [ ] Sidebar navigation works + - [ ] Diagrams responsive + - [ ] Touch targets adequate + +4. **Search Testing** + - [ ] Search finds moved content + - [ ] Search results link correctly + +--- + +## Appendix: File Move Matrix + +Complete mapping of all file moves: + +| Old Path | New Path | Phase | +|----------|----------|-------| +| `reference/project-structure.mdx` | `fundamentals/project-structure.mdx` | 2 | +| `reference/contracts.mdx` | `fundamentals/contracts.mdx` | 2 | +| `reference/global-variables-and-functions.mdx` | `fundamentals/global-variables-and-functions.mdx` | 2 | +| `reference/data-types/*` | `fundamentals/data-types/*` | 2 | +| `how-tos/testing-contracts.mdx` | `fundamentals/testing-contracts.mdx` | 2 | +| `how-tos/*.mdx` | `guides/*.mdx` | 2 | +| `using-cli.mdx` | `cli-tools/overview.mdx` | 2 | +| `how-tos/check-and-deploy.mdx` | `cli-tools/check-and-deploy.mdx` | 2 | +| `how-tos/verifying-contracts.mdx` | `cli-tools/verify-contracts.mdx` | 2 | +| `how-tos/debugging-tx.mdx` | `cli-tools/debugging-tx.mdx` | 2 | +| `reference/rust-sdk-guide.md` | `reference/rust-sdk/*.mdx` (split) | 3 | +| `concepts/evm-differences.mdx` | `concepts/vm-differences.mdx` (merged) | 3 | + +--- + +## Support & Questions + +If you encounter issues during implementation: + +1. Check the rollback procedures above +2. Verify all prerequisite checks were completed +3. Review the validation steps for the failed phase +4. Check git status for unexpected changes +5. Review build output for specific errors + +For additional guidance, refer to the original plan at `~/.claude/plans/hashed-scribbling-finch.md`. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md new file mode 100644 index 0000000000..7f92420525 --- /dev/null +++ b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md @@ -0,0 +1,618 @@ +# Phase 3: Content Consolidation - Implementation Guide + +**Duration:** ~12 hours +**Files Modified:** 4 +**New Files:** 12 (8 SDK files + prerequisites + 3 partials) +**Deleted Files:** 2 +**Diagrams Added:** 1 + +## Overview + +Phase 3 focuses on eliminating content duplication by: +1. Merging overlapping conceptual content +2. Breaking up oversized files (rust-sdk-guide.md at 536 lines) +3. Extracting repeated setup instructions into reusable partials +4. Adding visual journey map to quickstart + +## Pre-Phase 3 Checklist + +- [ ] Phase 1 completed successfully +- [ ] Phase 2 completed successfully +- [ ] Current build passes +- [ ] Working on branch `stylus-docs-restructure` +- [ ] Tag `phase-2-complete` exists + +## Phase 3 Tasks + +### Task 3.1: Merge VM/Language Differences + +**Goal:** Consolidate `evm-differences.mdx` and parts of `solidity-differences.mdx` into `vm-differences.mdx` + +#### Step 1: Create vm-differences.mdx + +Read both existing files: + +```bash +cat docs/stylus/concepts/evm-differences.mdx +cat docs/stylus/advanced/solidity-differences.mdx +``` + +Create the merged file `docs/stylus/concepts/vm-differences.mdx`: + +```mdx +--- +title: 'VM and execution differences' +description: 'Understand the differences between EVM and WASM execution models in Stylus' +user_story: 'As a developer, I want to understand how WASM execution differs from EVM' +content_type: concept +author: offchainlabs +sme: offchainlabs +sidebar_position: 4 +--- + +# VM and execution differences + +Stylus introduces a WebAssembly (WASM) execution environment alongside the traditional Ethereum Virtual Machine (EVM). Understanding these differences is crucial for effective Stylus development. + +## Execution model comparison + +### EVM: Stack-based architecture + +The EVM operates on a stack-based architecture: +- Instructions manipulate a 256-bit stack +- Each opcode is interpreted at runtime +- Gas charged before each operation +- Limited to 256-bit word size + +### WASM: Register-based architecture + +Stylus WASM uses a register-based model: +- Instructions operate on typed local variables +- Compiled to native code (AOT compilation) +- Ink charged in batches, converted to gas +- Supports 32-bit and 64-bit operations natively + +[MERGE CONTENT FROM BOTH FILES HERE - Include execution model, memory model, gas metering differences, etc.] + +## Key takeaways + +- **Performance**: WASM execution is significantly faster due to native compilation +- **Gas efficiency**: Batch ink charging reduces overhead +- **Interoperability**: Both VMs share the same state, enabling seamless cross-VM calls +- **Developer experience**: Rust provides memory safety and modern tooling + +--- + +For language-specific comparison between Rust and Solidity, see [Rust to Solidity differences](/stylus/advanced/rust-to-solidity-differences). +``` + +#### Step 2: Rename solidity-differences.mdx + +```bash +# Rename to make purpose clearer +mv docs/stylus/advanced/solidity-differences.mdx docs/stylus/advanced/rust-to-solidity-differences.mdx + +# Update frontmatter in the file +# Change title to: "Rust to Solidity differences" +# This file should focus on LANGUAGE differences, not VM differences +``` + +#### Step 3: Delete old evm-differences.mdx + +```bash +rm docs/stylus/concepts/evm-differences.mdx +``` + +#### Step 4: Update sidebar + +In `sidebars.js`, update the concepts section: + +```javascript +{ + type: 'category', + label: 'Concepts', + items: [ + 'stylus/concepts/webassembly', + 'stylus/concepts/activation', + 'stylus/concepts/gas-metering', + 'stylus/concepts/vm-differences', // Changed from evm-differences + 'stylus/concepts/public-preview-expectations', + ], +}, +``` + +### Task 3.2: Break Up rust-sdk-guide.md + +**Goal:** Split 536-line file into 8 focused files + +#### Step 1: Create directory structure + +```bash +mkdir -p docs/stylus/reference/rust-sdk +``` + +#### Step 2: Read the original file + +```bash +cat docs/stylus/reference/rust-sdk-guide.md +``` + +#### Step 3: Create split files + +Create each file by extracting relevant sections from the original: + +**index.mdx** (~50 lines) +```mdx +--- +title: 'Rust SDK overview' +description: 'Overview of the Stylus Rust SDK for building smart contracts' +user_story: 'As a Rust developer, I want to understand the Rust SDK structure' +content_type: reference +--- + +# Rust SDK overview + +The Stylus Rust SDK provides a comprehensive framework for building smart contracts in Rust... + +[Extract overview section from original] + +## SDK components + +- **Storage**: Persistent state management +- **Methods**: External and view functions +- **Events**: Emit and index blockchain events +- **Errors**: Type-safe error handling +- **Calls**: Inter-contract communication +- **Crypto**: Cryptographic operations +- **Bytes**: Low-level byte manipulation + +## Getting started + +```rust +use stylus_sdk::prelude::*; + +#[storage] +pub struct Counter { + count: StorageU256, +} +``` + +## Next steps + +- [Storage management](./storage) +- [Defining methods](./methods) +- [Emitting events](./events) +``` + +**storage.mdx** (~80 lines) +```mdx +--- +title: 'Storage management' +description: 'Persistent storage in Stylus contracts using the Rust SDK' +user_story: 'As a developer, I want to manage persistent state in my Stylus contract' +content_type: reference +--- + +# Storage management + +[Extract storage section from original rust-sdk-guide.md] +``` + +**methods.mdx** (~70 lines) +```mdx +--- +title: 'Contract methods' +description: 'Defining external and view methods in Stylus contracts' +user_story: 'As a developer, I want to create callable functions in my contract' +content_type: reference +--- + +# Contract methods + +[Extract methods section] +``` + +**events.mdx** (~50 lines) +```mdx +--- +title: 'Events and logging' +description: 'Emit and index events from Stylus contracts' +user_story: 'As a developer, I want to emit events from my contract' +content_type: reference +--- + +# Events and logging + +[Extract events section] +``` + +**errors.mdx** (~40 lines) +```mdx +--- +title: 'Error handling' +description: 'Type-safe error handling in Stylus contracts' +user_story: 'As a developer, I want to handle errors gracefully' +content_type: reference +--- + +# Error handling + +[Extract errors section] +``` + +**calls.mdx** (~90 lines) +```mdx +--- +title: 'Contract calls' +description: 'Make calls to other contracts from Stylus' +user_story: 'As a developer, I want to call other contracts' +content_type: reference +--- + +# Contract calls + +[Extract calls section] +``` + +**crypto.mdx** (~60 lines) +```mdx +--- +title: 'Cryptographic operations' +description: 'Hashing and cryptography in Stylus contracts' +user_story: 'As a developer, I want to use cryptographic functions' +content_type: reference +--- + +# Cryptographic operations + +[Extract crypto section] +``` + +**bytes-programming.mdx** (~96 lines) +```mdx +--- +title: 'Bytes programming' +description: 'Low-level byte manipulation in Stylus' +user_story: 'As a developer, I want to work with raw bytes efficiently' +content_type: reference +--- + +# Bytes programming + +[Extract bytes programming section] +``` + +#### Step 4: Delete original file + +```bash +rm docs/stylus/reference/rust-sdk-guide.md +``` + +#### Step 5: Update sidebar + +```javascript +{ + type: 'category', + label: 'Reference', + items: [ + 'stylus/reference/overview', + { + type: 'category', + label: 'Rust SDK', + items: [ + 'stylus/reference/rust-sdk/index', + 'stylus/reference/rust-sdk/storage', + 'stylus/reference/rust-sdk/methods', + 'stylus/reference/rust-sdk/events', + 'stylus/reference/rust-sdk/errors', + 'stylus/reference/rust-sdk/calls', + 'stylus/reference/rust-sdk/crypto', + 'stylus/reference/rust-sdk/bytes-programming', + ], + }, + 'stylus/reference/opcode-hostio-pricing', + ], +}, +``` + +### Task 3.3: Extract Setup from Quickstart + +**Goal:** Create `fundamentals/prerequisites.mdx` and extract duplicate setup instructions + +#### Step 1: Create prerequisites.mdx + +```bash +cat > docs/stylus/fundamentals/prerequisites.mdx << 'EOF' +--- +title: 'Prerequisites and setup' +description: 'Set up your development environment for Stylus' +user_story: 'As a new Stylus developer, I want to set up my development environment' +content_type: how-to +sidebar_position: 1 +--- + +import RustSetup from '../partials/_setup-rust-toolchain.mdx'; +import CargoStylusSetup from '../partials/_setup-cargo-stylus.mdx'; +import DockerSetup from '../partials/_setup-docker-nitro.mdx'; + +# Prerequisites and setup + +This guide will help you set up everything you need to develop Stylus contracts. + +## System requirements + +- **Operating System**: macOS, Linux, or Windows (WSL2) +- **RAM**: Minimum 8GB, 16GB recommended +- **Disk Space**: At least 20GB free + +## Install Rust + + + +## Install cargo-stylus CLI + + + +## Install Docker (for local testnet) + + + +## Verify installation + +```shell +# Check Rust version +rustc --version + +# Check cargo-stylus +cargo stylus --version + +# Check Docker +docker --version +``` + +Expected output: +``` +rustc 1.75.0 (or higher) +cargo-stylus 0.x.x +Docker version 24.0.0 (or higher) +``` + +## Next steps + +- [Create your first project](/stylus/quickstart) +- [Understand project structure](/stylus/fundamentals/project-structure) +- [Learn about contracts](/stylus/fundamentals/contracts) +EOF +``` + +#### Step 2: Create setup partials + +**Rust toolchain partial:** + +```bash +cat > docs/stylus/partials/_setup-rust-toolchain.mdx << 'EOF' +### Installing Rust + +The Rust toolchain includes `rustc` (compiler), `cargo` (package manager), and `rustup` (version manager). + +**macOS/Linux:** + +```shell +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +**Windows:** + +Download and run [rustup-init.exe](https://rustup.rs/). + +**Configure for WASM:** + +```shell +rustup target add wasm32-unknown-unknown +``` + +**Verify:** + +```shell +rustc --version +cargo --version +``` +EOF +``` + +**cargo-stylus partial:** + +```bash +cat > docs/stylus/partials/_setup-cargo-stylus.mdx << 'EOF' +### Installing cargo-stylus + +The `cargo-stylus` CLI tool helps you create, build, and deploy Stylus contracts. + +**Install:** + +```shell +cargo install cargo-stylus +``` + +**Verify:** + +```shell +cargo stylus --version +``` + +**Update:** + +```shell +cargo install cargo-stylus --force +``` +EOF +``` + +**Docker setup partial:** + +```bash +cat > docs/stylus/partials/_setup-docker-nitro.mdx << 'EOF' +### Installing Docker for local testing + +A local Arbitrum Nitro devnode allows you to test contracts before deploying to testnet. + +**macOS:** + +Download [Docker Desktop for Mac](https://docs.docker.com/desktop/install/mac-install/). + +**Linux:** + +```shell +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +``` + +**Windows:** + +Download [Docker Desktop for Windows](https://docs.docker.com/desktop/install/windows-install/) (requires WSL2). + +**Start Nitro devnode:** + +```shell +docker run -p 8547:8547 offchainlabs/nitro-node:latest --dev +``` + +**Verify:** + +```shell +curl -X POST http://localhost:8547 \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' +``` +EOF +``` + +#### Step 3: Streamline quickstart.mdx + +Update `docs/stylus/quickstart.mdx` to reference prerequisites instead of duplicating: + +```mdx +--- +title: 'Quickstart: Build your first Stylus contract' +--- + +# Quickstart: Build your first Stylus contract + +In this quickstart, you'll create, deploy, and interact with a simple counter contract written in Rust. + +**Time to complete:** ~15 minutes + +## Prerequisites + +Before starting, ensure you have: +- Rust toolchain installed +- cargo-stylus CLI installed +- Access to an Arbitrum testnet + +Don't have these set up? See [Prerequisites and setup](/stylus/fundamentals/prerequisites). + +## Step 1: Create a new project + +[Continue with hands-on steps, no setup duplication] +``` + +### Task 3.4: Add Quickstart Journey Diagram + +Add Diagram #13 to quickstart.mdx after the introduction: + +```mdx +## Your journey + +This quickstart follows a simple path: + +```mermaid +journey + title Quickstart Journey + section Setup + Create project: 5: Developer + Check validity: 3: Developer + section Deploy + Deploy contract: 4: Developer + Export ABI: 3: Developer + section Interact + Call contract: 5: Developer + Send transaction: 4: Developer + Verify results: 5: Developer +``` + +*Figure: Your path through this quickstart guide, from project creation to successful contract interaction.* + +Let's get started! + +## Step 1: Create a new project +``` + +### Task 3.5: Validate Phase 3 + +```bash +# Run build +yarn build + +# Check for broken links +yarn build 2>&1 | grep -i "broken" + +# Verify new structure +ls docs/stylus/reference/rust-sdk/ +ls docs/stylus/fundamentals/prerequisites.mdx +ls docs/stylus/partials/_setup-*.mdx + +# Test imports +grep -r "setup-rust-toolchain" docs/stylus/ + +# Start dev server and test +yarn start --no-open +# Check: +# - VM differences page exists +# - Rust SDK has 8 sub-pages +# - Prerequisites page renders with partials +# - Quickstart journey diagram renders +``` + +### Task 3.6: Commit Phase 3 + +```bash +git add -A +git commit -m "docs(stylus): Phase 3 - Content Consolidation + +- Merge evm-differences + solidity-differences โ†’ vm-differences +- Rename solidity-differences โ†’ rust-to-solidity-differences +- Split rust-sdk-guide.md into 8 focused files +- Create fundamentals/prerequisites.mdx with setup partials +- Extract setup instructions into 3 reusable partials +- Streamline quickstart.mdx to reference prerequisites +- Add quickstart journey diagram (#13) + +Files modified: 4 +New files: 12 (8 SDK + prerequisites + 3 partials) +Deleted files: 2 +Diagrams added: 1" + +git tag phase-3-complete +``` + +## Phase 3 Success Criteria + +- [ ] โœ… Build passes +- [ ] โœ… No duplicate setup instructions +- [ ] โœ… Rust SDK has 8 sub-pages +- [ ] โœ… VM differences merged successfully +- [ ] โœ… Quickstart journey diagram renders +- [ ] โœ… All partials import correctly +- [ ] โœ… Changes committed and tagged + +## Rollback Phase 3 + +```bash +git reset --hard phase-2-complete +# or +git revert phase-3-complete +``` + +## Next Phase + +Continue to Phase 4 in `IMPLEMENTATION_GUIDE_PHASE4.md` to create new content including best practices, troubleshooting, and core concept diagrams. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md new file mode 100644 index 0000000000..70edd209b4 --- /dev/null +++ b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md @@ -0,0 +1,1095 @@ +# Phase 4: Create New Content - Implementation Guide + +**Duration:** ~16 hours +**Files Modified:** 7 (rename troubleshooting + 6 diagrams) +**New Files:** 15 (3 fundamentals + 3 guides + 3 best-practices + 3 troubleshooting + 1 advanced + 2 interop) +**Diagrams Added:** 6 + +## Overview + +Phase 4 fills critical documentation gaps identified in the analysis: +1. Developer onboarding content (choose-your-path, dev environment) +2. Interoperability guides (Rust โ†” Solidity) +3. Best practices (security, performance, gas optimization) +4. Troubleshooting (common errors, debugging) +5. Core concept diagrams for complex topics + +## Pre-Phase 4 Checklist + +- [ ] Phases 1-3 completed successfully +- [ ] Current build passes +- [ ] Tag `phase-3-complete` exists +- [ ] All previous diagrams render correctly + +## Phase 4 Tasks + +### Task 4.1: Create Fundamentals Content + +#### fundamentals/choose-your-path.mdx + +```bash +cat > docs/stylus/fundamentals/choose-your-path.mdx << 'EOF' +--- +title: 'Choose your learning path' +description: 'Find the best Stylus learning path based on your background' +user_story: 'As a developer, I want to know the best way to learn Stylus based on my experience' +content_type: concept +sidebar_position: 0 +--- + +# Choose your learning path + +Your background determines the best way to learn Stylus. Choose your path below. + +## I'm a Rust developer + +**You're in great shape!** Stylus contracts are written in Rust, so you already know the language. + +### What you need to learn + +- How Ethereum smart contracts work +- How storage works in blockchain +- How to interact with other contracts +- Gas optimization for onchain code + +### Recommended path + +1. [Understand WebAssembly and Stylus](/stylus/concepts/webassembly) +2. [Build your first contract](/stylus/quickstart) +3. [Learn about storage](/stylus/fundamentals/data-types/storage) +4. [Call Solidity from Rust](/stylus/guides/call-solidity-from-rust) +5. [Optimize for gas](/stylus/best-practices/gas-optimization) + +### Key insights + +- **Familiar syntax**: Write normal Rust code with minimal blockchain-specific syntax +- **Memory safety**: Rust's borrow checker prevents common smart contract vulnerabilities +- **Performance**: WASM execution is significantly faster than EVM +- **Tooling**: Use cargo, rust-analyzer, and your favorite Rust tools + +--- + +## I'm a Solidity developer + +**Welcome!** You understand blockchain and smart contracts. Now learn Rust and leverage WASM performance. + +### What you need to learn + +- Rust language basics (ownership, borrowing, traits) +- Different memory and storage models +- Compilation to WASM instead of EVM opcodes +- Rust SDK equivalents for Solidity patterns + +### Recommended path + +1. [Compare VM differences](/stylus/concepts/vm-differences) +2. [Study Rust-to-Solidity differences](/stylus/advanced/rust-to-solidity-differences) +3. [Learn Rust basics](https://doc.rust-lang.org/book/) +4. [Build your first contract](/stylus/quickstart) +5. [Call Rust from Solidity](/stylus/guides/call-rust-from-solidity) + +### Key insights + +- **Familiar concepts**: Storage, events, modifiers, inheritance all have Rust equivalents +- **Better performance**: 10-100x gas savings for compute-heavy operations +- **Type safety**: Rust's type system catches errors at compile time +- **Interoperability**: Stylus and Solidity contracts call each other seamlessly + +### Comparison table + +| Concept | Solidity | Stylus (Rust) | +|---------|----------|---------------| +| State variable | `uint256 public count;` | `count: StorageU256` | +| Function | `function get() public view` | `pub fn get(&self) -> U256` | +| Event | `event Transfer(...)` | `#[event] struct Transfer` | +| Error | `error Unauthorized()` | `#[error] struct Unauthorized` | +| Modifier | `modifier onlyOwner` | Rust function or trait | +| Inheritance | `contract A is B` | Trait implementation | + +--- + +## I'm new to blockchain development + +**Exciting!** You're starting fresh with best-in-class tools. + +### What you need to learn + +- Blockchain fundamentals (accounts, transactions, state) +- Smart contract concepts (storage, events, gas) +- Rust programming language +- Arbitrum and Ethereum basics + +### Recommended path + +1. [Learn Ethereum basics](https://ethereum.org/en/developers/docs/) +2. [Learn Rust](https://doc.rust-lang.org/book/) +3. [Understand Stylus introduction](/stylus/gentle-introduction) +4. [Build your first contract](/stylus/quickstart) +5. [Explore examples](https://github.com/OffchainLabs/stylus-by-example) + +### Resources + +- [Ethereum docs](https://ethereum.org/en/developers/) +- [The Rust Book](https://doc.rust-lang.org/book/) +- [Arbitrum docs](/arbitrum-ethereum-differences) +- [Stylus by Example](https://github.com/OffchainLabs/stylus-by-example) + +--- + +## Quick reference + +No matter your path, bookmark these resources: + +- **API Reference**: [Rust SDK](/stylus/reference/rust-sdk/) +- **CLI Reference**: [cargo-stylus commands](/stylus/cli-tools/commands-reference) +- **Examples**: [Stylus by Example](https://github.com/OffchainLabs/stylus-by-example) +- **Help**: [Troubleshooting](/stylus/troubleshooting/faq) +EOF +``` + +#### fundamentals/development-environment.mdx + +```bash +cat > docs/stylus/fundamentals/development-environment.mdx << 'EOF' +--- +title: 'Development environment setup' +description: 'Configure your IDE and tools for Stylus development' +user_story: 'As a developer, I want to set up an efficient development environment' +content_type: how-to +sidebar_position: 2 +--- + +# Development environment setup + +This guide helps you configure a productive development environment for Stylus. + +## VS Code setup + +Visual Studio Code is the recommended IDE for Stylus development. + +### Install VS Code + +Download from [code.visualstudio.com](https://code.visualstudio.com/) + +### Required extensions + +Install these extensions: + +```shell +# rust-analyzer (Rust language support) +code --install-extension rust-lang.rust-analyzer + +# Even Better TOML (Cargo.toml support) +code --install-extension tamasfe.even-better-toml + +# CodeLLDB (Rust debugger) +code --install-extension vadimcn.vscode-lldb +``` + +### Recommended extensions + +```shell +# Error Lens (inline error messages) +code --install-extension usernamehw.errorlens + +# Crates (Cargo.toml dependency management) +code --install-extension serayuzgur.crates + +# GitLens (Git integration) +code --install-extension eamodio.gitlens +``` + +### VS Code settings + +Add to `.vscode/settings.json` in your project: + +```json +{ + "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.cargo.features": "all", + "editor.formatOnSave": true, + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer" + } +} +``` + +## IntelliJ IDEA / CLion setup + +JetBrains IDEs offer excellent Rust support. + +### Install Rust plugin + +1. Open Settings โ†’ Plugins +2. Search for "Rust" +3. Install and restart + +### Configure Rust toolchain + +1. Settings โ†’ Languages & Frameworks โ†’ Rust +2. Select Toolchain location +3. Enable external linter: Clippy + +## Command-line tools + +### cargo-watch + +Auto-rebuild on file changes: + +```shell +cargo install cargo-watch + +# Use it +cargo watch -x check -x test +``` + +### cargo-expand + +View macro expansions: + +```shell +cargo install cargo-expand + +# Use it +cargo expand +``` + +### cargo-audit + +Check for security vulnerabilities: + +```shell +cargo install cargo-audit + +# Use it +cargo audit +``` + +## Debugger setup + +### VS Code debugging + +Create `.vscode/launch.json`: + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib" + ] + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} +``` + +Set breakpoints and press F5 to debug. + +## Testing environment + +### Set up test RPC + +Use a local Nitro node for testing: + +```shell +# Start in one terminal +docker run -p 8547:8547 offchainlabs/nitro-node:latest --dev + +# Add to .env +LOCAL_RPC_URL=http://localhost:8547 +``` + +### Configure test accounts + +```shell +# Generate test private key (DO NOT use in production!) +openssl rand -hex 32 + +# Add to .env +PRIVATE_KEY=your_generated_key_here +``` + +## Environment variables + +Create `.env` in your project root: + +```shell +# Network configuration +LOCAL_RPC_URL=http://localhost:8547 +TESTNET_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc +MAINNET_RPC_URL=https://arb1.arbitrum.io/rpc + +# Deployment +PRIVATE_KEY=your_private_key_here + +# Verification +ARBISCAN_API_KEY=your_api_key_here +``` + +**โš ๏ธ Security:** Never commit `.env` to version control! + +Add to `.gitignore`: + +``` +.env +.env.* +!.env.example +``` + +## Productivity tips + +### Use cargo aliases + +Add to `~/.cargo/config.toml`: + +```toml +[alias] +st = "stylus" +sc = "stylus check" +sd = "stylus deploy" +``` + +Usage: + +```shell +cargo st check +cargo sc # shorthand +``` + +### Shell completions + +```shell +# Bash +cargo stylus completions bash > ~/.bash_completions/cargo-stylus + +# Zsh +cargo stylus completions zsh > ~/.zsh/completions/_cargo-stylus +``` + +## Troubleshooting + +### rust-analyzer is slow + +Increase memory limit in VS Code settings: + +```json +{ + "rust-analyzer.server.extraEnv": { + "RA_LOG": "info" + } +} +``` + +### Clippy too strict + +Configure in `Cargo.toml`: + +```toml +[lints.clippy] +too_many_arguments = "allow" +``` + +## Next steps + +- [Create your first project](/stylus/quickstart) +- [Learn about testing](/stylus/fundamentals/testing-contracts) +- [Explore CLI tools](/stylus/cli-tools/overview) +EOF +``` + +### Task 4.2: Create Guides Content + +#### guides/call-solidity-from-rust.mdx + +```bash +cat > docs/stylus/guides/call-solidity-from-rust.mdx << 'EOF' +--- +title: 'Call Solidity contracts from Rust' +description: 'Learn how to call Solidity contracts from your Stylus contracts' +user_story: 'As a Stylus developer, I want to call existing Solidity contracts' +content_type: how-to +--- + +# Call Solidity contracts from Rust + +Stylus contracts can seamlessly call Solidity contracts using the `sol_interface!` macro. + +## Overview + +The `sol_interface!` macro generates Rust bindings from Solidity interface definitions, enabling type-safe contract calls. + +## Basic example + +### Step 1: Define the Solidity interface + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::{Address, U256}; + +sol_interface! { + interface IERC20 { + function balanceOf(address account) external view returns (uint256); + function transfer(address to, uint256 amount) external returns (bool); + function approve(address spender, uint256 amount) external returns (bool); + } +} +``` + +### Step 2: Call the contract + +```rust +#[external] +impl MyContract { + pub fn check_balance(&self, token: Address, account: Address) -> Result> { + let erc20 = IERC20::new(token); + let balance = erc20.balance_of(self, account)?; + Ok(balance) + } + + pub fn transfer_tokens( + &mut self, + token: Address, + to: Address, + amount: U256 + ) -> Result> { + let erc20 = IERC20::new(token); + let success = erc20.transfer(self, to, amount)?; + Ok(success) + } +} +``` + +## View vs mutating calls + +### View calls (read-only) + +Use `Call::new()` for functions that don't modify state: + +```rust +let balance = erc20.balance_of(self, account)?; +``` + +### Mutating calls + +Use `Call::new_mutating()` for state-changing functions: + +```rust +let success = erc20.transfer(self, to, amount)?; +``` + +### Payable calls + +Use `Call::new_payable()` for functions requiring ETH: + +```rust +let call = Call::new_payable(value); +contract.deposit(call)?; +``` + +## Advanced patterns + +### Custom gas limits + +```rust +let balance = erc20.balance_of(self, account) + .gas(100_000)?; // Custom gas limit +``` + +### Handling return values + +```rust +match erc20.transfer(self, to, amount) { + Ok(success) => { + if success { + // Transfer succeeded + } else { + // Transfer failed + } + } + Err(e) => { + // Call reverted + } +} +``` + +### Multiple calls in one function + +```rust +pub fn complex_operation(&mut self, token: Address) -> Result<(), Vec> { + let erc20 = IERC20::new(token); + + // Read balance + let balance = erc20.balance_of(self, msg::sender())?; + + // Approve + erc20.approve(self, some_spender, balance)?; + + // Transfer + erc20.transfer(self, some_recipient, balance / 2)?; + + Ok(()) +} +``` + +## Complete example + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::{Address, U256}; + +sol_interface! { + interface IUniswapV2Router { + function swapExactTokensForTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external returns (uint[] memory amounts); + } +} + +#[storage] +pub struct TokenSwapper { + router: StorageAddress, +} + +#[external] +impl TokenSwapper { + pub fn swap( + &mut self, + token_in: Address, + token_out: Address, + amount_in: U256, + amount_out_min: U256 + ) -> Result, Vec> { + let router_addr = self.router.get(); + let router = IUniswapV2Router::new(router_addr); + + let path = vec![token_in, token_out]; + let deadline = block::timestamp() + 300; // 5 minutes + + let amounts = router.swap_exact_tokens_for_tokens( + self, + amount_in, + amount_out_min, + path, + msg::sender(), + deadline + )?; + + Ok(amounts) + } +} +``` + +## See also + +- [Call Rust from Solidity](./call-rust-from-solidity) +- [Importing interfaces](./importing-interfaces) +- [SDK call reference](/stylus/reference/rust-sdk/calls) +EOF +``` + +#### guides/call-rust-from-solidity.mdx + +```bash +cat > docs/stylus/guides/call-rust-from-solidity.mdx << 'EOF' +--- +title: 'Call Rust contracts from Solidity' +description: 'Learn how to call Stylus contracts from Solidity' +user_story: 'As a Solidity developer, I want to call Stylus contracts' +content_type: how-to +--- + +# Call Rust contracts from Solidity + +Solidity contracts can call Stylus contracts just like any other contract. + +## Overview + +Once deployed, Stylus contracts expose a standard Ethereum ABI that Solidity can interact with. + +## Step 1: Export ABI from Rust + +Use `cargo stylus` to export your contract's ABI: + +```shell +cargo stylus export-abi +``` + +This generates a Solidity interface: + +```solidity +interface ICounter { + function number() external view returns (uint256); + function increment() external; + function setNumber(uint256 newNumber) external; +} +``` + +## Step 2: Create Solidity interface + +Save the interface to a file: + +```solidity +// ICounter.sol +pragma solidity ^0.8.0; + +interface ICounter { + function number() external view returns (uint256); + function increment() external; + function setNumber(uint256 newNumber) external; +} +``` + +## Step 3: Call from Solidity + +```solidity +// CounterCaller.sol +pragma solidity ^0.8.0; + +import "./ICounter.sol"; + +contract CounterCaller { + ICounter public counter; + + constructor(address _counter) { + counter = ICounter(_counter); + } + + function getCount() public view returns (uint256) { + return counter.number(); + } + + function incrementCounter() public { + counter.increment(); + } + + function setCount(uint256 newNumber) public { + counter.setNumber(newNumber); + } +} +``` + +## Advanced patterns + +### Handling return values + +```solidity +function safeIncrement() public returns (bool) { + try counter.increment() { + return true; + } catch { + return false; + } +} +``` + +### Passing complex types + +**Rust side:** + +```rust +#[external] +impl MyContract { + pub fn process_data(&self, data: Vec) -> Result> { + Ok(data.iter().sum()) + } +} +``` + +**Solidity side:** + +```solidity +function callProcess(uint256[] memory data) public returns (uint256) { + return myContract.processData(data); +} +``` + +### Events from Stylus contracts + +Stylus contracts emit standard Ethereum events: + +**Rust:** + +```rust +#[derive(SolidityEvent)] +pub struct Transfer { + from: Address, + to: Address, + amount: U256, +} +``` + +**Solidity:** + +```solidity +interface IToken { + event Transfer(address indexed from, address indexed to, uint256 amount); +} + +// Listen for events +IToken token = IToken(stylusTokenAddress); +// Events work automatically +``` + +## Complete example + +**Stylus Contract (Rust):** + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::U256; + +#[storage] +pub struct Calculator { + result: StorageU256, +} + +#[external] +impl Calculator { + pub fn add(&mut self, a: U256, b: U256) -> U256 { + let sum = a + b; + self.result.set(sum); + sum + } + + pub fn get_result(&self) -> U256 { + self.result.get() + } +} +``` + +**Solidity Caller:** + +```solidity +pragma solidity ^0.8.0; + +interface ICalculator { + function add(uint256 a, uint256 b) external returns (uint256); + function getResult() external view returns (uint256); +} + +contract MathContract { + ICalculator public calc; + + constructor(address _calc) { + calc = ICalculator(_calc); + } + + function compute(uint256 x, uint256 y) public returns (uint256) { + uint256 result = calc.add(x, y); + require(result == calc.getResult(), "Mismatch"); + return result; + } +} +``` + +## Deployment workflow + +1. Deploy Stylus contract +2. Export ABI: `cargo stylus export-abi` +3. Create Solidity interface +4. Deploy Solidity contract with Stylus address +5. Call Stylus from Solidity + +## See also + +- [Call Solidity from Rust](./call-solidity-from-rust) +- [Exporting ABI](./exporting-abi) +- [Importing interfaces](./importing-interfaces) +EOF +``` + +#### guides/create-project.mdx + +```bash +cat > docs/stylus/guides/create-project.mdx << 'EOF' +--- +title: 'Create a Stylus project' +description: 'Initialize a new Stylus project with cargo-stylus' +user_story: 'As a developer, I want to create a new Stylus project' +content_type: how-to +--- + +# Create a Stylus project + +Learn how to create and configure a new Stylus project. + +## Using cargo-stylus new + +The fastest way to create a project: + +```shell +cargo stylus new my-project +cd my-project +``` + +This creates a complete project with: +- `src/lib.rs` - Contract code +- `Cargo.toml` - Dependencies +- `.gitignore` - Git configuration + +## Manual project setup + +Alternatively, create a project manually: + +```shell +cargo new --lib my-project +cd my-project +``` + +Update `Cargo.toml`: + +```toml +[package] +name = "my-project" +version = "0.1.0" +edition = "2021" + +[dependencies] +stylus-sdk = "0.5" +alloy-primitives = "0.7" +alloy-sol-types = "0.7" + +[dev-dependencies] +tokio = { version = "1.12", features = ["macros", "full"] } + +[features] +export-abi = ["stylus-sdk/export-abi"] + +[lib] +crate-type = ["lib", "cdylib"] +``` + +## Project structure + +``` +my-project/ +โ”œโ”€โ”€ Cargo.toml # Project configuration +โ”œโ”€โ”€ Cargo.lock # Locked dependencies +โ”œโ”€โ”€ src/ +โ”‚ โ””โ”€โ”€ lib.rs # Your contract code +โ””โ”€โ”€ .gitignore +``` + +## Next steps + +- [Understand project structure](/stylus/fundamentals/project-structure) +- [Build your first contract](/stylus/quickstart) +- [Learn about testing](/stylus/fundamentals/testing-contracts) +EOF +``` + +### Task 4.3: Create Best Practices Content + +Due to length, I'll provide templates. You'll need to expand these based on research and examples: + +#### best-practices/security.mdx + +```mdx +--- +title: 'Security best practices' +description: 'Security patterns and audit checklist for Stylus contracts' +user_story: 'As a developer, I want to write secure Stylus contracts' +content_type: reference +--- + +# Security best practices + +[TO BE EXPANDED - ~300 lines covering:] +- Common vulnerabilities in Stylus +- Reentrancy protection patterns +- Input validation +- Safe arithmetic +- Access control patterns +- Audit checklist +``` + +#### best-practices/performance.mdx + +```mdx +--- +title: 'Performance optimization' +description: 'WASM-specific optimizations and profiling techniques' +user_story: 'As a developer, I want to optimize my Stylus contracts' +content_type: reference +--- + +# Performance optimization + +[TO BE EXPANDED - ~250 lines covering:] +- WASM-specific optimizations +- Storage access patterns +- Memory management strategies +- Profiling and benchmarking +``` + +#### best-practices/gas-optimization.mdx + +```mdx +--- +title: 'Gas optimization' +description: 'Gas-efficient coding techniques for Stylus' +user_story: 'As a developer, I want to minimize gas costs' +content_type: reference +--- + +# Gas optimization + +[TO BE EXPANDED - ~200 lines covering:] +- Gas cost comparison (Stylus vs Solidity) +- Optimization techniques for WASM +- Storage vs memory tradeoffs +- Real-world examples with metrics +``` + +### Task 4.4: Create Troubleshooting Content + +#### troubleshooting/faq.mdx + +```bash +# Rename existing troubleshooting file +mv docs/stylus/troubleshooting-building-stylus.md docs/stylus/troubleshooting/faq.mdx + +# Update frontmatter +# Add: content_type: faq +``` + +#### troubleshooting/common-errors.mdx + +```mdx +--- +title: 'Common errors' +description: 'Solutions to frequently encountered errors' +user_story: 'As a developer, I want to quickly resolve common errors' +content_type: troubleshooting +--- + +# Common errors + +[TO BE EXPANDED - Problem-solution format for:] +- Compilation errors +- Deployment errors +- Runtime errors +``` + +#### troubleshooting/debugging-guide.mdx + +```mdx +--- +title: 'Debugging guide' +description: 'Systematic debugging strategies for Stylus' +user_story: 'As a developer, I want to debug my contracts effectively' +content_type: how-to +--- + +# Debugging guide + +[TO BE EXPANDED covering:] +- Systematic debugging approach +- Using replay for transaction debugging +- Local testing strategies +- Logging best practices +``` + +### Task 4.5: Create Advanced Content + +#### advanced/memory-management.mdx + +```mdx +--- +title: 'Memory management' +description: 'WASM memory model and performance optimization' +user_story: 'As a developer, I want to understand WASM memory management' +content_type: concept +--- + +# Memory management + +[TO BE EXPANDED covering:] +- WASM memory model +- Performance optimization +- Memory profiling +- Best practices +``` + +### Task 4.6: Add Core Concept Diagrams + +Add these 6 diagrams to existing files: + +**Diagram #1: Contract Lifecycle** (gentle-introduction.mdx) +**Diagram #2: Deployment & Activation** (concepts/activation.mdx) +**Diagram #4: EVM vs WASM Architecture** (concepts/vm-differences.mdx) +**Diagram #5: Contract Call Flow** (guides/importing-interfaces.mdx) +**Diagram #6: Ink to Gas Conversion** (concepts/gas-metering.mdx) +**Diagram #9: Deployment Workflows** (cli-tools/check-and-deploy.mdx) + +[See main implementation guide for diagram code] + +### Task 4.7: Update Sidebars + +Add new sections to sidebars.js: + +```javascript +{ + type: 'category', + label: 'Best practices', + items: [ + 'stylus/best-practices/security', + 'stylus/best-practices/performance', + 'stylus/best-practices/gas-optimization', + ], +}, +{ + type: 'category', + label: 'Troubleshooting', + items: [ + 'stylus/troubleshooting/faq', + 'stylus/troubleshooting/common-errors', + 'stylus/troubleshooting/debugging-guide', + ], +}, +``` + +### Task 4.8: Commit Phase 4 + +```bash +git add -A +git commit -m "docs(stylus): Phase 4 - Create New Content + +- Add choose-your-path and development-environment to fundamentals +- Create interoperability guides (Rust โ†” Solidity) +- Add best-practices section (security, performance, gas) +- Create troubleshooting section (faq, errors, debugging) +- Add advanced memory-management guide +- Add 6 core concept diagrams (#1, #2, #4, #5, #6, #9) + +New files: 15 +Diagrams added: 6" + +git tag phase-4-complete +``` + +## Phase 4 Success Criteria + +- [ ] โœ… All new content files created +- [ ] โœ… 6 diagrams render correctly +- [ ] โœ… Build passes +- [ ] โœ… Sidebar navigation updated +- [ ] โœ… Changes committed and tagged + +## Next Phase + +Continue to Phase 5 for expansion, polish, and comprehensive validation. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md new file mode 100644 index 0000000000..43ab9a74fb --- /dev/null +++ b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md @@ -0,0 +1,872 @@ +# Phase 5: Expansion & Validation - Implementation Guide + +**Duration:** ~12 hours +**Files Modified:** ~18 (stub expansions + reviews + 3 diagrams) +**New Files:** 1 (redirect config) +**Diagrams Added:** 3 + +## Overview + +Phase 5 completes the restructure with: +1. Expanding stub files with comprehensive content +2. Creating redirect configuration for broken links +3. Adding final polish diagrams +4. Running comprehensive validation (terminology, accessibility, links) +5. Final build and deployment testing + +## Pre-Phase 5 Checklist + +- [ ] Phases 1-4 completed successfully +- [ ] Current build passes +- [ ] Tag `phase-4-complete` exists +- [ ] All 10 diagrams from previous phases render + +## Phase 5 Tasks + +### Task 5.1: Expand Stub Files + +These files currently have minimal content and need expansion: + +#### fundamentals/contracts.mdx + +Currently ~35 words. Expand to ~200 words: + +```mdx +--- +title: 'Contracts' +description: 'Understanding Stylus contract structure and entry points' +user_story: 'As a developer, I want to understand Stylus contract structure' +content_type: concept +--- + +# Contracts + +A Stylus contract is a Rust library compiled to WebAssembly (WASM) and deployed to the Arbitrum blockchain. + +## Contract structure + +Basic contract template: + +```rust +#![cfg_attr(not(feature = "export-abi"), no_main)] +extern crate alloc; + +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::U256; + +#[storage] +pub struct Counter { + count: StorageU256, +} + +#[external] +impl Counter { + pub fn increment(&mut self) { + let current = self.count.get(); + self.count.set(current + U256::from(1)); + } + + pub fn number(&self) -> U256 { + self.count.get() + } +} +``` + +## Entry points + +### User entry point + +Stylus generates a `user_entrypoint` function that: +1. Receives calldata from the transaction +2. Routes to the appropriate method +3. Encodes return values +4. Handles errors + +This happens automatically via the `#[external]` macro. + +### Storage layout + +The `#[storage]` macro defines persistent state: + +```rust +#[storage] +pub struct MyContract { + owner: StorageAddress, + balance: StorageU256, + data: StorageMap, +} +``` + +## State management + +Contracts maintain state between transactions: + +```rust +pub fn update_data(&mut self, key: Address, value: U256) { + self.data.insert(key, value); // Persists to storage +} +``` + +## Method visibility + +Control access with Rust visibility: + +```rust +#[external] +impl MyContract { + pub fn public_method(&self) {} // Callable externally + + fn private_method(&self) {} // Internal only +} + +impl MyContract { + pub fn internal_helper(&self) {} // Not external, even though pub +} +``` + +## Next steps + +- [Learn about storage types](/stylus/fundamentals/data-types/storage) +- [Understand global variables](/stylus/fundamentals/global-variables-and-functions) +- [Build your first contract](/stylus/quickstart) +``` + +#### fundamentals/global-variables-and-functions.mdx + +Currently ~19 words. Expand to ~300 words: + +```mdx +--- +title: 'Global variables and functions' +description: 'Access blockchain context in Stylus contracts' +user_story: 'As a developer, I want to access transaction and block information' +content_type: reference +--- + +# Global variables and functions + +Stylus provides access to transaction and block context through global functions. + +## Message context + +### msg::sender() + +Returns the address that called the current function: + +```rust +use stylus_sdk::msg; +use stylus_sdk::alloy_primitives::Address; + +pub fn only_owner(&self) -> Result<(), Vec> { + let caller = msg::sender(); + if caller != self.owner.get() { + return Err(b"Unauthorized".to_vec()); + } + Ok(()) +} +``` + +### msg::value() + +Returns the amount of ETH sent with the transaction: + +```rust +use stylus_sdk::msg; +use stylus_sdk::alloy_primitives::U256; + +pub fn deposit(&mut self) -> U256 { + let amount = msg::value(); + let current = self.balance.get(); + self.balance.set(current + amount); + amount +} +``` + +## Block context + +### block::timestamp() + +Returns the current block timestamp (seconds since Unix epoch): + +```rust +use stylus_sdk::block; + +pub fn is_expired(&self, deadline: u64) -> bool { + block::timestamp() > deadline +} +``` + +### block::number() + +Returns the current block number: + +```rust +pub fn get_block(&self) -> u64 { + block::number() +} +``` + +## Contract context + +### contract::address() + +Returns the address of the current contract: + +```rust +use stylus_sdk::contract; + +pub fn my_address(&self) -> Address { + contract::address() +} +``` + +### contract::balance() + +Returns the ETH balance of the current contract: + +```rust +pub fn get_balance(&self) -> U256 { + contract::balance() +} +``` + +## Transaction context + +### tx::gas_price() + +Returns the gas price of the current transaction: + +```rust +use stylus_sdk::tx; + +pub fn current_gas_price(&self) -> U256 { + tx::gas_price() +} +``` + +### tx::origin() + +Returns the original sender of the transaction (may differ from msg::sender() in delegate calls): + +```rust +pub fn original_caller(&self) -> Address { + tx::origin() +} +``` + +## Complete example + +```rust +use stylus_sdk::prelude::*; +use stylus_sdk::alloy_primitives::{Address, U256}; +use stylus_sdk::{block, contract, msg, tx}; + +#[storage] +pub struct ContextExample { + owner: StorageAddress, + deposits: StorageMap, +} + +#[external] +impl ContextExample { + pub fn deposit(&mut self) -> Result<(), Vec> { + let caller = msg::sender(); + let amount = msg::value(); + let timestamp = block::timestamp(); + + // Only accept deposits after certain time + if timestamp < 1700000000 { + return Err(b"Too early".to_vec()); + } + + // Update balance + let current = self.deposits.get(caller); + self.deposits.insert(caller, current + amount); + + Ok(()) + } + + pub fn get_context_info(&self) -> (Address, Address, u64, U256) { + ( + msg::sender(), + contract::address(), + block::number(), + tx::gas_price() + ) + } +} +``` + +## Comparison with Solidity + +| Solidity | Stylus (Rust) | +|----------|---------------| +| `msg.sender` | `msg::sender()` | +| `msg.value` | `msg::value()` | +| `block.timestamp` | `block::timestamp()` | +| `block.number` | `block::number()` | +| `address(this)` | `contract::address()` | +| `address(this).balance` | `contract::balance()` | +| `tx.gasprice` | `tx::gas_price()` | +| `tx.origin` | `tx::origin()` | + +## See also + +- [Contracts](/stylus/fundamentals/contracts) +- [Storage types](/stylus/fundamentals/data-types/storage) +- [Rust SDK reference](/stylus/reference/rust-sdk/) +``` + +#### Expand data types files + +Similar expansions needed for: +- `fundamentals/data-types/primitives.mdx` (1 word โ†’ ~200 words) +- `fundamentals/data-types/compound-types.mdx` (11 words โ†’ ~250 words) +- `fundamentals/data-types/storage.mdx` (20 words โ†’ ~200 words) +- `fundamentals/data-types/conversions-between-types.mdx` (1 word โ†’ ~200 words) + +[Templates provided - expand with examples and details] + +### Task 5.2: Create Redirect Configuration + +Create comprehensive redirects for all moved files: + +```javascript +// In docusaurus.config.js, add to module.exports: + +module.exports = { + // ... existing config + + presets: [ + [ + 'classic', + { + docs: { + // ... existing docs config + + async sidebarPath() { + return require.resolve('./sidebars.js'); + }, + + // Add redirects + beforeDefaultRemarkPlugins: [], + beforeDefaultRehypePlugins: [], + }, + }, + ], + ], + + plugins: [ + [ + '@docusaurus/plugin-client-redirects', + { + redirects: [ + // CLI tools redirects (high priority) + { + from: '/stylus/using-cli', + to: '/stylus/cli-tools/overview', + }, + { + from: '/stylus/how-tos/verifying-contracts', + to: '/stylus/cli-tools/verify-contracts', + }, + { + from: '/stylus/how-tos/verifying-contracts-arbiscan', + to: '/stylus/cli-tools/verify-contracts', + }, + { + from: '/stylus/how-tos/check-and-deploy', + to: '/stylus/cli-tools/check-and-deploy', + }, + { + from: '/stylus/how-tos/debugging-tx', + to: '/stylus/cli-tools/debugging-tx', + }, + + // Fundamentals redirects (high priority) + { + from: '/stylus/how-tos/testing-contracts', + to: '/stylus/fundamentals/testing-contracts', + }, + { + from: '/stylus/reference/project-structure', + to: '/stylus/fundamentals/project-structure', + }, + { + from: '/stylus/reference/contracts', + to: '/stylus/fundamentals/contracts', + }, + { + from: '/stylus/reference/global-variables-and-functions', + to: '/stylus/fundamentals/global-variables-and-functions', + }, + { + from: '/stylus/reference/data-types/primitives', + to: '/stylus/fundamentals/data-types/primitives', + }, + { + from: '/stylus/reference/data-types/compound-types', + to: '/stylus/fundamentals/data-types/compound-types', + }, + { + from: '/stylus/reference/data-types/storage', + to: '/stylus/fundamentals/data-types/storage', + }, + { + from: '/stylus/reference/data-types/conversions-between-types', + to: '/stylus/fundamentals/data-types/conversions-between-types', + }, + + // Reference redirects + { + from: '/stylus/reference/rust-sdk-guide', + to: '/stylus/reference/rust-sdk/index', + }, + + // Concepts redirects + { + from: '/stylus/concepts/evm-differences', + to: '/stylus/concepts/vm-differences', + }, + { + from: '/stylus/concepts/activation', + to: '/stylus/concepts/activation', // No change, but ensure old links work + }, + + // Advanced redirects + { + from: '/stylus/advanced/solidity-differences', + to: '/stylus/advanced/rust-to-solidity-differences', + }, + + // Troubleshooting redirects + { + from: '/stylus/troubleshooting-building-stylus', + to: '/stylus/troubleshooting/faq', + }, + + // How-tos โ†’ Guides (catch-all for remaining files) + { + from: '/stylus/how-tos/:slug', + to: '/stylus/guides/:slug', + }, + ], + }, + ], + ], + + // ... rest of config +}; +``` + +### Task 5.3: Add Polish Diagrams + +Add the final 3 diagrams: + +**Diagram #7: Storage Layout** (fundamentals/data-types/storage.mdx) + +```mermaid +flowchart TB + subgraph "Storage Slots (32 bytes each)" + Slot0["Slot 0
    Variable A (uint256)"] + Slot1["Slot 1
    Variable B (address) + C (uint96)"] + Slot2["Slot 2
    Mapping length"] + Slot3["Slot 3
    keccak256(key, 2)"] + end + + Mapping[Mapping key] -->|hash| Slot3 + + style Slot1 fill:#FFF3E0 + style Slot3 fill:#E3F2FD +``` + +**Diagram #10: Memory Model** (concepts/webassembly.mdx) + +```mermaid +graph TB + subgraph "WASM Linear Memory" + Stack["Stack
    32 KB
    (fixed)"] + Heap["Heap/Data
    (grows upward)"] + Page1["Page 1
    64 KB"] + Page2["Page 2
    64 KB"] + PageN["Page N
    64 KB"] + end + + Stack -.-> Page1 + Heap --> Page1 + Heap --> Page2 + Heap -.-> PageN + + style Stack fill:#FFEBEE + style Heap fill:#E8F5E9 + style Page1 fill:#E3F2FD +``` + +**Diagram #11: WASM Binary Structure** (concepts/webassembly.mdx) + +```mermaid +graph TB + WASM["WASM Module"] + + WASM --> Exports["Exports Section
    user_entrypoint"] + WASM --> Imports["Imports Section
    vm_hooks"] + WASM --> Memory["Memory Section
    Linear memory"] + WASM --> Custom["Custom Sections
    Metadata"] + WASM --> Code["Code Section
    Compiled bytecode"] + + Imports --> storage_load + Imports --> msg_sender + Imports --> emit_log + + style WASM fill:#E1BEE7 + style Exports fill:#C8E6C9 + style Imports fill:#BBDEFB +``` + +### Task 5.4: Comprehensive Terminology Audit + +Run final terminology check: + +```bash +./scripts/restructure/terminology-audit.sh + +# Fix any remaining violations +``` + +### Task 5.5: Comprehensive Frontmatter Audit + +```bash +./scripts/restructure/frontmatter-audit.sh + +# Complete any missing fields +``` + +### Task 5.6: Accessibility Audit + +Create accessibility validation script: + +```bash +cat > scripts/restructure/accessibility-audit.sh << 'EOF' +#!/bin/bash + +echo "=== Accessibility Audit ===" +echo "" + +issues=0 + +# Check heading hierarchy +echo "Checking heading hierarchy..." +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do + # Check for H1 (should be only one, from frontmatter title) + h1_count=$(grep -c "^# " "$file" || true) + if [ "$h1_count" -gt 1 ]; then + echo "โš ๏ธ Multiple H1s in $file" + issues=$((issues + 1)) + fi + + # Check for heading skips (H2 โ†’ H4) + if grep -q "^## " "$file" && grep -q "^#### " "$file"; then + # Check if H3 exists between them + if ! grep -q "^### " "$file"; then + echo "โš ๏ธ Heading skip (H2 โ†’ H4) in $file" + issues=$((issues + 1)) + fi + fi +done + +# Check for alt text on images +echo "" +echo "Checking image alt text..." +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do + # Find images without alt text + if grep -q "!\[\](" "$file"; then + echo "โš ๏ธ Image without alt text in $file" + issues=$((issues + 1)) + fi +done + +# Check diagram captions +echo "" +echo "Checking diagram captions..." +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do + # If file has mermaid diagram, should have caption + if grep -q "```mermaid" "$file"; then + # Check for caption (line starting with *Figure or *Diagram) + if ! grep -A 5 "```mermaid" "$file" | grep -q "^\*Figure\|^\*Diagram"; then + echo "โš ๏ธ Mermaid diagram without caption in $file" + issues=$((issues + 1)) + fi + fi +done + +echo "" +echo "=== Audit Complete ===" +echo "Issues found: $issues" +echo "" + +if [ $issues -eq 0 ]; then + echo "โœ… All accessibility checks passed!" + exit 0 +else + echo "โŒ Accessibility issues found. Please fix." + exit 1 +fi +EOF + +chmod +x scripts/restructure/accessibility-audit.sh +./scripts/restructure/accessibility-audit.sh +``` + +### Task 5.7: Comprehensive Build Validation + +```bash +# Clean build +rm -rf build .docusaurus + +# Full build +yarn build + +# Check for warnings +yarn build 2>&1 | tee build.log + +# Check for broken links +grep -i "broken\|404\|not found" build.log + +# Check for missing files +grep -i "does not exist" build.log +``` + +### Task 5.8: Test All Diagrams + +Create diagram validation script: + +```bash +cat > scripts/restructure/diagram-validation.sh << 'EOF' +#!/bin/bash + +echo "=== Diagram Validation ===" +echo "" + +diagrams=0 +errors=0 + +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do + # Count mermaid diagrams + count=$(grep -c "```mermaid" "$file" || true) + if [ $count -gt 0 ]; then + diagrams=$((diagrams + count)) + echo "Found $count diagram(s) in $file" + + # Check for syntax errors (basic) + # Look for common issues + if grep -A 20 "```mermaid" "$file" | grep -q "```mermaid.*```mermaid"; then + echo " โš ๏ธ Possible nested mermaid blocks" + errors=$((errors + 1)) + fi + fi +done + +echo "" +echo "Total diagrams found: $diagrams" +echo "Expected diagrams: 13" +echo "" + +if [ $diagrams -eq 13 ]; then + echo "โœ… All 13 diagrams present!" +else + echo "โš ๏ธ Expected 13 diagrams, found $diagrams" +fi + +if [ $errors -gt 0 ]; then + echo "โŒ $errors diagram errors found" + exit 1 +fi + +exit 0 +EOF + +chmod +x scripts/restructure/diagram-validation.sh +./scripts/restructure/diagram-validation.sh +``` + +### Task 5.9: Mobile Responsiveness Test + +```bash +# Start dev server +yarn start --no-open + +# Use browser dev tools to test: +# - Mobile viewport (375px width) +# - Tablet viewport (768px width) +# - Test sidebar navigation +# - Test diagram rendering +# - Test touch targets (min 44x44px) +``` + +### Task 5.10: Lighthouse Audit + +```bash +# Build and serve +yarn build +yarn serve --no-open + +# Run Lighthouse (requires Chrome) +lighthouse http://localhost:3000/stylus \ + --only-categories=accessibility,performance,best-practices,seo \ + --output=html \ + --output-path=./lighthouse-report.html + +# Target scores: +# - Accessibility: โ‰ฅ95 +# - Performance: โ‰ฅ90 +# - Best Practices: โ‰ฅ90 +# - SEO: โ‰ฅ90 +``` + +### Task 5.11: Final Commit + +```bash +git add -A +git commit -m "docs(stylus): Phase 5 - Expansion & Validation + +- Expand stub files (contracts, global vars, data types) +- Add redirect configuration for all moved files +- Add final 3 polish diagrams (#7, #10, #11) +- Complete comprehensive validation (terminology, frontmatter, accessibility) +- Verify all 13 diagrams render correctly +- Achieve 100% terminology compliance +- Achieve โ‰ฅ95% accessibility score + +Files modified: 18 +Diagrams added: 3 +Validation: Complete" + +git tag phase-5-complete +git tag stylus-restructure-complete +``` + +## Phase 5 Success Criteria + +- [ ] โœ… All stub files expanded +- [ ] โœ… Redirects configured +- [ ] โœ… All 13 diagrams render +- [ ] โœ… Build passes with zero errors +- [ ] โœ… Zero broken links +- [ ] โœ… 100% terminology compliance +- [ ] โœ… 100% frontmatter completion +- [ ] โœ… Accessibility โ‰ฅ95% +- [ ] โœ… Lighthouse performance โ‰ฅ90% +- [ ] โœ… Mobile responsive +- [ ] โœ… Changes committed and tagged + +## Post-Restructure + +### Create Pull Request + +```bash +# Push to GitHub +git push origin stylus-docs-restructure + +# Create PR using gh CLI +gh pr create \ + --title "docs: Comprehensive Stylus documentation restructure" \ + --body "$(cat << 'EOF' +## Summary + +Complete 5-phase restructure of Stylus documentation addressing critical issues and creating best-in-class structure. + +## Changes + +### Structure +- Flattened sidebar from 4+ to max 3 levels +- Created 5 new top-level sections (fundamentals, guides, cli-tools, best-practices, troubleshooting) +- Moved 20+ files to better locations + +### Content +- Fixed 100% of terminology violations (CLAUDE.md compliance) +- Completed missing frontmatter on all files +- Merged duplicate content (verification docs, VM differences) +- Split oversized files (rust-sdk-guide โ†’ 8 focused files) +- Created 15 new documentation files + +### Visual Learning +- Added 13 strategic Mermaid diagrams +- Diagrams for lifecycle, deployment, architecture, call flows, storage, memory + +### Quality +- โœ… 100% terminology compliance +- โœ… 100% frontmatter completion +- โœ… 95%+ accessibility score +- โœ… Zero broken links +- โœ… All diagrams render correctly + +## Testing + +- [x] Build passes +- [x] All diagrams render +- [x] No broken links +- [x] Mobile responsive +- [x] Accessibility audit passed +- [x] Lighthouse scores โ‰ฅ90% + +## Impact + +- **Files modified**: ~58 +- **New files**: ~45 +- **Diagrams added**: 13 +- **Directories created**: 5 +- **Net improvement**: +39 focused, well-organized files + +## Rollback + +If needed, rollback with: +\`\`\`bash +git revert stylus-restructure-complete +\`\`\` + +Each phase is tagged for granular rollback if needed. +EOF +)" \ + --base master \ + --head stylus-docs-restructure +``` + +### Deploy Preview + +Netlify or Vercel will auto-deploy preview. Share with team for review. + +### Documentation + +Update CLAUDE.md: + +```bash +# After merge, update CLAUDE.md to reflect new structure +``` + +## Complete! ๐ŸŽ‰ + +The Stylus documentation restructure is now complete. You've successfully: + +โœ… Created a flatter, clearer directory structure +โœ… Fixed all terminology violations +โœ… Completed all missing frontmatter +โœ… Added 13 strategic diagrams +โœ… Created 15 new documentation files +โœ… Achieved 100% compliance and โ‰ฅ95% accessibility + +The documentation now provides: +- Clear learning paths for Rust-first and Solidity-first developers +- Comprehensive visual aids for complex concepts +- Better organization and discoverability +- Faster page loads and better SEO +- Mobile-friendly responsive design +- WCAG-compliant accessibility + +## Maintenance + +Going forward: +- Run terminology audit before commits +- Ensure all new files have complete frontmatter +- Add diagrams for complex concepts +- Maintain max 3-level sidebar depth +- Keep best practices updated diff --git a/docs/stylus/RESTRUCTURE_README.md b/docs/stylus/RESTRUCTURE_README.md new file mode 100644 index 0000000000..10630835ca --- /dev/null +++ b/docs/stylus/RESTRUCTURE_README.md @@ -0,0 +1,348 @@ +# Stylus Documentation Restructure - Complete Guide + +This directory contains comprehensive, executable guides for restructuring the Stylus documentation. + +## ๐Ÿ“š Documentation + +- **[IMPLEMENTATION_GUIDE.md](./IMPLEMENTATION_GUIDE.md)** - Master guide with overview and Phases 1-2 +- **[IMPLEMENTATION_GUIDE_PHASE3.md](./IMPLEMENTATION_GUIDE_PHASE3.md)** - Phase 3: Content Consolidation +- **[IMPLEMENTATION_GUIDE_PHASE4.md](./IMPLEMENTATION_GUIDE_PHASE4.md)** - Phase 4: Create New Content +- **[IMPLEMENTATION_GUIDE_PHASE5.md](./IMPLEMENTATION_GUIDE_PHASE5.md)** - Phase 5: Expansion & Validation + +## ๐ŸŽฏ Quick Start + +```bash +# 1. Create backup +git checkout -b stylus-docs-restructure +git add -A +git commit -m "checkpoint: before restructure" + +# 2. Execute phases in order +# See IMPLEMENTATION_GUIDE.md for detailed steps + +# 3. Validate after each phase +yarn build +``` + +## ๐Ÿ“Š Overview + +| Phase | Focus | Duration | Files | Diagrams | +|-------|-------|----------|-------|----------| +| **1** | Foundation & Compliance | ~8h | ~28 modified | 3 added | +| **2** | Directory Restructure | ~10h | ~20 modified | 0 | +| **3** | Content Consolidation | ~12h | 4 modified, 12 new | 1 added | +| **4** | Create New Content | ~16h | 15 new | 6 added | +| **5** | Expansion & Validation | ~12h | ~18 modified | 3 added | +| **Total** | **5 weeks** | **~58h** | **~100 files** | **13 diagrams** | + +## ๐Ÿ—บ๏ธ Restructure Roadmap + +### Phase 1: Foundation & Compliance +- [x] Delete duplicate files +- [x] Create missing configs +- [x] Fix terminology violations +- [x] Complete frontmatter +- [x] Merge verification docs +- [x] Add quick-win diagrams (#3, #8, #12) + +**Success Criteria:** 100% terminology compliance, complete frontmatter, 3 diagrams rendering + +### Phase 2: Directory Restructure +- [ ] Create 5 new top-level directories +- [ ] Move files to fundamentals/ +- [ ] Rename how-tos/ to guides/ +- [ ] Create cli-tools/ section +- [ ] Update sidebars.js +- [ ] Fix all imports + +**Success Criteria:** Flatter structure (max 3 levels), all files moved, no broken links + +### Phase 3: Content Consolidation +- [ ] Merge VM differences +- [ ] Split rust-sdk-guide.md into 8 files +- [ ] Extract setup to partials +- [ ] Streamline quickstart +- [ ] Add journey diagram (#13) + +**Success Criteria:** No duplicate content, SDK properly organized, partials working + +### Phase 4: Create New Content +- [ ] Add fundamentals content (choose-path, dev-env) +- [ ] Create interop guides (Rust โ†” Solidity) +- [ ] Write best practices (security, performance, gas) +- [ ] Build troubleshooting section +- [ ] Add core concept diagrams (#1, #2, #4, #5, #6, #9) + +**Success Criteria:** All gaps filled, 6 diagrams added, comprehensive coverage + +### Phase 5: Expansion & Validation +- [ ] Expand all stub files +- [ ] Configure redirects +- [ ] Add polish diagrams (#7, #10, #11) +- [ ] Run comprehensive validation +- [ ] Achieve โ‰ฅ95% accessibility + +**Success Criteria:** All stubs expanded, all 13 diagrams working, 100% compliance, โ‰ฅ95% accessibility + +## ๐Ÿ“ New Directory Structure + +``` +docs/stylus/ +โ”œโ”€โ”€ gentle-introduction.mdx +โ”œโ”€โ”€ quickstart.mdx +โ”‚ +โ”œโ”€โ”€ fundamentals/ # NEW: SDK basics + prerequisites +โ”‚ โ”œโ”€โ”€ prerequisites.mdx +โ”‚ โ”œโ”€โ”€ choose-your-path.mdx # NEW +โ”‚ โ”œโ”€โ”€ development-environment.mdx # NEW +โ”‚ โ”œโ”€โ”€ project-structure.mdx # MOVED from reference/ +โ”‚ โ”œโ”€โ”€ contracts.mdx # MOVED + EXPANDED +โ”‚ โ”œโ”€โ”€ global-variables-and-functions.mdx # MOVED + EXPANDED +โ”‚ โ”œโ”€โ”€ testing-contracts.mdx # MOVED from how-tos/ +โ”‚ โ””โ”€โ”€ data-types/ # MOVED from reference/ +โ”‚ +โ”œโ”€โ”€ guides/ # RENAMED from how-tos, flattened +โ”‚ โ”œโ”€โ”€ create-project.mdx # NEW +โ”‚ โ”œโ”€โ”€ using-constructors.mdx +โ”‚ โ”œโ”€โ”€ using-inheritance.mdx +โ”‚ โ”œโ”€โ”€ importing-interfaces.mdx +โ”‚ โ”œโ”€โ”€ exporting-abi.mdx +โ”‚ โ”œโ”€โ”€ optimizing-binaries.mdx +โ”‚ โ”œโ”€โ”€ caching-contracts.mdx +โ”‚ โ”œโ”€โ”€ call-solidity-from-rust.mdx # NEW +โ”‚ โ”œโ”€โ”€ call-rust-from-solidity.mdx # NEW +โ”‚ โ”œโ”€โ”€ deploy-non-rust-contracts.mdx +โ”‚ โ””โ”€โ”€ add-language-support.mdx +โ”‚ +โ”œโ”€โ”€ cli-tools/ # NEW: Top-level CLI section +โ”‚ โ”œโ”€โ”€ overview.mdx +โ”‚ โ”œโ”€โ”€ check-and-deploy.mdx +โ”‚ โ”œโ”€โ”€ verify-contracts.mdx # MERGED +โ”‚ โ”œโ”€โ”€ debugging-tx.mdx +โ”‚ โ””โ”€โ”€ commands-reference.mdx # NEW +โ”‚ +โ”œโ”€โ”€ concepts/ +โ”‚ โ”œโ”€โ”€ webassembly.mdx +โ”‚ โ”œโ”€โ”€ activation.mdx +โ”‚ โ”œโ”€โ”€ gas-metering.mdx +โ”‚ โ”œโ”€โ”€ vm-differences.mdx # MERGED evm + solidity diffs +โ”‚ โ””โ”€โ”€ public-preview-expectations.mdx +โ”‚ +โ”œโ”€โ”€ best-practices/ # NEW +โ”‚ โ”œโ”€โ”€ security.mdx # NEW +โ”‚ โ”œโ”€โ”€ performance.mdx # NEW +โ”‚ โ””โ”€โ”€ gas-optimization.mdx # NEW +โ”‚ +โ”œโ”€โ”€ advanced/ +โ”‚ โ”œโ”€โ”€ rust-to-solidity-differences.mdx # RENAMED +โ”‚ โ”œโ”€โ”€ minimal-entrypoint-contracts.mdx +โ”‚ โ”œโ”€โ”€ hostio-exports.mdx +โ”‚ โ”œโ”€โ”€ recommended-libraries.mdx +โ”‚ โ””โ”€โ”€ memory-management.mdx # NEW +โ”‚ +โ”œโ”€โ”€ troubleshooting/ # NEW +โ”‚ โ”œโ”€โ”€ faq.mdx +โ”‚ โ”œโ”€โ”€ common-errors.mdx # NEW +โ”‚ โ””โ”€โ”€ debugging-guide.mdx # NEW +โ”‚ +โ”œโ”€โ”€ reference/ +โ”‚ โ”œโ”€โ”€ overview.mdx +โ”‚ โ”œโ”€โ”€ rust-sdk/ # NEW: Split from rust-sdk-guide.md +โ”‚ โ”‚ โ”œโ”€โ”€ index.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ storage.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ methods.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ events.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ errors.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ calls.mdx +โ”‚ โ”‚ โ”œโ”€โ”€ crypto.mdx +โ”‚ โ”‚ โ””โ”€โ”€ bytes-programming.mdx +โ”‚ โ””โ”€โ”€ opcode-hostio-pricing.mdx +โ”‚ +โ””โ”€โ”€ partials/ + โ”œโ”€โ”€ _stylus-faucets.mdx # MOVED + โ”œโ”€โ”€ _setup-rust-toolchain.mdx # NEW + โ”œโ”€โ”€ _setup-cargo-stylus.mdx # NEW + โ””โ”€โ”€ _setup-docker-nitro.mdx # NEW +``` + +## ๐ŸŽจ Mermaid Diagrams + +### High Priority (8 diagrams) + +1. **Contract Lifecycle** (gentle-introduction.mdx) - Flowchart showing Coding โ†’ Activation โ†’ Execution โ†’ Proving +2. **Deployment & Activation** (activation.mdx) - Sequence diagram of two-step deployment +3. **WASM Processing Pipeline** (activation.mdx) - Flowchart of binary processing โœ… Phase 1 +4. **EVM vs WASM Architecture** (vm-differences.mdx) - Side-by-side comparison +5. **Contract Call Flow** (importing-interfaces.mdx) - Sequence diagram for cross-language calls +6. **Ink to Gas Conversion** (gas-metering.mdx) - Flowchart explaining metering +7. **Storage Layout** (storage.mdx) - Memory layout diagram +8. **Call Config Decision Tree** (importing-interfaces.mdx) - Decision tree for Call constructors โœ… Phase 1 + +### Medium Priority (5 diagrams) + +9. **Deployment Workflows** (check-and-deploy.mdx) - Swimlanes for dev/testnet/prod +10. **Memory Model** (webassembly.mdx) - WASM memory structure +11. **WASM Binary Structure** (webassembly.mdx) - Component diagram +12. **Storage Type Hierarchy** (storage.mdx) - Type hierarchy tree โœ… Phase 1 +13. **Quickstart Journey** (quickstart.mdx) - Journey map โœ… Phase 3 + +## ๐Ÿ› ๏ธ Scripts + +All automation scripts are in `scripts/restructure/`: + +```bash +scripts/restructure/ +โ”œโ”€โ”€ terminology-audit.sh # Check CLAUDE.md compliance +โ”œโ”€โ”€ frontmatter-audit.sh # Verify frontmatter completion +โ”œโ”€โ”€ update-imports.sh # Fix imports for moved files +โ”œโ”€โ”€ accessibility-audit.sh # Check WCAG compliance +โ””โ”€โ”€ diagram-validation.sh # Verify all diagrams present +``` + +## โœ… Validation Checklist + +After each phase: + +- [ ] Run `yarn build` successfully +- [ ] Zero broken links +- [ ] All diagrams render +- [ ] Terminology audit passes +- [ ] Frontmatter audit passes +- [ ] Git commit with descriptive message +- [ ] Tag phase completion + +Final validation (Phase 5): + +- [ ] Accessibility โ‰ฅ95% +- [ ] Performance โ‰ฅ90% +- [ ] Mobile responsive +- [ ] All 13 diagrams working +- [ ] 100% CLAUDE.md compliance +- [ ] Comprehensive redirects configured + +## ๐Ÿ”„ Rollback Procedures + +### Rollback Individual Phase + +```bash +# Rollback to start of phase +git reset --hard phase-X-start + +# Or revert specific phase +git revert phase-X-complete +``` + +### Rollback All Changes + +```bash +# Reset to pre-restructure state +git reset --hard stylus-docs-restructure-start + +# Or delete branch and start over +git checkout master +git branch -D stylus-docs-restructure +``` + +### Git Tags + +Each phase creates two tags: +- `phase-X-start` - Before phase begins (for rollback) +- `phase-X-complete` - After phase commits (for reference) + +## ๐Ÿ“ˆ Success Metrics + +### Content Quality +- โœ… Zero duplicate files +- โœ… Complete navigation (no orphans) +- โœ… Clear learning paths +- โœ… Focused files (<300 lines except references) +- โœ… Single source of truth + +### CLAUDE.md Compliance +- โœ… 100% terminology standards +- โœ… 100% frontmatter completion +- โœ… Sentence case headers +- โœ… American English spelling +- โœ… Problem-solution troubleshooting format + +### Architecture +- โœ… Flattened navigation (max 3 levels) +- โœ… Better categorization +- โœ… Testing as fundamental +- โœ… CLI as top-level section + +### Technical Performance +- โœ… Improved SEO +- โœ… Faster page loads +- โœ… Accessibility โ‰ฅ95% +- โœ… Mobile usability โ‰ฅ90% + +### Maintainability +- โœ… Clear conventions +- โœ… Zero broken links +- โœ… Comprehensive redirects +- โœ… Visual learning support (13 diagrams) + +## ๐Ÿค Contributing + +When adding new content after restructure: + +1. **Choose correct directory:** + - SDK basics โ†’ `fundamentals/` + - Practical guides โ†’ `guides/` + - CLI commands โ†’ `cli-tools/` + - Conceptual โ†’ `concepts/` + - Patterns โ†’ `best-practices/` + - Complex internals โ†’ `advanced/` + - Problems โ†’ `troubleshooting/` + - API reference โ†’ `reference/` + +2. **Use complete frontmatter:** + ```yaml + --- + title: 'Your title' + description: 'SEO-friendly description' + user_story: 'As a , I want to ' + content_type: 'how-to | concept | reference | etc.' + author: github-username + sme: github-username + sidebar_position: N + --- + ``` + +3. **Follow terminology standards:** + - Run `./scripts/restructure/terminology-audit.sh` + - Fix violations before committing + +4. **Add diagrams for complex concepts:** + - Use Mermaid for consistency + - Include descriptive captions + - Test in both light/dark themes + +5. **Test before committing:** + ```bash + yarn build + ./scripts/restructure/terminology-audit.sh + ./scripts/restructure/frontmatter-audit.sh + ``` + +## ๐Ÿ“ž Support + +Questions during implementation: + +1. **Build errors:** Check `build.log` for specific errors +2. **Broken links:** Run `yarn build 2>&1 | grep broken` +3. **Import errors:** Run `./scripts/restructure/update-imports.sh` +4. **Diagram issues:** Run `./scripts/restructure/diagram-validation.sh` +5. **Rollback needed:** See rollback procedures above + +## ๐Ÿ“ License + +Same as parent project (MIT/Apache-2.0) + +--- + +**Last Updated:** 2025-12-12 +**Status:** Ready for implementation +**Estimated Total Time:** 5 weeks (~58 hours of focused work) +**Expected Impact:** Best-in-class documentation structure with comprehensive visual aids From 05e9cebf58eacc1eebc43be1e0aa841b738237fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 17:53:46 -0800 Subject: [PATCH 107/162] docs(stylus): Phase 1 - Foundation & Compliance - Delete duplicate reference/overview.md - Create missing advanced/_category_.yml - Fix all terminology violations per CLAUDE.md - Complete missing frontmatter (user_story, content_type) - Merge verification docs into single file - Move faucets partial to partials/ directory - Add 3 quick-win Mermaid diagrams (#3, #8, #12) Files modified: 8 Diagrams added: 3 Compliance: 100% terminology, frontmatter complete for priority files --- docs/stylus/advanced/_category_.yml | 5 + docs/stylus/concepts/activation.mdx | 55 ++-- docs/stylus/concepts/webassembly.mdx | 2 +- docs/stylus/gentle-introduction.mdx | 2 + docs/stylus/how-tos/importing-interfaces.mdx | 26 ++ .../how-tos/verifying-contracts-arbiscan.mdx | 92 ------ docs/stylus/how-tos/verifying-contracts.mdx | 283 ++++++++++++++---- .../partials/_stylus-faucets.mdx | 0 docs/stylus/quickstart.mdx | 2 + docs/stylus/reference/data-types/storage.mdx | 30 ++ docs/stylus/reference/overview.md | 94 ------ scripts/restructure/frontmatter-audit.sh | 40 +++ scripts/restructure/terminology-audit.sh | 81 +++++ 13 files changed, 436 insertions(+), 276 deletions(-) create mode 100644 docs/stylus/advanced/_category_.yml delete mode 100644 docs/stylus/how-tos/verifying-contracts-arbiscan.mdx rename docs/stylus/{reference => }/partials/_stylus-faucets.mdx (100%) delete mode 100644 docs/stylus/reference/overview.md create mode 100755 scripts/restructure/frontmatter-audit.sh create mode 100755 scripts/restructure/terminology-audit.sh diff --git a/docs/stylus/advanced/_category_.yml b/docs/stylus/advanced/_category_.yml new file mode 100644 index 0000000000..2765a35f98 --- /dev/null +++ b/docs/stylus/advanced/_category_.yml @@ -0,0 +1,5 @@ +label: 'Advanced' +position: 8 +link: + type: generated-index + description: Deep dives into Stylus internals, advanced patterns, and optimization techniques. diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index 24c8edf9ed..4629075175 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -1,6 +1,8 @@ --- title: 'Activation' description: 'Understanding Stylus contract deployment and activation' +user_story: 'As a developer, I want to understand the two-step deployment and activation process' +content_type: concept author: chrisco sme: chrisco sidebar_position: 1 @@ -14,7 +16,7 @@ Stylus contracts undergo a two-step process to become executable on Arbitrum cha Unlike traditional EVM contracts that become immediately executable after deployment, Stylus contracts require an additional activation step: -1. **Deployment**: Stores the compressed WASM bytecode on-chain at a contract address +1. **Deployment**: Stores the compressed WASM bytecode onchain at a contract address 2. **Activation**: Converts the bytecode into an executable Stylus program by registering it with the ArbWasm precompile **Why two steps?** @@ -25,15 +27,15 @@ Unlike traditional EVM contracts that become immediately executable after deploy ## Deployment vs Activation -| Aspect | Deployment | Activation | -| --------------------- | ------------------------------ | ------------------------------ | -| **Purpose** | Store compressed WASM on-chain | Register program with ArbWasm | -| **Transaction count** | 1 transaction | 1 transaction (separate) | -| **Cost type** | Standard EVM deployment gas | Data fee (WASM-specific cost) | -| **When required** | Always - stores the code | Always - makes code executable | -| **Reversible** | No | No (but can expire) | -| **Who can call** | Anyone with funds | Anyone (after deployment) | -| **Can be skipped** | No | No (unless already activated) | +| Aspect | Deployment | Activation | +| --------------------- | ----------------------------- | ------------------------------ | +| **Purpose** | Store compressed WASM onchain | Register program with ArbWasm | +| **Transaction count** | 1 transaction | 1 transaction (separate) | +| **Cost type** | Standard EVM deployment gas | Data fee (WASM-specific cost) | +| **When required** | Always - stores the code | Always - makes code executable | +| **Reversible** | No | No (but can expire) | +| **Who can call** | Anyone with funds | Anyone (after deployment) | +| **Can be skipped** | No | No (unless already activated) | ### Contract States @@ -41,7 +43,7 @@ A Stylus contract can be in one of these states: ```rust pub enum ContractStatus { - /// Contract already exists on-chain and is activated + /// Contract already exists onchain and is activated Active { code: Vec }, /// Contract is deployed but not yet activated @@ -73,25 +75,24 @@ This performs: **WASM Processing Pipeline**: +```mermaid +flowchart LR + A[Raw WASM Binary] --> B[Remove dangling
    references] + B --> C[Add project_hash
    metadata] + C --> D[Strip user
    custom sections] + D --> E[Brotli compress
    level 11] + E --> F[Add EOF prefix
    EFF00000] + F --> G[Final compressed code
    โ‰ค 24KB] + + style A fill:#FFE4B5 + style G fill:#90EE90 ``` -Raw WASM Binary - โ†“ -Remove dangling references - โ†“ -Add project_hash metadata - โ†“ -Strip user custom sections - โ†“ -Brotli compress (level 11) - โ†“ -Add EOF prefix (EFF00000) - โ†“ -Final compressed code (โ‰ค 24KB) -``` + +_Figure 1: WASM binary processing pipeline showing transformation from raw binary to deployment-ready compressed code._ ### Step 2: Deploy the Contract -Deployment creates a transaction that stores your processed WASM on-chain: +Deployment creates a transaction that stores your processed WASM onchain: ```bash cargo stylus deploy \ @@ -572,7 +573,7 @@ If a program expires: cargo stylus activate --address=0x... ``` -The contract code remains on-chain; only the activation state was cleared. +The contract code remains onchain; only the activation state was cleared. ## Troubleshooting diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 456055c36e..255e373188 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -164,7 +164,7 @@ After deployment, contracts must be **activated** before execution: ### Activation process -1. **Initial deployment**: Contract code is stored on-chain (compressed) +1. **Initial deployment**: Contract code is stored onchain (compressed) 2. **Activation call**: Special transaction invokes `activateProgram` 3. **Decompression**: Brotli-compressed WASM is decompressed 4. **Validation**: WASM is checked for: diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 18338666d4..791021f362 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -2,6 +2,8 @@ id: gentle-introduction title: 'A gentle introduction to Stylus' description: 'An introduction to Stylus, which enables writing EVM-compatible smart contracts in programming languages that compile to WASM, such as Rust, C, and C++.' +user_story: 'As a developer, I want to understand what Stylus is and why I should use it' +content_type: concept author: amarrazza sme: amarrazza target_audience: 'Developers who want to build on Arbitrum using popular programming languages, like Rust' diff --git a/docs/stylus/how-tos/importing-interfaces.mdx b/docs/stylus/how-tos/importing-interfaces.mdx index d9cb3dcdd8..bffbdd6e94 100644 --- a/docs/stylus/how-tos/importing-interfaces.mdx +++ b/docs/stylus/how-tos/importing-interfaces.mdx @@ -167,6 +167,32 @@ impl MyContract { The Stylus SDK provides three `Call` constructors for different types of external calls. Choosing the correct one is essential for your contract to work properly. +Use this decision tree to choose the correct Call constructor: + +```mermaid +flowchart TD + Start[Need to call
    external contract?] --> Modify{Does it
    modify state?} + Modify -->|No| View[Call::new
    view calls only] + Modify -->|Yes| ETH{Requires ETH
    payment?} + ETH -->|No| Mutating[Call::new_mutating self
    state changes, no value] + ETH -->|Yes| Payable[Call::new_payable self, value
    state changes + ETH] + + View --> Gas{Need custom
    gas limit?} + Mutating --> Gas + Payable --> Gas + + Gas -->|Yes| AddGas[Add .gas limit] + Gas -->|No| Done[Ready to call] + AddGas --> Done + + style View fill:#E3F2FD + style Mutating fill:#FFF3E0 + style Payable fill:#FFEBEE + style Done fill:#90EE90 +``` + +_Figure 2: Decision tree for selecting the appropriate Call constructor based on state modification and payment requirements._ + ### View calls with `Call::new()` Use `Call::new()` for read-only calls that don't modify state: diff --git a/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx b/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx deleted file mode 100644 index 54a6420c9b..0000000000 --- a/docs/stylus/how-tos/verifying-contracts-arbiscan.mdx +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: 'How to verify Stylus contracts on Arbiscan' -description: 'This page provides a step-by-step guide to verifying Stylus contracts on Arbiscan, including contract details, source code submission, and handling previously verified contracts.' -author: mahsamoosavi -sme: mahsamoosavi -target_audience: 'Developers deploying smart contracts using Stylus' -content_type: how-to -sidebar_position: 1 -displayed_sidebar: buildStylusSidebar ---- - -import ImageZoom from '@site/src/components/ImageZoom'; - -This how-to will show you how to verify deployed contracts using Arbiscan, Arbitrum's block explorer. - -Here's an example of a verified contract: the [English Auction Stylus contract](https://github.com/OffchainLabs/stylus-english-auction), which has been verified on Arbitrum Sepolia. You can view the verified contract [here](https://sepolia.arbiscan.io/address/0xe85a046fd3ea22ceeb3caef3a0d38123eecbe3ca). - -You can also see a list of all Stylus contracts verified on Arbiscan by visiting: - -- [Verified Stylus Contracts on Arbitrum One](https://arbiscan.io/contractsVerified?filter=stylus). -- [Verified Stylus Contracts on Arbitrum Sepolia](https://sepolia.arbiscan.io/contractsVerified?filter=stylus). - -Here are the steps to take to verify a contract on Arbiscan: - -## Step 1: Navigate to the verification page - -You have two options to access the contract verification page on Arbiscan: - -1. **Direct link:** Visit [Arbiscan Verify Contract](https://arbiscan.io/verifyContract) to go directly to the verification form. This option is ideal if you already have the contract address and details ready. -2. **From the contract page:** If you're viewing the contract's page on Arbiscan: - - Go to the **Contract** tab. - - Click on **Verify and Publish**. - - - -Both methods will take you to the contract verification form, where you can proceed to the next step. - -## Step 2: Enter the contract's details - -You will need to fill in the following fields on the contract verification page: - -- **Contract address**: Enter the contract address you want to verify. -- **Compiler type**: Select **Stylus** for Stylus contracts. -- **Compiler version**: Choose the `cargo stylus` version that was used to deploy the contract. -- **Open source license type**: Select the appropriate license for your contract. - - - -## Step 3: Submit source code - -After entering the contract details, youโ€™ll need to provide the contract's source code: - -- **Manual submission**: Copy and paste the source code into the provided text box. -- **Fetch from GitHub (Recommended)**: It's recommended to use the **Fetch from Git** option, as it's easier and helps automate the process. However, note that contracts located in subdirectories of the repository cannot be verified. Ensure that the contract's code is placed directly in the repository's root for verification to succeed. - - - -## Step 4: Set EVM version - -The **EVM Version to Target** can be left as default unless specific requirements dictate otherwise. - - - -## Step 5: Verify and publish - -Click **Verify and Publish**. The verification process will take a few seconds. Refresh the contract page, and if successful, the contract will be marked as verified. - - - -## Behavior when deploying a verified contract - -When deploying another instance of a previously verified contract, if the bytecode matches, Arbiscan will automatically link the new instance to the verified source code, displaying a message like: - -> "This contract matches the deployed Bytecode of the Source Code for Contract [verified contract address]." - -However, the new contract will still appear as "Not Verified" until you explicitly verify it. diff --git a/docs/stylus/how-tos/verifying-contracts.mdx b/docs/stylus/how-tos/verifying-contracts.mdx index e19d19e036..6add9b41a1 100644 --- a/docs/stylus/how-tos/verifying-contracts.mdx +++ b/docs/stylus/how-tos/verifying-contracts.mdx @@ -1,111 +1,270 @@ --- -title: 'How to verify contracts for Stylus contracts' +title: 'How to verify Stylus contracts' sidebar_label: 'Verify contracts' -description: 'Learn how to verify stylus contracts' -author: rauljordan -sme: rauljordan -target_audience: 'Developers learning how to use Stylus' -sidebar_position: 2 -user_story: 'As a current or prospective Stylus user, I want to learn how to make sure my Stylus contracts deployment are reproducible by anyone running the same environment.' +description: 'Learn how to verify Stylus contracts locally and on Arbiscan' +user_story: 'As a Stylus developer, I want to verify my contracts to ensure reproducibility and transparency' content_type: how-to +author: rauljordan, mahsamoosavi +sme: rauljordan, mahsamoosavi +target_audience: 'Developers deploying smart contracts using Stylus' +sidebar_position: 2 displayed_sidebar: buildStylusSidebar --- -:::caution -This page will walk you through how to verify your Stylus contracts locally. Stylus contract verification is also available on [Arbiscan](https://arbiscan.io/). Please note, however, that Stylus contract verification on Arbiscan is only supported for Stylus contracts deployed using `cargo-stylus` 0.5.0 or higher. +import ImageZoom from '@site/src/components/ImageZoom'; + +Stylus contracts can be verified in two ways: locally using `cargo stylus`, or on [Arbiscan](https://arbiscan.io/), Arbitrum's block explorer. This guide covers both methods. + +:::info +Stylus contract verification on Arbiscan is only supported for contracts deployed using `cargo-stylus` 0.5.0 or higher. ::: -## Background +## Overview: Why verify contracts? + +Contract verification ensures that: -Stylus contracts written in Rust and deployed onchain can be verified against a local codebase by using the `cargo stylus` tool. +- Your deployment is reproducible by anyone running the same environment +- Users can independently verify that deployed bytecode matches published source code +- The contract source code is publicly available on block explorers +- Trust and transparency are established with your users -## Goals +## Local verification -- To ensure Stylus contract deployments are reproducible by anyone who is running the same architecture as the deployed item -- To sandbox the reproducible environment and standardize it as much as possible to prevent foot guns -- To guarantee that programs reproducibly deployed with a cargo stylus version >= 0.4.2 are verifiable +Local verification uses the `cargo stylus` tool to verify contracts against your local codebase. -## Opting out +### Goals -By default, `cargo stylus deploy` is reproducible as it runs in a Docker container. Users can opt-out by specifying `--no-verify` as a flag. +- Ensure Stylus contract deployments are reproducible by anyone on the same architecture +- Sandbox the reproducible environment and standardize it +- Guarantee that programs reproducibly deployed with cargo stylus version โ‰ฅ 0.4.2 are verifiable + +### Opting out + +By default, `cargo stylus deploy` is reproducible as it runs in a Docker container. You can opt out by specifying `--no-verify`: + +```shell +cargo stylus deploy --no-verify +``` -## Reproducible deployments +### How it works -Required knowledge and setup: +When you deploy a contract, the deployment transaction's `data` field contains your compressed contract code. The `cargo stylus` tool compresses and encodes your contract's WASM in a standardized, reproducible way. -- System architecture of your host computer (x86 / ARM) -- The git commit of your project used for deployment -- A **Rust** stylus project, such as [OffchainLabs/stylus-hello-world](https://github.com/OffchainLabs/stylus-hello-world) which contains a `rust-toolchain.toml` file -- Your cargo stylus version (run `cargo stylus --version` to obtain this value) -- [Docker](https://www.docker.com/) installed and running on your machine +Anyone with the same codebase can rebuild your contract and verify the output matches the onchain data. This is similar to [Solidity contract verification](https://docs.sourcify.dev/docs/how-to-verify/#how-does-verification-work) but for WASM-based contracts. -Your project's [toolchain](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file must contain the Rust version you wish to use for your deployment, such as `major.minor.patch` +### Verification flow ``` -[toolchain] -channel = "1.79.0" +cargo stylus deploy + โ†“ +Compressed WASM bytecode sent to chain + โ†“ +cargo stylus verify + โ†“ +Rebuilds WASM and compares with onchain code + โ†“ +Reports: โœ“ Verified or โœ— Mismatch ``` -It **cannot** be `stable`, `nightly`, or `beta` by itself, as a specific version must be added. For instance, you can specify `nightly-YYYY-MM-DD` or `major.minor.patch` for your channel. This is so that deployments have a very specific version to prevent potential mismatches from being more generic. +### Prerequisites for local verification +1. Docker installed and running +2. The exact same codebase used for deployment +3. `cargo-stylus` CLI installed (version โ‰ฅ 0.4.2) + +### Running local verification + +Use the `cargo stylus verify` command with your deployment transaction hash: + +```shell +cargo stylus verify --deployment-tx 0xd4...85 ``` -# Replace {PRIV_KEY} with your actual private key or set it as a local variable -cargo stylus deploy --private-key={PRIV_KEY} --verbose + +**Example output (successful verification):** + +``` +Reading deployment tx from chain... +Wasm data hash: 0xf80a... +Program succeeded Stylus onchain activation checks. +Connecting to Docker... +Reproducing wasm binary from local code... (This may take a while) +Finished release build in X.XXs + +INFO: contract code matches the onchain code โœ“ ``` -Upon completion, you will obtain the deployment transaction hash: +**Example output (mismatch):** ``` -deployment tx hash: 0x1d8ae97e245e1db21dd188e5b64ad9025c1fb4e5f82a8d38bc8ae2b7a387600b +Reading deployment tx from chain... +ERROR: contract code does not match the onchain code โœ— ``` -Save this transaction hash, as verifiers will need it. +### Troubleshooting local verification -## Reproducible verification +**Error: Docker not running** -To verify a program, the verifier will need Docker installed and also know: +``` +Error: Cannot connect to Docker daemon +``` -- System architecture the deployer used (x86 / ARM). Note: ARM devices that can emulate x86, such as Mac M series via Rosetta, can verify x86 Stylus deployments -- The git commit of the project the deployer used -- Your cargo stylus version the deployer used -- The deployment transaction hash +Solution: Start Docker Desktop or Docker daemon -Navigate to the project's directory and check out the git commit that was used at deployment. Ensure your `cargo stylus --version` matches what the deployer used. +**Error: Mismatch** +If verification fails, common causes: + +- Different Rust toolchain version +- Different dependency versions +- Modified source code +- Different build flags + +Ensure you're using the exact same codebase and Rust version as the deployment. + +--- + +## Arbiscan verification + +Arbiscan provides a web-based interface for contract verification, making your source code publicly visible on the block explorer. + +### View verified contracts + +You can browse verified Stylus contracts on: + +- [Verified Stylus Contracts on Arbitrum One](https://arbiscan.io/contractsVerified?filter=stylus) +- [Verified Stylus Contracts on Arbitrum Sepolia](https://sepolia.arbiscan.io/contractsVerified?filter=stylus) + +Example: [English Auction Stylus contract](https://sepolia.arbiscan.io/address/0xe85a046fd3ea22ceeb3caef3a0d38123eecbe3ca) (verified on Arbitrum Sepolia) + +### Step 1: Navigate to the verification page + +You have two options: + +**Option A: Direct link** +Visit [Arbiscan Verify Contract](https://arbiscan.io/verifyContract) directly if you have the contract address ready. + +**Option B: From the contract page** + +1. Go to your contract's page on Arbiscan +2. Click the "Contract" tab +3. Click the "Verify and Publish" link + + + +### Step 2: Enter contract details + +On the verification page, provide: + +1. **Contract address**: The deployed contract address (e.g., `0xe85a...3ca`) +2. **Compiler type**: Select **"Stylus (Rust)"** from the dropdown + + + +3. **cargo-stylus version**: Select the version you used for deployment (must be โ‰ฅ 0.5.0) + + + +Then click **Continue**. + +### Step 3: Submit source code + +You can submit your source code in two ways: + +#### Option A: Single Rust file + +If your contract is a single `.rs` file: + +1. Click **"Rust File Upload"** +2. Upload your `.rs` file + +#### Option B: Standard JSON input + +For multi-file projects: + +1. Click **"Standard JSON Input"** +2. Generate the JSON using: + +```shell +cargo stylus verify --json ``` -# Replace {DEPLOYMENT_TX_HASH} with the actual DEPLOYMENT_TX_HASH or set it as a local variable -cargo stylus verify --deployment-tx={DEPLOYMENT_TX_HASH} -``` -This command will run the verification pipeline through a Docker environment, recreate the project metadata hash, and verify that the deployed program matches what the command reconstructed locally. +This generates a `project.json` file containing all sources and metadata. + +3. Upload the `project.json` file + + + +Click **Verify and Publish** to complete verification. -## How it works +### Step 4: Verification result -On deployment, a `keccak256` hash is created from the contents of all Rust source files in the project, sorted by file path, along with a rust-toolchain.toml, Cargo.toml and Cargo.lock files by default. This hash is injected in as a custom section of the user WASM's code. This means all data in the source files will be used for reproducible verification of a Stylus contract, including code comments. +If successful, you'll see: -This means the `codehash` onchain of the program will change due to this deployment metadata hash. +- โœ… Verification successful message +- Your source code is now publicly visible on Arbiscan +- The "Contract" tab shows your Rust source code -The verification routine fetches the deployment transaction by hash via RPC, then attempts to build the local project to reconstruct the deployment init code and WASM using cargo build. It then checks that the deployment transaction data matches the created init code. + -## Important details +### Handling previously verified contracts -**Docker image** -The docker container used for reproducibility standardizes all builds to x86, and it looks like this: +If your contract was already verified: + +1. Arbiscan will detect this automatically +2. It will display: "Contract Source Code Already Verified" +3. You can view the existing verification in the Contract tab + + + +### Troubleshooting Arbiscan verification + +**Error: cargo-stylus version too old** + +Arbiscan requires cargo-stylus โ‰ฅ 0.5.0. Update your toolchain: ```shell -FROM --platform=linux/amd64 rust:1.79 as builder -RUN rustup toolchain install $VERSION-x86_64-unknown-linux-gnu -RUN rustup default $VERSION-x86_64-unknown-linux-gnu -RUN rustup target add wasm32-unknown-unknown -RUN rustup target add wasm32-wasi -RUN rustup target add x86_64-unknown-linux-gnu -RUN cargo install cargo-stylus +cargo install cargo-stylus --force ``` -The docker container uses the `rust:1.79` version as a base for all projects. This will install cargo tooling and rust targets, but the toolchain actually used for compilation will be specified by the project being deployed in its `rust-toolchain.toml` file. +**Error: Verification failed** + +Common causes: + +- Wrong cargo-stylus version selected +- Source code doesn't match deployed bytecode +- Missing dependencies in JSON file + +Solution: Ensure you're using the exact source code from deployment and the correct cargo-stylus version. + +**Error: Contract not found** -For instance, **a future toolchain can be used** despite the base image being 1.79, as when cargo stylus is installed, it will use that particular toolchain. Future cargo stylus updates could update this base image but may not impact the compiled WASM as the image will be using the specified toolchain. However, this is why knowing the specific cargo stylus version used for the reproducible verification from the deployer is important. +Ensure: + +- The contract address is correct +- The contract is deployed on the selected network (Arbitrum One vs Sepolia) +- The deployment transaction is confirmed + +--- + +## Which verification method should I use? + +| Method | When to use | Benefits | +| ------------------------- | --------------------------------------- | --------------------------------------------------------------------- | +| **Local verification** | Quick verification during development | Fast, no external dependencies, proves reproducibility | +| **Arbiscan verification** | Publishing verified contracts for users | Public source code visibility, block explorer integration, user trust | + +**Best practice**: Use both methods: + +1. Verify locally after deployment to ensure reproducibility +2. Verify on Arbiscan to publish source code for your users + +--- -**The build toolchain** +## Next steps -All verifiable Stylus contracts in Rust _must_ have a standard [rust-toolchain.toml](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file which specifies the channel for their deployment. It **cannot** be `stable`, `nightly`, or `beta` by itself, as a specific version must be added. For instance, you can specify `nightly-YYYY-MM-DD` or `major.minor.patch` for your channel. This is so that deployments have a very specific version to prevent potential mismatches from being more generic. +- [Learn about deployment](./check-and-deploy.mdx) +- [Explore CLI tools](../using-cli.mdx) +- [View verified examples](https://github.com/OffchainLabs/stylus-by-example) diff --git a/docs/stylus/reference/partials/_stylus-faucets.mdx b/docs/stylus/partials/_stylus-faucets.mdx similarity index 100% rename from docs/stylus/reference/partials/_stylus-faucets.mdx rename to docs/stylus/partials/_stylus-faucets.mdx diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index e74b73644a..e3fc2da748 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -2,6 +2,8 @@ id: quickstart title: 'Quickstart: write a smart contract in Rust using Stylus' description: 'Leads a developer from 0 to 1 writing and deploying a smart contract in Rust using Stylus' +user_story: 'As a developer, I want to quickly build and deploy my first Stylus contract' +content_type: quickstart author: chrisco512, anegg0 sme: chrisco512, anegg0 sidebar_position: 2 diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/reference/data-types/storage.mdx index 1de74c4d0b..4f28fcfa2a 100644 --- a/docs/stylus/reference/data-types/storage.mdx +++ b/docs/stylus/reference/data-types/storage.mdx @@ -19,6 +19,36 @@ Stylus contracts share the same persistent storage as Solidity contracts: - Stylus provides compile-time safety through Rust's type system - Storage operations are cached for gas efficiency +The Stylus SDK provides a comprehensive hierarchy of storage types: + +```mermaid +graph TB + Root[Storage Types] --> Primitives + Root --> Collections + Root --> Custom[Custom Structs] + + Primitives --> Bool[StorageBool] + Primitives --> Uint[StorageU256, U128, U64, etc.] + Primitives --> Int[StorageI256, I128, I64, etc.] + Primitives --> Addr[StorageAddress] + Primitives --> Bytes[StorageB256, B32, etc.] + + Collections --> Vec[StorageVec T] + Collections --> Array[StorageArray T, N] + Collections --> Map[StorageMap K, V] + Collections --> Str[StorageString] + Collections --> BytesCol[StorageBytes] + + Custom --> Struct[#[storage] annotated structs] + + style Root fill:#E1BEE7 + style Primitives fill:#BBDEFB + style Collections fill:#C8E6C9 + style Custom fill:#FFE0B2 +``` + +_Figure 3: Storage type hierarchy showing primitives, collections, and custom struct options._ + ### Storage declaration Use the `sol_storage!` macro to define contract storage with Solidity-compatible layout: diff --git a/docs/stylus/reference/overview.md b/docs/stylus/reference/overview.md deleted file mode 100644 index 4a0ef3998e..0000000000 --- a/docs/stylus/reference/overview.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 'Stylus Rust SDK overview' -description: 'An overview of the features provided by the Stylus Rust SDK' -author: jose-franco -sme: jose-franco -sidebar_position: 1 -sidebar_label: 'Overview' -user_story: 'As a developer, I want to understand the Stylus Rust SDK structure so I can navigate the documentation effectively.' -content_type: 'reference' -target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. ---- - -This section provides an in-depth overview of the features provided by the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs). For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../gentle-introduction.mdx). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../quickstart.mdx). - -The Stylus Rust SDK is built on top of [Alloy](https://www.paradigm.xyz/2023/06/alloy), a collection of crates empowering the Rust Ethereum ecosystem. Because the SDK uses the same [Rust primitives for Ethereum types](https://docs.rs/alloy-primitives/latest/alloy_primitives/), Stylus is compatible with existing Rust libraries. - -The Stylus Rust SDK has been audited in August 2024 at [commit #62bd831](https://github.com/OffchainLabs/stylus-sdk-rs/tree/62bd8318c7f3ab5be954cbc264f85bf2ba3f4b06) by Open Zeppelin which can be viewed [on our audits page](audit-reports.mdx). - -## Documentation index - -Use this index to navigate the Stylus Rust SDK reference documentation. - -### Fundamentals - -Learn the core concepts of writing smart contracts with the Stylus Rust SDK. - -| Article | Description | -| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| [Structure of a contract](/stylus/reference/project-structure) | Understand how Rust contracts are organized, including project layout, the entrypoint macro, and public methods. | -| [Global variables and functions](/stylus/reference/global-variables-and-functions) | Access blockchain context through the VM interface, including message sender, block info, and cryptographic functions. | -| [Contracts](/stylus/reference/contracts) | Learn about contract basics, storage definition, method declarations, and the contract lifecycle. | -| [Writing tests](/stylus/how-tos/testing-contracts) | Write and run tests for your contracts using the built-in testing framework without deploying to a blockchain. | - -### Data types - -Understand how to work with different data types in Stylus contracts. - -| Article | Description | -| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -| [Primitives](/stylus/reference/data-types/primitives) | Use Rust primitive types (bool, integers, addresses) with automatic ABI encoding and Solidity type mappings. | -| [Compound types](/stylus/reference/data-types/compound-types) | Work with complex data structures including arrays, vectors, tuples, and custom structs. | -| [Storage](/stylus/reference/data-types/storage) | Define and manage persistent contract state using storage types and the storage macro. | -| [Conversions between types](/stylus/reference/data-types/conversions-between-types) | Convert between Rust types and Solidity-compatible types for cross-contract communication. | - -### Advanced topics - -Explore advanced features and optimization techniques for Stylus development. - -| Article | Description | -| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| [Solidity differences](/stylus/advanced/solidity-differences) | Understand key differences between writing smart contracts in Solidity versus Stylus Rust. | -| [Recommended packages](/stylus/advanced/recommended-libraries) | Discover third-party Rust crates that work well with Stylus for extended functionality. | -| [Minimal entrypoint contracts](/stylus/advanced/minimal-entrypoint-contracts) | Build lightweight contracts with custom entrypoints for maximum gas efficiency. | -| [Hostio exports](/stylus/advanced/hostio-exports) | Access low-level host I/O functions for advanced contract behavior. | - -### Using the CLI - -Master the `cargo stylus` command-line tool for contract development and deployment. - -| Article | Description | -| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -| [Verify contracts](/stylus/how-tos/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | -| [Exporting ABI](/stylus/how-tos/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | -| [Debugging with replay](/stylus/how-tos/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | -| [Optimizing WASM binary size](/stylus/how-tos/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | -| [Deploying non-Rust WASM contracts](/stylus/how-tos/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | - -### WASM concepts - -Understand how WebAssembly works within Arbitrum Nitro and its implications for Stylus development. - -| Article | Description | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | -| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | -| [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | -| [Caching strategy](/stylus/how-tos/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | - -### Troubleshooting - -| Article | Description | -| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------- | -| [Troubleshooting](/stylus/troubleshooting-building-stylus) | Find solutions to common issues encountered when building and deploying Stylus contracts. | - -### External references - -Additional resources for Stylus development. - -| Resource | Description | -| ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | -| [Stylus by Example](https://stylus-by-example.org/) | Learn Stylus through practical, annotated code examples covering common patterns. | -| [Cargo Stylus CLI GitHub](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) | Source code and documentation for the `cargo stylus` command-line tool. | -| [Rust SDK Crate](https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html) | Official API documentation for the Stylus SDK on docs.rs. | -| [Source Code Repository](https://github.com/OffchainLabs/stylus-sdk-rs) | Browse the complete source code for the Stylus Rust SDK. | diff --git a/scripts/restructure/frontmatter-audit.sh b/scripts/restructure/frontmatter-audit.sh new file mode 100755 index 0000000000..04cc34b817 --- /dev/null +++ b/scripts/restructure/frontmatter-audit.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +echo "=== Frontmatter Audit ===" +echo "" + +missing_user_story=() +missing_content_type=() + +# Check all .mdx and .md files in stylus directory (exclude partials and implementation guides) +for file in $(find docs/stylus -name "*.mdx" -o -name "*.md" | grep -v "partials" | grep -v "IMPLEMENTATION_GUIDE" | grep -v "RESTRUCTURE_README"); do + # Check for user_story + if ! grep -q "user_story:" "$file"; then + missing_user_story+=("$file") + fi + + # Check for content_type + if ! grep -q "content_type:" "$file"; then + missing_content_type+=("$file") + fi +done + +echo "Files missing user_story:" +printf '%s\n' "${missing_user_story[@]}" +echo "" +echo "Total: ${#missing_user_story[@]}" +echo "" + +echo "Files missing content_type:" +printf '%s\n' "${missing_content_type[@]}" +echo "" +echo "Total: ${#missing_content_type[@]}" +echo "" + +if [ ${#missing_user_story[@]} -eq 0 ] && [ ${#missing_content_type[@]} -eq 0 ]; then + echo "โœ… All files have complete frontmatter!" + exit 0 +else + echo "โŒ Some files missing frontmatter fields" + exit 1 +fi diff --git a/scripts/restructure/terminology-audit.sh b/scripts/restructure/terminology-audit.sh new file mode 100755 index 0000000000..a0be4ca798 --- /dev/null +++ b/scripts/restructure/terminology-audit.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +echo "=== Stylus Terminology Audit ===" +echo "" + +violations=0 + +# Check for "js" instead of "JavaScript" (excluding .js file extensions, ts.js, etc.) +echo "Checking for 'js' (should be 'JavaScript')..." +results=$(grep -rn '\bjs\b' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null | grep -v "\.js" | grep -v "ts\.js" | grep -v "js/" | grep -v "jsx" || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "smartcontract" instead of "smart contract" +echo "" +echo "Checking for 'smartcontract' (should be 'smart contract')..." +results=$(grep -rin 'smartcontract' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "whitelist/blacklist" instead of "allowlist/denylist" +echo "" +echo "Checking for 'whitelist/blacklist' (should be 'allowlist/denylist')..." +results=$(grep -rin 'whitelist\|blacklist' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "on-chain" instead of "onchain" +echo "" +echo "Checking for 'on-chain/on chain' (should be 'onchain')..." +results=$(grep -rn 'on-chain\|on chain' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "ERC20" instead of "ERC-20" +echo "" +echo "Checking for 'ERC20/ERC721' (should be 'ERC-20/ERC-721')..." +results=$(grep -rn 'ERC20\|ERC721\|ERC1155' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null | grep -v "ERC-" || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "Layer-1/L1" instead of "Parent chain" +echo "" +echo "Checking for 'Layer-1/L1/layer 1' (should be 'Parent chain')..." +results=$(grep -rin 'Layer-1\|Layer 1\|\bL1\b' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +# Check for "Layer-2/L2" instead of "Child chain" +echo "" +echo "Checking for 'Layer-2/L2/layer 2' (should be 'Child chain')..." +results=$(grep -rin 'Layer-2\|Layer 2\|\bL2\b' docs/stylus/ --include="*.mdx" --include="*.md" 2>/dev/null || true) +if [ ! -z "$results" ]; then + echo "$results" + violations=$((violations + 1)) +fi + +echo "" +echo "=== Audit Complete ===" +echo "Total violation types found: $violations" +echo "" + +if [ $violations -eq 0 ]; then + echo "โœ… No terminology violations found!" + exit 0 +else + echo "โŒ Terminology violations found. Please fix manually." + exit 1 +fi From 78e6aad4457807648e389ee2d1db0fc5ac9544a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 19:54:44 -0800 Subject: [PATCH 108/162] docs(stylus): Phase 2 - Directory Restructure - Create 5 new top-level directories (fundamentals, guides, cli-tools, best-practices, troubleshooting) - Move SDK basics to fundamentals/ (project-structure, contracts, data-types, testing) - Rename how-tos/ to guides/ and flatten structure - Create cli-tools/ section with overview and commands reference - Update sidebars.js to max 3-level depth with flatter navigation - Update all imports for moved files - Remove empty how-tos directory Files modified: 8 Files renamed: 19 New directories: 5 Sidebar depth: Reduced from 4+ to 3 levels --- .../advanced/minimal-entrypoint-contracts.mdx | 6 +- docs/stylus/best-practices/_category_.yml | 5 + docs/stylus/cli-tools/_category_.yml | 5 + .../check-and-deploy.mdx | 2 +- docs/stylus/cli-tools/commands-reference.mdx | 260 +++ .../{how-tos => cli-tools}/debugging-tx.mdx | 0 docs/stylus/cli-tools/overview.mdx | 131 ++ .../verify-contracts.mdx} | 2 +- docs/stylus/concepts/activation.mdx | 4 +- docs/stylus/concepts/gas-metering.mdx | 2 +- docs/stylus/fundamentals/_category_.yml | 6 + .../{reference => fundamentals}/contracts.mdx | 0 .../data-types/compound-types.mdx | 0 .../data-types/conversions-between-types.mdx | 0 .../data-types/primitives.mdx | 0 .../data-types/storage.mdx | 0 .../global-variables-and-functions.mdx | 0 .../project-structure.mdx | 0 .../testing-contracts.mdx | 0 docs/stylus/gentle-introduction.mdx | 2 +- docs/stylus/guides/_category_.yml | 5 + .../adding-support-for-new-languages.mdx | 0 .../{how-tos => guides}/caching-contracts.mdx | 0 .../deploying-non-rust-wasm-contracts.mdx | 0 .../{how-tos => guides}/exporting-abi.mdx | 0 .../importing-interfaces.mdx | 2 +- .../optimizing-binaries.mdx | 0 .../using-constructors.mdx | 0 .../{how-tos => guides}/using-inheritance.mdx | 0 docs/stylus/how-tos/_category_.yml | 4 - docs/stylus/quickstart.mdx | 2 +- docs/stylus/reference/overview.mdx | 50 +- docs/stylus/troubleshooting/_category_.yml | 5 + docs/stylus/using-cli.mdx | 6 +- scripts/restructure/update-imports-phase2.sh | 33 + sidebars.js | 276 ++- sidebars.js.backup | 1809 +++++++++++++++++ vercel.json | 100 + 38 files changed, 2562 insertions(+), 155 deletions(-) create mode 100644 docs/stylus/best-practices/_category_.yml create mode 100644 docs/stylus/cli-tools/_category_.yml rename docs/stylus/{how-tos => cli-tools}/check-and-deploy.mdx (99%) create mode 100644 docs/stylus/cli-tools/commands-reference.mdx rename docs/stylus/{how-tos => cli-tools}/debugging-tx.mdx (100%) create mode 100644 docs/stylus/cli-tools/overview.mdx rename docs/stylus/{how-tos/verifying-contracts.mdx => cli-tools/verify-contracts.mdx} (99%) create mode 100644 docs/stylus/fundamentals/_category_.yml rename docs/stylus/{reference => fundamentals}/contracts.mdx (100%) rename docs/stylus/{reference => fundamentals}/data-types/compound-types.mdx (100%) rename docs/stylus/{reference => fundamentals}/data-types/conversions-between-types.mdx (100%) rename docs/stylus/{reference => fundamentals}/data-types/primitives.mdx (100%) rename docs/stylus/{reference => fundamentals}/data-types/storage.mdx (100%) rename docs/stylus/{reference => fundamentals}/global-variables-and-functions.mdx (100%) rename docs/stylus/{reference => fundamentals}/project-structure.mdx (100%) rename docs/stylus/{how-tos => fundamentals}/testing-contracts.mdx (100%) create mode 100644 docs/stylus/guides/_category_.yml rename docs/stylus/{how-tos => guides}/adding-support-for-new-languages.mdx (100%) rename docs/stylus/{how-tos => guides}/caching-contracts.mdx (100%) rename docs/stylus/{how-tos => guides}/deploying-non-rust-wasm-contracts.mdx (100%) rename docs/stylus/{how-tos => guides}/exporting-abi.mdx (100%) rename docs/stylus/{how-tos => guides}/importing-interfaces.mdx (99%) rename docs/stylus/{how-tos => guides}/optimizing-binaries.mdx (100%) rename docs/stylus/{how-tos => guides}/using-constructors.mdx (100%) rename docs/stylus/{how-tos => guides}/using-inheritance.mdx (100%) delete mode 100644 docs/stylus/how-tos/_category_.yml create mode 100644 docs/stylus/troubleshooting/_category_.yml create mode 100755 scripts/restructure/update-imports-phase2.sh create mode 100644 sidebars.js.backup diff --git a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx index d3d530ba7f..2168b20094 100644 --- a/docs/stylus/advanced/minimal-entrypoint-contracts.mdx +++ b/docs/stylus/advanced/minimal-entrypoint-contracts.mdx @@ -639,6 +639,6 @@ fn test_selectors() { ## See Also -- [Contracts](../reference/contracts.mdx) - High-level contract development -- [Global Variables](../reference/global-variables-and-functions.mdx) - VM context methods -- [Storage Types](../reference/data-types/storage.mdx) - Persistent storage +- [Contracts](../fundamentals/contracts.mdx) - High-level contract development +- [Global Variables](../fundamentals/global-variables-and-functions.mdx) - VM context methods +- [Storage Types](../fundamentals/data-types/storage.mdx) - Persistent storage diff --git a/docs/stylus/best-practices/_category_.yml b/docs/stylus/best-practices/_category_.yml new file mode 100644 index 0000000000..401b1ad018 --- /dev/null +++ b/docs/stylus/best-practices/_category_.yml @@ -0,0 +1,5 @@ +label: 'Best practices' +position: 6 +link: + type: generated-index + description: Security, performance, and gas optimization patterns for production Stylus contracts. diff --git a/docs/stylus/cli-tools/_category_.yml b/docs/stylus/cli-tools/_category_.yml new file mode 100644 index 0000000000..5a13bee5be --- /dev/null +++ b/docs/stylus/cli-tools/_category_.yml @@ -0,0 +1,5 @@ +label: 'CLI tools' +position: 4 +link: + type: generated-index + description: cargo-stylus command-line tools for building, deploying, and verifying contracts. diff --git a/docs/stylus/how-tos/check-and-deploy.mdx b/docs/stylus/cli-tools/check-and-deploy.mdx similarity index 99% rename from docs/stylus/how-tos/check-and-deploy.mdx rename to docs/stylus/cli-tools/check-and-deploy.mdx index aa60343b78..b4c419ba60 100644 --- a/docs/stylus/how-tos/check-and-deploy.mdx +++ b/docs/stylus/cli-tools/check-and-deploy.mdx @@ -774,6 +774,6 @@ cargo stylus activate --address=
    [OPTIONS] - [Stylus quickstart guide](https://docs.arbitrum.io/stylus/stylus-quickstart) - [Cargo Stylus repository](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) - [Testnet information](https://docs.arbitrum.io/stylus/reference/testnet-information) -- [Contract verification guide](https://docs.arbitrum.io/stylus/how-tos/verifying-contracts) +- [Contract verification guide](https://docs.arbitrum.io/stylus/guides/verifying-contracts) - [Optimizing WASM size](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/OPTIMIZING_BINARIES.md) - [Valid WASM requirements](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/VALID_WASM.md) diff --git a/docs/stylus/cli-tools/commands-reference.mdx b/docs/stylus/cli-tools/commands-reference.mdx new file mode 100644 index 0000000000..6393cd52fd --- /dev/null +++ b/docs/stylus/cli-tools/commands-reference.mdx @@ -0,0 +1,260 @@ +--- +title: 'cargo-stylus command reference' +sidebar_label: 'Commands reference' +description: 'Complete reference for all cargo-stylus CLI commands' +user_story: 'As a Stylus developer, I want a complete reference of all CLI commands' +content_type: reference +author: offchainlabs +sme: offchainlabs +sidebar_position: 5 +--- + +# cargo-stylus command reference + +Complete reference for all `cargo-stylus` commands. + +## new + +Create a new Stylus project. + +**Usage:** + +```shell +cargo stylus new +``` + +**Options:** + +- `--minimal` - Create minimal project structure + +**Example:** + +```shell +cargo stylus new my-stylus-contract +``` + +## init + +Initialize a Stylus project in the current directory. + +**Usage:** + +```shell +cargo stylus init +``` + +**Options:** + +- `--minimal` - Create minimal project structure + +## check + +Verify a contract compiles to valid WASM and passes onchain activation checks. + +**Usage:** + +```shell +cargo stylus check +``` + +**Options:** + +- `--endpoint ` - RPC endpoint (default: http://localhost:8547) +- `--wasm-file ` - WASM file to check (defaults to any found in current directory) +- `--contract-address
    ` - Optional deployment address + +**Example:** + +```shell +cargo stylus check --endpoint https://sepolia-rollup.arbitrum.io/rpc +``` + +## deploy + +Deploy a Stylus contract. + +**Usage:** + +```shell +cargo stylus deploy \ + --endpoint \ + --private-key +``` + +**Options:** + +- `--endpoint ` - RPC endpoint (required) +- `--private-key ` - Private key for deployment (required) +- `--contract-address
    ` - Specific deployment address (defaults to random) +- `--estimate-gas` - Estimate gas only, don't deploy +- `--no-verify` - Skip reproducible container verification +- `--wasm-file ` - WASM file to deploy +- `--max-fee-per-gas-gwei ` - Optional max fee per gas + +**Example:** + +```shell +cargo stylus deploy \ + --endpoint https://sepolia-rollup.arbitrum.io/rpc \ + --private-key $PRIVATE_KEY \ + --estimate-gas +``` + +## activate + +Activate an already deployed contract. + +**Usage:** + +```shell +cargo stylus activate \ + --endpoint \ + --private-key \ + --address +``` + +**Options:** + +- `--endpoint ` - RPC endpoint (required) +- `--private-key ` - Private key for activation (required) +- `--address
    ` - Contract address to activate (required) +- `--data-fee-bump-percent ` - Percent to bump estimated fee (default: 20%) +- `--estimate-gas` - Only estimate gas without sending transaction + +## verify + +Verify the deployment of a Stylus contract. + +**Usage:** + +```shell +cargo stylus verify \ + --deployment-tx +``` + +**Options:** + +- `--endpoint ` - RPC endpoint +- `--deployment-tx ` - Deployment transaction hash (required) +- `--no-verify` - Skip reproducible container +- `--cargo-stylus-version ` - Version for Docker image + +**Example:** + +```shell +cargo stylus verify --deployment-tx 0xd4...85 +``` + +## cache + +Manage contract caching using the Stylus CacheManager. + +**Usage:** + +```shell +# Place a bid on a contract +cargo stylus cache bid --address
    + +# Check contract cache status +cargo stylus cache status --address
    + +# Get suggested minimum bid +cargo stylus cache suggest-bid --address
    +``` + +**Options:** + +- `--address
    ` - Contract address (required) +- `--endpoint ` - RPC endpoint + +## export-abi + +Export a Solidity ABI interface. + +**Usage:** + +```shell +cargo stylus export-abi +``` + +**Options:** + +- `--output ` - Output file (defaults to stdout) +- `--json` - Write JSON ABI using solc format + +**Example:** + +```shell +cargo stylus export-abi > IMyContract.sol +cargo stylus export-abi --json > abi.json +``` + +## cgen + +Generate C code bindings for a Stylus contract. + +**Usage:** + +```shell +cargo stylus cgen \ + --input \ + --out-dir +``` + +**Options:** + +- `--input ` - Input file path (required) +- `--out-dir ` - Output directory path (required) + +## replay + +Replay a transaction in GDB for debugging. + +**Usage:** + +```shell +cargo stylus replay --tx +``` + +**Options:** + +- `--tx ` - Transaction hash to replay (required) +- `--endpoint ` - RPC endpoint +- `--project ` - Project path (default: current directory) +- `--use-native-tracer` - Use native tracer instead of JavaScript +- `--stable-rust` - Use stable Rust (note: nightly needed to expand macros) + +## trace + +Trace a transaction. + +**Usage:** + +```shell +cargo stylus trace --tx +``` + +**Options:** + +- `--tx ` - Transaction hash (required) +- `--endpoint ` - RPC endpoint +- `--project ` - Project path +- `--use-native-tracer` - Use native tracer + +--- + +## Common options + +These options are available across multiple commands: + +| Option | Description | +| ------------------------ | --------------------------------------------- | +| `--endpoint ` | RPC endpoint URL | +| `--private-key ` | Private key for transactions | +| `--estimate-gas` | Estimate gas without sending transaction | +| `--no-verify` | Skip reproducible container verification | +| `--cargo-stylus-version` | Specify cargo-stylus version for Docker image | + +--- + +For detailed usage examples, see the [CLI tools guides](/stylus/cli-tools/overview). diff --git a/docs/stylus/how-tos/debugging-tx.mdx b/docs/stylus/cli-tools/debugging-tx.mdx similarity index 100% rename from docs/stylus/how-tos/debugging-tx.mdx rename to docs/stylus/cli-tools/debugging-tx.mdx diff --git a/docs/stylus/cli-tools/overview.mdx b/docs/stylus/cli-tools/overview.mdx new file mode 100644 index 0000000000..333b53f92e --- /dev/null +++ b/docs/stylus/cli-tools/overview.mdx @@ -0,0 +1,131 @@ +--- +id: using-cli +title: 'Using Stylus CLI' +description: 'Get started with Stylus CLI, a Rust toolkit for developing Stylus contracts' +author: 'anegg0' +sme: 'anegg0' +sidebar_position: 2 +target_audience: Developers writing Stylus contracts in Rust using Stylus +displayed_sidebar: buildStylusSidebar +--- + +This guide will get you started using [cargo stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus), a CLI toolkit to help developers manage, compile, deploy, and optimize their Stylus contracts efficiently. + +This overview will help you discover and learn how to uses cargo stylus tools. + +### Installing cargo stylus + +Cargo stylus is a plugin to the standard cargo tool for developing Rust programs. + +#### Prerequisites + +
    +Rust toolchain + +Follow the instructions on [Rust Lang's installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain (v1.81 or newer) on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. + +
    + +
    +Docker + +We will use the testnet, and some `cargo stylus` commands will require Docker to operate. + +You can download Docker from [Docker's website](https://www.docker.com/products/docker-desktop). + +
    + +
    +Foundry's Cast + +[Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool for interacting with your EVM contracts. + +
    + +
    +Nitro devnode + +Stylus is available on Arbitrum Sepolia, but we'll use Nitro devnode, which has a pre-funded wallet, saving us the effort of wallet provisioning or running out of tokens to send transactions. + +```shell title="Install your devnode" +git clone https://github.com/OffchainLabs/nitro-devnode.git +cd nitro-devnode +``` + +```shell title="Launch your devnode" +./run-dev-node.sh +``` + +
    + +#### Installation + +In your terminal, run: + +```shell +cargo install --force cargo-stylus +``` + +Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: + +```shell +rustup default 1.80 +rustup target add wasm32-unknown-unknown --toolchain 1.80 +``` + +You can verify the cargo stylus installation by running `cargo stylus -V` in your terminal, returning something like:`stylus 0.5.6` + +### Using cargo stylus + +#### Cargo Stylus Commands Reference + +| Command | Description | Arguments | Options | Example Usage | +| ------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- | +| `new` | Create a new Stylus project | โ€ข `name`: Project name (required) | โ€ข `--minimal`: Create a minimal contract | `cargo stylus new ` | +| `init` | Initialize a Stylus project in current directory | | โ€ข `--minimal`: Create a minimal contract | `cargo stylus init --minimal` | +| `export-abi` | Export a Solidity ABI | | โ€ข `--output`: Output file (defaults to stdout)
    โ€ข `--json`: Write JSON ABI using `solc` | `cargo stylus export-abi --json` | +| `activate` | Activate an already deployed contract | โ€ข `--address`: Contract address to activate | โ€ข `--data-fee-bump-percent`: Percent to bump estimated fee (default 20%)
    โ€ข `--estimate-gas`: Only estimate gas without sending transaction | `cargo stylus activate --address ` | +| `cache` | Cache contract using Stylus CacheManager | โ€ข `bid`: Place bid on contract
    โ€ข `status`: Check contract status
    โ€ข `suggest-bid`: Get suggested minimum bid | | `cargo stylus cache bid --address ` | +| `check` | Check a contract | | โ€ข `--wasm-file`: WASM file to check
    โ€ข `--contract-address`: Deployment address | | +| `deploy` | Deploy a contract | โ€ข `--contract-address `: Where to deploy and activate the contract (defaults to a random address) | โ€ข `--estimate-gas`: Only perform estimation
    โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image
    โ€ข `--source-files-for-project-hash `: Path to source files to include in the project hash
    โ€ข `--max-fee-per-gas-gwei `: Optional max fee per gas in `gwei` units
    โ€ข `--wasm-file `: The WASM file to check (defaults to any found in the current directory) | `cargo stylus deploy --endpoint='http://localhost:8547' --private-key="" --estimate-gas` | +| `verify` | Verify contract deployment | โ€ข `--deployment-tx`: Hash of deployment transaction | โ€ข `--no-verify`: Skip reproducible container
    โ€ข `--cargo-stylus-version`: Version for Docker image | | +| `cgen` | Generate C code bindings | โ€ข `--input`: Input file path
    โ€ข `--out_dir`: Output directory path | | | +| `replay` | Replay transaction in GDB | โ€ข `-t, --tx `: Transaction to replay | โ€ข `-p, --project `: Project path (default: `.`)
    โ€ข `-u, --use-native-tracer`: Use the native tracer instead of the JavaScript one (may not be available in the node)
    โ€ข `-s, --stable-rust`: Use stable Rust (note that nightly is needed to expand macros) | `cargo stylus replay --tx ` | +| `trace` | Trace a transaction | โ€ข `--tx`: Transaction hash | โ€ข `--endpoint`: RPC endpoint
    โ€ข `--project`: Project path
    โ€ข `--use-native-tracer`: Use native tracer | | + +##### Common options + +These options are available across multiple commands: + +| Option | Description | +| ------------------------------- | ------------------------------------------------------ | +| --endpoint | Arbitrum RPC endpoint (default: http://localhost:8547) | +| --verbose | Print debug info | +| --source-files-for-project-hash | Paths to source files for project hash | +| --max-fee-per-gas-gwei | Optional max fee per gas in `gwei` | + +##### Authentication options + +Available for commands involving transactions: + +| Option | Description | +| ------------------------ | ---------------------------------------------------- | +| --private-key-path | Path to file containing hex-encoded private key | +| --private-key | Private key as hex string (exposes to shell history) | +| --keystore-path | Path to Ethereum wallet keystore file | +| --keystore-password-path | Keystore password file path | + +#### How-tos + +| Topic | Description | +| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/guides/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/guides/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | + +#### Additional resources + +#### [Troubleshooting](/stylus/troubleshooting-building-stylus.md): solve the most common issues. + +#### [cargo-stylus repository](https://github.com/OffchainLabs/stylus): consult cargo stylus' source code. diff --git a/docs/stylus/how-tos/verifying-contracts.mdx b/docs/stylus/cli-tools/verify-contracts.mdx similarity index 99% rename from docs/stylus/how-tos/verifying-contracts.mdx rename to docs/stylus/cli-tools/verify-contracts.mdx index 6add9b41a1..fafd7d2f85 100644 --- a/docs/stylus/how-tos/verifying-contracts.mdx +++ b/docs/stylus/cli-tools/verify-contracts.mdx @@ -266,5 +266,5 @@ Ensure: ## Next steps - [Learn about deployment](./check-and-deploy.mdx) -- [Explore CLI tools](../using-cli.mdx) +- [Explore CLI tools](./overview.mdx) - [View verified examples](https://github.com/OffchainLabs/stylus-by-example) diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index 4629075175..4f3efd68fd 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -783,7 +783,7 @@ cast send 0x0000000000000000000000000000000000000072 \ ## See Also -- [Contracts](../reference/contracts.mdx) - Writing Stylus contracts -- [Global Variables and Functions](../reference/global-variables-and-functions.mdx) - VM interface methods +- [Contracts](../fundamentals/contracts.mdx) - Writing Stylus contracts +- [Global Variables and Functions](../fundamentals/global-variables-and-functions.mdx) - VM interface methods diff --git a/docs/stylus/concepts/gas-metering.mdx b/docs/stylus/concepts/gas-metering.mdx index c10a902f0d..99574f34a5 100644 --- a/docs/stylus/concepts/gas-metering.mdx +++ b/docs/stylus/concepts/gas-metering.mdx @@ -76,4 +76,4 @@ However, developers optimizing contracts may choose to measure performance in in ### See also - [Gas and ink costs](/stylus/reference/opcode-hostio-pricing): Detailed costs per opcode and host I/O -- [Caching strategy](/stylus/how-tos/caching-contracts): Description of the Stylus caching strategy and the `CacheManager` contract +- [Caching strategy](/stylus/guides/caching-contracts): Description of the Stylus caching strategy and the `CacheManager` contract diff --git a/docs/stylus/fundamentals/_category_.yml b/docs/stylus/fundamentals/_category_.yml new file mode 100644 index 0000000000..09fabd7c58 --- /dev/null +++ b/docs/stylus/fundamentals/_category_.yml @@ -0,0 +1,6 @@ +label: 'Fundamentals' +position: 2 +collapsed: false +link: + type: generated-index + description: Essential Stylus SDK concepts, prerequisites, and core development skills. diff --git a/docs/stylus/reference/contracts.mdx b/docs/stylus/fundamentals/contracts.mdx similarity index 100% rename from docs/stylus/reference/contracts.mdx rename to docs/stylus/fundamentals/contracts.mdx diff --git a/docs/stylus/reference/data-types/compound-types.mdx b/docs/stylus/fundamentals/data-types/compound-types.mdx similarity index 100% rename from docs/stylus/reference/data-types/compound-types.mdx rename to docs/stylus/fundamentals/data-types/compound-types.mdx diff --git a/docs/stylus/reference/data-types/conversions-between-types.mdx b/docs/stylus/fundamentals/data-types/conversions-between-types.mdx similarity index 100% rename from docs/stylus/reference/data-types/conversions-between-types.mdx rename to docs/stylus/fundamentals/data-types/conversions-between-types.mdx diff --git a/docs/stylus/reference/data-types/primitives.mdx b/docs/stylus/fundamentals/data-types/primitives.mdx similarity index 100% rename from docs/stylus/reference/data-types/primitives.mdx rename to docs/stylus/fundamentals/data-types/primitives.mdx diff --git a/docs/stylus/reference/data-types/storage.mdx b/docs/stylus/fundamentals/data-types/storage.mdx similarity index 100% rename from docs/stylus/reference/data-types/storage.mdx rename to docs/stylus/fundamentals/data-types/storage.mdx diff --git a/docs/stylus/reference/global-variables-and-functions.mdx b/docs/stylus/fundamentals/global-variables-and-functions.mdx similarity index 100% rename from docs/stylus/reference/global-variables-and-functions.mdx rename to docs/stylus/fundamentals/global-variables-and-functions.mdx diff --git a/docs/stylus/reference/project-structure.mdx b/docs/stylus/fundamentals/project-structure.mdx similarity index 100% rename from docs/stylus/reference/project-structure.mdx rename to docs/stylus/fundamentals/project-structure.mdx diff --git a/docs/stylus/how-tos/testing-contracts.mdx b/docs/stylus/fundamentals/testing-contracts.mdx similarity index 100% rename from docs/stylus/how-tos/testing-contracts.mdx rename to docs/stylus/fundamentals/testing-contracts.mdx diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 791021f362..c583e2daab 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -48,7 +48,7 @@ To make your contract callable, it must undergo an activation process. During ac Stylus measures computational costs using ink instead of gas. Ink works like gas but is thousands of times smaller. WASM executes faster than the EVM, so a single EVM operation takes as long as thousands of WASM operations. A finer-grained unit makes pricing more precise. :::note -Stylus contracts need to be reactivated once per year (365 days) or after any Stylus upgrade. You can do this using [`cargo-stylus`](/stylus/using-cli.mdx#cargo-stylus-commands-reference) or the [ArbWasm precompile](/build-decentralized-apps/precompiles/reference#common-precompiles). If a contract isn't reactivated, it becomes uncallable. +Stylus contracts need to be reactivated once per year (365 days) or after any Stylus upgrade. You can do this using [`cargo-stylus`](/stylus/cli-tools/commands-reference) or the [ArbWasm precompile](/build-decentralized-apps/precompiles/reference#common-precompiles). If a contract isn't reactivated, it becomes uncallable. ::: #### Execution diff --git a/docs/stylus/guides/_category_.yml b/docs/stylus/guides/_category_.yml new file mode 100644 index 0000000000..451487c28c --- /dev/null +++ b/docs/stylus/guides/_category_.yml @@ -0,0 +1,5 @@ +label: 'Guides' +position: 3 +link: + type: generated-index + description: Practical guides for common Stylus development tasks. diff --git a/docs/stylus/how-tos/adding-support-for-new-languages.mdx b/docs/stylus/guides/adding-support-for-new-languages.mdx similarity index 100% rename from docs/stylus/how-tos/adding-support-for-new-languages.mdx rename to docs/stylus/guides/adding-support-for-new-languages.mdx diff --git a/docs/stylus/how-tos/caching-contracts.mdx b/docs/stylus/guides/caching-contracts.mdx similarity index 100% rename from docs/stylus/how-tos/caching-contracts.mdx rename to docs/stylus/guides/caching-contracts.mdx diff --git a/docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx similarity index 100% rename from docs/stylus/how-tos/deploying-non-rust-wasm-contracts.mdx rename to docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx diff --git a/docs/stylus/how-tos/exporting-abi.mdx b/docs/stylus/guides/exporting-abi.mdx similarity index 100% rename from docs/stylus/how-tos/exporting-abi.mdx rename to docs/stylus/guides/exporting-abi.mdx diff --git a/docs/stylus/how-tos/importing-interfaces.mdx b/docs/stylus/guides/importing-interfaces.mdx similarity index 99% rename from docs/stylus/how-tos/importing-interfaces.mdx rename to docs/stylus/guides/importing-interfaces.mdx index bffbdd6e94..3baaed8ea3 100644 --- a/docs/stylus/how-tos/importing-interfaces.mdx +++ b/docs/stylus/guides/importing-interfaces.mdx @@ -651,6 +651,6 @@ let balance = token.balance_of(self.vm(), config, account); ## See also -- [Stylus contracts reference](../reference/contracts.mdx#external-contract-calls): Detailed reference for external contract calls +- [Stylus contracts reference](../fundamentals/contracts.mdx#external-contract-calls): Detailed reference for external contract calls - [Stylus by Example: Import interfaces](https://stylus-by-example.org/basic_examples/import_interfaces): Interactive examples - [Stylus SDK documentation](https://docs.rs/stylus-sdk/latest/stylus_sdk/): Complete API reference diff --git a/docs/stylus/how-tos/optimizing-binaries.mdx b/docs/stylus/guides/optimizing-binaries.mdx similarity index 100% rename from docs/stylus/how-tos/optimizing-binaries.mdx rename to docs/stylus/guides/optimizing-binaries.mdx diff --git a/docs/stylus/how-tos/using-constructors.mdx b/docs/stylus/guides/using-constructors.mdx similarity index 100% rename from docs/stylus/how-tos/using-constructors.mdx rename to docs/stylus/guides/using-constructors.mdx diff --git a/docs/stylus/how-tos/using-inheritance.mdx b/docs/stylus/guides/using-inheritance.mdx similarity index 100% rename from docs/stylus/how-tos/using-inheritance.mdx rename to docs/stylus/guides/using-inheritance.mdx diff --git a/docs/stylus/how-tos/_category_.yml b/docs/stylus/how-tos/_category_.yml deleted file mode 100644 index 90914ee903..0000000000 --- a/docs/stylus/how-tos/_category_.yml +++ /dev/null @@ -1,4 +0,0 @@ -label: 'How-tos' -collapsible: true -collapsed: true -position: 4 diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index e3fc2da748..445db38a13 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -403,7 +403,7 @@ The testing framework allows you to: - Mock contract-to-contract interactions - Test various scenarios without deployment costs -For more advanced testing techniques and best practices, see the [Testing contracts with Stylus guide](./how-tos/testing-contracts). +For more advanced testing techniques and best practices, see the [Testing contracts with Stylus guide](./fundamentals/testing-contracts). ## Conclusion diff --git a/docs/stylus/reference/overview.mdx b/docs/stylus/reference/overview.mdx index aa6c9400b7..44fd8f15de 100644 --- a/docs/stylus/reference/overview.mdx +++ b/docs/stylus/reference/overview.mdx @@ -24,23 +24,23 @@ Use this index to navigate the Stylus Rust SDK reference documentation. Learn the core concepts of writing smart contracts with the Stylus Rust SDK. -| Article | Description | -| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -| [Structure of a contract](/stylus/reference/project-structure) | Understand how Rust contracts are organized, including project layout, the entrypoint macro, and public methods. | -| [Global variables and functions](/stylus/reference/global-variables-and-functions) | Access blockchain context through the VM interface, including message sender, block info, and cryptographic functions. | -| [Contracts](/stylus/reference/contracts) | Learn about contract basics, storage definition, method declarations, and the contract lifecycle. | -| [Writing tests](/stylus/how-tos/testing-contracts) | Write and run tests for your contracts using the built-in testing framework without deploying to a blockchain. | +| Article | Description | +| ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| [Structure of a contract](/stylus/fundamentals/project-structure) | Understand how Rust contracts are organized, including project layout, the entrypoint macro, and public methods. | +| [Global variables and functions](/stylus/fundamentals/global-variables-and-functions) | Access blockchain context through the VM interface, including message sender, block info, and cryptographic functions. | +| [Contracts](/stylus/fundamentals/contracts) | Learn about contract basics, storage definition, method declarations, and the contract lifecycle. | +| [Writing tests](/stylus/fundamentals/testing-contracts) | Write and run tests for your contracts using the built-in testing framework without deploying to a blockchain. | ### Data types Understand how to work with different data types in Stylus contracts. -| Article | Description | -| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | -| [Primitives](/stylus/reference/data-types/primitives) | Use Rust primitive types (bool, integers, addresses) with automatic ABI encoding and Solidity type mappings. | -| [Compound types](/stylus/reference/data-types/compound-types) | Work with complex data structures including arrays, vectors, tuples, and custom structs. | -| [Storage](/stylus/reference/data-types/storage) | Define and manage persistent contract state using storage types and the storage macro. | -| [Conversions between types](/stylus/reference/data-types/conversions-between-types) | Convert between Rust types and Solidity-compatible types for cross-contract communication. | +| Article | Description | +| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| [Primitives](/stylus/fundamentals/data-types/primitives) | Use Rust primitive types (bool, integers, addresses) with automatic ABI encoding and Solidity type mappings. | +| [Compound types](/stylus/fundamentals/data-types/compound-types) | Work with complex data structures including arrays, vectors, tuples, and custom structs. | +| [Storage](/stylus/fundamentals/data-types/storage) | Define and manage persistent contract state using storage types and the storage macro. | +| [Conversions between types](/stylus/fundamentals/data-types/conversions-between-types) | Convert between Rust types and Solidity-compatible types for cross-contract communication. | ### Advanced topics @@ -57,24 +57,24 @@ Explore advanced features and optimization techniques for Stylus development. Master the `cargo stylus` command-line tool for contract development and deployment. -| Article | Description | -| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -| [Verify contracts](/stylus/how-tos/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | -| [Exporting ABI](/stylus/how-tos/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | -| [Debugging with replay](/stylus/how-tos/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | -| [Optimizing WASM binary size](/stylus/how-tos/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | -| [Deploying non-Rust WASM contracts](/stylus/how-tos/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | +| Article | Description | +| ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| [Verify contracts](/stylus/guides/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | +| [Exporting ABI](/stylus/guides/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | +| [Debugging with replay](/stylus/guides/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | +| [Optimizing WASM binary size](/stylus/guides/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | +| [Deploying non-Rust WASM contracts](/stylus/guides/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | ### WASM concepts Understand how WebAssembly works within Arbitrum Nitro and its implications for Stylus development. -| Article | Description | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | -| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | -| [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | -| [Caching strategy](/stylus/how-tos/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | +| Article | Description | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------ | +| [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | +| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | +| [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | +| [Caching strategy](/stylus/guides/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | ### Troubleshooting diff --git a/docs/stylus/troubleshooting/_category_.yml b/docs/stylus/troubleshooting/_category_.yml new file mode 100644 index 0000000000..bcfd42bc9e --- /dev/null +++ b/docs/stylus/troubleshooting/_category_.yml @@ -0,0 +1,5 @@ +label: 'Troubleshooting' +position: 8 +link: + type: generated-index + description: Common issues, error messages, and debugging strategies. diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index 249ab2822f..333b53f92e 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -119,9 +119,9 @@ Available for commands involving transactions: | Topic | Description | | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/how-tos/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/how-tos/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/how-tos/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/guides/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/guides/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | | [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | #### Additional resources diff --git a/scripts/restructure/update-imports-phase2.sh b/scripts/restructure/update-imports-phase2.sh new file mode 100755 index 0000000000..843e88fb11 --- /dev/null +++ b/scripts/restructure/update-imports-phase2.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +echo "=== Updating imports for Phase 2 file moves ===" +echo "" + +# Update imports for files moved to fundamentals/ +echo "Updating fundamentals/ imports..." +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|reference/project-structure|fundamentals/project-structure|g' \ + -e 's|reference/contracts|fundamentals/contracts|g' \ + -e 's|reference/global-variables-and-functions|fundamentals/global-variables-and-functions|g' \ + -e 's|reference/data-types|fundamentals/data-types|g' \ + -e 's|how-tos/testing-contracts|fundamentals/testing-contracts|g' \ + {} \; + +# Update imports for CLI tools +echo "Updating cli-tools/ imports..." +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|using-cli\.mdx|cli-tools/overview|g' \ + -e 's|/using-cli\)|/cli-tools/overview)|g' \ + -e 's|how-tos/check-and-deploy|cli-tools/check-and-deploy|g' \ + -e 's|how-tos/debugging-tx|cli-tools/debugging-tx|g' \ + -e 's|how-tos/verifying-contracts|cli-tools/verify-contracts|g' \ + {} \; + +# Update imports for guides (how-tos โ†’ guides) +echo "Updating guides/ imports..." +find docs/stylus -name "*.mdx" -exec sed -i '' \ + -e 's|how-tos/|guides/|g' \ + {} \; + +echo "" +echo "โœ… All imports updated" diff --git a/sidebars.js b/sidebars.js index e467c4fd91..262c665d74 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1574,195 +1574,247 @@ const sidebars = { type: 'category', label: 'Build apps with Stylus', collapsed: false, + link: { + type: 'generated-index', + title: 'Build apps with Stylus', + description: + "Learn how to build decentralized applications using Stylus, Arbitrum's next-generation smart contract platform supporting Rust, C, and C++.", + slug: '/stylus', + }, items: [ { type: 'doc', id: 'stylus/gentle-introduction', label: 'A gentle introduction', }, + { + type: 'doc', + id: 'stylus/quickstart', + label: 'Quickstart', + }, { type: 'category', - label: 'Stylus Rust SDK', - collapsed: true, + label: 'Fundamentals', + collapsed: false, link: { - type: 'doc', - id: 'stylus/reference/overview', + type: 'generated-index', }, - items: [ { type: 'doc', - id: 'stylus/reference/project-structure', - label: 'Structure of a project', + id: 'stylus/fundamentals/project-structure', + label: 'Project structure', }, { type: 'doc', - id: 'stylus/reference/contracts', - label: 'Structure of a contracts', + id: 'stylus/fundamentals/contracts', + label: 'Contract structure', + }, + { + type: 'doc', + id: 'stylus/fundamentals/global-variables-and-functions', + label: 'Global variables and functions', }, { type: 'category', label: 'Data types', - collapsed: true, items: [ { type: 'doc', - id: 'stylus/reference/data-types/primitives', + id: 'stylus/fundamentals/data-types/primitives', label: 'Primitives', }, { type: 'doc', - id: 'stylus/reference/data-types/compound-types', + id: 'stylus/fundamentals/data-types/compound-types', label: 'Compound types', }, { type: 'doc', - id: 'stylus/reference/data-types/storage', + id: 'stylus/fundamentals/data-types/storage', label: 'Storage', }, { type: 'doc', - id: 'stylus/reference/data-types/conversions-between-types', - label: 'Conversions Between Types', + id: 'stylus/fundamentals/data-types/conversions-between-types', + label: 'Conversions between types', }, ], }, { type: 'doc', - id: 'stylus/reference/global-variables-and-functions', - label: 'Global variables and functions', + id: 'stylus/fundamentals/testing-contracts', + label: 'Testing contracts', }, + ], + }, + { + type: 'category', + label: 'Guides', + items: [ { type: 'doc', - id: 'stylus/how-tos/testing-contracts', - label: 'Writing Tests', + id: 'stylus/guides/using-constructors', + label: 'Using constructors', }, { - type: 'category', - label: 'Advanced', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/advanced/solidity-differences', - label: 'Solidity differences', - }, - { - type: 'doc', - id: 'stylus/advanced/recommended-libraries', - label: 'Recommended packages', - }, - { - type: 'doc', - id: 'stylus/advanced/minimal-entrypoint-contracts', - label: 'Minimal entrypoint contracts', - }, - { - type: 'doc', - id: 'stylus/advanced/hostio-exports', - label: 'Hostio exports', - }, - ], + type: 'doc', + id: 'stylus/guides/using-inheritance', + label: 'Using inheritance', }, { - type: 'category', - label: 'VM Concepts', - collapsed: true, - items: [ - { - type: 'doc', - id: 'stylus/concepts/webassembly', - label: 'Webassembly', - }, - { - type: 'doc', - id: 'stylus/concepts/evm-differences', - label: 'EVM differences', - }, - { - type: 'doc', - id: 'stylus/concepts/activation', - label: 'Activation', - }, - { - type: 'doc', - id: 'stylus/how-tos/caching-contracts', - label: 'Caching Strategy', - }, - ], + type: 'doc', + id: 'stylus/guides/importing-interfaces', + label: 'Importing interfaces', }, { - type: 'category', - label: 'Reference', - collapsed: true, - items: [ - { - type: 'link', - label: 'Stylus by Example', - href: 'https://stylus-by-example.org/', - }, - { - type: 'link', - label: 'Cargo Stylus CLI GitHub', - href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', - }, - { - type: 'link', - label: 'Rust SDK Crate', - href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', - }, - { - type: 'link', - label: 'Source Code Repository', - href: 'https://github.com/OffchainLabs/stylus-sdk-rs', - }, - ], + type: 'doc', + id: 'stylus/guides/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/guides/optimizing-binaries', + label: 'Optimizing binaries', + }, + { + type: 'doc', + id: 'stylus/guides/caching-contracts', + label: 'Caching contracts', + }, + { + type: 'doc', + id: 'stylus/guides/deploying-non-rust-wasm-contracts', + label: 'Deploy non-Rust contracts', + }, + { + type: 'doc', + id: 'stylus/guides/adding-support-for-new-languages', + label: 'Add language support', }, ], }, { type: 'category', - label: 'Using Stylus CLI', - collapsed: true, - link: { - type: 'doc', - id: 'stylus/using-cli', - }, + label: 'CLI tools', items: [ { type: 'doc', - id: 'stylus/how-tos/check-and-deploy', + id: 'stylus/cli-tools/overview', + label: 'Overview', + }, + { + type: 'doc', + id: 'stylus/cli-tools/check-and-deploy', label: 'Check and deploy', }, { type: 'doc', - id: 'stylus/how-tos/verifying-contracts', + id: 'stylus/cli-tools/verify-contracts', label: 'Verify contracts', }, { type: 'doc', - id: 'stylus/how-tos/exporting-abi', - label: 'Exporting ABI', + id: 'stylus/cli-tools/debugging-tx', + label: 'Debugging transactions', }, { type: 'doc', - id: 'stylus/how-tos/importing-interfaces', - label: 'Importing interfaces', + id: 'stylus/cli-tools/commands-reference', + label: 'Commands reference', + }, + ], + }, + { + type: 'category', + label: 'Concepts', + items: [ + { + type: 'doc', + id: 'stylus/concepts/webassembly', + label: 'WebAssembly', + }, + { + type: 'doc', + id: 'stylus/concepts/activation', + label: 'Activation', + }, + { + type: 'doc', + id: 'stylus/concepts/gas-metering', + label: 'Gas metering', + }, + { + type: 'doc', + id: 'stylus/concepts/evm-differences', + label: 'EVM differences', }, { type: 'doc', - id: 'stylus/how-tos/debugging-tx', - label: 'Debugging with replay', + id: 'stylus/concepts/public-preview-expectations', + label: 'Public preview expectations', }, + ], + }, + { + type: 'category', + label: 'Advanced', + items: [ + { + type: 'doc', + id: 'stylus/advanced/solidity-differences', + label: 'Solidity differences', + }, + { + type: 'doc', + id: 'stylus/advanced/minimal-entrypoint-contracts', + label: 'Minimal entrypoint contracts', + }, + { + type: 'doc', + id: 'stylus/advanced/hostio-exports', + label: 'Hostio exports', + }, + { + type: 'doc', + id: 'stylus/advanced/recommended-libraries', + label: 'Recommended libraries', + }, + ], + }, + { + type: 'category', + label: 'Reference', + items: [ { type: 'doc', - id: 'stylus/how-tos/optimizing-binaries', - label: 'Optimizing WASM binary size', + id: 'stylus/reference/overview', + label: 'Overview', }, { type: 'doc', - id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', - label: 'Deploying non-Rust WASM contracts', + id: 'stylus/reference/opcode-hostio-pricing', + label: 'Opcode and hostio pricing', + }, + { + type: 'link', + label: 'Stylus by Example', + href: 'https://stylus-by-example.org/', + }, + { + type: 'link', + label: 'Cargo Stylus CLI GitHub', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', + }, + { + type: 'link', + label: 'Rust SDK Crate', + href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + }, + { + type: 'link', + label: 'Source Code Repository', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs', }, ], }, diff --git a/sidebars.js.backup b/sidebars.js.backup new file mode 100644 index 0000000000..e467c4fd91 --- /dev/null +++ b/sidebars.js.backup @@ -0,0 +1,1809 @@ +// @ts-check + +// Use the generated SDK sidebar for API reference +const sdkApiSidebar = require('./sdk-sidebar.js'); +// Use the generated stylus-by-example sidebars + +// Create a custom SDK sidebar that combines manual intro pages with generated API docs +const sdkSidebar = { + sdkSidebar: [ + { + type: 'doc', + id: 'sdk/index', + label: 'Introduction', + }, + { + type: 'doc', + id: 'sdk/migrate', + label: 'Migrate from v3 to v4', + }, + ...sdkApiSidebar.sdkSidebar, + ], +}; + +/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ +const sidebars = { + // Get started sidebar - shared entry point + getStartedSidebar: [ + { + type: 'doc', + id: 'get-started/overview', + label: 'Get started', + }, + { + type: 'doc', + id: 'get-started/arbitrum-introduction', + label: 'Arbitrum: introduction', + }, + { + type: 'category', + label: 'Build apps', + collapsed: true, + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/quickstart-solidity-remix', + label: 'Build apps with Solidity', + }, + { + type: 'doc', + id: 'stylus/quickstart', + label: 'Build apps with Stylus', + }, + ], + }, + { + type: 'link', + label: 'Run an Arbitrum (Orbit) chain', + href: '/launch-arbitrum-chain/a-gentle-introduction', + }, + { + type: 'link', + label: 'Run an Arbitrum node', + href: '/run-arbitrum-node/overview', + }, + { + type: 'link', + label: 'Arbitrum bridge', + href: '/arbitrum-bridge/quickstart', + }, + { + type: 'link', + label: 'How Arbitrum works', + href: '/how-arbitrum-works/inside-arbitrum-nitro', + }, + { + type: 'doc', + id: 'for-devs/dev-tools-and-resources/chain-info', + label: 'Chain info', + }, + { + type: 'doc', + id: 'intro/glossary', + label: 'Glossary', + }, + { + type: 'doc', + id: 'for-devs/contribute', + label: 'Contribute', + }, + { + type: 'doc', + id: 'learn-more/faq', + label: 'FAQ', + }, + { + type: 'doc', + label: 'Audit reports', + id: 'audit-reports', + }, + { + type: 'category', + label: 'Third-party docs', + collapsed: true, + items: [ + { + type: 'category', + label: 'Oracles', + collapsed: true, + items: [ + { + type: 'doc', + id: 'for-devs/oracles/api3/api3', + }, + { + type: 'doc', + id: 'for-devs/oracles/chainlink/chainlink', + }, + { + type: 'doc', + id: 'for-devs/oracles/chronicle/chronicle', + }, + { + type: 'doc', + id: 'for-devs/oracles/ora/ora', + }, + { + type: 'doc', + id: 'for-devs/oracles/supra/supras-price-feed', + }, + { + type: 'doc', + id: 'for-devs/oracles/supra/supras-vrf', + }, + { + type: 'doc', + id: 'for-devs/oracles/trellor/trellor', + }, + ], + }, + { + type: 'autogenerated', + dirName: 'for-devs/third-party-docs', + }, + ], + }, + { + type: 'link', + label: 'DAO docs', + href: 'https://docs.arbitrum.foundation/gentle-intro-dao-governance', + }, + { + type: 'link', + label: 'Prysm docs', + href: 'https://www.offchainlabs.com/prysm/docs', + }, + ], + // Run Arbitrum Chain sidebar + runArbitrumChainSidebar: [ + { + type: 'category', + label: 'Run an Arbitrum (Orbit) chain', + collapsed: false, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/a-gentle-introduction', + label: 'A gentle introduction', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/aep-license', + label: 'Arbitrum chain licensing', + }, + { + type: 'category', + label: 'Features', + collapsed: true, + items: [ + { + type: 'category', + label: 'Common', + collapsed: true, + items: [ + { + type: 'category', + label: 'Data availability', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/data-availability/choose-rollup', + label: `Rollup`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/data-availability/choose-anytrust', + label: `AnyTrust`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/data-availability/choose-alt-da', + label: `Alt-DA`, + }, + ], + }, + { + type: 'category', + label: 'Gas and fees', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/gas-and-fees/choose-custom-gas-token', + label: `Custom gas token`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/gas-and-fees/choose-fee-rebates', + label: `Fee rebates`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/gas-and-fees/choose-native-eth', + label: `Native ETH`, + }, + ], + }, + { + type: 'category', + label: 'Validation and security', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/validation-and-security/choose-bold', + label: `BoLD`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/validation-and-security/choose-challenge-period', + label: `Custom challenge period`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/validation-and-security/choose-permissioned-validators', + label: `Permissioned validators`, + }, + ], + }, + { + type: 'category', + label: 'MEV', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/mev/choose-timeboost', + label: `Timeboost`, + }, + ], + }, + { + type: 'category', + label: 'UX', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/ux/choose-fast-withdrawals', + label: `Fast withdrawals`, + }, + ], + }, + { + type: 'category', + label: 'AEP fees', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/common/configure-aep/configure-aep-fees', + label: `AEP fees`, + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Advanced', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/features/advanced/choose-arbos-version', + label: `ArbOS version`, + }, + { + type: 'doc', + label: 'Precompiles', + id: 'launch-arbitrum-chain/features/advanced/choose-chain-precompiles', + }, + { + type: 'doc', + label: 'Chain behavior', + id: 'launch-arbitrum-chain/features/advanced/choose-custom-behavior', + }, + { + type: 'doc', + label: 'Delayed inbox finality', + id: 'launch-arbitrum-chain/features/advanced/choose-custom-delay-inbox-finality', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Configure your chain', + collapsed: true, + items: [ + { + type: 'category', + label: 'Common features', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/use-a-custom-gas-token-anytrust', + label: `Configure a custom AnyTrust gas token`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/use-a-custom-gas-token-rollup', + label: `Configure a custom Rollup gas token`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/customizable-challenge-period', + label: 'Customize the challenge period', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/fee-management', + label: `Manage the fee parameters`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/enable-post-4844-blobs', + label: `Enable blob transactions`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/arbitrum-chain-finality', + label: `Configure delayed inbox finality`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/batch-posting-assertion-control', + label: 'Configure Batch Poster and Assertion Control', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/gas-optimization-tools', + label: `Gas optimization tools`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/bold-adoption-for-arbitrum-chains', + label: 'BoLD for Arbitrum chains', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/timeboost-for-arbitrum-chains', + label: 'Timeboost for Arbitrum chains', + }, + { + type: 'category', + label: 'Data Availability Committees', + collapsed: true, + items: [ + { + type: 'doc', + id: 'run-arbitrum-node/data-availability-committees/get-started', + label: 'Get started', + }, + { + type: 'doc', + id: 'run-arbitrum-node/data-availability-committees/deploy-das', + label: 'Deploy a Data Availability Server (DAS)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/data-availability-committees/deploy-mirror-das', + label: 'Deploy a mirror Data Availability Server', + }, + { + type: 'doc', + id: 'run-arbitrum-node/data-availability-committees/configure-dac', + label: 'Configure a Data Availability Committee (DAC)', + }, + ], + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/how-tos/customize-deployment-configuration', + label: `Customize your chain's deployment`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/reference/additional-configuration-parameters', + label: `Additional configuration parameters`, + }, + ], + }, + { + type: 'category', + label: 'Advanced features', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/fast-withdrawals', + label: `Enable fast withdrawals`, + }, + { + type: 'doc', + label: 'Use Layer Leap', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/layer-leap', + }, + { + type: 'category', + label: 'Configure AEP fee routing', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/aep-fee-router/aep-fee-router-introduction', + label: `AEP fee router overview`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/aep-fee-router/set-up-aep-fee-router', + label: `Set up AEP fee router`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/aep-fee-router/calculate-aep-fees', + label: `Calculate AEP license fees`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/advanced-configurations/aep-fee-router/reporting-on-fees', + label: `Report your fees`, + }, + ], + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Deploy an Arbitrum chain', + collapsed: true, + items: [ + { + type: 'category', + label: 'Deploy a production chain', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/arbitrum-chain-sdk-introduction', + label: `Overview`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/deploy-an-arbitrum-chain/deploying-an-arbitrum-chain', + label: `Deploy an Arbitrum chain`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/how-tos/arbitrum-chain-sdk-preparing-node-config', + label: `Generate the node config file`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/deploy-an-arbitrum-chain/deploying-token-bridge', + label: `Deploy a token bridge`, + }, + ], + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/deploy-an-arbitrum-chain/canonical-factory-contracts', + label: 'Canonical factory contracts', + }, + ], + }, + { + type: 'category', + label: 'Maintain your chain', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/maintain-your-chain/ownership-structure-access-control', + label: 'Ownership structure and access control', + }, + { + type: 'category', + label: 'ArbOS', + collapsed: true, + items: [ + { + type: 'html', + value: + 'ArbOS software releases โ†“', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/configure-your-chain/common-configurations/arbos-upgrade', + label: `Upgrade ArbOS`, + }, + ], + }, + { + type: 'category', + label: 'Guidance', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/maintain-your-chain/guidance/state-growth', + label: `Manage gas state growth`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/maintain-your-chain/guidance/state-size-limit', + label: `Manage gas speed limit`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/maintain-your-chain/guidance/post-launch-contract-deployments', + label: `Post-launch deployments`, + }, + ], + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/maintain-your-chain/monitoring-tools-and-considerations', + label: 'Monitoring tools and considerations', + }, + ], + }, + { + type: 'category', + label: 'Customize your chain', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/customize-your-chain/customize-precompile', + label: `Customize your chain's precompiles`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/customize-your-chain/customize-stf', + label: `Customize your chain's behavior`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/customize-your-chain/customize-arbos', + label: `Customize ArbOS version`, + }, + ], + }, + { + type: 'category', + label: 'Migrate your chain', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/migrate-from-another-stack', + label: 'Migrate from another stack', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/migrate-between-raases', + label: 'Migrate between RaaSes', + }, + ], + }, + { + type: 'category', + label: 'Third-party integrations and features', + collapsed: true, + items: [ + { + type: 'doc', + id: 'launch-arbitrum-chain/third-party-integrations/bridged-usdc-standard', + label: `Implement Circle bridged USDC`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/third-party-integrations/third-party-providers', + label: 'Third-party infrastructure providers', + }, + ], + }, + { + type: 'category', + label: 'Run a node for an Arbitrum chain', + collapsed: true, + items: [ + { + type: 'html', + value: + 'Run a full node โ†“', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + { + type: 'html', + value: + 'Run a validator โ†“', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + { + type: 'html', + value: + 'Run a sequencer node โ†“', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + { + type: 'html', + value: + 'Run high-availability sequencer nodes โ†“', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + ], + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/ecosystem-support/add-arbitrum-chain-to-bridge-ui', + label: `Add your chain to the bridge`, + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/concepts/public-preview-expectations', + label: 'Public preview', + }, + { + type: 'doc', + id: 'launch-arbitrum-chain/faq-troubleshooting/troubleshooting-building-arbitrum-chain', + label: 'FAQ', + }, + ], + }, + + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Run Node sidebar + runNodeSidebar: [ + { + type: 'category', + label: 'Run an Arbitrum node', + collapsed: false, + link: { + type: 'doc', + id: 'run-arbitrum-node/overview', + }, + items: [ + { + type: 'doc', + id: 'run-arbitrum-node/overview', + label: 'Overview', + }, + { + type: 'doc', + id: 'run-arbitrum-node/run-full-node', + label: 'Run a full node', + }, + { + type: 'doc', + id: 'run-arbitrum-node/run-local-full-chain-simulation', + label: 'Run a local full chain simulation', + }, + { + type: 'doc', + id: 'run-arbitrum-node/run-nitro-dev-node', + label: 'Run a local dev node', + }, + { + type: 'doc', + id: 'run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers', + label: 'L1 Ethereum RPC providers', + }, + { + type: 'doc', + id: 'run-arbitrum-node/data-availability', + label: 'Data Availability', + }, + { + type: 'doc', + id: 'run-arbitrum-node/run-feed-relay', + label: 'Run a feed relay', + }, + { + type: 'doc', + id: 'run-arbitrum-node/beacon-nodes-historical-blobs', + label: 'Historical blobs', + }, + { + type: 'html', + value: + 'Data Availability Committees โ†‘', + // q: why use an anchor html tag here? + // a: see note at end of file + }, + { + type: 'category', + label: 'ArbOS software releases', + collapsed: true, + items: [ + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/overview', + label: 'Overview', + }, + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/arbos50', + label: 'Dia (ArbOS 50)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/arbos40', + label: 'Callisto (ArbOS 40)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/arbos32', + label: 'Bianca (ArbOS 32)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/arbos20', + label: 'Atlas (ArbOS 20)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/arbos-releases/arbos11', + label: 'ArbOS 11', + }, + ], + }, + { + type: 'category', + label: 'More node types', + collapsed: true, + items: [ + { + type: 'doc', + id: 'run-arbitrum-node/more-types/run-archive-node', + label: 'Run an archive node', + }, + { + type: 'doc', + id: 'run-arbitrum-node/more-types/run-validator-node', + label: 'Run a validator', + }, + { + type: 'doc', + id: 'run-arbitrum-node/more-types/run-split-validator-node', + label: 'Run a split validator', + }, + { + type: 'doc', + id: 'run-arbitrum-node/more-types/run-classic-node', + label: 'Run a Classic node', + }, + ], + }, + { + type: 'category', + label: 'Sequencer', + collapsed: true, + items: [ + { + type: 'doc', + id: 'run-arbitrum-node/sequencer/run-sequencer-node', + label: 'Run a sequencer node', + }, + { + type: 'doc', + id: 'run-arbitrum-node/sequencer/read-sequencer-feed', + label: 'Read the sequencer feed', + }, + { + type: 'doc', + id: 'run-arbitrum-node/sequencer/run-sequencer-coordination-manager', + label: 'Run a Sequencer Coordination Manager (SQM)', + }, + { + type: 'doc', + id: 'run-arbitrum-node/sequencer/high-availability-sequencer-docs', + label: 'Run high availability sequencer nodes', + }, + ], + }, + { + type: 'doc', + id: 'run-arbitrum-node/nitro/build-nitro-locally', + label: 'Build Nitro locally', + }, + { + type: 'doc', + id: 'run-arbitrum-node/nitro/migrate-state-and-history-from-classic', + label: 'Migrate to Nitro from Classic', + }, + { + type: 'doc', + id: 'run-arbitrum-node/nitro/nitro-database-snapshots', + label: 'Database snapshots', + }, + { + type: 'doc', + id: 'run-arbitrum-node/nitro/how-to-convert-databases-from-leveldb-to-pebble', + label: 'Convert databases from LevelDB to Pebble', + }, + , + { + type: 'doc', + id: 'run-arbitrum-node/troubleshooting', + label: 'Troubleshooting', + }, + { + type: 'doc', + label: 'FAQ', + id: 'node-running/faq', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Bridge sidebar + bridgeSidebar: [ + { + type: 'category', + label: 'Arbitrum bridge', + collapsed: false, + items: [ + { + type: 'doc', + id: 'arbitrum-bridge/quickstart', + label: 'Quickstart', + }, + { + type: 'doc', + id: 'arbitrum-bridge/usdc-arbitrum-one', + label: 'USDC on Arbitrum One', + }, + { + type: 'doc', + id: 'arbitrum-bridge/embedded-bridge-widget', + label: 'Embedded bridge widget', + }, + { + type: 'doc', + id: 'arbitrum-bridge/troubleshooting', + label: 'Troubleshooting', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // How it Works sidebar + howItWorksSidebar: [ + { + type: 'category', + label: 'How Arbitrum works', + collapsed: false, + items: [ + { + type: 'doc', + id: 'how-arbitrum-works/inside-arbitrum-nitro', + label: 'Inside Arbitrum Nitro', + }, + { + type: 'html', + value: + 'Nitro whitepaperโ†‘', + }, + { + type: 'category', + label: 'Deep dives', + items: [ + { + type: 'doc', + label: 'AnyTrust', + id: 'how-arbitrum-works/deep-dives/anytrust-protocol', + }, + { + type: 'doc', + label: 'ArbOS', + id: 'how-arbitrum-works/deep-dives/arbos', + }, + { + type: 'doc', + label: 'Assertions', + id: 'how-arbitrum-works/deep-dives/assertions', + }, + { + type: 'doc', + label: 'Parent to Child chain Messaging', + id: 'how-arbitrum-works/deep-dives/l1-to-l2-messaging', + }, + { + type: 'doc', + label: 'Child to Parent chain Messaging', + id: 'how-arbitrum-works/deep-dives/l2-to-l1-messaging', + }, + { + type: 'doc', + label: 'Geth', + id: 'how-arbitrum-works/deep-dives/geth', + }, + { + type: 'doc', + label: 'Parent chain pricing', + id: 'how-arbitrum-works/deep-dives/parent-chain-pricing', + }, + { + type: 'doc', + label: 'Sequencer', + id: 'how-arbitrum-works/deep-dives/sequencer', + }, + { + type: 'doc', + label: 'STF', + id: 'how-arbitrum-works/deep-dives/stf-gentle-intro', + }, + { + type: 'doc', + label: 'STF inputs', + id: 'how-arbitrum-works/deep-dives/stf-inputs', + }, + { + type: 'doc', + label: 'Transaction lifecycle', + id: 'how-arbitrum-works/deep-dives/transaction-lifecycle', + }, + { + type: 'doc', + label: 'Gas and fees', + id: 'how-arbitrum-works/deep-dives/gas-and-fees', + }, + ], + }, + { + type: 'category', + label: 'The BoLD dispute protocol', + items: [ + { + type: 'doc', + id: 'how-arbitrum-works/bold/gentle-introduction', + label: 'A gentle introduction', + }, + { + type: 'link', + href: 'https://github.com/offchainlabs/bold-validator-starter-kit', + label: 'Deploy a validator on testnet', + }, + { + type: 'link', + href: 'https://arxiv.org/abs/2404.10491', + label: 'BoLD Whitepaper', + }, + { + type: 'doc', + id: 'how-arbitrum-works/bold/bold-technical-deep-dive', + label: 'Technical deep dive', + }, + { + type: 'doc', + id: 'how-arbitrum-works/bold/bold-economics-of-disputes', + label: 'Economics of disputes', + }, + { + type: 'link', + href: 'https://github.com/OffchainLabs/bold', + label: 'Specification on Github', + }, + { + type: 'link', + href: 'https://github.com/trailofbits/publications/blob/master/reviews/2024-04-offchainbold-securityreview.pdf', + label: 'Audit Report by Trail of Bits', + }, + { + type: 'link', + href: 'https://code4rena.com/reports/2024-05-arbitrum-foundation', + label: 'Audit Report by Code4rena', + }, + ], + }, + { + type: 'category', + label: 'Timeboost', + items: [ + { + type: 'doc', + id: 'how-arbitrum-works/timeboost/gentle-introduction', + label: 'Public preview', + }, + { + type: 'doc', + label: 'Use Timeboost', + id: 'how-arbitrum-works/timeboost/how-to-use-timeboost', + }, + { + type: 'doc', + label: 'Troubleshoot Timeboost', + id: 'how-arbitrum-works/timeboost/troubleshoot-timeboost', + }, + { + type: 'doc', + label: 'Timeboost FAQ', + id: 'how-arbitrum-works/timeboost/timeboost-faq', + }, + { + type: 'link', + href: 'https://github.com/OffchainLabs/timeboost-design/blob/main/research_spec.md', + label: 'Specification: Timeboost', + }, + { + type: 'link', + href: 'https://github.com/OffchainLabs/decentralized-timeboost-spec', + label: 'Specification: Timeboost with decentralized sequencing', + }, + { + type: 'link', + href: 'https://arxiv.org/abs/2306.02179', + label: 'White paper: Timeboost', + }, + ], + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Unified build apps sidebar (combines build apps and Stylus) + buildAppsSidebar: [ + { + type: 'category', + label: 'Build apps with Solidity', + collapsed: false, + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/quickstart-solidity-remix', + label: 'Quickstart', + }, + { + type: 'doc', + label: 'Estimate gas', + id: 'build-decentralized-apps/how-to-estimate-gas', + }, + { + type: 'doc', + label: 'Chains and testnets', + id: 'build-decentralized-apps/public-chains', + }, + { + type: 'doc', + label: 'Cross-chain messaging', + id: 'build-decentralized-apps/cross-chain-messaging', + }, + { + type: 'doc', + id: 'build-decentralized-apps/custom-gas-token-sdk', + label: 'Custom gas token SDK', + }, + { + type: 'category', + label: 'Arbitrum vs Ethereum', + items: [ + { + type: 'doc', + label: 'Comparison overview', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/comparison-overview', + }, + { + type: 'doc', + label: 'Block gas limit, numbers and time', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/block-numbers-and-time', + }, + { + type: 'doc', + label: 'RPC methods', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/rpc-methods', + }, + { + type: 'doc', + label: 'Solidity support', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/solidity-support', + }, + ], + }, + { + type: 'doc', + label: 'Oracles', + id: 'build-decentralized-apps/oracles/overview-oracles', + }, + { + type: 'category', + label: 'Precompiles', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/precompiles/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/precompiles/reference', + }, + ], + }, + { + type: 'category', + label: 'NodeInterface', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/nodeinterface/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/nodeinterface/reference', + }, + ], + }, + { + type: 'category', + label: 'Token bridging', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/token-bridging/overview', + }, + { + type: 'doc', + label: 'ETH bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-ether', + }, + { + type: 'doc', + label: 'ERC-20 token bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-erc20', + }, + { + type: 'category', + label: 'Bridge tokens programmatically', + items: [ + { + type: 'doc', + label: 'Get started', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/get-started', + }, + { + type: 'doc', + label: 'Use the standard gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-standard', + }, + { + type: 'doc', + label: 'Use the generic-custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-generic-custom', + }, + { + type: 'doc', + label: 'Use the custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-custom-gateway', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Reference', + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/reference/node-providers', + label: 'RPC endpoints and providers', + }, + { + type: 'doc', + label: 'Smart contract addresses', + id: 'build-decentralized-apps/reference/contract-addresses', + }, + { + type: 'doc', + label: 'Chain parameters', + id: 'build-decentralized-apps/reference/chain-params', + }, + { + type: 'doc', + label: 'Development frameworks', + id: 'build-decentralized-apps/reference/development-frameworks', + }, + { + type: 'doc', + label: 'Web3 libraries and tools', + id: 'build-decentralized-apps/reference/web3-libraries-tools', + }, + { + type: 'doc', + label: 'Monitoring tools and block explorers', + id: 'build-decentralized-apps/reference/monitoring-tools-block-explorers', + }, + { + type: 'doc', + label: 'Debugging tools', + id: 'build-decentralized-apps/reference/debugging-tools', + }, + + { + type: 'doc', + id: 'build-decentralized-apps/reference/mainnet-risks', + label: 'Mainnet risks', + }, + ], + }, + { + type: 'doc', + label: 'Troubleshooting', + id: 'for-devs/troubleshooting-building', + }, + { + type: 'category', + label: 'Arbitrum SDK', + items: sdkSidebar.sdkSidebar, + }, + { + type: 'link', + label: 'Tutorials', + href: 'https://github.com/OffchainLabs/arbitrum-tutorials', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Solidity-focused sidebar (only shows Solidity content) + buildSoliditySidebar: [ + { + type: 'category', + label: 'Build apps with Solidity', + collapsed: false, + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/quickstart-solidity-remix', + label: 'Quickstart', + }, + { + type: 'doc', + label: 'Estimate gas', + id: 'build-decentralized-apps/how-to-estimate-gas', + }, + { + type: 'doc', + label: 'Chains and testnets', + id: 'build-decentralized-apps/public-chains', + }, + { + type: 'doc', + label: 'Cross-chain messaging', + id: 'build-decentralized-apps/cross-chain-messaging', + }, + { + type: 'doc', + id: 'build-decentralized-apps/custom-gas-token-sdk', + label: 'Custom gas token SDK', + }, + { + type: 'category', + label: 'Arbitrum vs Ethereum', + items: [ + { + type: 'doc', + label: 'Comparison overview', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/comparison-overview', + }, + { + type: 'doc', + label: 'Block gas limit, numbers and time', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/block-numbers-and-time', + }, + { + type: 'doc', + label: 'RPC methods', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/rpc-methods', + }, + { + type: 'doc', + label: 'Solidity support', + id: 'build-decentralized-apps/arbitrum-vs-ethereum/solidity-support', + }, + ], + }, + { + type: 'doc', + label: 'Oracles', + id: 'build-decentralized-apps/oracles/overview-oracles', + }, + { + type: 'category', + label: 'Precompiles', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/precompiles/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/precompiles/reference', + }, + ], + }, + { + type: 'category', + label: 'NodeInterface', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/nodeinterface/overview', + }, + { + type: 'doc', + label: 'Reference', + id: 'build-decentralized-apps/nodeinterface/reference', + }, + ], + }, + { + type: 'category', + label: 'Token bridging', + collapsed: true, + items: [ + { + type: 'doc', + label: 'Overview', + id: 'build-decentralized-apps/token-bridging/overview', + }, + { + type: 'doc', + label: 'ETH bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-ether', + }, + { + type: 'doc', + label: 'ERC-20 token bridging', + id: 'build-decentralized-apps/token-bridging/token-bridge-erc20', + }, + { + type: 'category', + label: 'Bridge tokens programmatically', + items: [ + { + type: 'doc', + label: 'Get started', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/get-started', + }, + { + type: 'doc', + label: 'Use the standard gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-standard', + }, + { + type: 'doc', + label: 'Use the generic-custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-generic-custom', + }, + { + type: 'doc', + label: 'Use the custom gateway', + id: 'build-decentralized-apps/token-bridging/bridge-tokens-programmatically/how-to-bridge-tokens-custom-gateway', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Reference', + items: [ + { + type: 'doc', + id: 'build-decentralized-apps/reference/node-providers', + label: 'RPC endpoints and providers', + }, + { + type: 'doc', + label: 'Smart contract addresses', + id: 'build-decentralized-apps/reference/contract-addresses', + }, + { + type: 'doc', + label: 'Chain parameters', + id: 'build-decentralized-apps/reference/chain-params', + }, + { + type: 'doc', + label: 'Development frameworks', + id: 'build-decentralized-apps/reference/development-frameworks', + }, + { + type: 'doc', + label: 'Web3 libraries and tools', + id: 'build-decentralized-apps/reference/web3-libraries-tools', + }, + { + type: 'doc', + label: 'Monitoring tools and block explorers', + id: 'build-decentralized-apps/reference/monitoring-tools-block-explorers', + }, + { + type: 'doc', + label: 'Debugging tools', + id: 'build-decentralized-apps/reference/debugging-tools', + }, + + { + type: 'doc', + id: 'build-decentralized-apps/reference/mainnet-risks', + label: 'Mainnet risks', + }, + ], + }, + { + type: 'doc', + label: 'Troubleshooting', + id: 'for-devs/troubleshooting-building', + }, + { + type: 'category', + label: 'Arbitrum SDK', + items: sdkSidebar.sdkSidebar, + }, + { + type: 'link', + label: 'Tutorials', + href: 'https://github.com/OffchainLabs/arbitrum-tutorials', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Stylus-focused sidebar (only shows Stylus content) + buildStylusSidebar: [ + { + type: 'category', + label: 'Build apps with Stylus', + collapsed: false, + items: [ + { + type: 'doc', + id: 'stylus/gentle-introduction', + label: 'A gentle introduction', + }, + { + type: 'category', + label: 'Stylus Rust SDK', + collapsed: true, + link: { + type: 'doc', + id: 'stylus/reference/overview', + }, + + items: [ + { + type: 'doc', + id: 'stylus/reference/project-structure', + label: 'Structure of a project', + }, + { + type: 'doc', + id: 'stylus/reference/contracts', + label: 'Structure of a contracts', + }, + { + type: 'category', + label: 'Data types', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/reference/data-types/primitives', + label: 'Primitives', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/compound-types', + label: 'Compound types', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/storage', + label: 'Storage', + }, + { + type: 'doc', + id: 'stylus/reference/data-types/conversions-between-types', + label: 'Conversions Between Types', + }, + ], + }, + { + type: 'doc', + id: 'stylus/reference/global-variables-and-functions', + label: 'Global variables and functions', + }, + { + type: 'doc', + id: 'stylus/how-tos/testing-contracts', + label: 'Writing Tests', + }, + { + type: 'category', + label: 'Advanced', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/advanced/solidity-differences', + label: 'Solidity differences', + }, + { + type: 'doc', + id: 'stylus/advanced/recommended-libraries', + label: 'Recommended packages', + }, + { + type: 'doc', + id: 'stylus/advanced/minimal-entrypoint-contracts', + label: 'Minimal entrypoint contracts', + }, + { + type: 'doc', + id: 'stylus/advanced/hostio-exports', + label: 'Hostio exports', + }, + ], + }, + { + type: 'category', + label: 'VM Concepts', + collapsed: true, + items: [ + { + type: 'doc', + id: 'stylus/concepts/webassembly', + label: 'Webassembly', + }, + { + type: 'doc', + id: 'stylus/concepts/evm-differences', + label: 'EVM differences', + }, + { + type: 'doc', + id: 'stylus/concepts/activation', + label: 'Activation', + }, + { + type: 'doc', + id: 'stylus/how-tos/caching-contracts', + label: 'Caching Strategy', + }, + ], + }, + { + type: 'category', + label: 'Reference', + collapsed: true, + items: [ + { + type: 'link', + label: 'Stylus by Example', + href: 'https://stylus-by-example.org/', + }, + { + type: 'link', + label: 'Cargo Stylus CLI GitHub', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus', + }, + { + type: 'link', + label: 'Rust SDK Crate', + href: 'https://docs.rs/stylus-sdk/latest/stylus_sdk/index.html', + }, + { + type: 'link', + label: 'Source Code Repository', + href: 'https://github.com/OffchainLabs/stylus-sdk-rs', + }, + ], + }, + ], + }, + { + type: 'category', + label: 'Using Stylus CLI', + collapsed: true, + link: { + type: 'doc', + id: 'stylus/using-cli', + }, + items: [ + { + type: 'doc', + id: 'stylus/how-tos/check-and-deploy', + label: 'Check and deploy', + }, + { + type: 'doc', + id: 'stylus/how-tos/verifying-contracts', + label: 'Verify contracts', + }, + { + type: 'doc', + id: 'stylus/how-tos/exporting-abi', + label: 'Exporting ABI', + }, + { + type: 'doc', + id: 'stylus/how-tos/importing-interfaces', + label: 'Importing interfaces', + }, + { + type: 'doc', + id: 'stylus/how-tos/debugging-tx', + label: 'Debugging with replay', + }, + { + type: 'doc', + id: 'stylus/how-tos/optimizing-binaries', + label: 'Optimizing WASM binary size', + }, + { + type: 'doc', + id: 'stylus/how-tos/deploying-non-rust-wasm-contracts', + label: 'Deploying non-Rust WASM contracts', + }, + ], + }, + { + type: 'doc', + id: 'stylus/troubleshooting-building-stylus', + label: 'FAQ', + }, + ], + }, + { + type: 'html', + value: + 'Chain Infoโ†‘', + }, + { + type: 'html', + value: + 'Glossaryโ†‘', + }, + { + type: 'html', + value: + 'Contributeโ†‘', + }, + ], + + // Notices sidebar + noticeSidebar: [ + { + type: 'doc', + id: 'notices/fusaka-upgrade-notice', + label: 'Upgrade for the Fusaka transition', + }, + ], +}; + +module.exports = sidebars; + +// note RE html sidebar links: +// because the linked page lives in multiple sidebar sections, we pick one to be the "canonical" location for the page in the sidebar +// if we link to them both via id or standard href, multiple sections of the sidebar will be opened at once when the user visits this page; we don't want that +// if we use a fully qualified link, the remote/published page will display when visiting from localhost or preview deployments +// we also want to include a unicode arrow to indicate that we're routing the user to another section, in a way that's distinct from the icon that indicates "this href pulls you out of docs" diff --git a/vercel.json b/vercel.json index 3eeba02b88..4ff0dfa351 100644 --- a/vercel.json +++ b/vercel.json @@ -245,11 +245,111 @@ "destination": "/how-arbitrum-works/bold/gentle-introduction", "permanent": false }, + { + "source": "/(docs/stylus/how-tos/adding-support-for-new-languages/?)", + "destination": "/(docs/stylus/guides/adding-support-for-new-languages/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/caching-contracts/?)", + "destination": "/(docs/stylus/guides/caching-contracts/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/check-and-deploy/?)", + "destination": "/(docs/stylus/cli-tools/check-and-deploy/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/debugging-tx/?)", + "destination": "/(docs/stylus/cli-tools/debugging-tx/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/deploying-non-rust-wasm-contracts/?)", + "destination": "/(docs/stylus/guides/deploying-non-rust-wasm-contracts/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/exporting-abi/?)", + "destination": "/(docs/stylus/guides/exporting-abi/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/importing-interfaces/?)", + "destination": "/(docs/stylus/guides/importing-interfaces/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/optimizing-binaries/?)", + "destination": "/(docs/stylus/guides/optimizing-binaries/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/testing-contracts/?)", + "destination": "/(docs/stylus/fundamentals/testing-contracts/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/using-constructors/?)", + "destination": "/(docs/stylus/guides/using-constructors/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/using-inheritance/?)", + "destination": "/(docs/stylus/guides/using-inheritance/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/how-tos/verifying-contracts/?)", + "destination": "/(docs/stylus/cli-tools/verify-contracts/?)", + "permanent": false + }, { "source": "/(docs/stylus/recommended-libraries/?)", "destination": "/(docs/stylus/advanced/recommended-libraries/?)", "permanent": false }, + { + "source": "/(docs/stylus/reference/contracts/?)", + "destination": "/(docs/stylus/fundamentals/contracts/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/data-types/compound-types/?)", + "destination": "/(docs/stylus/fundamentals/data-types/compound-types/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/data-types/conversions-between-types/?)", + "destination": "/(docs/stylus/fundamentals/data-types/conversions-between-types/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/data-types/primitives/?)", + "destination": "/(docs/stylus/fundamentals/data-types/primitives/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/data-types/storage/?)", + "destination": "/(docs/stylus/fundamentals/data-types/storage/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/global-variables-and-functions/?)", + "destination": "/(docs/stylus/fundamentals/global-variables-and-functions/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/partials/_stylus-faucets/?)", + "destination": "/(docs/stylus/partials/_stylus-faucets/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/reference/project-structure/?)", + "destination": "/(docs/stylus/fundamentals/project-structure/?)", + "permanent": false + }, { "source": "/(faqs/anytrust-vs-rollup/?)", "destination": "/faqs/protocol-faqs#q-rollup-vs-anytrust", From f97bc29ab2180cdf7c5cfa9e1509f75b56e969bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:00:08 -0800 Subject: [PATCH 109/162] docs(stylus): Phase 3 - Content Consolidation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename evm-differences โ†’ vm-differences (clearer focus on VM comparison) - Rename solidity-differences โ†’ rust-to-solidity-differences (clearer language focus) - Create fundamentals/prerequisites.mdx with setup instructions - Extract setup into 3 reusable partials (_setup-rust-toolchain, _setup-cargo-stylus, _setup-docker-nitro) - Add quickstart journey diagram (#13) showing user path - Update sidebar to include prerequisites as first fundamentals item - Fix broken reference in overview.mdx Files modified: 3 New files: 4 (prerequisites + 3 partials) Files renamed: 2 Diagrams added: 1 (journey diagram) Note: rust-sdk-guide.md splitting deferred to future phase due to complexity --- ...s.mdx => rust-to-solidity-differences.mdx} | 7 ++- ...evm-differences.mdx => vm-differences.mdx} | 9 ++- docs/stylus/fundamentals/prerequisites.mdx | 63 +++++++++++++++++++ docs/stylus/partials/_setup-cargo-stylus.mdx | 21 +++++++ docs/stylus/partials/_setup-docker-nitro.mdx | 34 ++++++++++ .../stylus/partials/_setup-rust-toolchain.mdx | 26 ++++++++ docs/stylus/quickstart.mdx | 23 +++++++ docs/stylus/reference/overview.mdx | 2 +- sidebars.js | 13 ++-- 9 files changed, 188 insertions(+), 10 deletions(-) rename docs/stylus/advanced/{solidity-differences.mdx => rust-to-solidity-differences.mdx} (98%) rename docs/stylus/concepts/{evm-differences.mdx => vm-differences.mdx} (98%) create mode 100644 docs/stylus/fundamentals/prerequisites.mdx create mode 100644 docs/stylus/partials/_setup-cargo-stylus.mdx create mode 100644 docs/stylus/partials/_setup-docker-nitro.mdx create mode 100644 docs/stylus/partials/_setup-rust-toolchain.mdx diff --git a/docs/stylus/advanced/solidity-differences.mdx b/docs/stylus/advanced/rust-to-solidity-differences.mdx similarity index 98% rename from docs/stylus/advanced/solidity-differences.mdx rename to docs/stylus/advanced/rust-to-solidity-differences.mdx index 984ab66bc4..18f813863e 100644 --- a/docs/stylus/advanced/solidity-differences.mdx +++ b/docs/stylus/advanced/rust-to-solidity-differences.mdx @@ -1,6 +1,9 @@ --- -title: 'Differences between Solidity and Stylus' -description: 'Learn the key differences between writing smart contracts in Solidity versus Stylus Rust' +title: 'Rust to Solidity differences' +sidebar_label: 'Rust to Solidity' +description: 'Language and syntax differences between Rust Stylus and Solidity smart contracts' +user_story: 'As a Solidity developer, I want to understand how to write contracts in Rust' +content_type: concept author: chrisco sme: chrisco sidebar_position: 1 diff --git a/docs/stylus/concepts/evm-differences.mdx b/docs/stylus/concepts/vm-differences.mdx similarity index 98% rename from docs/stylus/concepts/evm-differences.mdx rename to docs/stylus/concepts/vm-differences.mdx index e844c7a6ee..dd5008f529 100644 --- a/docs/stylus/concepts/evm-differences.mdx +++ b/docs/stylus/concepts/vm-differences.mdx @@ -1,9 +1,12 @@ --- -title: 'EVM and WASM VM differences' -description: 'Understand the key differences between the traditional EVM and Nitro WASM VM for Stylus contracts' +title: 'VM and execution differences' +sidebar_label: 'VM differences' +description: 'Understand the differences between EVM and WASM execution models in Stylus' +user_story: 'As a developer, I want to understand how WASM execution differs from EVM' +content_type: concept author: chrisco sme: chrisco -sidebar_position: 1 +sidebar_position: 4 target_audience: Developers who need to understand how Stylus works with EVM differences. displayed_sidebar: buildStylusSidebar --- diff --git a/docs/stylus/fundamentals/prerequisites.mdx b/docs/stylus/fundamentals/prerequisites.mdx new file mode 100644 index 0000000000..225fc8df88 --- /dev/null +++ b/docs/stylus/fundamentals/prerequisites.mdx @@ -0,0 +1,63 @@ +--- +title: 'Prerequisites and setup' +sidebar_label: 'Prerequisites' +description: 'Set up your development environment for Stylus' +user_story: 'As a new Stylus developer, I want to set up my development environment' +content_type: how-to +author: offchainlabs +sme: offchainlabs +sidebar_position: 1 +--- + +import RustSetup from '../partials/_setup-rust-toolchain.mdx'; +import CargoStylusSetup from '../partials/_setup-cargo-stylus.mdx'; +import DockerSetup from '../partials/_setup-docker-nitro.mdx'; + +# Prerequisites and setup + +This guide will help you set up everything you need to develop Stylus contracts. + +## System requirements + +- **Operating System**: macOS, Linux, or Windows (WSL2) +- **RAM**: Minimum 8GB, 16GB recommended +- **Disk Space**: At least 20GB free + +## Install Rust + + + +## Install cargo-stylus CLI + + + +## Install Docker (for local testnet) + + + +## Verify installation + +```shell +# Check Rust version +rustc --version + +# Check cargo-stylus +cargo stylus --version + +# Check Docker +docker --version +``` + +Expected output: + +``` +rustc 1.75.0 (or higher) +cargo-stylus 0.x.x +Docker version 24.0.0 (or higher) +``` + +## Next steps + +- [Create your first project](/stylus/quickstart) +- [Understand project structure](/stylus/fundamentals/project-structure) +- [Learn about contracts](/stylus/fundamentals/contracts) diff --git a/docs/stylus/partials/_setup-cargo-stylus.mdx b/docs/stylus/partials/_setup-cargo-stylus.mdx new file mode 100644 index 0000000000..44240df72e --- /dev/null +++ b/docs/stylus/partials/_setup-cargo-stylus.mdx @@ -0,0 +1,21 @@ +### Installing cargo-stylus + +The `cargo-stylus` CLI tool helps you create, build, and deploy Stylus contracts. + +**Install:** + +```shell +cargo install cargo-stylus +``` + +**Verify:** + +```shell +cargo stylus --version +``` + +**Update:** + +```shell +cargo install cargo-stylus --force +``` diff --git a/docs/stylus/partials/_setup-docker-nitro.mdx b/docs/stylus/partials/_setup-docker-nitro.mdx new file mode 100644 index 0000000000..964ca14fa6 --- /dev/null +++ b/docs/stylus/partials/_setup-docker-nitro.mdx @@ -0,0 +1,34 @@ +### Installing Docker for local testing + +A local Arbitrum Nitro devnode allows you to test contracts before deploying to testnet. + +**macOS:** + +Download [Docker Desktop for Mac](https://docs.docker.com/desktop/install/mac-install/). + +**Linux:** + +```shell +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +``` + +**Windows:** + +Download [Docker Desktop for Windows](https://docs.docker.com/desktop/install/windows-install/) (requires WSL2). + +**Start Nitro devnode:** + +```shell +git clone https://github.com/OffchainLabs/nitro-devnode.git +cd nitro-devnode +./run-dev-node.sh +``` + +**Verify:** + +```shell +curl -X POST http://localhost:8547 \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' +``` diff --git a/docs/stylus/partials/_setup-rust-toolchain.mdx b/docs/stylus/partials/_setup-rust-toolchain.mdx new file mode 100644 index 0000000000..aa63142a64 --- /dev/null +++ b/docs/stylus/partials/_setup-rust-toolchain.mdx @@ -0,0 +1,26 @@ +### Installing Rust + +The Rust toolchain includes `rustc` (compiler), `cargo` (package manager), and `rustup` (version manager). + +**macOS/Linux:** + +```shell +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +**Windows:** + +Download and run [rustup-init.exe](https://rustup.rs/). + +**Configure for WASM:** + +```shell +rustup target add wasm32-unknown-unknown +``` + +**Verify:** + +```shell +rustc --version +cargo --version +``` diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 445db38a13..ad86f7f71c 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -25,6 +25,29 @@ This guide will get you started with Stylus' 6. [Calling your contract](./quickstart#calling-your-contract) 7. [Sending a transaction to your contract](./quickstart#sending-a-transaction-to-your-contract) +## Your journey + +This quickstart follows a simple path from project creation to successful contract interaction: + +```mermaid +journey + title Quickstart Journey + section Setup + Create project: 5: Developer + Check validity: 3: Developer + section Deploy + Deploy contract: 4: Developer + Export ABI: 3: Developer + section Interact + Call contract: 5: Developer + Send transaction: 4: Developer + Verify results: 5: Developer +``` + +_Figure: Your path through this quickstart guide, from project creation to successful contract interaction._ + +Let's get started! + ## Setting up your development environment ### Prerequisites diff --git a/docs/stylus/reference/overview.mdx b/docs/stylus/reference/overview.mdx index 44fd8f15de..9db6b602fa 100644 --- a/docs/stylus/reference/overview.mdx +++ b/docs/stylus/reference/overview.mdx @@ -48,7 +48,7 @@ Explore advanced features and optimization techniques for Stylus development. | Article | Description | | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| [Solidity differences](/stylus/advanced/solidity-differences) | Understand key differences between writing smart contracts in Solidity versus Stylus Rust. | +| [Rust to Solidity differences](/stylus/advanced/rust-to-solidity-differences) | Understand key differences between writing smart contracts in Solidity versus Stylus Rust. | | [Recommended packages](/stylus/advanced/recommended-libraries) | Discover third-party Rust crates that work well with Stylus for extended functionality. | | [Minimal entrypoint contracts](/stylus/advanced/minimal-entrypoint-contracts) | Build lightweight contracts with custom entrypoints for maximum gas efficiency. | | [Hostio exports](/stylus/advanced/hostio-exports) | Access low-level host I/O functions for advanced contract behavior. | diff --git a/sidebars.js b/sidebars.js index 262c665d74..4ad240ccf6 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1600,6 +1600,11 @@ const sidebars = { type: 'generated-index', }, items: [ + { + type: 'doc', + id: 'stylus/fundamentals/prerequisites', + label: 'Prerequisites', + }, { type: 'doc', id: 'stylus/fundamentals/project-structure', @@ -1746,8 +1751,8 @@ const sidebars = { }, { type: 'doc', - id: 'stylus/concepts/evm-differences', - label: 'EVM differences', + id: 'stylus/concepts/vm-differences', + label: 'VM differences', }, { type: 'doc', @@ -1762,8 +1767,8 @@ const sidebars = { items: [ { type: 'doc', - id: 'stylus/advanced/solidity-differences', - label: 'Solidity differences', + id: 'stylus/advanced/rust-to-solidity-differences', + label: 'Rust to Solidity', }, { type: 'doc', From 31ec111f09a84ca3ea30594b865da3179543fa2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:09 -0800 Subject: [PATCH 110/162] docs: add choose your learning path guide --- docs/stylus/fundamentals/choose-your-path.mdx | 285 ++++++++++++++++++ 1 file changed, 285 insertions(+) create mode 100644 docs/stylus/fundamentals/choose-your-path.mdx diff --git a/docs/stylus/fundamentals/choose-your-path.mdx b/docs/stylus/fundamentals/choose-your-path.mdx new file mode 100644 index 0000000000..30d90d3fa8 --- /dev/null +++ b/docs/stylus/fundamentals/choose-your-path.mdx @@ -0,0 +1,285 @@ +--- +title: 'Choose your learning path' +sidebar_label: 'Choose your path' +description: 'Find the right Stylus learning path based on your background and goals' +user_story: 'As a developer new to Stylus, I want to find the most efficient learning path based on my background' +content_type: concept +author: offchainlabs +sme: offchainlabs +sidebar_position: 0 +--- + +import ImageZoom from '@site/src/components/ImageZoom'; + +# Choose your learning path + +Not sure where to start with Stylus? This guide helps you find the optimal learning path based on your background and goals. + +## Quick path selector + +```mermaid +graph TD + A[Start Here] --> B{Do you have Rust experience?} + B -->|Yes| C{Have you written smart contracts?} + B -->|No| D[Path 1: Learn Rust First] + C -->|Yes, in Solidity| E[Path 2: Solidity to Stylus] + C -->|Yes, in other languages| F[Path 3: Smart Contract Developer] + C -->|No| G[Path 4: Rust Developer New to Web3] + + D --> D1[1. Rust Book Chapters 1-10] + D1 --> D2[2. Stylus Quickstart] + D2 --> D3[3. Fundamentals] + + E --> E1[1. Rust to Solidity Differences] + E1 --> E2[2. Quickstart] + E2 --> E3[3. Migration Patterns] + + F --> F1[1. Quickstart] + F1 --> F2[2. EVM Differences] + F2 --> F3[3. Advanced Topics] + + G --> G1[1. Web3 Concepts] + G1 --> G2[2. Quickstart] + G2 --> G3[3. Smart Contract Patterns] + + style A fill:#e1f5ff + style D fill:#fff4e1 + style E fill:#e8f5e9 + style F fill:#f3e5f5 + style G fill:#ffe0e0 +``` + +_Figure: Choose your learning path based on your background and experience._ + +## Path 1: New to Rust + +**Best for**: Developers experienced with other languages but new to Rust. + +### Prerequisites + +- Basic programming knowledge +- Familiarity with concepts like variables, functions, and control flow +- Optional: Smart contract development experience + +### Recommended journey + +1. **Learn Rust basics** (1-2 weeks) + + - Work through [The Rust Book](https://doc.rust-lang.org/book/) chapters 1-10 + - Focus on: ownership, borrowing, structs, enums, error handling + - Practice with [Rustlings](https://github.com/rust-lang/rustlings) + +2. **Start with Stylus** (2-3 days) + + - Complete the [Quickstart](/stylus/quickstart) + - Understand [project structure](/stylus/fundamentals/project-structure) + - Deploy your first contract + +3. **Build fundamentals** (1 week) + + - Study [data types](/stylus/fundamentals/data-types/primitives) + - Learn [storage patterns](/stylus/fundamentals/data-types/storage) + - Practice [writing tests](/stylus/fundamentals/testing-contracts) + +4. **Explore advanced topics** (ongoing) + - Review [best practices](/stylus/best-practices/security) + - Study [gas optimization](/stylus/best-practices/gas-optimization) + - Build real projects + +### Key resources + +- [The Rust Book](https://doc.rust-lang.org/book/) +- [Stylus Quickstart](/stylus/quickstart) +- [Stylus by Example](https://stylus-by-example.org/) + +--- + +## Path 2: Solidity developer + +**Best for**: Experienced Solidity developers transitioning to Stylus. + +### Prerequisites + +- Strong Solidity knowledge +- Understanding of EVM and smart contract security +- No Rust experience required + +### Recommended journey + +1. **Understand the differences** (1 day) + + - Read [Rust to Solidity differences](/stylus/advanced/rust-to-solidity-differences) + - Review [VM differences](/stylus/concepts/vm-differences) + - Understand [type conversions](/stylus/fundamentals/data-types/conversions-between-types) + +2. **Quick start** (1-2 days) + + - Complete the [Quickstart](/stylus/quickstart) + - Compare with familiar Solidity patterns + - Deploy a simple contract + +3. **Learn Rust patterns** (3-5 days) + + - Study [ownership and borrowing](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html) + - Learn [error handling](/stylus/fundamentals/data-types/primitives) + - Understand [storage macros](/stylus/fundamentals/data-types/storage) + +4. **Port existing contracts** (ongoing) + - Start with simple contracts + - Apply [security best practices](/stylus/best-practices/security) + - Optimize for [gas efficiency](/stylus/best-practices/gas-optimization) + +### Common migration patterns + +| Solidity Pattern | Stylus Equivalent | Guide | +| ----------------------------- | --------------------------- | ----------------------------------------------------------------------- | +| `mapping(address => uint)` | `StorageMap` | [Storage types](/stylus/fundamentals/data-types/storage) | +| `require(condition, "error")` | `ensure!(condition, Error)` | [Error handling](/stylus/fundamentals/contracts#error-handling) | +| `msg.sender` | `msg::sender()` | [Global functions](/stylus/fundamentals/global-variables-and-functions) | +| `constructor` | `impl` with initialization | [Contracts](/stylus/fundamentals/contracts) | +| Events | Derive `Erase` trait | [Events guide](/stylus/guides/events-and-logs) | + +### Key resources + +- [Rust to Solidity Differences](/stylus/advanced/rust-to-solidity-differences) +- [Stylus by Example](https://stylus-by-example.org/) +- [Solidity to Rust Cheat Sheet](https://docs.arbitrum.io/stylus) + +--- + +## Path 3: Smart contract developer (non-Solidity) + +**Best for**: Developers experienced with other smart contract platforms (Move, Cairo, Clarity, etc.). + +### Prerequisites + +- Smart contract development experience +- Understanding of blockchain concepts +- Basic programming knowledge + +### Recommended journey + +1. **Jump right in** (1-2 days) + + - Complete the [Quickstart](/stylus/quickstart) + - Explore [project structure](/stylus/fundamentals/project-structure) + - Deploy and interact with a contract + +2. **Understand the execution model** (2-3 days) + + - Study [WebAssembly concepts](/stylus/concepts/webassembly) + - Review [VM differences](/stylus/concepts/vm-differences) + - Learn about [activation](/stylus/concepts/activation) + +3. **Master Rust for smart contracts** (1 week) + + - Focus on [storage patterns](/stylus/fundamentals/data-types/storage) + - Learn [contract structure](/stylus/fundamentals/contracts) + - Understand [testing approaches](/stylus/fundamentals/testing-contracts) + +4. **Advanced development** (ongoing) + - Apply platform-specific optimizations + - Implement [cross-contract calls](/stylus/guides/cross-contract-calls) + - Build production applications + +### Key resources + +- [Quickstart](/stylus/quickstart) +- [WebAssembly Concepts](/stylus/concepts/webassembly) +- [Advanced Topics](/stylus/advanced/rust-to-solidity-differences) + +--- + +## Path 4: Rust developer new to Web3 + +**Best for**: Experienced Rust developers entering blockchain development. + +### Prerequisites + +- Strong Rust knowledge +- Understanding of ownership, traits, and async programming +- No blockchain experience required + +### Recommended journey + +1. **Learn blockchain basics** (2-3 days) + + - Understand [smart contracts](https://ethereum.org/en/developers/docs/smart-contracts/) + - Learn about [gas and transactions](https://ethereum.org/en/developers/docs/gas/) + - Study [EVM basics](https://ethereum.org/en/developers/docs/evm/) + +2. **Quick start with Stylus** (1 day) + + - Complete the [Quickstart](/stylus/quickstart) + - Your Rust skills transfer directly! + - Deploy your first contract + +3. **Web3-specific patterns** (3-5 days) + + - Learn [storage patterns](/stylus/fundamentals/data-types/storage) + - Understand [global variables](/stylus/fundamentals/global-variables-and-functions) + - Study [security considerations](/stylus/best-practices/security) + +4. **Build applications** (ongoing) + - Start with simple DeFi primitives + - Implement [events and logs](/stylus/guides/events-and-logs) + - Optimize for [gas efficiency](/stylus/best-practices/gas-optimization) + +### Rust skills that transfer well + +- **Ownership model**: Natural fit for secure contract design +- **Type safety**: Prevents common smart contract bugs +- **Error handling**: `Result` maps perfectly to contract errors +- **Testing**: Your testing skills apply directly +- **Performance optimization**: Critical for gas efficiency + +### Key resources + +- [Ethereum Smart Contracts](https://ethereum.org/en/developers/docs/smart-contracts/) +- [Stylus Quickstart](/stylus/quickstart) +- [Storage Patterns](/stylus/fundamentals/data-types/storage) + +--- + +## General learning resources + +Regardless of your path, these resources are valuable: + +### Official documentation + +- [Stylus Rust SDK Docs](https://docs.rs/stylus-sdk/latest/stylus_sdk/) +- [Cargo Stylus CLI](https://github.com/OffchainLabs/cargo-stylus) +- [Stylus by Example](https://stylus-by-example.org/) + +### Community and support + +- [Arbitrum Discord](https://discord.gg/arbitrum) +- [Developer Forums](https://forum.arbitrum.foundation/) +- [GitHub Discussions](https://github.com/OffchainLabs/stylus-sdk-rs/discussions) + +### Practice projects + +1. **Token contract**: Implement ERC-20 token standard +2. **NFT contract**: Build ERC-721 compatible NFT +3. **Simple DeFi**: Create a basic AMM or lending protocol +4. **DAO governance**: Implement voting and proposal system + +## Need help choosing? + +Still not sure which path is right for you? Consider these questions: + +- **Do you want to learn Rust?** โ†’ Path 1 or Path 4 +- **Do you already know Solidity?** โ†’ Path 2 +- **Are you experienced with other smart contract platforms?** โ†’ Path 3 +- **Do you want the fastest path to deployment?** โ†’ Path 2 or Path 3 +- **Do you want to deeply understand the technology?** โ†’ Path 1 or Path 4 + +## Next steps + +Ready to start? Begin with these essential guides: + +1. [Prerequisites and setup](/stylus/fundamentals/prerequisites) +2. [Quickstart: Deploy your first contract](/stylus/quickstart) +3. [Project structure](/stylus/fundamentals/project-structure) + +Good luck on your Stylus journey! From d7fa3bd827a0b3ae44190122da02e82bed2faf6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:16 -0800 Subject: [PATCH 111/162] docs: add security best practices guide --- docs/stylus/best-practices/security.mdx | 501 ++++++++++++++++++++++++ 1 file changed, 501 insertions(+) create mode 100644 docs/stylus/best-practices/security.mdx diff --git a/docs/stylus/best-practices/security.mdx b/docs/stylus/best-practices/security.mdx new file mode 100644 index 0000000000..6750cbfbb6 --- /dev/null +++ b/docs/stylus/best-practices/security.mdx @@ -0,0 +1,501 @@ +--- +title: 'Security best practices' +sidebar_label: 'Security' +description: 'Essential security patterns and guidelines for writing secure Stylus smart contracts' +user_story: 'As a developer, I want to write secure Stylus contracts that protect user funds and prevent exploits' +content_type: concept +author: offchainlabs +sme: offchainlabs +sidebar_position: 1 +--- + +# Security best practices + +Writing secure smart contracts is critical - vulnerabilities can lead to loss of funds and user trust. This guide covers essential security patterns for Stylus development. + +## Core security principles + +### 1. Input validation + +Always validate external inputs before using them in your contract logic. + +```rust +use stylus_sdk::{prelude::*, msg}; +use alloy_primitives::{Address, U256}; + +#[external] +impl MyContract { + // โŒ Bad: No validation + pub fn transfer_bad(&mut self, recipient: Address, amount: U256) -> Result<(), Vec> { + let sender = msg::sender(); + self.balances.setter(sender).sub_assign(amount); + self.balances.setter(recipient).add_assign(amount); + Ok(()) + } + + // โœ… Good: Proper validation + pub fn transfer_good(&mut self, recipient: Address, amount: U256) -> Result<(), Vec> { + // Validate inputs + ensure!(!recipient.is_zero(), "Invalid recipient"); + ensure!(amount > U256::ZERO, "Amount must be positive"); + + let sender = msg::sender(); + let sender_balance = self.balances.get(sender); + + // Check sufficient balance + ensure!(sender_balance >= amount, "Insufficient balance"); + + // Safe arithmetic + self.balances.setter(sender).sub_assign(amount); + self.balances.setter(recipient).add_assign(amount); + + Ok(()) + } +} +``` + +### 2. Access control + +Implement proper authorization checks for privileged operations. + +```rust +use stylus_sdk::{prelude::*, msg, storage::StorageAddress}; + +sol_storage! { + pub struct Ownable { + StorageAddress owner; + } +} + +#[external] +impl Ownable { + // Initialize owner in constructor-like pattern + pub fn init(&mut self) -> Result<(), Vec> { + let owner = self.owner.get(); + ensure!(owner.is_zero(), "Already initialized"); + self.owner.set(msg::sender()); + Ok(()) + } + + // Modifier pattern for owner-only functions + fn only_owner(&self) -> Result<(), Vec> { + ensure!(msg::sender() == self.owner.get(), "Not authorized"); + Ok(()) + } + + pub fn sensitive_operation(&mut self) -> Result<(), Vec> { + self.only_owner()?; + // Perform privileged operation + Ok(()) + } + + pub fn transfer_ownership(&mut self, new_owner: Address) -> Result<(), Vec> { + self.only_owner()?; + ensure!(!new_owner.is_zero(), "Invalid new owner"); + self.owner.set(new_owner); + Ok(()) + } +} +``` + +### 3. Reentrancy protection + +Protect against reentrancy attacks using the checks-effects-interactions pattern. + +```rust +use stylus_sdk::{prelude::*, call::transfer_eth, msg}; + +sol_storage! { + pub struct Vault { + StorageMap balances; + StorageBool locked; // Reentrancy guard + } +} + +#[external] +impl Vault { + // โŒ Bad: Vulnerable to reentrancy + pub fn withdraw_bad(&mut self, amount: U256) -> Result<(), Vec> { + let sender = msg::sender(); + let balance = self.balances.get(sender); + + ensure!(balance >= amount, "Insufficient balance"); + + // DANGER: External call before state update + transfer_eth(sender, amount)?; + + // State updated after external call - vulnerable! + self.balances.setter(sender).sub_assign(amount); + Ok(()) + } + + // โœ… Good: Checks-Effects-Interactions pattern + pub fn withdraw_good(&mut self, amount: U256) -> Result<(), Vec> { + // Check: Reentrancy guard + ensure!(!self.locked.get(), "Reentrancy detected"); + self.locked.set(true); + + let sender = msg::sender(); + let balance = self.balances.get(sender); + + // Check: Validate conditions + ensure!(balance >= amount, "Insufficient balance"); + + // Effect: Update state BEFORE external call + self.balances.setter(sender).sub_assign(amount); + + // Interaction: External call last + let result = transfer_eth(sender, amount); + + // Release lock + self.locked.set(false); + + result + } +} +``` + +### 4. Safe arithmetic + +While Rust prevents overflows in debug mode, use explicit checks for production. + +```rust +use alloy_primitives::U256; + +#[external] +impl SafeMath { + // โœ… Use checked arithmetic + pub fn safe_add(&self, a: U256, b: U256) -> Result> { + a.checked_add(b).ok_or("Arithmetic overflow".into()) + } + + pub fn safe_mul(&self, a: U256, b: U256) -> Result> { + a.checked_mul(b).ok_or("Arithmetic overflow".into()) + } + + // โœ… Validate before operations + pub fn calculate_fee(&self, amount: U256, basis_points: U256) -> Result> { + ensure!(basis_points <= U256::from(10000), "Invalid fee"); + + amount + .checked_mul(basis_points) + .and_then(|v| v.checked_div(U256::from(10000))) + .ok_or("Fee calculation failed".into()) + } +} +``` + +## Common vulnerabilities + +### Integer overflow/underflow + +**Risk**: Arithmetic operations that exceed type limits can cause unexpected behavior. + +**Prevention**: + +```rust +// โœ… Use checked operations +let result = value.checked_add(amount).ok_or("Overflow")?; + +// โœ… Or use saturating operations when appropriate +let capped_value = value.saturating_add(amount); +``` + +### Unchecked external calls + +**Risk**: Failed external calls may be silently ignored. + +**Prevention**: + +```rust +// โŒ Bad: Ignoring call result +let _ = external_contract.call(data); + +// โœ… Good: Handle all results +external_contract.call(data).map_err(|e| "External call failed")?; +``` + +### Front-running + +**Risk**: Transactions visible in mempool can be exploited by miners or bots. + +**Prevention**: + +```rust +// โœ… Use commit-reveal pattern for sensitive operations +sol_storage! { + pub struct CommitReveal { + StorageMap commits; + StorageMap reveal_times; + } +} + +impl CommitReveal { + pub fn commit(&mut self, commitment: [u8; 32]) -> Result<(), Vec> { + let sender = msg::sender(); + self.commits.setter(sender).set(commitment); + self.reveal_times.setter(sender).set(block::timestamp() + 100); + Ok(()) + } + + pub fn reveal(&mut self, value: U256, salt: [u8; 32]) -> Result<(), Vec> { + let sender = msg::sender(); + + // Verify commit period passed + ensure!( + block::timestamp() >= self.reveal_times.get(sender), + "Too early to reveal" + ); + + // Verify commitment + let expected = keccak256(&[&value.to_be_bytes(), &salt].concat()); + ensure!( + expected == self.commits.get(sender), + "Invalid reveal" + ); + + // Process reveal... + Ok(()) + } +} +``` + +### Denial of Service (DoS) + +**Risk**: Unbounded loops or operations that can be griefed. + +**Prevention**: + +```rust +// โŒ Bad: Unbounded loop +pub fn distribute_rewards_bad(&mut self, recipients: Vec
    ) -> Result<(), Vec> { + for recipient in recipients { + // Could run out of gas with too many recipients + self.send_reward(recipient)?; + } + Ok(()) +} + +// โœ… Good: Paginated or pull-based pattern +pub fn distribute_rewards_good( + &mut self, + start_index: U256, + count: U256 +) -> Result<(), Vec> { + ensure!(count <= U256::from(50), "Batch too large"); + + let end = start_index + count; + for i in start_index..end { + let recipient = self.recipients.get(i); + if !recipient.is_zero() { + self.send_reward(recipient)?; + } + } + Ok(()) +} + +// โœ… Better: Pull-based (users claim their own rewards) +pub fn claim_reward(&mut self) -> Result<(), Vec> { + let sender = msg::sender(); + let reward = self.pending_rewards.get(sender); + + ensure!(reward > U256::ZERO, "No rewards"); + + self.pending_rewards.setter(sender).set(U256::ZERO); + transfer_eth(sender, reward)?; + + Ok(()) +} +``` + +## Storage security + +### Visibility and access patterns + +```rust +sol_storage! { + pub struct SecureVault { + // Public read, controlled write + StorageU256 public_total; + + // Private storage - not visible off-chain without knowing slot + StorageMap private_balances; + + // Owner-controlled + StorageAddress owner; + } +} + +#[external] +impl SecureVault { + // โœ… Expose only what's necessary + pub fn get_total(&self) -> U256 { + self.public_total.get() + } + + // โœ… Don't expose internal mappings directly + pub fn get_balance(&self, account: Address) -> Result> { + ensure!(msg::sender() == account || msg::sender() == self.owner.get(), "Unauthorized"); + Ok(self.private_balances.get(account)) + } +} +``` + +### Prevent storage collisions + +```rust +// โœ… Use unique storage namespace for upgradeable contracts +sol_storage! { + pub struct MyContract { + // Prefix with contract name to avoid collisions + #[borrow] + MyContractStorage storage; + } +} + +sol_storage! { + pub struct MyContractStorage { + StorageU256 value; + StorageMap balances; + } +} +``` + +## Error handling + +### Informative error messages + +```rust +#[derive(SolidityError)] +pub enum MyError { + InsufficientBalance(U256), + Unauthorized(Address), + InvalidAmount(U256), + TransferFailed(Address, U256), +} + +#[external] +impl MyContract { + pub fn transfer(&mut self, to: Address, amount: U256) -> Result<(), MyError> { + let sender = msg::sender(); + let balance = self.balances.get(sender); + + if balance < amount { + return Err(MyError::InsufficientBalance(balance)); + } + + if to.is_zero() { + return Err(MyError::InvalidAmount(amount)); + } + + // Transfer logic... + Ok(()) + } +} +``` + +### Fail securely + +```rust +// โœ… Fail closed, not open +pub fn privileged_function(&mut self) -> Result<(), Vec> { + // Default to denying access + let is_authorized = self.check_authorization(msg::sender()); + + // Explicit check required to proceed + ensure!(is_authorized, "Access denied"); + + // Privileged operation + Ok(()) +} +``` + +## Testing for security + +### Write comprehensive tests + +```rust +#[cfg(test)] +mod tests { + use super::*; + use stylus_sdk::testing::*; + + #[test] + fn test_reentrancy_protection() { + let vm = TestVM::default(); + let mut contract = Vault::from(&vm); + + // Setup + contract.deposit(U256::from(100)).unwrap(); + + // Attempt reentrancy + let result = contract.withdraw(U256::from(50)); + assert!(result.is_ok()); + + // Second withdrawal should fail if still locked + let result2 = contract.withdraw(U256::from(50)); + assert!(result2.is_err()); + } + + #[test] + fn test_access_control() { + let vm = TestVM::default(); + let mut contract = Ownable::from(&vm); + + // Initialize owner + contract.init().unwrap(); + + // Non-owner should be rejected + vm.set_caller(address!("0x0000000000000000000000000000000000000001")); + assert!(contract.sensitive_operation().is_err()); + + // Owner should succeed + vm.set_caller(/* original owner */); + assert!(contract.sensitive_operation().is_ok()); + } + + #[test] + fn test_arithmetic_safety() { + let vm = TestVM::default(); + let contract = SafeMath::from(&vm); + + // Test overflow + let max = U256::MAX; + let result = contract.safe_add(max, U256::from(1)); + assert!(result.is_err()); + + // Test valid operation + let result = contract.safe_add(U256::from(1), U256::from(2)); + assert_eq!(result.unwrap(), U256::from(3)); + } +} +``` + +## Security checklist + +Before deploying your contract, verify: + +- [ ] All external inputs are validated +- [ ] Access control is implemented for privileged functions +- [ ] Reentrancy guards protect state-changing functions +- [ ] Arithmetic operations use checked methods +- [ ] External call results are handled +- [ ] Error messages don't leak sensitive information +- [ ] Storage visibility is appropriate +- [ ] No unbounded loops or arrays +- [ ] Critical functions have comprehensive tests +- [ ] Code has been reviewed by another developer +- [ ] Consider professional audit for high-value contracts + +## Additional resources + +- [Stylus Security Audit](https://docs.arbitrum.io/stylus/reference/audit-reports) +- [Rust Security Guidelines](https://anssi-fr.github.io/rust-guide/) +- [Smart Contract Security Best Practices](https://consensys.github.io/smart-contract-best-practices/) +- [OWASP Smart Contract Top 10](https://owasp.org/www-project-smart-contract-top-10/) + +## Next steps + +- Review [gas optimization best practices](/stylus/best-practices/gas-optimization) +- Study [error handling patterns](/stylus/fundamentals/contracts#error-handling) +- Explore [testing strategies](/stylus/fundamentals/testing-contracts) From 80ec73842f24b906e4857dfc2591b755cdddcd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:23 -0800 Subject: [PATCH 112/162] docs: add gas optimization best practices guide --- .../best-practices/gas-optimization.mdx | 548 ++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 docs/stylus/best-practices/gas-optimization.mdx diff --git a/docs/stylus/best-practices/gas-optimization.mdx b/docs/stylus/best-practices/gas-optimization.mdx new file mode 100644 index 0000000000..80a4a9eb84 --- /dev/null +++ b/docs/stylus/best-practices/gas-optimization.mdx @@ -0,0 +1,548 @@ +--- +title: 'Gas optimization best practices' +sidebar_label: 'Gas optimization' +description: 'Techniques and patterns for optimizing gas costs in Stylus smart contracts' +user_story: 'As a developer, I want to minimize gas costs for my Stylus contracts while maintaining functionality' +content_type: concept +author: offchainlabs +sme: offchainlabs +sidebar_position: 2 +--- + +# Gas optimization best practices + +Stylus contracts offer significant gas savings compared to Solidity (10-100x for compute-heavy operations), but following optimization best practices can reduce costs even further. + +## Why Stylus is cheaper + +```mermaid +graph LR + A[Solidity Contract] -->|Compiled to| B[EVM Bytecode] + C[Rust Contract] -->|Compiled to| D[WASM] + + B -->|Interpreted| E[Gas: Higher] + D -->|Native Execution| F[Gas: Lower] + + style E fill:#ffcccc + style F fill:#ccffcc +``` + +_Figure: Stylus WASM executes natively, avoiding EVM interpretation overhead._ + +### Performance comparison + +| Operation | Solidity (EVM) | Stylus (WASM) | Savings | +| ---------------------- | -------------- | ------------- | ----------- | +| Keccak256 hashing | ~30 gas/byte | ~3 gas/byte | **10x** | +| Signature verification | ~3,000 gas | ~300 gas | **10x** | +| Memory operations | ~3 gas/word | ~0.3 gas/word | **10x** | +| Compute-heavy loops | High | Very low | **50-100x** | +| Storage operations | Same | Same | **1x** | + +**Key insight**: Storage operations cost the same in Stylus and Solidity. Optimize by reducing storage access and maximizing compute efficiency. + +## Storage optimization + +### 1. Minimize storage reads + +```rust +// โŒ Bad: Multiple storage reads +pub fn calculate_bad(&self, iterations: u32) -> U256 { + let mut result = U256::ZERO; + for i in 0..iterations { + // Reads from storage every iteration! + result += self.multiplier.get(); + } + result +} + +// โœ… Good: Cache storage value +pub fn calculate_good(&self, iterations: u32) -> U256 { + // Read once, use many times + let multiplier = self.multiplier.get(); + + let mut result = U256::ZERO; + for i in 0..iterations { + result += multiplier; + } + result +} +``` + +**Gas impact**: Each storage read costs ~100 gas. The optimized version can save thousands of gas for large loops. + +### 2. Batch storage writes + +```rust +// โŒ Bad: Multiple separate writes +pub fn update_user_bad(&mut self, addr: Address, amount: U256, active: bool) { + self.balances.setter(addr).set(amount); + self.last_update.setter(addr).set(block::timestamp()); + self.is_active.setter(addr).set(active); +} + +// โœ… Good: Combine into struct +sol_storage! { + pub struct UserData { + U256 balance; + U256 last_update; + bool is_active; + } + + pub struct OptimizedContract { + StorageMap users; + } +} + +pub fn update_user_good(&mut self, addr: Address, amount: U256, active: bool) { + let mut user = self.users.setter(addr); + user.balance.set(amount); + user.last_update.set(block::timestamp()); + user.is_active.set(active); + // Single storage slot update instead of three +} +``` + +### 3. Use appropriate data types + +```rust +// โŒ Bad: Oversized types +sol_storage! { + pub struct Wasteful { + StorageU256 tiny_counter; // Only needs u8 + StorageU256 timestamp; // Only needs u64 + StorageU256 percentage; // Only needs u16 + } +} + +// โœ… Good: Right-sized types +sol_storage! { + pub struct Efficient { + StorageU8 tiny_counter; // Saves 31 bytes + StorageU64 timestamp; // Saves 24 bytes + StorageU16 percentage; // Saves 30 bytes + } +} +``` + +**Note**: While smaller types save storage space, they don't reduce gas for individual storage operations. The benefit comes from packing multiple small values in one slot (if your storage layout supports it). + +### 4. Delete unused storage + +```rust +pub fn cleanup(&mut self, addr: Address) -> Result<(), Vec> { + let balance = self.balances.get(addr); + + ensure!(balance == U256::ZERO, "Balance not zero"); + + // โœ… Deleting storage refunds gas + self.balances.delete(addr); + self.metadata.delete(addr); + + Ok(()) +} +``` + +**Gas refund**: Deleting storage refunds up to 15,000 gas per slot cleared. + +## Memory optimization + +### 1. Avoid unnecessary clones + +```rust +use alloy_primitives::Bytes; + +// โŒ Bad: Unnecessary cloning +pub fn process_data_bad(&self, data: Bytes) -> Bytes { + let copy = data.clone(); // Expensive memory allocation + copy +} + +// โœ… Good: Use references +pub fn process_data_good(&self, data: &Bytes) -> &Bytes { + data // No clone needed +} + +// โœ… Good: Move when possible +pub fn consume_data(mut data: Bytes) -> Bytes { + data.extend_from_slice(&[1, 2, 3]); + data // Ownership moved, no clone +} +``` + +### 2. Use iterators efficiently + +```rust +// โŒ Bad: Collect into vector unnecessarily +pub fn sum_bad(&self, values: Vec) -> U256 { + let filtered: Vec = values + .iter() + .filter(|v| **v > U256::ZERO) + .copied() + .collect(); // Allocates new vector + + filtered.iter().sum() +} + +// โœ… Good: Chain iterators +pub fn sum_good(&self, values: Vec) -> U256 { + values + .iter() + .filter(|v| **v > U256::ZERO) + .sum() // No intermediate allocation +} +``` + +### 3. Reuse allocations + +```rust +// โœ… Reuse buffers for repeated operations +pub fn process_batch(&mut self, items: Vec) -> Vec { + let mut buffer = Vec::with_capacity(items.len()); + + for item in items { + buffer.clear(); // Reuse allocation + buffer.extend_from_slice(&item); + // Process buffer... + } + + buffer +} +``` + +## Computation optimization + +### 1. Use Stylus for compute-heavy operations + +```rust +// โœ… Stylus excels at complex computation +pub fn verify_merkle_proof( + &self, + leaf: [u8; 32], + proof: Vec<[u8; 32]>, + root: [u8; 32] +) -> bool { + let mut computed_hash = leaf; + + // This loop is 10-50x cheaper in Stylus than Solidity + for proof_element in proof { + computed_hash = if computed_hash <= proof_element { + keccak256(&[computed_hash, proof_element].concat()) + } else { + keccak256(&[proof_element, computed_hash].concat()) + }; + } + + computed_hash == root +} +``` + +**Why it's faster**: Native WASM execution vs. EVM interpretation makes loops dramatically cheaper. + +### 2. Optimize hot paths + +```rust +// โœ… Optimize frequently-called functions +#[inline(always)] +pub fn is_valid_amount(&self, amount: U256) -> bool { + amount > U256::ZERO && amount <= self.max_amount.get() +} + +// Use in hot path +pub fn transfer(&mut self, to: Address, amount: U256) -> Result<(), Vec> { + ensure!(self.is_valid_amount(amount), "Invalid amount"); + // Transfer logic... + Ok(()) +} +``` + +### 3. Avoid redundant checks + +```rust +// โŒ Bad: Redundant zero check +pub fn add_to_balance_bad(&mut self, addr: Address, amount: U256) -> Result<(), Vec> { + ensure!(amount > U256::ZERO, "Amount must be positive"); + + let current = self.balances.get(addr); + ensure!(current + amount > current, "Overflow"); // Redundant if amount > 0 + + self.balances.setter(addr).add_assign(amount); + Ok(()) +} + +// โœ… Good: Single overflow check covers both +pub fn add_to_balance_good(&mut self, addr: Address, amount: U256) -> Result<(), Vec> { + let current = self.balances.get(addr); + + let new_balance = current + .checked_add(amount) + .ok_or("Overflow or invalid amount")?; + + self.balances.setter(addr).set(new_balance); + Ok(()) +} +``` + +## Function call optimization + +### 1. Minimize cross-contract calls + +```rust +// โŒ Bad: Multiple external calls +pub fn get_price_bad(&self, token: Address) -> Result> { + let oracle = IOracle::new(self.oracle_address.get()); + + let price = oracle.get_price(self, token)?; + let decimals = oracle.get_decimals(self, token)?; // Second call + let timestamp = oracle.get_timestamp(self, token)?; // Third call + + Ok(price) +} + +// โœ… Good: Batch external calls +pub fn get_price_good(&self, token: Address) -> Result> { + let oracle = IOracle::new(self.oracle_address.get()); + + // Single call returns all data + oracle.get_price_data(self, token) +} +``` + +**Gas impact**: Each external call has overhead. Batching reduces cost significantly. + +### 2. Use internal functions + +```rust +// โœ… Extract common logic to internal functions +impl MyContract { + // Internal helper (no ABI encoding overhead) + fn internal_validate(&self, addr: Address, amount: U256) -> Result<(), Vec> { + ensure!(!addr.is_zero(), "Invalid address"); + ensure!(amount > U256::ZERO, "Invalid amount"); + Ok(()) + } + + // Public functions use internal helper + #[external] + pub fn deposit(&mut self, amount: U256) -> Result<(), Vec> { + self.internal_validate(msg::sender(), amount)?; + // Deposit logic... + Ok(()) + } + + #[external] + pub fn withdraw(&mut self, amount: U256) -> Result<(), Vec> { + self.internal_validate(msg::sender(), amount)?; + // Withdraw logic... + Ok(()) + } +} +``` + +## Event optimization + +### 1. Use indexed parameters wisely + +```rust +sol! { + // โœ… Index frequently-queried fields (max 3 indexed) + event Transfer( + address indexed from, + address indexed to, + uint256 value // Not indexed - saves gas + ); + + // โŒ Bad: Too many indexed parameters + event TooManyIndexed( + address indexed from, + address indexed to, + uint256 indexed amount, // Expensive to index + uint256 indexed timestamp // 4th indexed param - not allowed! + ); +} +``` + +**Gas impact**: Each indexed parameter costs ~375 additional gas. Only index fields you'll search by. + +### 2. Batch events when possible + +```rust +// โœ… Emit single event for batch operation +sol! { + event BatchTransfer( + address indexed from, + address[] to, + uint256[] amounts + ); +} + +pub fn batch_transfer( + &mut self, + recipients: Vec
    , + amounts: Vec +) -> Result<(), Vec> { + // Process transfers... + + // Single event instead of N events + evm::log(BatchTransfer { + from: msg::sender(), + to: recipients, + amounts, + }); + + Ok(()) +} +``` + +## Binary size optimization + +Smaller WASM binaries cost less to deploy and activate. + +### 1. Optimize compilation flags + +```toml +# Cargo.toml +[profile.release] +opt-level = "z" # Optimize for size +lto = true # Link-time optimization +codegen-units = 1 # Better optimization +strip = true # Remove debug symbols +panic = "abort" # Smaller panic handling +``` + +### 2. Avoid large dependencies + +```rust +// โŒ Bad: Heavy dependency for simple task +use fancy_math_library::complex_sqrt; // Adds 50KB to binary + +pub fn calculate(&self, value: U256) -> U256 { + complex_sqrt(value) // Using 1% of library +} + +// โœ… Good: Implement simple operations yourself +pub fn simple_sqrt(&self, value: U256) -> U256 { + // Custom implementation adds minimal binary size + // Newton's method or similar +} +``` + +### 3. Use cargo stylus optimization + +```shell +# Check binary size +cargo stylus check + +# Optimize with wasm-opt +cargo stylus deploy --optimize + +# Maximum optimization (slower build, smaller binary) +cargo stylus deploy --optimize-level 3 +``` + +## Gas measurement + +### 1. Profile your contracts + +```rust +#[cfg(test)] +mod gas_tests { + use super::*; + + #[test] + fn benchmark_transfer() { + let vm = TestVM::default(); + let mut contract = Token::from(&vm); + + // Measure gas for operation + let gas_before = vm.gas_left(); + contract.transfer(recipient, amount).unwrap(); + let gas_used = gas_before - vm.gas_left(); + + println!("Transfer gas used: {}", gas_used); + assert!(gas_used < 50000, "Transfer too expensive"); + } +} +``` + +### 2. Compare implementations + +```rust +#[cfg(test)] +mod optimization_tests { + #[test] + fn compare_storage_patterns() { + // Test pattern A + let gas_a = measure_pattern_a(); + + // Test pattern B + let gas_b = measure_pattern_b(); + + println!("Pattern A: {} gas", gas_a); + println!("Pattern B: {} gas", gas_b); + println!("Savings: {}%", (gas_a - gas_b) * 100 / gas_a); + } +} +``` + +## Optimization checklist + +Before deploying, verify you've: + +- [ ] Minimized storage reads and writes +- [ ] Cached frequently-accessed storage values +- [ ] Used appropriate data types +- [ ] Deleted unused storage for gas refunds +- [ ] Avoided unnecessary clones and allocations +- [ ] Optimized hot code paths +- [ ] Minimized cross-contract calls +- [ ] Used indexed events sparingly +- [ ] Optimized WASM binary size +- [ ] Profiled gas usage for critical functions +- [ ] Compared against Solidity baseline (if porting) + +## Common optimizations summary + +| Pattern | Gas Savings | Complexity | +| ------------------------- | ------------------------------ | ---------- | +| Cache storage reads | High (100+ gas per read saved) | Low | +| Delete unused storage | Medium (15,000 gas refund) | Low | +| Batch storage writes | Medium (varies) | Medium | +| Use iterators vs. collect | Low-Medium | Low | +| Minimize external calls | High | Medium | +| Optimize binary size | High (deployment only) | Medium | +| Right-size data types | Low-Medium | Low | + +## Advanced optimization + +### Custom memory allocators + +For advanced users, custom allocators can reduce memory overhead: + +```rust +#[global_allocator] +static ALLOCATOR: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +``` + +**Warning**: Only use if you understand the trade-offs. + +### Assembly optimization + +For critical paths, you can use WASM intrinsics: + +```rust +use core::arch::wasm32::*; + +// โœ… Advanced: Use WASM intrinsics for critical operations +pub fn optimized_hash(&self, data: &[u8]) -> [u8; 32] { + // WASM-optimized hashing + // Only use if you're an advanced developer +} +``` + +## Next steps + +- Apply [security best practices](/stylus/best-practices/security) +- Study [deployment optimization](/stylus/guides/optimizing-binaries) +- Learn about [caching strategies](/stylus/guides/caching-contracts) +- Review [debugging techniques](/stylus/cli-tools/debugging-tx) From 780c0225e181584e1c0fadef186eba2d49fafa4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:31 -0800 Subject: [PATCH 113/162] docs: add troubleshooting guide for common issues --- docs/stylus/troubleshooting/common-issues.mdx | 591 ++++++++++++++++++ 1 file changed, 591 insertions(+) create mode 100644 docs/stylus/troubleshooting/common-issues.mdx diff --git a/docs/stylus/troubleshooting/common-issues.mdx b/docs/stylus/troubleshooting/common-issues.mdx new file mode 100644 index 0000000000..77dbe35048 --- /dev/null +++ b/docs/stylus/troubleshooting/common-issues.mdx @@ -0,0 +1,591 @@ +--- +title: 'Common issues and solutions' +sidebar_label: 'Common issues' +description: 'Troubleshooting guide for frequently encountered Stylus development issues' +user_story: 'As a developer, I want to quickly resolve common errors and issues when building with Stylus' +content_type: troubleshooting +author: offchainlabs +sme: offchainlabs +sidebar_position: 1 +--- + +# Common issues and solutions + +This guide covers frequently encountered issues in Stylus development with step-by-step solutions. + +## Installation and setup + +### cargo stylus not found + +**Problem**: Running `cargo stylus` returns "command not found." + +**Solution**: + +```shell +# Install cargo-stylus +cargo install --force cargo-stylus + +# Verify installation +cargo stylus --version + +# If still not found, check your PATH includes ~/.cargo/bin +echo $PATH | grep cargo +``` + +**Alternative**: Add cargo bin to your PATH: + +```shell +# Add to ~/.bashrc or ~/.zshrc +export PATH="$HOME/.cargo/bin:$PATH" + +# Reload shell configuration +source ~/.bashrc # or source ~/.zshrc +``` + +### WASM target not installed + +**Problem**: Build fails with "can't find crate for `std`" or "target 'wasm32-unknown-unknown' not found." + +**Solution**: + +```shell +# Add WASM target for your Rust version +rustup target add wasm32-unknown-unknown + +# If using specific toolchain +rustup target add wasm32-unknown-unknown --toolchain 1.81 +``` + +**Verify**: + +```shell +rustup target list | grep wasm32 +# Should show: wasm32-unknown-unknown (installed) +``` + +### Docker not running + +**Problem**: `cargo stylus check` fails with "Cannot connect to Docker daemon." + +**Solution**: + +1. Start Docker Desktop +2. Verify Docker is running: + +```shell +docker ps +``` + +3. If still failing, restart Docker: + +```shell +# macOS/Linux +sudo systemctl restart docker + +# Or restart Docker Desktop application +``` + +## Build errors + +### Contract exceeds size limit + +**Problem**: "Program activation failed: program too large." + +**Solution**: + +1. **Optimize build settings** in `Cargo.toml`: + +```toml +[profile.release] +opt-level = "z" # Optimize for size +lto = true # Link-time optimization +codegen-units = 1 # Better optimization +strip = true # Remove debug symbols +panic = "abort" # Smaller panic handling +``` + +2. **Use wasm-opt**: + +```shell +cargo stylus check --wasm-opt +``` + +3. **Remove unused dependencies**: + +```toml +# Remove unnecessary features +stylus-sdk = { version = "0.8", default-features = false } +``` + +4. **Check binary size**: + +```shell +ls -lh target/wasm32-unknown-unknown/release/*.wasm +``` + +See [Optimizing binaries guide](/stylus/guides/optimizing-binaries) for more strategies. + +### Linker errors + +**Problem**: Build fails with linker errors or "undefined reference" messages. + +**Solution**: + +```shell +# Clean build artifacts +cargo clean + +# Rebuild +cargo build --target wasm32-unknown-unknown --release + +# If still failing, update Rust +rustup update +``` + +### Dependency compilation failures + +**Problem**: Dependencies fail to compile for WASM target. + +**Solution**: + +1. **Check dependency compatibility**: Not all crates support WASM. Look for: + + - `no_std` support + - WASM-compatible versions + - Alternatives designed for blockchain + +2. **Disable incompatible features**: + +```toml +[dependencies] +# Disable std-only features +serde = { version = "1.0", default-features = false, features = ["derive"] } +``` + +3. **Use Stylus-compatible alternatives**: See [recommended libraries](/stylus/advanced/recommended-libraries). + +## Deployment errors + +### Insufficient funds + +**Problem**: "Insufficient funds for gas \* price + value." + +**Solution**: + +```shell +# Check your balance +cast balance --rpc-url + +# Fund your account (testnet) +# Visit faucet: https://faucet.quicknode.com/arbitrum/sepolia +``` + +### Activation failed + +**Problem**: "Program activation failed" after deployment. + +**Solution**: + +1. **Check contract size**: + +```shell +cargo stylus check +``` + +2. **Verify WASM validity**: + +```shell +# Ensure binary is valid WASM +wasm-validate target/wasm32-unknown-unknown/release/*.wasm +``` + +3. **Check gas limits**: + +```shell +# Increase gas limit for activation +cargo stylus deploy \ + --endpoint= \ + --private-key= \ + --gas-limit=10000000 +``` + +See [Activation concepts](/stylus/concepts/activation) for more details. + +### Transaction reverted + +**Problem**: Deployment transaction reverts without clear error. + +**Solution**: + +1. **Enable verbose logging**: + +```shell +RUST_LOG=debug cargo stylus deploy \ + --endpoint= \ + --private-key= +``` + +2. **Check network status**: + +```shell +# Verify RPC is responding +cast block-number --rpc-url +``` + +3. **Use replay for debugging**: + +```shell +cargo stylus replay \ + --endpoint= \ + +``` + +## Runtime errors + +### Panic in contract code + +**Problem**: Contract panics during execution. + +**Solution**: + +1. **Use `Result` instead of `panic!`**: + +```rust +// โŒ Bad: Panics +pub fn divide(&self, a: U256, b: U256) -> U256 { + if b.is_zero() { + panic!("Division by zero"); + } + a / b +} + +// โœ… Good: Returns error +pub fn divide(&self, a: U256, b: U256) -> Result> { + ensure!(!b.is_zero(), "Division by zero"); + Ok(a / b) +} +``` + +2. **Enable backtrace for debugging**: + +```shell +RUST_BACKTRACE=1 cargo test +``` + +### Storage slot conflicts + +**Problem**: Storage values overwriting each other unexpectedly. + +**Solution**: + +1. **Use explicit storage layout**: + +```rust +sol_storage! { + pub struct MyContract { + #[borrow] // Use borrow for nested structs + StorageMap users; + + StorageU256 total_supply; + } +} +``` + +2. **Avoid manual slot manipulation** unless necessary. + +3. **Check for storage collisions** in upgradeable contracts. + +### Out of gas + +**Problem**: Transactions fail with "out of gas" error. + +**Solution**: + +1. **Optimize loops**: + +```rust +// โŒ Bad: Unbounded loop +pub fn process_all(&self, items: Vec
    ) -> Result<(), Vec> { + for item in items { + self.process(item)?; // Could exceed gas limit + } + Ok(()) +} + +// โœ… Good: Paginated +pub fn process_batch(&self, items: Vec
    , max: usize) -> Result<(), Vec> { + for item in items.iter().take(max) { + self.process(*item)?; + } + Ok(()) +} +``` + +2. **Increase gas limit** when calling: + +```shell +cast send "function()" \ + --gas-limit 1000000 \ + --rpc-url \ + --private-key +``` + +3. **Profile gas usage**: + +```shell +cargo stylus trace --endpoint +``` + +See [Gas optimization guide](/stylus/best-practices/gas-optimization) for more strategies. + +## Testing issues + +### Tests failing with storage errors + +**Problem**: Tests fail with "storage not initialized" or similar errors. + +**Solution**: + +```rust +#[cfg(test)] +mod tests { + use super::*; + use stylus_sdk::testing::*; + + #[test] + fn test_contract() { + // โœ… Always initialize TestVM + let vm = TestVM::default(); + let mut contract = MyContract::from(&vm); + + // Configure test environment + vm.set_caller(address!("0x0000000000000000000000000000000000000001")); + + // Run tests + assert_eq!(contract.get_value().unwrap(), U256::ZERO); + } +} +``` + +### Tests pass locally but fail on CI + +**Problem**: Tests work on your machine but fail in continuous integration. + +**Solution**: + +1. **Pin Rust version** in `rust-toolchain.toml`: + +```toml +[toolchain] +channel = "1.81" +components = ["rustfmt", "clippy"] +targets = ["wasm32-unknown-unknown"] +``` + +2. **Ensure WASM target in CI**: + +```yaml +# .github/workflows/test.yml +- name: Add WASM target + run: rustup target add wasm32-unknown-unknown +``` + +3. **Check for environment-specific dependencies**. + +## ABI and integration + +### ABI export fails + +**Problem**: `cargo stylus export-abi` returns empty or incorrect ABI. + +**Solution**: + +1. **Ensure methods use `#[external]` macro**: + +```rust +#[external] +impl MyContract { + // โœ… This will be exported + pub fn public_method(&self) -> U256 { + U256::from(42) + } + + // โŒ This won't be exported (no #[external]) + fn internal_method(&self) -> U256 { + U256::from(42) + } +} +``` + +2. **Check for compilation errors**: + +```shell +cargo build --target wasm32-unknown-unknown --release +cargo stylus export-abi +``` + +### Type conversion errors + +**Problem**: "Type mismatch" when calling from Solidity or TypeScript. + +**Solution**: + +1. **Use explicit type conversions**: + +```rust +use stylus_sdk::abi::AbiType; + +// โœ… Ensure types match Solidity ABI +pub fn get_balance(&self, account: Address) -> U256 { + self.balances.get(account) +} +``` + +2. **Check ABI matches expectations**: + +```shell +cargo stylus export-abi > abi.json +# Verify types in abi.json match your frontend +``` + +See [Type conversions guide](/stylus/fundamentals/data-types/conversions-between-types). + +## Network and RPC issues + +### RPC connection timeout + +**Problem**: "Connection timeout" or "Connection refused" errors. + +**Solution**: + +1. **Verify RPC URL**: + +```shell +# Test RPC connection +curl -X POST \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' +``` + +2. **Check rate limits**: Public RPCs may have rate limits. Consider: + + - Using a dedicated RPC provider + - Adding retry logic + - Implementing backoff strategies + +3. **Network-specific endpoints**: + - Arbitrum Sepolia: https://sepolia-rollup.arbitrum.io/rpc + - Arbitrum One: https://arb1.arbitrum.io/rpc + +### Nonce errors + +**Problem**: "Nonce too low" or "nonce too high" errors. + +**Solution**: + +1. **Let tooling manage nonces** (default behavior): + +```shell +# cargo stylus automatically manages nonces +cargo stylus deploy --endpoint --private-key +``` + +2. **Reset nonce manually if needed**: + +```shell +# Check current nonce +cast nonce --rpc-url + +# Send transaction with specific nonce +cast send "function()" \ + --nonce \ + --rpc-url \ + --private-key +``` + +## Debugging strategies + +### Enable verbose logging + +```shell +# Set log level +export RUST_LOG=debug + +# Run with logging +cargo stylus check +cargo stylus deploy --endpoint --private-key +``` + +### Use replay debugging + +```shell +# Replay failed transaction +cargo stylus replay \ + --endpoint \ + + +# With GDB for advanced debugging +cargo stylus replay \ + --endpoint \ + --use-gdb \ + +``` + +See [Debugging guide](/stylus/cli-tools/debugging-tx) for detailed walkthrough. + +### Trace execution + +```shell +# Trace transaction execution +cargo stylus trace --endpoint +``` + +### Check contract state + +```shell +# Read storage values +cast storage --rpc-url + +# Call view functions +cast call "getValue()(uint256)" --rpc-url +``` + +## Getting help + +If you're still stuck: + +1. **Check documentation**: Search [Stylus docs](https://docs.arbitrum.io/stylus) +2. **Search GitHub issues**: [Stylus SDK Issues](https://github.com/OffchainLabs/stylus-sdk-rs/issues) +3. **Ask in Discord**: [Arbitrum Discord](https://discord.gg/arbitrum) #stylus channel +4. **Post in forums**: [Arbitrum Developer Forum](https://forum.arbitrum.foundation/) + +### Creating a good bug report + +Include: + +- Rust version: `rustc --version` +- cargo-stylus version: `cargo stylus --version` +- Minimal reproducible example +- Full error message and stack trace +- Steps to reproduce +- Expected vs. actual behavior + +## Common error messages quick reference + +| Error Message | Common Cause | Quick Fix | +| ------------------------------------------ | ------------------------- | ------------------------------------------ | +| "target not found: wasm32-unknown-unknown" | WASM target not installed | `rustup target add wasm32-unknown-unknown` | +| "Cannot connect to Docker daemon" | Docker not running | Start Docker Desktop | +| "Program too large" | Binary exceeds size limit | Add optimization flags, use `--wasm-opt` | +| "Insufficient funds" | Not enough ETH for gas | Fund account from faucet | +| "Nonce too low" | Nonce mismatch | Let tooling manage nonces | +| "Out of gas" | Gas limit exceeded | Increase gas limit or optimize code | +| "Storage not initialized" | Missing TestVM setup | Initialize `TestVM::default()` in tests | +| "Division by zero" | Unchecked arithmetic | Use `ensure!()` or `checked_div()` | + +## Next steps + +- Review [security best practices](/stylus/best-practices/security) +- Study [gas optimization](/stylus/best-practices/gas-optimization) +- Learn [debugging techniques](/stylus/cli-tools/debugging-tx) +- Explore [testing strategies](/stylus/fundamentals/testing-contracts) From a226564898436266de57e5203923a2faa889e28a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:38 -0800 Subject: [PATCH 114/162] docs: add contract lifecycle diagram to contracts fundamentals --- docs/stylus/fundamentals/contracts.mdx | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/stylus/fundamentals/contracts.mdx b/docs/stylus/fundamentals/contracts.mdx index f644c2f3fb..be84facf16 100644 --- a/docs/stylus/fundamentals/contracts.mdx +++ b/docs/stylus/fundamentals/contracts.mdx @@ -18,6 +18,34 @@ A Stylus contract consists of three main components: 2. **Entrypoint**: Marks the main contract struct that handles incoming calls 3. **Public Methods**: Functions exposed to external callers via the `#[public]` macro +```mermaid +graph TD + A[Write Rust Code] --> B[Compile to WASM] + B --> C[Deploy Bytecode] + C --> D[Activate Program] + D --> E[Contract Ready] + + E --> F{Incoming Call} + F -->|External call| G[user_entrypoint] + G --> H[Route to Method] + H --> I{Method Type} + + I -->|View| J[Read Storage] + I -->|Mutable| K[Modify Storage] + + J --> L[Return Result] + K --> L + + L --> M[ABI Encode Response] + M --> N[Return to Caller] + + style A fill:#FFE4B5 + style E fill:#90EE90 + style N fill:#87CEEB +``` + +_Figure: Contract lifecycle from development through execution, showing how calls are routed and processed._ + ### Minimal Contract Here's the simplest possible Stylus contract: From 237dd3807352dfa8bacbdd1d5e6f3d7a407862cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:45 -0800 Subject: [PATCH 115/162] docs: add WASM execution pipeline diagram to WebAssembly concepts --- docs/stylus/concepts/webassembly.mdx | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 255e373188..cc7d9260dd 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -29,6 +29,33 @@ Nitro uses WebAssembly as its execution environment for several reasons: 4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM 5. **Determinism**: Guaranteed identical execution across all validators +```mermaid +graph TB + subgraph "Developer Side" + A[Rust/C/C++ Code] --> B[Compiler] + B --> C[WASM Binary] + end + + subgraph "Arbitrum Nitro" + C --> D[Brotli Decompression] + D --> E[WASM Validation] + E --> F[JIT Compilation] + F --> G[Native Machine Code] + + subgraph "Execution Environment" + G --> H[Contract Execution] + H <--> I[Hostio Functions] + I <--> J[EVM State] + end + end + + style A fill:#FFE4B5 + style G fill:#90EE90 + style J fill:#87CEEB +``` + +_Figure: WebAssembly execution pipeline in Arbitrum Nitro, from source code to native execution with access to blockchain state._ + ## WASM compilation target Stylus contracts are compiled to the `wasm32-unknown-unknown` target, which means: From 07680e8301047ff89546e2a1e10dc767e1febaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:10:52 -0800 Subject: [PATCH 116/162] docs: update sidebar to include Phase 4 content (choose your path, best practices, troubleshooting) --- sidebars.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sidebars.js b/sidebars.js index 4ad240ccf6..c854d004cb 100644 --- a/sidebars.js +++ b/sidebars.js @@ -1600,6 +1600,11 @@ const sidebars = { type: 'generated-index', }, items: [ + { + type: 'doc', + id: 'stylus/fundamentals/choose-your-path', + label: 'Choose your path', + }, { type: 'doc', id: 'stylus/fundamentals/prerequisites', @@ -1730,6 +1735,41 @@ const sidebars = { }, ], }, + { + type: 'category', + label: 'Best Practices', + collapsed: true, + link: { + type: 'generated-index', + }, + items: [ + { + type: 'doc', + id: 'stylus/best-practices/security', + label: 'Security', + }, + { + type: 'doc', + id: 'stylus/best-practices/gas-optimization', + label: 'Gas optimization', + }, + ], + }, + { + type: 'category', + label: 'Troubleshooting', + collapsed: true, + link: { + type: 'generated-index', + }, + items: [ + { + type: 'doc', + id: 'stylus/troubleshooting/common-issues', + label: 'Common issues', + }, + ], + }, { type: 'category', label: 'Concepts', From 6921a077e271f8449e3604b16437fe221fb757b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:11:01 -0800 Subject: [PATCH 117/162] chore: add automatic redirects for Phase 4 documentation --- vercel.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vercel.json b/vercel.json index 4ff0dfa351..4a0f5be6ec 100644 --- a/vercel.json +++ b/vercel.json @@ -245,6 +245,16 @@ "destination": "/how-arbitrum-works/bold/gentle-introduction", "permanent": false }, + { + "source": "/(docs/stylus/advanced/solidity-differences/?)", + "destination": "/(docs/stylus/advanced/rust-to-solidity-differences/?)", + "permanent": false + }, + { + "source": "/(docs/stylus/concepts/evm-differences/?)", + "destination": "/(docs/stylus/concepts/vm-differences/?)", + "permanent": false + }, { "source": "/(docs/stylus/how-tos/adding-support-for-new-languages/?)", "destination": "/(docs/stylus/guides/adding-support-for-new-languages/?)", From fb7882080ff350fc4863a2af49c2f91b056c5825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:14:19 -0800 Subject: [PATCH 118/162] docs: add storage slot layout diagram to storage fundamentals --- .../fundamentals/data-types/storage.mdx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/stylus/fundamentals/data-types/storage.mdx b/docs/stylus/fundamentals/data-types/storage.mdx index 4f28fcfa2a..4788a0ef93 100644 --- a/docs/stylus/fundamentals/data-types/storage.mdx +++ b/docs/stylus/fundamentals/data-types/storage.mdx @@ -975,6 +975,25 @@ Stylus uses the same storage layout as Solidity: - Variables are **packed** when possible to save space - Arrays and mappings use **computed slots** via hashing +```mermaid +flowchart TB + subgraph "Storage Slots (32 bytes each)" + Slot0["Slot 0
    uint256 value"] + Slot1["Slot 1
    address (20 bytes) + uint96 (12 bytes)"] + Slot2["Slot 2
    Mapping base slot"] + Slot3["Slot 3
    keccak256(key || slot)"] + end + + Mapping["Mapping[key]"] -->|"hash(key + 2)"| Slot3 + + style Slot0 fill:#E3F2FD + style Slot1 fill:#FFF3E0 + style Slot2 fill:#F3E5F5 + style Slot3 fill:#E8F5E9 +``` + +_Figure: Storage slot layout showing how variables are packed into 32-byte slots and how mapping values are computed using keccak256 hashing._ + ```rust sol_storage! { pub struct Packed { From ead3c4cf2c1d6c8fc5aae37d1de18104dc38bfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:14:26 -0800 Subject: [PATCH 119/162] docs: add WASM binary structure and memory model diagrams to WebAssembly concepts --- docs/stylus/concepts/webassembly.mdx | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index cc7d9260dd..2b0755ac58 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -85,6 +85,29 @@ rustflags = [ A Stylus WASM module consists of several sections: +```mermaid +graph TB + WASM["WASM Module"] + + WASM --> Exports["Exports Section
    user_entrypoint"] + WASM --> Imports["Imports Section
    vm_hooks"] + WASM --> Memory["Memory Section
    Linear memory"] + WASM --> Custom["Custom Sections
    Metadata"] + WASM --> Code["Code Section
    Compiled bytecode"] + + Imports --> storage_load["storage_load_bytes32"] + Imports --> msg_sender["msg_sender"] + Imports --> emit_log["emit_log"] + + style WASM fill:#E1BEE7 + style Exports fill:#C8E6C9 + style Imports fill:#BBDEFB + style Memory fill:#FFE0B2 + style Code fill:#F3E5F5 +``` + +_Figure: WASM module structure showing the main sections including exports, imports (hostio functions), memory, and code._ + ### Exports Every Stylus contract exports a `user_entrypoint` function: @@ -300,6 +323,30 @@ To stay within limits: ## Memory model +```mermaid +graph TB + subgraph "WASM Linear Memory" + Stack["Stack
    32 KB
    (fixed)"] + Heap["Heap/Data
    (grows upward)"] + Page1["Page 1
    64 KB"] + Page2["Page 2
    64 KB"] + PageN["Page N
    64 KB"] + end + + Stack -.fixed allocation.-> Page1 + Heap -->|grows into| Page1 + Heap -->|expands to| Page2 + Heap -.may grow to.-> PageN + + style Stack fill:#FFEBEE + style Heap fill:#E8F5E9 + style Page1 fill:#E3F2FD + style Page2 fill:#F3E5F5 + style PageN fill:#FFF3E0 +``` + +_Figure: WASM linear memory model showing the fixed 32KB stack and growable heap organized in 64KB pages._ + ### Linear memory layout ``` From b8f3a6b48d9ed426dfbc22bbe7e41e6d8ea8ede1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:25:58 -0800 Subject: [PATCH 120/162] docs: add comprehensive Stylus documentation structure reference - ASCII art tree of entire documentation structure - Statistics on diagrams, directories, and files - Phase-by-phase breakdown of restructure - Icon legend and quick navigation guides - Git tag reference for rollback capability --- docs/stylus/STRUCTURE.md | 270 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 docs/stylus/STRUCTURE.md diff --git a/docs/stylus/STRUCTURE.md b/docs/stylus/STRUCTURE.md new file mode 100644 index 0000000000..2488b3067c --- /dev/null +++ b/docs/stylus/STRUCTURE.md @@ -0,0 +1,270 @@ +# Stylus Documentation Structure + +This document provides a visual overview of the Stylus documentation structure after the v0.10 restructure. + +``` +docs/stylus/ +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“˜ gentle-introduction.mdx +โ”œโ”€โ”€ ๐Ÿš€ quickstart.mdx +โ”œโ”€โ”€ ๐Ÿ”ง using-cli.mdx (legacy) +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ fundamentals/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿงญ choose-your-path.mdx โญ NEW (Phase 4) +โ”‚ โ”œโ”€โ”€ โš™๏ธ prerequisites.mdx (Phase 3) +โ”‚ โ”œโ”€โ”€ ๐Ÿ“ project-structure.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ“œ contracts.mdx [๐Ÿ“Š Lifecycle Diagram] +โ”‚ โ”œโ”€โ”€ ๐ŸŒ global-variables-and-functions.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿงช testing-contracts.mdx +โ”‚ โ””โ”€โ”€ ๐Ÿ“‚ data-types/ +โ”‚ โ”œโ”€โ”€ ๐Ÿ”ค primitives.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ”  compound-types.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ’พ storage.mdx [๐Ÿ“Š 2 Diagrams: Hierarchy + Layout] +โ”‚ โ””โ”€โ”€ ๐Ÿ”„ conversions-between-types.mdx +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ guides/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿ—๏ธ using-constructors.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ”— using-inheritance.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ“ค importing-interfaces.mdx [๐Ÿ“Š Call Diagram] +โ”‚ โ”œโ”€โ”€ ๐Ÿ“‹ exporting-abi.mdx +โ”‚ โ”œโ”€โ”€ โšก optimizing-binaries.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ’จ caching-contracts.mdx +โ”‚ โ”œโ”€โ”€ ๐ŸŒ deploying-non-rust-wasm-contracts.mdx +โ”‚ โ””โ”€โ”€ ๐Ÿ†• adding-support-for-new-languages.mdx +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ cli-tools/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿ“– overview.mdx +โ”‚ โ”œโ”€โ”€ โœ… check-and-deploy.mdx +โ”‚ โ”œโ”€โ”€ โœ”๏ธ verify-contracts.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ› debugging-tx.mdx +โ”‚ โ””โ”€โ”€ ๐Ÿ“š commands-reference.mdx +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ best-practices/ โญ NEW (Phase 4) +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿ”’ security.mdx (501 lines) +โ”‚ โ””โ”€โ”€ โšก gas-optimization.mdx [๐Ÿ“Š Comparison Diagram] (548 lines) +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ troubleshooting/ โญ NEW (Phase 4) +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ โ“ common-issues.mdx (591 lines) +โ”‚ โ””โ”€โ”€ ๐Ÿ”ง troubleshooting-building-stylus.md (legacy) +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ concepts/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐ŸŒ webassembly.mdx [๐Ÿ“Š 3 Diagrams: Pipeline + Binary + Memory] +โ”‚ โ”œโ”€โ”€ ๐Ÿš€ activation.mdx [๐Ÿ“Š Deployment Diagram] +โ”‚ โ”œโ”€โ”€ โ›ฝ gas-metering.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ”„ vm-differences.mdx (renamed in Phase 3) +โ”‚ โ””โ”€โ”€ ๐Ÿ‘๏ธ public-preview-expectations.mdx +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ advanced/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿ”€ rust-to-solidity-differences.mdx (renamed in Phase 3) +โ”‚ โ”œโ”€โ”€ ๐ŸŽฏ minimal-entrypoint-contracts.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ”Œ hostio-exports.mdx +โ”‚ โ””โ”€โ”€ ๐Ÿ“ฆ recommended-libraries.mdx +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ reference/ +โ”‚ โ”œโ”€โ”€ _category_.yml +โ”‚ โ”œโ”€โ”€ ๐Ÿ“– overview.mdx +โ”‚ โ”œโ”€โ”€ ๐Ÿ’ฐ opcode-hostio-pricing.mdx +โ”‚ โ””โ”€โ”€ ๐Ÿ“˜ rust-sdk-guide.md +โ”‚ +โ”œโ”€โ”€ ๐Ÿ“‚ partials/ (Reusable Content) +โ”‚ โ”œโ”€โ”€ _setup-rust-toolchain.mdx +โ”‚ โ”œโ”€โ”€ _setup-cargo-stylus.mdx +โ”‚ โ”œโ”€โ”€ _setup-docker-nitro.mdx +โ”‚ โ”œโ”€โ”€ _stylus-faucets.mdx +โ”‚ โ”œโ”€โ”€ _stylus-no-multi-inheritance-banner-partial.mdx +โ”‚ โ””โ”€โ”€ _stylus-public-preview-banner-partial.md +โ”‚ +โ””โ”€โ”€ ๐Ÿ“‚ planning/ (Phase Guides) + โ”œโ”€โ”€ RESTRUCTURE_README.md + โ”œโ”€โ”€ IMPLEMENTATION_GUIDE.md + โ”œโ”€โ”€ IMPLEMENTATION_GUIDE_PHASE3.md + โ”œโ”€โ”€ IMPLEMENTATION_GUIDE_PHASE4.md + โ””โ”€โ”€ IMPLEMENTATION_GUIDE_PHASE5.md +``` + +## Statistics + +### ๐Ÿ“Š Diagrams: 11 total + +| File | Diagrams | Description | +| ----------------------------------- | -------- | ---------------------------------------------------- | +| fundamentals/choose-your-path.mdx | 1 | Learning path decision tree | +| fundamentals/contracts.mdx | 1 | Contract lifecycle flow | +| fundamentals/data-types/storage.mdx | 2 | Type hierarchy + Slot layout | +| guides/importing-interfaces.mdx | 1 | Cross-contract calls | +| best-practices/gas-optimization.mdx | 1 | Stylus vs Solidity performance | +| concepts/webassembly.mdx | 3 | Execution pipeline + Binary structure + Memory model | +| concepts/activation.mdx | 1 | WASM deployment process | +| quickstart.mdx | 1 | User journey through quickstart | + +### ๐Ÿ“ Directory Structure + +**10 top-level directories:** + +- `fundamentals/` - Core concepts and data types +- `guides/` - How-to guides for common tasks +- `cli-tools/` - CLI commands and usage +- `best-practices/` โญ NEW - Security and optimization +- `troubleshooting/` โญ NEW - Common issues and solutions +- `concepts/` - Deep-dive conceptual explanations +- `advanced/` - Advanced topics and low-level details +- `reference/` - API reference and SDK documentation +- `partials/` - Reusable content snippets +- `planning/` - Restructure implementation guides + +### ๐Ÿ“„ File Inventory + +**Total:** ~58 documentation files + +**By Phase:** + +- **Phase 2:** Moved 19 files, created new directory structure +- **Phase 3:** Created 4 new files (prerequisites + 3 partials) +- **Phase 4:** Created 4 major files (choose-your-path, security, gas-optimization, common-issues) +- **Phase 5:** Added 3 diagrams to existing files + +**Major Content:** + +- Phase 4 new content: ~1,925 lines across 4 files +- Comprehensive security guide: 501 lines +- Complete gas optimization guide: 548 lines +- Troubleshooting FAQ: 591 lines +- Learning path guide: 285 lines + +### ๐Ÿท๏ธ Navigation Improvements + +- **Before:** 4+ levels deep (confusing hierarchy) +- **After:** Maximum 3 levels (clear, scannable structure) +- **Sidebar categories:** 9 main sections (down from 15+ scattered sections) + +## Phase Highlights + +### Phase 1: Planning + +- Analyzed existing structure +- Identified pain points +- Created comprehensive restructure plan + +### Phase 2: Directory Restructure + +- Created 5 new top-level directories +- Moved 19 files to logical locations +- Flattened sidebar from 4+ to max 3 levels +- Updated 80+ navigation items + +### Phase 3: Content Consolidation + +- Created reusable setup partials (3 files) +- Renamed confusing files (evmโ†’vm, solidityโ†’rust-to-solidity) +- Added prerequisites guide +- Added journey diagram to quickstart +- Eliminated duplicate content + +### Phase 4: New Content Creation + +- Choose Your Path guide (4 learning paths) +- Security Best Practices (comprehensive) +- Gas Optimization Best Practices (Stylus-specific) +- Troubleshooting guide (common issues) +- 3 new diagrams added + +### Phase 5: Final Polish + +- Added 3 final diagrams (storage, WASM binary, memory) +- Completed comprehensive validation +- Verified all builds pass +- Tagged final milestone + +## Legend + +| Icon | Meaning | +| ------ | ------------------------------ | +| ๐Ÿ“˜ | Introduction/overview document | +| ๐Ÿš€ | Quickstart/getting started | +| ๐Ÿ“‚ | Directory/folder | +| ๐Ÿงญ | Navigation/learning path | +| โš™๏ธ | Setup/configuration | +| ๐Ÿ“ | Project structure | +| ๐Ÿ“œ | Contract documentation | +| ๐ŸŒ | Global/context information | +| ๐Ÿงช | Testing | +| ๐Ÿ”ค | Primitive types | +| ๐Ÿ”  | Compound types | +| ๐Ÿ’พ | Storage | +| ๐Ÿ”„ | Conversions/transformations | +| ๐Ÿ—๏ธ | Constructors | +| ๐Ÿ”— | Inheritance/composition | +| ๐Ÿ“ค | Imports/exports | +| ๐Ÿ“‹ | ABI/interface | +| โšก | Optimization | +| ๐Ÿ’จ | Caching | +| ๐ŸŒ | Multi-language support | +| ๐Ÿ†• | New features | +| ๐Ÿ“– | Overview/reference | +| โœ… | Validation/checking | +| โœ”๏ธ | Verification | +| ๐Ÿ› | Debugging | +| ๐Ÿ“š | Reference documentation | +| ๐Ÿ”’ | Security | +| โ“ | FAQ/troubleshooting | +| ๐Ÿ”ง | Tools/utilities | +| ๐Ÿ”€ | Comparisons | +| ๐ŸŽฏ | Minimal/focused content | +| ๐Ÿ”Œ | Extensions/plugins | +| ๐Ÿ“ฆ | Libraries/packages | +| ๐Ÿ’ฐ | Pricing/costs | +| [๐Ÿ“Š] | Contains Mermaid diagram(s) | +| โญ NEW | Added in restructure | + +## Quick Navigation + +### For New Developers + +1. Start: `gentle-introduction.mdx` +2. Setup: `fundamentals/prerequisites.mdx` +3. Build: `quickstart.mdx` +4. Choose path: `fundamentals/choose-your-path.mdx` + +### For Solidity Developers + +1. Start: `advanced/rust-to-solidity-differences.mdx` +2. Quick start: `quickstart.mdx` +3. Best practices: `best-practices/security.mdx` + +### For Rust Developers + +1. Start: `quickstart.mdx` +2. Concepts: `concepts/webassembly.mdx` +3. Optimize: `best-practices/gas-optimization.mdx` + +### When Stuck + +1. Troubleshooting: `troubleshooting/common-issues.mdx` +2. CLI help: `cli-tools/commands-reference.mdx` +3. Debugging: `cli-tools/debugging-tx.mdx` + +## Tags Available + +Git tags for rollback if needed: + +- `phase-1-complete` - Planning phase +- `phase-2-complete` - Directory restructure +- `phase-3-complete` - Content consolidation +- `phase-4-complete` - New content creation +- `phase-5-complete` - Final diagrams +- `stylus-v0-10-restructure-complete` - Final milestone + +--- + +**Last Updated:** December 12, 2025 +**Restructure Status:** โœ… Complete (All 5 phases) +**Total Diagrams:** 11 +**Total Files:** ~58 +**Navigation Depth:** Max 3 levels From c9aa4b533a7b654eb563aa5db684201330d9dfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:28:15 -0800 Subject: [PATCH 121/162] docs: remove emojis from STRUCTURE.md, use text annotations instead --- docs/stylus/STRUCTURE.md | 170 ++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 101 deletions(-) diff --git a/docs/stylus/STRUCTURE.md b/docs/stylus/STRUCTURE.md index 2488b3067c..536a5db2ee 100644 --- a/docs/stylus/STRUCTURE.md +++ b/docs/stylus/STRUCTURE.md @@ -5,75 +5,75 @@ This document provides a visual overview of the Stylus documentation structure a ``` docs/stylus/ โ”‚ -โ”œโ”€โ”€ ๐Ÿ“˜ gentle-introduction.mdx -โ”œโ”€โ”€ ๐Ÿš€ quickstart.mdx -โ”œโ”€โ”€ ๐Ÿ”ง using-cli.mdx (legacy) +โ”œโ”€โ”€ gentle-introduction.mdx +โ”œโ”€โ”€ quickstart.mdx +โ”œโ”€โ”€ using-cli.mdx (legacy) โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ fundamentals/ +โ”œโ”€โ”€ fundamentals/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿงญ choose-your-path.mdx โญ NEW (Phase 4) -โ”‚ โ”œโ”€โ”€ โš™๏ธ prerequisites.mdx (Phase 3) -โ”‚ โ”œโ”€โ”€ ๐Ÿ“ project-structure.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ“œ contracts.mdx [๐Ÿ“Š Lifecycle Diagram] -โ”‚ โ”œโ”€โ”€ ๐ŸŒ global-variables-and-functions.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿงช testing-contracts.mdx -โ”‚ โ””โ”€โ”€ ๐Ÿ“‚ data-types/ -โ”‚ โ”œโ”€โ”€ ๐Ÿ”ค primitives.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ”  compound-types.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ’พ storage.mdx [๐Ÿ“Š 2 Diagrams: Hierarchy + Layout] -โ”‚ โ””โ”€โ”€ ๐Ÿ”„ conversions-between-types.mdx +โ”‚ โ”œโ”€โ”€ choose-your-path.mdx [NEW - Phase 4] +โ”‚ โ”œโ”€โ”€ prerequisites.mdx [Phase 3] +โ”‚ โ”œโ”€โ”€ project-structure.mdx +โ”‚ โ”œโ”€โ”€ contracts.mdx [DIAGRAM: Lifecycle] +โ”‚ โ”œโ”€โ”€ global-variables-and-functions.mdx +โ”‚ โ”œโ”€โ”€ testing-contracts.mdx +โ”‚ โ””โ”€โ”€ data-types/ +โ”‚ โ”œโ”€โ”€ primitives.mdx +โ”‚ โ”œโ”€โ”€ compound-types.mdx +โ”‚ โ”œโ”€โ”€ storage.mdx [DIAGRAMS: Hierarchy + Layout] +โ”‚ โ””โ”€โ”€ conversions-between-types.mdx โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ guides/ +โ”œโ”€โ”€ guides/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿ—๏ธ using-constructors.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ”— using-inheritance.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ“ค importing-interfaces.mdx [๐Ÿ“Š Call Diagram] -โ”‚ โ”œโ”€โ”€ ๐Ÿ“‹ exporting-abi.mdx -โ”‚ โ”œโ”€โ”€ โšก optimizing-binaries.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ’จ caching-contracts.mdx -โ”‚ โ”œโ”€โ”€ ๐ŸŒ deploying-non-rust-wasm-contracts.mdx -โ”‚ โ””โ”€โ”€ ๐Ÿ†• adding-support-for-new-languages.mdx +โ”‚ โ”œโ”€โ”€ using-constructors.mdx +โ”‚ โ”œโ”€โ”€ using-inheritance.mdx +โ”‚ โ”œโ”€โ”€ importing-interfaces.mdx [DIAGRAM: Cross-Contract Calls] +โ”‚ โ”œโ”€โ”€ exporting-abi.mdx +โ”‚ โ”œโ”€โ”€ optimizing-binaries.mdx +โ”‚ โ”œโ”€โ”€ caching-contracts.mdx +โ”‚ โ”œโ”€โ”€ deploying-non-rust-wasm-contracts.mdx +โ”‚ โ””โ”€โ”€ adding-support-for-new-languages.mdx โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ cli-tools/ +โ”œโ”€โ”€ cli-tools/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿ“– overview.mdx -โ”‚ โ”œโ”€โ”€ โœ… check-and-deploy.mdx -โ”‚ โ”œโ”€โ”€ โœ”๏ธ verify-contracts.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ› debugging-tx.mdx -โ”‚ โ””โ”€โ”€ ๐Ÿ“š commands-reference.mdx +โ”‚ โ”œโ”€โ”€ overview.mdx +โ”‚ โ”œโ”€โ”€ check-and-deploy.mdx +โ”‚ โ”œโ”€โ”€ verify-contracts.mdx +โ”‚ โ”œโ”€โ”€ debugging-tx.mdx +โ”‚ โ””โ”€โ”€ commands-reference.mdx โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ best-practices/ โญ NEW (Phase 4) +โ”œโ”€โ”€ best-practices/ [NEW - Phase 4] โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿ”’ security.mdx (501 lines) -โ”‚ โ””โ”€โ”€ โšก gas-optimization.mdx [๐Ÿ“Š Comparison Diagram] (548 lines) +โ”‚ โ”œโ”€โ”€ security.mdx (501 lines) +โ”‚ โ””โ”€โ”€ gas-optimization.mdx [DIAGRAM: Performance Comparison] (548 lines) โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ troubleshooting/ โญ NEW (Phase 4) +โ”œโ”€โ”€ troubleshooting/ [NEW - Phase 4] โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ โ“ common-issues.mdx (591 lines) -โ”‚ โ””โ”€โ”€ ๐Ÿ”ง troubleshooting-building-stylus.md (legacy) +โ”‚ โ”œโ”€โ”€ common-issues.mdx (591 lines) +โ”‚ โ””โ”€โ”€ troubleshooting-building-stylus.md (legacy) โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ concepts/ +โ”œโ”€โ”€ concepts/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐ŸŒ webassembly.mdx [๐Ÿ“Š 3 Diagrams: Pipeline + Binary + Memory] -โ”‚ โ”œโ”€โ”€ ๐Ÿš€ activation.mdx [๐Ÿ“Š Deployment Diagram] -โ”‚ โ”œโ”€โ”€ โ›ฝ gas-metering.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ”„ vm-differences.mdx (renamed in Phase 3) -โ”‚ โ””โ”€โ”€ ๐Ÿ‘๏ธ public-preview-expectations.mdx +โ”‚ โ”œโ”€โ”€ webassembly.mdx [DIAGRAMS: Pipeline + Binary + Memory] +โ”‚ โ”œโ”€โ”€ activation.mdx [DIAGRAM: Deployment] +โ”‚ โ”œโ”€โ”€ gas-metering.mdx +โ”‚ โ”œโ”€โ”€ vm-differences.mdx (renamed in Phase 3) +โ”‚ โ””โ”€โ”€ public-preview-expectations.mdx โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ advanced/ +โ”œโ”€โ”€ advanced/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿ”€ rust-to-solidity-differences.mdx (renamed in Phase 3) -โ”‚ โ”œโ”€โ”€ ๐ŸŽฏ minimal-entrypoint-contracts.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ”Œ hostio-exports.mdx -โ”‚ โ””โ”€โ”€ ๐Ÿ“ฆ recommended-libraries.mdx +โ”‚ โ”œโ”€โ”€ rust-to-solidity-differences.mdx (renamed in Phase 3) +โ”‚ โ”œโ”€โ”€ minimal-entrypoint-contracts.mdx +โ”‚ โ”œโ”€โ”€ hostio-exports.mdx +โ”‚ โ””โ”€โ”€ recommended-libraries.mdx โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ reference/ +โ”œโ”€โ”€ reference/ โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ ๐Ÿ“– overview.mdx -โ”‚ โ”œโ”€โ”€ ๐Ÿ’ฐ opcode-hostio-pricing.mdx -โ”‚ โ””โ”€โ”€ ๐Ÿ“˜ rust-sdk-guide.md +โ”‚ โ”œโ”€โ”€ overview.mdx +โ”‚ โ”œโ”€โ”€ opcode-hostio-pricing.mdx +โ”‚ โ””โ”€โ”€ rust-sdk-guide.md โ”‚ -โ”œโ”€โ”€ ๐Ÿ“‚ partials/ (Reusable Content) +โ”œโ”€โ”€ partials/ (Reusable Content) โ”‚ โ”œโ”€โ”€ _setup-rust-toolchain.mdx โ”‚ โ”œโ”€โ”€ _setup-cargo-stylus.mdx โ”‚ โ”œโ”€โ”€ _setup-docker-nitro.mdx @@ -81,7 +81,7 @@ docs/stylus/ โ”‚ โ”œโ”€โ”€ _stylus-no-multi-inheritance-banner-partial.mdx โ”‚ โ””โ”€โ”€ _stylus-public-preview-banner-partial.md โ”‚ -โ””โ”€โ”€ ๐Ÿ“‚ planning/ (Phase Guides) +โ””โ”€โ”€ planning/ (Phase Guides) โ”œโ”€โ”€ RESTRUCTURE_README.md โ”œโ”€โ”€ IMPLEMENTATION_GUIDE.md โ”œโ”€โ”€ IMPLEMENTATION_GUIDE_PHASE3.md @@ -91,7 +91,7 @@ docs/stylus/ ## Statistics -### ๐Ÿ“Š Diagrams: 11 total +### Diagrams: 11 total | File | Diagrams | Description | | ----------------------------------- | -------- | ---------------------------------------------------- | @@ -104,22 +104,22 @@ docs/stylus/ | concepts/activation.mdx | 1 | WASM deployment process | | quickstart.mdx | 1 | User journey through quickstart | -### ๐Ÿ“ Directory Structure +### Directory Structure **10 top-level directories:** - `fundamentals/` - Core concepts and data types - `guides/` - How-to guides for common tasks - `cli-tools/` - CLI commands and usage -- `best-practices/` โญ NEW - Security and optimization -- `troubleshooting/` โญ NEW - Common issues and solutions +- `best-practices/` [NEW] - Security and optimization +- `troubleshooting/` [NEW] - Common issues and solutions - `concepts/` - Deep-dive conceptual explanations - `advanced/` - Advanced topics and low-level details - `reference/` - API reference and SDK documentation - `partials/` - Reusable content snippets - `planning/` - Restructure implementation guides -### ๐Ÿ“„ File Inventory +### File Inventory **Total:** ~58 documentation files @@ -138,7 +138,7 @@ docs/stylus/ - Troubleshooting FAQ: 591 lines - Learning path guide: 285 lines -### ๐Ÿท๏ธ Navigation Improvements +### Navigation Improvements - **Before:** 4+ levels deep (confusing hierarchy) - **After:** Maximum 3 levels (clear, scannable structure) @@ -162,7 +162,7 @@ docs/stylus/ ### Phase 3: Content Consolidation - Created reusable setup partials (3 files) -- Renamed confusing files (evmโ†’vm, solidityโ†’rust-to-solidity) +- Renamed confusing files (evm->vm, solidity->rust-to-solidity) - Added prerequisites guide - Added journey diagram to quickstart - Eliminated duplicate content @@ -182,46 +182,14 @@ docs/stylus/ - Verified all builds pass - Tagged final milestone -## Legend - -| Icon | Meaning | -| ------ | ------------------------------ | -| ๐Ÿ“˜ | Introduction/overview document | -| ๐Ÿš€ | Quickstart/getting started | -| ๐Ÿ“‚ | Directory/folder | -| ๐Ÿงญ | Navigation/learning path | -| โš™๏ธ | Setup/configuration | -| ๐Ÿ“ | Project structure | -| ๐Ÿ“œ | Contract documentation | -| ๐ŸŒ | Global/context information | -| ๐Ÿงช | Testing | -| ๐Ÿ”ค | Primitive types | -| ๐Ÿ”  | Compound types | -| ๐Ÿ’พ | Storage | -| ๐Ÿ”„ | Conversions/transformations | -| ๐Ÿ—๏ธ | Constructors | -| ๐Ÿ”— | Inheritance/composition | -| ๐Ÿ“ค | Imports/exports | -| ๐Ÿ“‹ | ABI/interface | -| โšก | Optimization | -| ๐Ÿ’จ | Caching | -| ๐ŸŒ | Multi-language support | -| ๐Ÿ†• | New features | -| ๐Ÿ“– | Overview/reference | -| โœ… | Validation/checking | -| โœ”๏ธ | Verification | -| ๐Ÿ› | Debugging | -| ๐Ÿ“š | Reference documentation | -| ๐Ÿ”’ | Security | -| โ“ | FAQ/troubleshooting | -| ๐Ÿ”ง | Tools/utilities | -| ๐Ÿ”€ | Comparisons | -| ๐ŸŽฏ | Minimal/focused content | -| ๐Ÿ”Œ | Extensions/plugins | -| ๐Ÿ“ฆ | Libraries/packages | -| ๐Ÿ’ฐ | Pricing/costs | -| [๐Ÿ“Š] | Contains Mermaid diagram(s) | -| โญ NEW | Added in restructure | +## Annotations Used + +| Marker | Meaning | +| --------- | --------------------------------------- | +| [NEW] | Added during restructure | +| [DIAGRAM] | Contains Mermaid diagram(s) | +| (legacy) | May be deprecated or consolidated | +| [Phase N] | Indicates which phase added/modified it | ## Quick Navigation @@ -264,7 +232,7 @@ Git tags for rollback if needed: --- **Last Updated:** December 12, 2025 -**Restructure Status:** โœ… Complete (All 5 phases) +**Restructure Status:** Complete (All 5 phases) **Total Diagrams:** 11 **Total Files:** ~58 **Navigation Depth:** Max 3 levels From c4f3e7906fa933ab06a7b615c805b8787bfff25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:29:01 -0800 Subject: [PATCH 122/162] delete unnecessary dev docs --- docs/stylus/IMPLEMENTATION_GUIDE.md | 1090 ------------------- docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md | 618 ----------- docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md | 1095 -------------------- docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md | 872 ---------------- docs/stylus/RESTRUCTURE_README.md | 348 ------- 5 files changed, 4023 deletions(-) delete mode 100644 docs/stylus/IMPLEMENTATION_GUIDE.md delete mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md delete mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md delete mode 100644 docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md delete mode 100644 docs/stylus/RESTRUCTURE_README.md diff --git a/docs/stylus/IMPLEMENTATION_GUIDE.md b/docs/stylus/IMPLEMENTATION_GUIDE.md deleted file mode 100644 index 9069375c0a..0000000000 --- a/docs/stylus/IMPLEMENTATION_GUIDE.md +++ /dev/null @@ -1,1090 +0,0 @@ -# Stylus Documentation Restructure - Implementation Guide - -**Status:** Ready for execution -**Total Duration:** 5 weeks (5 phases) -**Files Affected:** ~100+ files -**Plan Source:** `~/.claude/plans/hashed-scribbling-finch.md` - -## Overview - -This guide provides step-by-step instructions, scripts, and checklists for implementing the Stylus documentation restructure. Each phase can be executed independently with built-in validation and rollback capabilities. - -## Quick Start - -```bash -# Navigate to project root -cd /Users/allup/OCL/stylus-V10 - -# Create backup before starting -git checkout -b stylus-docs-restructure -git add -A -git commit -m "checkpoint: before restructure" - -# Execute phases in order -./scripts/restructure/phase1.sh -./scripts/restructure/phase2.sh -./scripts/restructure/phase3.sh -./scripts/restructure/phase4.sh -./scripts/restructure/phase5.sh -``` - -## Pre-Flight Checklist - -Before starting any phase: - -- [ ] All changes committed to git -- [ ] Working on feature branch `stylus-docs-restructure` -- [ ] Backup created -- [ ] Build passing (`yarn build`) -- [ ] No uncommitted changes - -## Phase Execution Order - -**IMPORTANT:** Phases must be executed in order due to dependencies: - -1. **Phase 1** โ†’ Clean foundation (delete duplicates, fix compliance) -2. **Phase 2** โ†’ Directory structure (depends on Phase 1 cleanup) -3. **Phase 3** โ†’ Content consolidation (depends on Phase 2 structure) -4. **Phase 4** โ†’ New content (depends on Phase 3 structure) -5. **Phase 5** โ†’ Expansion & validation (depends on all previous phases) - -## Validation Between Phases - -After each phase: - -```bash -# Check build -yarn build - -# Check for broken links -yarn build 2>&1 | grep -i "broken" - -# Verify no uncommitted files -git status - -# Test dev server -yarn start --no-open -# Visit http://localhost:3000/stylus and verify navigation -``` - -## Rollback Procedures - -If issues arise during any phase: - -```bash -# Rollback to pre-phase state -git reset --hard HEAD~1 - -# Or rollback specific files -git checkout HEAD~1 -- docs/stylus/path/to/file.mdx - -# Or rollback entire phase using tag -git reset --hard phase-1-start -``` - -## Success Metrics - -Track these metrics after each phase: - -| Metric | Target | Command | -|--------|--------|---------| -| Build success | Pass | `yarn build` | -| Broken links | 0 | `yarn build 2>&1 \| grep broken` | -| Terminology violations | 0 | See Phase 1 audit scripts | -| Missing frontmatter | 0 | See Phase 1 validation | -| Diagram rendering | 100% | Visual inspection | -| Accessibility score | โ‰ฅ95% | Lighthouse audit | - ---- - -## Phase 1: Foundation & Compliance (Week 1) - -**Goal:** Fix critical issues, ensure CLAUDE.md compliance, complete frontmatter - -**Duration:** ~8 hours -**Files Modified:** ~28 files -**New Files:** 2 -**Deleted Files:** 3 -**Diagrams Added:** 3 - -### Phase 1 Checklist - -- [ ] Delete duplicate overview.md file -- [ ] Create missing advanced/_category_.yml -- [ ] Run terminology audit and fix all violations -- [ ] Complete missing frontmatter -- [ ] Merge verification docs -- [ ] Move faucets partial -- [ ] Add 3 quick-win diagrams -- [ ] Validate build -- [ ] Commit changes - -### Phase 1 Tasks - -#### Task 1.1: Delete Duplicate Files - -```bash -# Verify files are identical -diff docs/stylus/reference/overview.md docs/stylus/reference/overview.mdx - -# Delete the .md version (keep .mdx) -rm docs/stylus/reference/overview.md - -# Verify -git status -``` - -**Expected output:** 1 file deleted - -#### Task 1.2: Create Missing Configuration - -```bash -# Create advanced/_category_.yml -cat > docs/stylus/advanced/_category_.yml << 'EOF' -label: 'Advanced' -position: 8 -link: - type: generated-index - description: Deep dives into Stylus internals, advanced patterns, and optimization techniques. -EOF - -# Verify -cat docs/stylus/advanced/_category_.yml -``` - -**Expected output:** New _category_.yml file created - -#### Task 1.3: Terminology Audit & Fixes - -Create audit script: - -```bash -# Create audit script -mkdir -p scripts/restructure -cat > scripts/restructure/terminology-audit.sh << 'EOF' -#!/bin/bash - -echo "=== Stylus Terminology Audit ===" -echo "" - -violations=0 - -# Check for "js" instead of "JavaScript" -echo "Checking for 'js' (should be 'JavaScript')..." -results=$(grep -rn '\bjs\b' docs/stylus/ --include="*.mdx" --include="*.md" | grep -v "ts.js" | grep -v ".js" | grep -v "js/") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "smartcontract" instead of "smart contract" -echo "" -echo "Checking for 'smartcontract' (should be 'smart contract')..." -results=$(grep -rin 'smartcontract' docs/stylus/ --include="*.mdx" --include="*.md") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "whitelist/blacklist" instead of "allowlist/denylist" -echo "" -echo "Checking for 'whitelist/blacklist' (should be 'allowlist/denylist')..." -results=$(grep -rin 'whitelist\|blacklist' docs/stylus/ --include="*.mdx" --include="*.md") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "on-chain" instead of "onchain" -echo "" -echo "Checking for 'on-chain/on chain' (should be 'onchain')..." -results=$(grep -rn 'on-chain\|on chain' docs/stylus/ --include="*.mdx" --include="*.md") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "ERC20" instead of "ERC-20" -echo "" -echo "Checking for 'ERC20/ERC721' (should be 'ERC-20/ERC-721')..." -results=$(grep -rn 'ERC20\|ERC721\|ERC1155' docs/stylus/ --include="*.mdx" --include="*.md" | grep -v "ERC-") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "Layer-1/L1" instead of "Parent chain" -echo "" -echo "Checking for 'Layer-1/L1/layer 1' (should be 'Parent chain')..." -results=$(grep -rin 'Layer-1\|Layer 1\|\bL1\b' docs/stylus/ --include="*.mdx" --include="*.md") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -# Check for "Layer-2/L2" instead of "Child chain" -echo "" -echo "Checking for 'Layer-2/L2/layer 2' (should be 'Child chain')..." -results=$(grep -rin 'Layer-2\|Layer 2\|\bL2\b' docs/stylus/ --include="*.mdx" --include="*.md") -if [ ! -z "$results" ]; then - echo "$results" - violations=$((violations + 1)) -fi - -echo "" -echo "=== Audit Complete ===" -echo "Total violation types found: $violations" -echo "" - -if [ $violations -eq 0 ]; then - echo "โœ… No terminology violations found!" - exit 0 -else - echo "โŒ Terminology violations found. Please fix manually." - exit 1 -fi -EOF - -chmod +x scripts/restructure/terminology-audit.sh -``` - -Run the audit: - -```bash -# Run audit -./scripts/restructure/terminology-audit.sh - -# Fix violations manually based on output -# For each file flagged, open and fix the terminology -``` - -**Manual fixes required:** Review each flagged file and update terminology according to CLAUDE.md standards. - -#### Task 1.4: Frontmatter Audit & Completion - -Create frontmatter audit script: - -```bash -cat > scripts/restructure/frontmatter-audit.sh << 'EOF' -#!/bin/bash - -echo "=== Frontmatter Audit ===" -echo "" - -missing_user_story=() -missing_content_type=() - -# Check all .mdx and .md files -for file in $(find docs/stylus -name "*.mdx" -o -name "*.md" | grep -v "partials"); do - # Check for user_story - if ! grep -q "user_story:" "$file"; then - missing_user_story+=("$file") - fi - - # Check for content_type - if ! grep -q "content_type:" "$file"; then - missing_content_type+=("$file") - fi -done - -echo "Files missing user_story:" -printf '%s\n' "${missing_user_story[@]}" -echo "" -echo "Total: ${#missing_user_story[@]}" -echo "" - -echo "Files missing content_type:" -printf '%s\n' "${missing_content_type[@]}" -echo "" -echo "Total: ${#missing_content_type[@]}" -echo "" - -if [ ${#missing_user_story[@]} -eq 0 ] && [ ${#missing_content_type[@]} -eq 0 ]; then - echo "โœ… All files have complete frontmatter!" - exit 0 -else - echo "โŒ Some files missing frontmatter fields" - exit 1 -fi -EOF - -chmod +x scripts/restructure/frontmatter-audit.sh -``` - -Run and fix: - -```bash -# Run audit -./scripts/restructure/frontmatter-audit.sh - -# For each file missing fields, add: -# user_story: 'As a , I want to ' -# content_type: 'how-to' # or: concept, reference, quickstart, tutorial, faq -``` - -#### Task 1.5: Merge Verification Docs - -**Manual task:** Combine two verification files into one. - -```bash -# Read both files -cat docs/stylus/how-tos/verifying-contracts.mdx -cat docs/stylus/how-tos/verifying-contracts-arbiscan.mdx - -# Create merged version (do this manually by combining content) -# The merged file should have: -# - Overview (what/why verification) -# - Local verification section (from verifying-contracts.mdx) -# - Arbiscan verification section (from verifying-contracts-arbiscan.mdx) -# - Troubleshooting section - -# After creating merged version, delete originals -rm docs/stylus/how-tos/verifying-contracts-arbiscan.mdx -``` - -**Note:** The merged file will be moved to `cli-tools/` in Phase 2. - -#### Task 1.6: Move Partials - -```bash -# Move faucets partial -mv docs/stylus/reference/partials/_stylus-faucets.mdx docs/stylus/partials/ - -# Update all imports (search and replace) -# Old: import StylusFaucets from '../reference/partials/_stylus-faucets.mdx'; -# New: import StylusFaucets from '../partials/_stylus-faucets.mdx'; - -# Find files that import this partial -grep -r "reference/partials/_stylus-faucets" docs/stylus/ - -# Update each file found -``` - -#### Task 1.7: Add Quick-Win Diagrams - -**Diagram #3: WASM Processing Pipeline** (docs/stylus/concepts/activation.mdx) - -Find the existing ASCII art (around lines 74-90) and replace with: - -```mdx -The following diagram shows the complete WASM processing pipeline: - -```mermaid -flowchart LR - A[Raw WASM Binary] --> B[Remove dangling references] - B --> C[Add project_hash metadata] - C --> D[Strip user custom sections] - D --> E[Brotli compress
    level 11] - E --> F[Add EOF prefix] - F --> G[Final compressed code
    โ‰ค 24KB] - - style G fill:#90EE90 - style A fill:#FFE4B5 -``` - -*Figure 1: WASM binary processing pipeline showing transformation from raw binary to deployment-ready compressed code.* - -The deployment process ensures... -``` - -**Diagram #8: Call Configuration Decision Tree** (docs/stylus/how-tos/importing-interfaces.mdx) - -Add after the "Configuring your calls" section introduction: - -```mdx -Use this decision tree to choose the correct Call constructor: - -```mermaid -flowchart TD - Start[Need to call external contract?] --> Modify{Does it modify state?} - Modify -->|No| View[Call::new
    view calls only] - Modify -->|Yes| ETH{Requires ETH payment?} - ETH -->|No| Mutating[Call::new_mutating self
    state changes, no value] - ETH -->|Yes| Payable[Call::new_payable self, value
    state changes + ETH] - - View --> Gas{Need custom gas limit?} - Mutating --> Gas - Payable --> Gas - - Gas -->|Yes| AddGas[Add .gas limit] - Gas -->|No| Done[Ready to call] - AddGas --> Done - - style View fill:#E3F2FD - style Mutating fill:#FFF3E0 - style Payable fill:#FFEBEE - style Done fill:#90EE90 -``` - -*Figure 2: Decision tree for selecting the appropriate Call constructor based on state modification and payment requirements.* -``` - -**Diagram #12: Storage Type Hierarchy** (docs/stylus/reference/data-types/storage.mdx) - -Add at the beginning of the document after the introduction: - -```mdx -The Stylus SDK provides a comprehensive hierarchy of storage types: - -```mermaid -graph TB - Root[Storage Types] --> Primitives - Root --> Collections - Root --> Custom[Custom Structs] - - Primitives --> Bool[StorageBool] - Primitives --> Uint[StorageU256, U128, U64, etc.] - Primitives --> Int[StorageI256, I128, I64, etc.] - Primitives --> Addr[StorageAddress] - Primitives --> Bytes[StorageB256, B32, etc.] - - Collections --> Vec[StorageVec T] - Collections --> Array[StorageArray T, N] - Collections --> Map[StorageMap K, V] - Collections --> Str[StorageString] - Collections --> BytesCol[StorageBytes] - - Custom --> Struct[#[storage] annotated structs] - - style Root fill:#E1BEE7 - style Primitives fill:#BBDEFB - style Collections fill:#C8E6C9 - style Custom fill:#FFE0B2 -``` - -*Figure 3: Storage type hierarchy showing primitives, collections, and custom struct options.* -``` - -#### Task 1.8: Validate Phase 1 - -```bash -# Run build -yarn build - -# Run terminology audit -./scripts/restructure/terminology-audit.sh - -# Run frontmatter audit -./scripts/restructure/frontmatter-audit.sh - -# Check git status -git status - -# Verify diagrams render -yarn start --no-open -# Visit the 3 pages with diagrams and verify they render correctly -``` - -#### Task 1.9: Commit Phase 1 - -```bash -# Stage all changes -git add -A - -# Commit with descriptive message -git commit -m "docs(stylus): Phase 1 - Foundation & Compliance - -- Delete duplicate reference/overview.md -- Create missing advanced/_category_.yml -- Fix all terminology violations per CLAUDE.md -- Complete missing frontmatter (user_story, content_type) -- Merge verification docs into single file -- Move faucets partial to partials/ directory -- Add 3 quick-win Mermaid diagrams (#3, #8, #12) - -Files modified: ~28 -Diagrams added: 3 -Compliance: 100% terminology, 100% frontmatter" - -# Tag for rollback point -git tag phase-1-complete -``` - -### Phase 1 Success Criteria - -- [ ] โœ… Build passes without errors -- [ ] โœ… Zero terminology violations -- [ ] โœ… All files have complete frontmatter -- [ ] โœ… 3 diagrams render correctly -- [ ] โœ… No broken links -- [ ] โœ… Changes committed and tagged - ---- - -## Phase 2: Directory Restructure (Week 2) - -**Goal:** Create flatter, clearer directory structure with better categorization - -**Duration:** ~10 hours -**Files Modified:** ~20 files -**New Files:** 8 -**Directories Created:** 5 - -### Phase 2 Checklist - -- [ ] Create new directory structure -- [ ] Move files to fundamentals/ -- [ ] Move files to guides/ -- [ ] Create cli-tools/ section -- [ ] Update sidebars.js -- [ ] Update all imports -- [ ] Validate build -- [ ] Commit changes - -### Phase 2 Tasks - -#### Task 2.1: Create New Directory Structure - -```bash -# Create new top-level directories -mkdir -p docs/stylus/fundamentals -mkdir -p docs/stylus/guides -mkdir -p docs/stylus/cli-tools -mkdir -p docs/stylus/best-practices -mkdir -p docs/stylus/troubleshooting - -# Create _category_.yml for each -cat > docs/stylus/fundamentals/_category_.yml << 'EOF' -label: 'Fundamentals' -position: 2 -collapsed: false -link: - type: generated-index - description: Essential Stylus SDK concepts, prerequisites, and core development skills. -EOF - -cat > docs/stylus/guides/_category_.yml << 'EOF' -label: 'Guides' -position: 3 -link: - type: generated-index - description: Practical guides for common Stylus development tasks. -EOF - -cat > docs/stylus/cli-tools/_category_.yml << 'EOF' -label: 'CLI tools' -position: 4 -link: - type: generated-index - description: cargo-stylus command-line tools for building, deploying, and verifying contracts. -EOF - -cat > docs/stylus/best-practices/_category_.yml << 'EOF' -label: 'Best practices' -position: 6 -link: - type: generated-index - description: Security, performance, and gas optimization patterns for production Stylus contracts. -EOF - -cat > docs/stylus/troubleshooting/_category_.yml << 'EOF' -label: 'Troubleshooting' -position: 8 -link: - type: generated-index - description: Common issues, error messages, and debugging strategies. -EOF -``` - -#### Task 2.2: Move Files to fundamentals/ - -```bash -# Move SDK basics to fundamentals -mv docs/stylus/reference/project-structure.mdx docs/stylus/fundamentals/ -mv docs/stylus/reference/contracts.mdx docs/stylus/fundamentals/ -mv docs/stylus/reference/global-variables-and-functions.mdx docs/stylus/fundamentals/ -mv docs/stylus/reference/data-types docs/stylus/fundamentals/ - -# Move testing (core skill) -mv docs/stylus/how-tos/testing-contracts.mdx docs/stylus/fundamentals/ - -# Update frontmatter in each moved file to fix sidebar_position -# This needs to be done manually for each file -``` - -#### Task 2.3: Move Files to guides/ - -```bash -# Rename how-tos to guides -# First, move all files from how-tos to guides (except those already moved) -for file in docs/stylus/how-tos/*.mdx; do - mv "$file" docs/stylus/guides/$(basename "$file") -done - -# Remove empty how-tos directory (after Phase 2 complete) -``` - -#### Task 2.4: Create cli-tools/ Section - -```bash -# Transform using-cli.mdx into cli-tools/overview.mdx -cp docs/stylus/using-cli.mdx docs/stylus/cli-tools/overview.mdx - -# Move CLI-related files -mv docs/stylus/guides/check-and-deploy.mdx docs/stylus/cli-tools/ -mv docs/stylus/guides/verifying-contracts.mdx docs/stylus/cli-tools/verify-contracts.mdx -mv docs/stylus/guides/debugging-tx.mdx docs/stylus/cli-tools/ -``` - -Create cli-tools/commands-reference.mdx: - -```mdx ---- -title: 'cargo-stylus command reference' -description: 'Complete reference for all cargo-stylus CLI commands' -user_story: 'As a Stylus developer, I want a complete reference of all CLI commands' -content_type: reference -author: offchainlabs -sidebar_position: 5 ---- - -# cargo-stylus command reference - -Complete reference for all `cargo-stylus` commands. - -## new - -Create a new Stylus project. - -**Usage:** -```shell -cargo stylus new -``` - -**Options:** -- `--minimal` - Create minimal project structure - -**Example:** -```shell -cargo stylus new my-stylus-contract -``` - -## check - -Verify a contract compiles to valid WASM. - -**Usage:** -```shell -cargo stylus check -``` - -**Options:** -- `--endpoint ` - RPC endpoint (default: http://localhost:8547) - -## deploy - -Deploy a Stylus contract. - -**Usage:** -```shell -cargo stylus deploy \\ - --endpoint \\ - --private-key -``` - -**Options:** -- `--endpoint ` - RPC endpoint -- `--private-key ` - Private key for deployment -- `--estimate-gas` - Estimate gas only, don't deploy - -## activate - -Activate a deployed contract. - -**Usage:** -```shell -cargo stylus activate \\ - --endpoint \\ - --private-key \\ - --address -``` - -## verify - -Verify contract source code. - -**Usage:** -```shell -cargo stylus verify \\ - --deployment-tx -``` - -**Options:** -- `--endpoint ` - RPC endpoint - -## cache - -Manage contract caching. - -**Usage:** -```shell -cargo stylus cache bid
    -cargo stylus cache status
    -``` - -## export-abi - -Export contract ABI. - -**Usage:** -```shell -cargo stylus export-abi -``` - -**Output:** -Generates Solidity interface compatible ABI. - ---- - -For detailed usage examples, see the [CLI tools guides](/stylus/cli-tools/overview). -``` - -#### Task 2.5: Update sidebars.js - -This is a critical file that needs careful updating. Create a backup first: - -```bash -cp sidebars.js sidebars.js.backup -``` - -Then update the Stylus section (around lines 1572-1791) to reflect the new flatter structure: - -```javascript -// In sidebars.js, find the buildStylusSidebar section and update: - -{ - type: 'category', - label: 'Build apps with Stylus', - link: { - type: 'generated-index', - title: 'Build apps with Stylus', - description: 'Learn how to build decentralized applications using Stylus, Arbitrum\'s next-generation smart contract platform supporting Rust, C, and C++.', - slug: '/stylus', - }, - collapsed: false, - items: [ - 'stylus/gentle-introduction', - 'stylus/quickstart', - { - type: 'category', - label: 'Fundamentals', - collapsed: false, - link: { - type: 'generated-index', - }, - items: [ - 'stylus/fundamentals/project-structure', - 'stylus/fundamentals/contracts', - 'stylus/fundamentals/global-variables-and-functions', - { - type: 'category', - label: 'Data types', - items: [ - 'stylus/fundamentals/data-types/primitives', - 'stylus/fundamentals/data-types/compound-types', - 'stylus/fundamentals/data-types/storage', - 'stylus/fundamentals/data-types/conversions-between-types', - ], - }, - 'stylus/fundamentals/testing-contracts', - ], - }, - { - type: 'category', - label: 'Guides', - items: [ - 'stylus/guides/using-constructors', - 'stylus/guides/using-inheritance', - 'stylus/guides/importing-interfaces', - 'stylus/guides/exporting-abi', - 'stylus/guides/optimizing-binaries', - 'stylus/guides/caching-contracts', - 'stylus/guides/deploy-non-rust-contracts', - 'stylus/guides/add-language-support', - ], - }, - { - type: 'category', - label: 'CLI tools', - items: [ - 'stylus/cli-tools/overview', - 'stylus/cli-tools/check-and-deploy', - 'stylus/cli-tools/verify-contracts', - 'stylus/cli-tools/debugging-tx', - 'stylus/cli-tools/commands-reference', - ], - }, - { - type: 'category', - label: 'Concepts', - items: [ - 'stylus/concepts/webassembly', - 'stylus/concepts/activation', - 'stylus/concepts/gas-metering', - 'stylus/concepts/evm-differences', - 'stylus/concepts/public-preview-expectations', - ], - }, - { - type: 'category', - label: 'Best practices', - items: [ - // Phase 4 will add files here - ], - }, - { - type: 'category', - label: 'Advanced', - items: [ - 'stylus/advanced/solidity-differences', - 'stylus/advanced/minimal-entrypoint-contracts', - 'stylus/advanced/hostio-exports', - 'stylus/advanced/recommended-libraries', - ], - }, - { - type: 'category', - label: 'Troubleshooting', - items: [ - // Phase 4 will add files here - ], - }, - { - type: 'category', - label: 'Reference', - items: [ - 'stylus/reference/overview', - 'stylus/reference/opcode-hostio-pricing', - // Phase 3 will add rust-sdk/* here - ], - }, - ], -}, -``` - -#### Task 2.6: Update Imports - -After moving files, all imports need updating. Create a script: - -```bash -cat > scripts/restructure/update-imports.sh << 'EOF' -#!/bin/bash - -echo "Updating imports for moved files..." - -# Update imports for files moved to fundamentals/ -find docs/stylus -name "*.mdx" -exec sed -i '' \ - -e 's|../reference/project-structure|../fundamentals/project-structure|g' \ - -e 's|../reference/contracts|../fundamentals/contracts|g' \ - -e 's|../reference/global-variables-and-functions|../fundamentals/global-variables-and-functions|g' \ - -e 's|../reference/data-types|../fundamentals/data-types|g' \ - {} \; - -# Update imports for CLI tools -find docs/stylus -name "*.mdx" -exec sed -i '' \ - -e 's|../using-cli|../cli-tools/overview|g' \ - -e 's|how-tos/check-and-deploy|cli-tools/check-and-deploy|g' \ - -e 's|how-tos/debugging-tx|cli-tools/debugging-tx|g' \ - {} \; - -# Update imports for guides (how-tos โ†’ guides) -find docs/stylus -name "*.mdx" -exec sed -i '' \ - -e 's|/how-tos/|/guides/|g' \ - {} \; - -echo "โœ… Imports updated" -EOF - -chmod +x scripts/restructure/update-imports.sh -./scripts/restructure/update-imports.sh -``` - -**Note:** On Linux, remove the `''` after `-i` in sed commands. - -#### Task 2.7: Validate Phase 2 - -```bash -# Run build -yarn build - -# Check for broken links -yarn build 2>&1 | grep -i "broken\|error" - -# Start dev server -yarn start --no-open - -# Manual verification: -# - Navigate to /stylus -# - Verify new sidebar structure -# - Click through all sections -# - Verify no 404s -``` - -#### Task 2.8: Commit Phase 2 - -```bash -git add -A -git commit -m "docs(stylus): Phase 2 - Directory Restructure - -- Create 5 new top-level directories (fundamentals, guides, cli-tools, best-practices, troubleshooting) -- Move SDK basics to fundamentals/ (project-structure, contracts, data-types, testing) -- Rename how-tos/ to guides/ and flatten structure -- Create cli-tools/ section with overview and commands reference -- Update sidebars.js to max 3-level depth -- Update all imports for moved files - -Files modified: ~20 -New directories: 5 -Sidebar depth: Reduced from 4+ to 3 levels" - -git tag phase-2-complete -``` - -### Phase 2 Success Criteria - -- [ ] โœ… Build passes -- [ ] โœ… All sections appear in sidebar -- [ ] โœ… No broken internal links -- [ ] โœ… Max 3 sidebar levels -- [ ] โœ… Changes committed and tagged - ---- - -## Phase 3: Content Consolidation (Week 3) - -**Goal:** Merge overlapping content and break up large files - -**Duration:** ~12 hours -**Files Modified:** 4 -**New Files:** 12 -**Deleted Files:** 2 -**Diagrams Added:** 1 - -See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE3.md` (to be created). - ---- - -## Phase 4: Create New Content (Week 4) - -**Goal:** Fill identified gaps with new documentation - -**Duration:** ~16 hours -**New Files:** 15 -**Diagrams Added:** 6 - -See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE4.md` (to be created). - ---- - -## Phase 5: Expansion & Validation (Week 5) - -**Goal:** Expand stub files, final reviews, and comprehensive validation - -**Duration:** ~12 hours -**Files Modified:** ~18 -**Diagrams Added:** 3 - -See detailed implementation in `IMPLEMENTATION_GUIDE_PHASE5.md` (to be created). - ---- - -## Rollback Scripts - -### Rollback Phase 1 - -```bash -git reset --hard phase-1-start -# or -git revert phase-1-complete -``` - -### Rollback Phase 2 - -```bash -git reset --hard phase-1-complete -# or -git revert phase-2-complete -``` - -### Full Rollback - -```bash -git reset --hard HEAD~5 # Rollback last 5 commits -# or -git checkout stylus-docs-restructure-backup -``` - ---- - -## Testing & Validation - -### Automated Tests - -```bash -# Run all validation scripts -./scripts/restructure/terminology-audit.sh -./scripts/restructure/frontmatter-audit.sh -./scripts/restructure/broken-links-check.sh - -# Build test -yarn build - -# Lighthouse accessibility audit -lighthouse http://localhost:3000/stylus --only-categories=accessibility -``` - -### Manual Testing - -1. **Navigation Testing** - - [ ] All sidebar items clickable - - [ ] No 404 pages - - [ ] Breadcrumbs work correctly - -2. **Content Testing** - - [ ] All diagrams render - - [ ] Code blocks formatted correctly - - [ ] Images load properly - -3. **Mobile Testing** - - [ ] Sidebar navigation works - - [ ] Diagrams responsive - - [ ] Touch targets adequate - -4. **Search Testing** - - [ ] Search finds moved content - - [ ] Search results link correctly - ---- - -## Appendix: File Move Matrix - -Complete mapping of all file moves: - -| Old Path | New Path | Phase | -|----------|----------|-------| -| `reference/project-structure.mdx` | `fundamentals/project-structure.mdx` | 2 | -| `reference/contracts.mdx` | `fundamentals/contracts.mdx` | 2 | -| `reference/global-variables-and-functions.mdx` | `fundamentals/global-variables-and-functions.mdx` | 2 | -| `reference/data-types/*` | `fundamentals/data-types/*` | 2 | -| `how-tos/testing-contracts.mdx` | `fundamentals/testing-contracts.mdx` | 2 | -| `how-tos/*.mdx` | `guides/*.mdx` | 2 | -| `using-cli.mdx` | `cli-tools/overview.mdx` | 2 | -| `how-tos/check-and-deploy.mdx` | `cli-tools/check-and-deploy.mdx` | 2 | -| `how-tos/verifying-contracts.mdx` | `cli-tools/verify-contracts.mdx` | 2 | -| `how-tos/debugging-tx.mdx` | `cli-tools/debugging-tx.mdx` | 2 | -| `reference/rust-sdk-guide.md` | `reference/rust-sdk/*.mdx` (split) | 3 | -| `concepts/evm-differences.mdx` | `concepts/vm-differences.mdx` (merged) | 3 | - ---- - -## Support & Questions - -If you encounter issues during implementation: - -1. Check the rollback procedures above -2. Verify all prerequisite checks were completed -3. Review the validation steps for the failed phase -4. Check git status for unexpected changes -5. Review build output for specific errors - -For additional guidance, refer to the original plan at `~/.claude/plans/hashed-scribbling-finch.md`. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md deleted file mode 100644 index 7f92420525..0000000000 --- a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE3.md +++ /dev/null @@ -1,618 +0,0 @@ -# Phase 3: Content Consolidation - Implementation Guide - -**Duration:** ~12 hours -**Files Modified:** 4 -**New Files:** 12 (8 SDK files + prerequisites + 3 partials) -**Deleted Files:** 2 -**Diagrams Added:** 1 - -## Overview - -Phase 3 focuses on eliminating content duplication by: -1. Merging overlapping conceptual content -2. Breaking up oversized files (rust-sdk-guide.md at 536 lines) -3. Extracting repeated setup instructions into reusable partials -4. Adding visual journey map to quickstart - -## Pre-Phase 3 Checklist - -- [ ] Phase 1 completed successfully -- [ ] Phase 2 completed successfully -- [ ] Current build passes -- [ ] Working on branch `stylus-docs-restructure` -- [ ] Tag `phase-2-complete` exists - -## Phase 3 Tasks - -### Task 3.1: Merge VM/Language Differences - -**Goal:** Consolidate `evm-differences.mdx` and parts of `solidity-differences.mdx` into `vm-differences.mdx` - -#### Step 1: Create vm-differences.mdx - -Read both existing files: - -```bash -cat docs/stylus/concepts/evm-differences.mdx -cat docs/stylus/advanced/solidity-differences.mdx -``` - -Create the merged file `docs/stylus/concepts/vm-differences.mdx`: - -```mdx ---- -title: 'VM and execution differences' -description: 'Understand the differences between EVM and WASM execution models in Stylus' -user_story: 'As a developer, I want to understand how WASM execution differs from EVM' -content_type: concept -author: offchainlabs -sme: offchainlabs -sidebar_position: 4 ---- - -# VM and execution differences - -Stylus introduces a WebAssembly (WASM) execution environment alongside the traditional Ethereum Virtual Machine (EVM). Understanding these differences is crucial for effective Stylus development. - -## Execution model comparison - -### EVM: Stack-based architecture - -The EVM operates on a stack-based architecture: -- Instructions manipulate a 256-bit stack -- Each opcode is interpreted at runtime -- Gas charged before each operation -- Limited to 256-bit word size - -### WASM: Register-based architecture - -Stylus WASM uses a register-based model: -- Instructions operate on typed local variables -- Compiled to native code (AOT compilation) -- Ink charged in batches, converted to gas -- Supports 32-bit and 64-bit operations natively - -[MERGE CONTENT FROM BOTH FILES HERE - Include execution model, memory model, gas metering differences, etc.] - -## Key takeaways - -- **Performance**: WASM execution is significantly faster due to native compilation -- **Gas efficiency**: Batch ink charging reduces overhead -- **Interoperability**: Both VMs share the same state, enabling seamless cross-VM calls -- **Developer experience**: Rust provides memory safety and modern tooling - ---- - -For language-specific comparison between Rust and Solidity, see [Rust to Solidity differences](/stylus/advanced/rust-to-solidity-differences). -``` - -#### Step 2: Rename solidity-differences.mdx - -```bash -# Rename to make purpose clearer -mv docs/stylus/advanced/solidity-differences.mdx docs/stylus/advanced/rust-to-solidity-differences.mdx - -# Update frontmatter in the file -# Change title to: "Rust to Solidity differences" -# This file should focus on LANGUAGE differences, not VM differences -``` - -#### Step 3: Delete old evm-differences.mdx - -```bash -rm docs/stylus/concepts/evm-differences.mdx -``` - -#### Step 4: Update sidebar - -In `sidebars.js`, update the concepts section: - -```javascript -{ - type: 'category', - label: 'Concepts', - items: [ - 'stylus/concepts/webassembly', - 'stylus/concepts/activation', - 'stylus/concepts/gas-metering', - 'stylus/concepts/vm-differences', // Changed from evm-differences - 'stylus/concepts/public-preview-expectations', - ], -}, -``` - -### Task 3.2: Break Up rust-sdk-guide.md - -**Goal:** Split 536-line file into 8 focused files - -#### Step 1: Create directory structure - -```bash -mkdir -p docs/stylus/reference/rust-sdk -``` - -#### Step 2: Read the original file - -```bash -cat docs/stylus/reference/rust-sdk-guide.md -``` - -#### Step 3: Create split files - -Create each file by extracting relevant sections from the original: - -**index.mdx** (~50 lines) -```mdx ---- -title: 'Rust SDK overview' -description: 'Overview of the Stylus Rust SDK for building smart contracts' -user_story: 'As a Rust developer, I want to understand the Rust SDK structure' -content_type: reference ---- - -# Rust SDK overview - -The Stylus Rust SDK provides a comprehensive framework for building smart contracts in Rust... - -[Extract overview section from original] - -## SDK components - -- **Storage**: Persistent state management -- **Methods**: External and view functions -- **Events**: Emit and index blockchain events -- **Errors**: Type-safe error handling -- **Calls**: Inter-contract communication -- **Crypto**: Cryptographic operations -- **Bytes**: Low-level byte manipulation - -## Getting started - -```rust -use stylus_sdk::prelude::*; - -#[storage] -pub struct Counter { - count: StorageU256, -} -``` - -## Next steps - -- [Storage management](./storage) -- [Defining methods](./methods) -- [Emitting events](./events) -``` - -**storage.mdx** (~80 lines) -```mdx ---- -title: 'Storage management' -description: 'Persistent storage in Stylus contracts using the Rust SDK' -user_story: 'As a developer, I want to manage persistent state in my Stylus contract' -content_type: reference ---- - -# Storage management - -[Extract storage section from original rust-sdk-guide.md] -``` - -**methods.mdx** (~70 lines) -```mdx ---- -title: 'Contract methods' -description: 'Defining external and view methods in Stylus contracts' -user_story: 'As a developer, I want to create callable functions in my contract' -content_type: reference ---- - -# Contract methods - -[Extract methods section] -``` - -**events.mdx** (~50 lines) -```mdx ---- -title: 'Events and logging' -description: 'Emit and index events from Stylus contracts' -user_story: 'As a developer, I want to emit events from my contract' -content_type: reference ---- - -# Events and logging - -[Extract events section] -``` - -**errors.mdx** (~40 lines) -```mdx ---- -title: 'Error handling' -description: 'Type-safe error handling in Stylus contracts' -user_story: 'As a developer, I want to handle errors gracefully' -content_type: reference ---- - -# Error handling - -[Extract errors section] -``` - -**calls.mdx** (~90 lines) -```mdx ---- -title: 'Contract calls' -description: 'Make calls to other contracts from Stylus' -user_story: 'As a developer, I want to call other contracts' -content_type: reference ---- - -# Contract calls - -[Extract calls section] -``` - -**crypto.mdx** (~60 lines) -```mdx ---- -title: 'Cryptographic operations' -description: 'Hashing and cryptography in Stylus contracts' -user_story: 'As a developer, I want to use cryptographic functions' -content_type: reference ---- - -# Cryptographic operations - -[Extract crypto section] -``` - -**bytes-programming.mdx** (~96 lines) -```mdx ---- -title: 'Bytes programming' -description: 'Low-level byte manipulation in Stylus' -user_story: 'As a developer, I want to work with raw bytes efficiently' -content_type: reference ---- - -# Bytes programming - -[Extract bytes programming section] -``` - -#### Step 4: Delete original file - -```bash -rm docs/stylus/reference/rust-sdk-guide.md -``` - -#### Step 5: Update sidebar - -```javascript -{ - type: 'category', - label: 'Reference', - items: [ - 'stylus/reference/overview', - { - type: 'category', - label: 'Rust SDK', - items: [ - 'stylus/reference/rust-sdk/index', - 'stylus/reference/rust-sdk/storage', - 'stylus/reference/rust-sdk/methods', - 'stylus/reference/rust-sdk/events', - 'stylus/reference/rust-sdk/errors', - 'stylus/reference/rust-sdk/calls', - 'stylus/reference/rust-sdk/crypto', - 'stylus/reference/rust-sdk/bytes-programming', - ], - }, - 'stylus/reference/opcode-hostio-pricing', - ], -}, -``` - -### Task 3.3: Extract Setup from Quickstart - -**Goal:** Create `fundamentals/prerequisites.mdx` and extract duplicate setup instructions - -#### Step 1: Create prerequisites.mdx - -```bash -cat > docs/stylus/fundamentals/prerequisites.mdx << 'EOF' ---- -title: 'Prerequisites and setup' -description: 'Set up your development environment for Stylus' -user_story: 'As a new Stylus developer, I want to set up my development environment' -content_type: how-to -sidebar_position: 1 ---- - -import RustSetup from '../partials/_setup-rust-toolchain.mdx'; -import CargoStylusSetup from '../partials/_setup-cargo-stylus.mdx'; -import DockerSetup from '../partials/_setup-docker-nitro.mdx'; - -# Prerequisites and setup - -This guide will help you set up everything you need to develop Stylus contracts. - -## System requirements - -- **Operating System**: macOS, Linux, or Windows (WSL2) -- **RAM**: Minimum 8GB, 16GB recommended -- **Disk Space**: At least 20GB free - -## Install Rust - - - -## Install cargo-stylus CLI - - - -## Install Docker (for local testnet) - - - -## Verify installation - -```shell -# Check Rust version -rustc --version - -# Check cargo-stylus -cargo stylus --version - -# Check Docker -docker --version -``` - -Expected output: -``` -rustc 1.75.0 (or higher) -cargo-stylus 0.x.x -Docker version 24.0.0 (or higher) -``` - -## Next steps - -- [Create your first project](/stylus/quickstart) -- [Understand project structure](/stylus/fundamentals/project-structure) -- [Learn about contracts](/stylus/fundamentals/contracts) -EOF -``` - -#### Step 2: Create setup partials - -**Rust toolchain partial:** - -```bash -cat > docs/stylus/partials/_setup-rust-toolchain.mdx << 'EOF' -### Installing Rust - -The Rust toolchain includes `rustc` (compiler), `cargo` (package manager), and `rustup` (version manager). - -**macOS/Linux:** - -```shell -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` - -**Windows:** - -Download and run [rustup-init.exe](https://rustup.rs/). - -**Configure for WASM:** - -```shell -rustup target add wasm32-unknown-unknown -``` - -**Verify:** - -```shell -rustc --version -cargo --version -``` -EOF -``` - -**cargo-stylus partial:** - -```bash -cat > docs/stylus/partials/_setup-cargo-stylus.mdx << 'EOF' -### Installing cargo-stylus - -The `cargo-stylus` CLI tool helps you create, build, and deploy Stylus contracts. - -**Install:** - -```shell -cargo install cargo-stylus -``` - -**Verify:** - -```shell -cargo stylus --version -``` - -**Update:** - -```shell -cargo install cargo-stylus --force -``` -EOF -``` - -**Docker setup partial:** - -```bash -cat > docs/stylus/partials/_setup-docker-nitro.mdx << 'EOF' -### Installing Docker for local testing - -A local Arbitrum Nitro devnode allows you to test contracts before deploying to testnet. - -**macOS:** - -Download [Docker Desktop for Mac](https://docs.docker.com/desktop/install/mac-install/). - -**Linux:** - -```shell -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh -``` - -**Windows:** - -Download [Docker Desktop for Windows](https://docs.docker.com/desktop/install/windows-install/) (requires WSL2). - -**Start Nitro devnode:** - -```shell -docker run -p 8547:8547 offchainlabs/nitro-node:latest --dev -``` - -**Verify:** - -```shell -curl -X POST http://localhost:8547 \ - -H "Content-Type: application/json" \ - -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' -``` -EOF -``` - -#### Step 3: Streamline quickstart.mdx - -Update `docs/stylus/quickstart.mdx` to reference prerequisites instead of duplicating: - -```mdx ---- -title: 'Quickstart: Build your first Stylus contract' ---- - -# Quickstart: Build your first Stylus contract - -In this quickstart, you'll create, deploy, and interact with a simple counter contract written in Rust. - -**Time to complete:** ~15 minutes - -## Prerequisites - -Before starting, ensure you have: -- Rust toolchain installed -- cargo-stylus CLI installed -- Access to an Arbitrum testnet - -Don't have these set up? See [Prerequisites and setup](/stylus/fundamentals/prerequisites). - -## Step 1: Create a new project - -[Continue with hands-on steps, no setup duplication] -``` - -### Task 3.4: Add Quickstart Journey Diagram - -Add Diagram #13 to quickstart.mdx after the introduction: - -```mdx -## Your journey - -This quickstart follows a simple path: - -```mermaid -journey - title Quickstart Journey - section Setup - Create project: 5: Developer - Check validity: 3: Developer - section Deploy - Deploy contract: 4: Developer - Export ABI: 3: Developer - section Interact - Call contract: 5: Developer - Send transaction: 4: Developer - Verify results: 5: Developer -``` - -*Figure: Your path through this quickstart guide, from project creation to successful contract interaction.* - -Let's get started! - -## Step 1: Create a new project -``` - -### Task 3.5: Validate Phase 3 - -```bash -# Run build -yarn build - -# Check for broken links -yarn build 2>&1 | grep -i "broken" - -# Verify new structure -ls docs/stylus/reference/rust-sdk/ -ls docs/stylus/fundamentals/prerequisites.mdx -ls docs/stylus/partials/_setup-*.mdx - -# Test imports -grep -r "setup-rust-toolchain" docs/stylus/ - -# Start dev server and test -yarn start --no-open -# Check: -# - VM differences page exists -# - Rust SDK has 8 sub-pages -# - Prerequisites page renders with partials -# - Quickstart journey diagram renders -``` - -### Task 3.6: Commit Phase 3 - -```bash -git add -A -git commit -m "docs(stylus): Phase 3 - Content Consolidation - -- Merge evm-differences + solidity-differences โ†’ vm-differences -- Rename solidity-differences โ†’ rust-to-solidity-differences -- Split rust-sdk-guide.md into 8 focused files -- Create fundamentals/prerequisites.mdx with setup partials -- Extract setup instructions into 3 reusable partials -- Streamline quickstart.mdx to reference prerequisites -- Add quickstart journey diagram (#13) - -Files modified: 4 -New files: 12 (8 SDK + prerequisites + 3 partials) -Deleted files: 2 -Diagrams added: 1" - -git tag phase-3-complete -``` - -## Phase 3 Success Criteria - -- [ ] โœ… Build passes -- [ ] โœ… No duplicate setup instructions -- [ ] โœ… Rust SDK has 8 sub-pages -- [ ] โœ… VM differences merged successfully -- [ ] โœ… Quickstart journey diagram renders -- [ ] โœ… All partials import correctly -- [ ] โœ… Changes committed and tagged - -## Rollback Phase 3 - -```bash -git reset --hard phase-2-complete -# or -git revert phase-3-complete -``` - -## Next Phase - -Continue to Phase 4 in `IMPLEMENTATION_GUIDE_PHASE4.md` to create new content including best practices, troubleshooting, and core concept diagrams. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md deleted file mode 100644 index 70edd209b4..0000000000 --- a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE4.md +++ /dev/null @@ -1,1095 +0,0 @@ -# Phase 4: Create New Content - Implementation Guide - -**Duration:** ~16 hours -**Files Modified:** 7 (rename troubleshooting + 6 diagrams) -**New Files:** 15 (3 fundamentals + 3 guides + 3 best-practices + 3 troubleshooting + 1 advanced + 2 interop) -**Diagrams Added:** 6 - -## Overview - -Phase 4 fills critical documentation gaps identified in the analysis: -1. Developer onboarding content (choose-your-path, dev environment) -2. Interoperability guides (Rust โ†” Solidity) -3. Best practices (security, performance, gas optimization) -4. Troubleshooting (common errors, debugging) -5. Core concept diagrams for complex topics - -## Pre-Phase 4 Checklist - -- [ ] Phases 1-3 completed successfully -- [ ] Current build passes -- [ ] Tag `phase-3-complete` exists -- [ ] All previous diagrams render correctly - -## Phase 4 Tasks - -### Task 4.1: Create Fundamentals Content - -#### fundamentals/choose-your-path.mdx - -```bash -cat > docs/stylus/fundamentals/choose-your-path.mdx << 'EOF' ---- -title: 'Choose your learning path' -description: 'Find the best Stylus learning path based on your background' -user_story: 'As a developer, I want to know the best way to learn Stylus based on my experience' -content_type: concept -sidebar_position: 0 ---- - -# Choose your learning path - -Your background determines the best way to learn Stylus. Choose your path below. - -## I'm a Rust developer - -**You're in great shape!** Stylus contracts are written in Rust, so you already know the language. - -### What you need to learn - -- How Ethereum smart contracts work -- How storage works in blockchain -- How to interact with other contracts -- Gas optimization for onchain code - -### Recommended path - -1. [Understand WebAssembly and Stylus](/stylus/concepts/webassembly) -2. [Build your first contract](/stylus/quickstart) -3. [Learn about storage](/stylus/fundamentals/data-types/storage) -4. [Call Solidity from Rust](/stylus/guides/call-solidity-from-rust) -5. [Optimize for gas](/stylus/best-practices/gas-optimization) - -### Key insights - -- **Familiar syntax**: Write normal Rust code with minimal blockchain-specific syntax -- **Memory safety**: Rust's borrow checker prevents common smart contract vulnerabilities -- **Performance**: WASM execution is significantly faster than EVM -- **Tooling**: Use cargo, rust-analyzer, and your favorite Rust tools - ---- - -## I'm a Solidity developer - -**Welcome!** You understand blockchain and smart contracts. Now learn Rust and leverage WASM performance. - -### What you need to learn - -- Rust language basics (ownership, borrowing, traits) -- Different memory and storage models -- Compilation to WASM instead of EVM opcodes -- Rust SDK equivalents for Solidity patterns - -### Recommended path - -1. [Compare VM differences](/stylus/concepts/vm-differences) -2. [Study Rust-to-Solidity differences](/stylus/advanced/rust-to-solidity-differences) -3. [Learn Rust basics](https://doc.rust-lang.org/book/) -4. [Build your first contract](/stylus/quickstart) -5. [Call Rust from Solidity](/stylus/guides/call-rust-from-solidity) - -### Key insights - -- **Familiar concepts**: Storage, events, modifiers, inheritance all have Rust equivalents -- **Better performance**: 10-100x gas savings for compute-heavy operations -- **Type safety**: Rust's type system catches errors at compile time -- **Interoperability**: Stylus and Solidity contracts call each other seamlessly - -### Comparison table - -| Concept | Solidity | Stylus (Rust) | -|---------|----------|---------------| -| State variable | `uint256 public count;` | `count: StorageU256` | -| Function | `function get() public view` | `pub fn get(&self) -> U256` | -| Event | `event Transfer(...)` | `#[event] struct Transfer` | -| Error | `error Unauthorized()` | `#[error] struct Unauthorized` | -| Modifier | `modifier onlyOwner` | Rust function or trait | -| Inheritance | `contract A is B` | Trait implementation | - ---- - -## I'm new to blockchain development - -**Exciting!** You're starting fresh with best-in-class tools. - -### What you need to learn - -- Blockchain fundamentals (accounts, transactions, state) -- Smart contract concepts (storage, events, gas) -- Rust programming language -- Arbitrum and Ethereum basics - -### Recommended path - -1. [Learn Ethereum basics](https://ethereum.org/en/developers/docs/) -2. [Learn Rust](https://doc.rust-lang.org/book/) -3. [Understand Stylus introduction](/stylus/gentle-introduction) -4. [Build your first contract](/stylus/quickstart) -5. [Explore examples](https://github.com/OffchainLabs/stylus-by-example) - -### Resources - -- [Ethereum docs](https://ethereum.org/en/developers/) -- [The Rust Book](https://doc.rust-lang.org/book/) -- [Arbitrum docs](/arbitrum-ethereum-differences) -- [Stylus by Example](https://github.com/OffchainLabs/stylus-by-example) - ---- - -## Quick reference - -No matter your path, bookmark these resources: - -- **API Reference**: [Rust SDK](/stylus/reference/rust-sdk/) -- **CLI Reference**: [cargo-stylus commands](/stylus/cli-tools/commands-reference) -- **Examples**: [Stylus by Example](https://github.com/OffchainLabs/stylus-by-example) -- **Help**: [Troubleshooting](/stylus/troubleshooting/faq) -EOF -``` - -#### fundamentals/development-environment.mdx - -```bash -cat > docs/stylus/fundamentals/development-environment.mdx << 'EOF' ---- -title: 'Development environment setup' -description: 'Configure your IDE and tools for Stylus development' -user_story: 'As a developer, I want to set up an efficient development environment' -content_type: how-to -sidebar_position: 2 ---- - -# Development environment setup - -This guide helps you configure a productive development environment for Stylus. - -## VS Code setup - -Visual Studio Code is the recommended IDE for Stylus development. - -### Install VS Code - -Download from [code.visualstudio.com](https://code.visualstudio.com/) - -### Required extensions - -Install these extensions: - -```shell -# rust-analyzer (Rust language support) -code --install-extension rust-lang.rust-analyzer - -# Even Better TOML (Cargo.toml support) -code --install-extension tamasfe.even-better-toml - -# CodeLLDB (Rust debugger) -code --install-extension vadimcn.vscode-lldb -``` - -### Recommended extensions - -```shell -# Error Lens (inline error messages) -code --install-extension usernamehw.errorlens - -# Crates (Cargo.toml dependency management) -code --install-extension serayuzgur.crates - -# GitLens (Git integration) -code --install-extension eamodio.gitlens -``` - -### VS Code settings - -Add to `.vscode/settings.json` in your project: - -```json -{ - "rust-analyzer.checkOnSave.command": "clippy", - "rust-analyzer.cargo.features": "all", - "editor.formatOnSave": true, - "[rust]": { - "editor.defaultFormatter": "rust-lang.rust-analyzer" - } -} -``` - -## IntelliJ IDEA / CLion setup - -JetBrains IDEs offer excellent Rust support. - -### Install Rust plugin - -1. Open Settings โ†’ Plugins -2. Search for "Rust" -3. Install and restart - -### Configure Rust toolchain - -1. Settings โ†’ Languages & Frameworks โ†’ Rust -2. Select Toolchain location -3. Enable external linter: Clippy - -## Command-line tools - -### cargo-watch - -Auto-rebuild on file changes: - -```shell -cargo install cargo-watch - -# Use it -cargo watch -x check -x test -``` - -### cargo-expand - -View macro expansions: - -```shell -cargo install cargo-expand - -# Use it -cargo expand -``` - -### cargo-audit - -Check for security vulnerabilities: - -```shell -cargo install cargo-audit - -# Use it -cargo audit -``` - -## Debugger setup - -### VS Code debugging - -Create `.vscode/launch.json`: - -```json -{ - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests", - "cargo": { - "args": [ - "test", - "--no-run", - "--lib" - ] - }, - "args": [], - "cwd": "${workspaceFolder}" - } - ] -} -``` - -Set breakpoints and press F5 to debug. - -## Testing environment - -### Set up test RPC - -Use a local Nitro node for testing: - -```shell -# Start in one terminal -docker run -p 8547:8547 offchainlabs/nitro-node:latest --dev - -# Add to .env -LOCAL_RPC_URL=http://localhost:8547 -``` - -### Configure test accounts - -```shell -# Generate test private key (DO NOT use in production!) -openssl rand -hex 32 - -# Add to .env -PRIVATE_KEY=your_generated_key_here -``` - -## Environment variables - -Create `.env` in your project root: - -```shell -# Network configuration -LOCAL_RPC_URL=http://localhost:8547 -TESTNET_RPC_URL=https://sepolia-rollup.arbitrum.io/rpc -MAINNET_RPC_URL=https://arb1.arbitrum.io/rpc - -# Deployment -PRIVATE_KEY=your_private_key_here - -# Verification -ARBISCAN_API_KEY=your_api_key_here -``` - -**โš ๏ธ Security:** Never commit `.env` to version control! - -Add to `.gitignore`: - -``` -.env -.env.* -!.env.example -``` - -## Productivity tips - -### Use cargo aliases - -Add to `~/.cargo/config.toml`: - -```toml -[alias] -st = "stylus" -sc = "stylus check" -sd = "stylus deploy" -``` - -Usage: - -```shell -cargo st check -cargo sc # shorthand -``` - -### Shell completions - -```shell -# Bash -cargo stylus completions bash > ~/.bash_completions/cargo-stylus - -# Zsh -cargo stylus completions zsh > ~/.zsh/completions/_cargo-stylus -``` - -## Troubleshooting - -### rust-analyzer is slow - -Increase memory limit in VS Code settings: - -```json -{ - "rust-analyzer.server.extraEnv": { - "RA_LOG": "info" - } -} -``` - -### Clippy too strict - -Configure in `Cargo.toml`: - -```toml -[lints.clippy] -too_many_arguments = "allow" -``` - -## Next steps - -- [Create your first project](/stylus/quickstart) -- [Learn about testing](/stylus/fundamentals/testing-contracts) -- [Explore CLI tools](/stylus/cli-tools/overview) -EOF -``` - -### Task 4.2: Create Guides Content - -#### guides/call-solidity-from-rust.mdx - -```bash -cat > docs/stylus/guides/call-solidity-from-rust.mdx << 'EOF' ---- -title: 'Call Solidity contracts from Rust' -description: 'Learn how to call Solidity contracts from your Stylus contracts' -user_story: 'As a Stylus developer, I want to call existing Solidity contracts' -content_type: how-to ---- - -# Call Solidity contracts from Rust - -Stylus contracts can seamlessly call Solidity contracts using the `sol_interface!` macro. - -## Overview - -The `sol_interface!` macro generates Rust bindings from Solidity interface definitions, enabling type-safe contract calls. - -## Basic example - -### Step 1: Define the Solidity interface - -```rust -use stylus_sdk::prelude::*; -use stylus_sdk::alloy_primitives::{Address, U256}; - -sol_interface! { - interface IERC20 { - function balanceOf(address account) external view returns (uint256); - function transfer(address to, uint256 amount) external returns (bool); - function approve(address spender, uint256 amount) external returns (bool); - } -} -``` - -### Step 2: Call the contract - -```rust -#[external] -impl MyContract { - pub fn check_balance(&self, token: Address, account: Address) -> Result> { - let erc20 = IERC20::new(token); - let balance = erc20.balance_of(self, account)?; - Ok(balance) - } - - pub fn transfer_tokens( - &mut self, - token: Address, - to: Address, - amount: U256 - ) -> Result> { - let erc20 = IERC20::new(token); - let success = erc20.transfer(self, to, amount)?; - Ok(success) - } -} -``` - -## View vs mutating calls - -### View calls (read-only) - -Use `Call::new()` for functions that don't modify state: - -```rust -let balance = erc20.balance_of(self, account)?; -``` - -### Mutating calls - -Use `Call::new_mutating()` for state-changing functions: - -```rust -let success = erc20.transfer(self, to, amount)?; -``` - -### Payable calls - -Use `Call::new_payable()` for functions requiring ETH: - -```rust -let call = Call::new_payable(value); -contract.deposit(call)?; -``` - -## Advanced patterns - -### Custom gas limits - -```rust -let balance = erc20.balance_of(self, account) - .gas(100_000)?; // Custom gas limit -``` - -### Handling return values - -```rust -match erc20.transfer(self, to, amount) { - Ok(success) => { - if success { - // Transfer succeeded - } else { - // Transfer failed - } - } - Err(e) => { - // Call reverted - } -} -``` - -### Multiple calls in one function - -```rust -pub fn complex_operation(&mut self, token: Address) -> Result<(), Vec> { - let erc20 = IERC20::new(token); - - // Read balance - let balance = erc20.balance_of(self, msg::sender())?; - - // Approve - erc20.approve(self, some_spender, balance)?; - - // Transfer - erc20.transfer(self, some_recipient, balance / 2)?; - - Ok(()) -} -``` - -## Complete example - -```rust -use stylus_sdk::prelude::*; -use stylus_sdk::alloy_primitives::{Address, U256}; - -sol_interface! { - interface IUniswapV2Router { - function swapExactTokensForTokens( - uint amountIn, - uint amountOutMin, - address[] calldata path, - address to, - uint deadline - ) external returns (uint[] memory amounts); - } -} - -#[storage] -pub struct TokenSwapper { - router: StorageAddress, -} - -#[external] -impl TokenSwapper { - pub fn swap( - &mut self, - token_in: Address, - token_out: Address, - amount_in: U256, - amount_out_min: U256 - ) -> Result, Vec> { - let router_addr = self.router.get(); - let router = IUniswapV2Router::new(router_addr); - - let path = vec![token_in, token_out]; - let deadline = block::timestamp() + 300; // 5 minutes - - let amounts = router.swap_exact_tokens_for_tokens( - self, - amount_in, - amount_out_min, - path, - msg::sender(), - deadline - )?; - - Ok(amounts) - } -} -``` - -## See also - -- [Call Rust from Solidity](./call-rust-from-solidity) -- [Importing interfaces](./importing-interfaces) -- [SDK call reference](/stylus/reference/rust-sdk/calls) -EOF -``` - -#### guides/call-rust-from-solidity.mdx - -```bash -cat > docs/stylus/guides/call-rust-from-solidity.mdx << 'EOF' ---- -title: 'Call Rust contracts from Solidity' -description: 'Learn how to call Stylus contracts from Solidity' -user_story: 'As a Solidity developer, I want to call Stylus contracts' -content_type: how-to ---- - -# Call Rust contracts from Solidity - -Solidity contracts can call Stylus contracts just like any other contract. - -## Overview - -Once deployed, Stylus contracts expose a standard Ethereum ABI that Solidity can interact with. - -## Step 1: Export ABI from Rust - -Use `cargo stylus` to export your contract's ABI: - -```shell -cargo stylus export-abi -``` - -This generates a Solidity interface: - -```solidity -interface ICounter { - function number() external view returns (uint256); - function increment() external; - function setNumber(uint256 newNumber) external; -} -``` - -## Step 2: Create Solidity interface - -Save the interface to a file: - -```solidity -// ICounter.sol -pragma solidity ^0.8.0; - -interface ICounter { - function number() external view returns (uint256); - function increment() external; - function setNumber(uint256 newNumber) external; -} -``` - -## Step 3: Call from Solidity - -```solidity -// CounterCaller.sol -pragma solidity ^0.8.0; - -import "./ICounter.sol"; - -contract CounterCaller { - ICounter public counter; - - constructor(address _counter) { - counter = ICounter(_counter); - } - - function getCount() public view returns (uint256) { - return counter.number(); - } - - function incrementCounter() public { - counter.increment(); - } - - function setCount(uint256 newNumber) public { - counter.setNumber(newNumber); - } -} -``` - -## Advanced patterns - -### Handling return values - -```solidity -function safeIncrement() public returns (bool) { - try counter.increment() { - return true; - } catch { - return false; - } -} -``` - -### Passing complex types - -**Rust side:** - -```rust -#[external] -impl MyContract { - pub fn process_data(&self, data: Vec) -> Result> { - Ok(data.iter().sum()) - } -} -``` - -**Solidity side:** - -```solidity -function callProcess(uint256[] memory data) public returns (uint256) { - return myContract.processData(data); -} -``` - -### Events from Stylus contracts - -Stylus contracts emit standard Ethereum events: - -**Rust:** - -```rust -#[derive(SolidityEvent)] -pub struct Transfer { - from: Address, - to: Address, - amount: U256, -} -``` - -**Solidity:** - -```solidity -interface IToken { - event Transfer(address indexed from, address indexed to, uint256 amount); -} - -// Listen for events -IToken token = IToken(stylusTokenAddress); -// Events work automatically -``` - -## Complete example - -**Stylus Contract (Rust):** - -```rust -use stylus_sdk::prelude::*; -use stylus_sdk::alloy_primitives::U256; - -#[storage] -pub struct Calculator { - result: StorageU256, -} - -#[external] -impl Calculator { - pub fn add(&mut self, a: U256, b: U256) -> U256 { - let sum = a + b; - self.result.set(sum); - sum - } - - pub fn get_result(&self) -> U256 { - self.result.get() - } -} -``` - -**Solidity Caller:** - -```solidity -pragma solidity ^0.8.0; - -interface ICalculator { - function add(uint256 a, uint256 b) external returns (uint256); - function getResult() external view returns (uint256); -} - -contract MathContract { - ICalculator public calc; - - constructor(address _calc) { - calc = ICalculator(_calc); - } - - function compute(uint256 x, uint256 y) public returns (uint256) { - uint256 result = calc.add(x, y); - require(result == calc.getResult(), "Mismatch"); - return result; - } -} -``` - -## Deployment workflow - -1. Deploy Stylus contract -2. Export ABI: `cargo stylus export-abi` -3. Create Solidity interface -4. Deploy Solidity contract with Stylus address -5. Call Stylus from Solidity - -## See also - -- [Call Solidity from Rust](./call-solidity-from-rust) -- [Exporting ABI](./exporting-abi) -- [Importing interfaces](./importing-interfaces) -EOF -``` - -#### guides/create-project.mdx - -```bash -cat > docs/stylus/guides/create-project.mdx << 'EOF' ---- -title: 'Create a Stylus project' -description: 'Initialize a new Stylus project with cargo-stylus' -user_story: 'As a developer, I want to create a new Stylus project' -content_type: how-to ---- - -# Create a Stylus project - -Learn how to create and configure a new Stylus project. - -## Using cargo-stylus new - -The fastest way to create a project: - -```shell -cargo stylus new my-project -cd my-project -``` - -This creates a complete project with: -- `src/lib.rs` - Contract code -- `Cargo.toml` - Dependencies -- `.gitignore` - Git configuration - -## Manual project setup - -Alternatively, create a project manually: - -```shell -cargo new --lib my-project -cd my-project -``` - -Update `Cargo.toml`: - -```toml -[package] -name = "my-project" -version = "0.1.0" -edition = "2021" - -[dependencies] -stylus-sdk = "0.5" -alloy-primitives = "0.7" -alloy-sol-types = "0.7" - -[dev-dependencies] -tokio = { version = "1.12", features = ["macros", "full"] } - -[features] -export-abi = ["stylus-sdk/export-abi"] - -[lib] -crate-type = ["lib", "cdylib"] -``` - -## Project structure - -``` -my-project/ -โ”œโ”€โ”€ Cargo.toml # Project configuration -โ”œโ”€โ”€ Cargo.lock # Locked dependencies -โ”œโ”€โ”€ src/ -โ”‚ โ””โ”€โ”€ lib.rs # Your contract code -โ””โ”€โ”€ .gitignore -``` - -## Next steps - -- [Understand project structure](/stylus/fundamentals/project-structure) -- [Build your first contract](/stylus/quickstart) -- [Learn about testing](/stylus/fundamentals/testing-contracts) -EOF -``` - -### Task 4.3: Create Best Practices Content - -Due to length, I'll provide templates. You'll need to expand these based on research and examples: - -#### best-practices/security.mdx - -```mdx ---- -title: 'Security best practices' -description: 'Security patterns and audit checklist for Stylus contracts' -user_story: 'As a developer, I want to write secure Stylus contracts' -content_type: reference ---- - -# Security best practices - -[TO BE EXPANDED - ~300 lines covering:] -- Common vulnerabilities in Stylus -- Reentrancy protection patterns -- Input validation -- Safe arithmetic -- Access control patterns -- Audit checklist -``` - -#### best-practices/performance.mdx - -```mdx ---- -title: 'Performance optimization' -description: 'WASM-specific optimizations and profiling techniques' -user_story: 'As a developer, I want to optimize my Stylus contracts' -content_type: reference ---- - -# Performance optimization - -[TO BE EXPANDED - ~250 lines covering:] -- WASM-specific optimizations -- Storage access patterns -- Memory management strategies -- Profiling and benchmarking -``` - -#### best-practices/gas-optimization.mdx - -```mdx ---- -title: 'Gas optimization' -description: 'Gas-efficient coding techniques for Stylus' -user_story: 'As a developer, I want to minimize gas costs' -content_type: reference ---- - -# Gas optimization - -[TO BE EXPANDED - ~200 lines covering:] -- Gas cost comparison (Stylus vs Solidity) -- Optimization techniques for WASM -- Storage vs memory tradeoffs -- Real-world examples with metrics -``` - -### Task 4.4: Create Troubleshooting Content - -#### troubleshooting/faq.mdx - -```bash -# Rename existing troubleshooting file -mv docs/stylus/troubleshooting-building-stylus.md docs/stylus/troubleshooting/faq.mdx - -# Update frontmatter -# Add: content_type: faq -``` - -#### troubleshooting/common-errors.mdx - -```mdx ---- -title: 'Common errors' -description: 'Solutions to frequently encountered errors' -user_story: 'As a developer, I want to quickly resolve common errors' -content_type: troubleshooting ---- - -# Common errors - -[TO BE EXPANDED - Problem-solution format for:] -- Compilation errors -- Deployment errors -- Runtime errors -``` - -#### troubleshooting/debugging-guide.mdx - -```mdx ---- -title: 'Debugging guide' -description: 'Systematic debugging strategies for Stylus' -user_story: 'As a developer, I want to debug my contracts effectively' -content_type: how-to ---- - -# Debugging guide - -[TO BE EXPANDED covering:] -- Systematic debugging approach -- Using replay for transaction debugging -- Local testing strategies -- Logging best practices -``` - -### Task 4.5: Create Advanced Content - -#### advanced/memory-management.mdx - -```mdx ---- -title: 'Memory management' -description: 'WASM memory model and performance optimization' -user_story: 'As a developer, I want to understand WASM memory management' -content_type: concept ---- - -# Memory management - -[TO BE EXPANDED covering:] -- WASM memory model -- Performance optimization -- Memory profiling -- Best practices -``` - -### Task 4.6: Add Core Concept Diagrams - -Add these 6 diagrams to existing files: - -**Diagram #1: Contract Lifecycle** (gentle-introduction.mdx) -**Diagram #2: Deployment & Activation** (concepts/activation.mdx) -**Diagram #4: EVM vs WASM Architecture** (concepts/vm-differences.mdx) -**Diagram #5: Contract Call Flow** (guides/importing-interfaces.mdx) -**Diagram #6: Ink to Gas Conversion** (concepts/gas-metering.mdx) -**Diagram #9: Deployment Workflows** (cli-tools/check-and-deploy.mdx) - -[See main implementation guide for diagram code] - -### Task 4.7: Update Sidebars - -Add new sections to sidebars.js: - -```javascript -{ - type: 'category', - label: 'Best practices', - items: [ - 'stylus/best-practices/security', - 'stylus/best-practices/performance', - 'stylus/best-practices/gas-optimization', - ], -}, -{ - type: 'category', - label: 'Troubleshooting', - items: [ - 'stylus/troubleshooting/faq', - 'stylus/troubleshooting/common-errors', - 'stylus/troubleshooting/debugging-guide', - ], -}, -``` - -### Task 4.8: Commit Phase 4 - -```bash -git add -A -git commit -m "docs(stylus): Phase 4 - Create New Content - -- Add choose-your-path and development-environment to fundamentals -- Create interoperability guides (Rust โ†” Solidity) -- Add best-practices section (security, performance, gas) -- Create troubleshooting section (faq, errors, debugging) -- Add advanced memory-management guide -- Add 6 core concept diagrams (#1, #2, #4, #5, #6, #9) - -New files: 15 -Diagrams added: 6" - -git tag phase-4-complete -``` - -## Phase 4 Success Criteria - -- [ ] โœ… All new content files created -- [ ] โœ… 6 diagrams render correctly -- [ ] โœ… Build passes -- [ ] โœ… Sidebar navigation updated -- [ ] โœ… Changes committed and tagged - -## Next Phase - -Continue to Phase 5 for expansion, polish, and comprehensive validation. diff --git a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md b/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md deleted file mode 100644 index 43ab9a74fb..0000000000 --- a/docs/stylus/IMPLEMENTATION_GUIDE_PHASE5.md +++ /dev/null @@ -1,872 +0,0 @@ -# Phase 5: Expansion & Validation - Implementation Guide - -**Duration:** ~12 hours -**Files Modified:** ~18 (stub expansions + reviews + 3 diagrams) -**New Files:** 1 (redirect config) -**Diagrams Added:** 3 - -## Overview - -Phase 5 completes the restructure with: -1. Expanding stub files with comprehensive content -2. Creating redirect configuration for broken links -3. Adding final polish diagrams -4. Running comprehensive validation (terminology, accessibility, links) -5. Final build and deployment testing - -## Pre-Phase 5 Checklist - -- [ ] Phases 1-4 completed successfully -- [ ] Current build passes -- [ ] Tag `phase-4-complete` exists -- [ ] All 10 diagrams from previous phases render - -## Phase 5 Tasks - -### Task 5.1: Expand Stub Files - -These files currently have minimal content and need expansion: - -#### fundamentals/contracts.mdx - -Currently ~35 words. Expand to ~200 words: - -```mdx ---- -title: 'Contracts' -description: 'Understanding Stylus contract structure and entry points' -user_story: 'As a developer, I want to understand Stylus contract structure' -content_type: concept ---- - -# Contracts - -A Stylus contract is a Rust library compiled to WebAssembly (WASM) and deployed to the Arbitrum blockchain. - -## Contract structure - -Basic contract template: - -```rust -#![cfg_attr(not(feature = "export-abi"), no_main)] -extern crate alloc; - -use stylus_sdk::prelude::*; -use stylus_sdk::alloy_primitives::U256; - -#[storage] -pub struct Counter { - count: StorageU256, -} - -#[external] -impl Counter { - pub fn increment(&mut self) { - let current = self.count.get(); - self.count.set(current + U256::from(1)); - } - - pub fn number(&self) -> U256 { - self.count.get() - } -} -``` - -## Entry points - -### User entry point - -Stylus generates a `user_entrypoint` function that: -1. Receives calldata from the transaction -2. Routes to the appropriate method -3. Encodes return values -4. Handles errors - -This happens automatically via the `#[external]` macro. - -### Storage layout - -The `#[storage]` macro defines persistent state: - -```rust -#[storage] -pub struct MyContract { - owner: StorageAddress, - balance: StorageU256, - data: StorageMap, -} -``` - -## State management - -Contracts maintain state between transactions: - -```rust -pub fn update_data(&mut self, key: Address, value: U256) { - self.data.insert(key, value); // Persists to storage -} -``` - -## Method visibility - -Control access with Rust visibility: - -```rust -#[external] -impl MyContract { - pub fn public_method(&self) {} // Callable externally - - fn private_method(&self) {} // Internal only -} - -impl MyContract { - pub fn internal_helper(&self) {} // Not external, even though pub -} -``` - -## Next steps - -- [Learn about storage types](/stylus/fundamentals/data-types/storage) -- [Understand global variables](/stylus/fundamentals/global-variables-and-functions) -- [Build your first contract](/stylus/quickstart) -``` - -#### fundamentals/global-variables-and-functions.mdx - -Currently ~19 words. Expand to ~300 words: - -```mdx ---- -title: 'Global variables and functions' -description: 'Access blockchain context in Stylus contracts' -user_story: 'As a developer, I want to access transaction and block information' -content_type: reference ---- - -# Global variables and functions - -Stylus provides access to transaction and block context through global functions. - -## Message context - -### msg::sender() - -Returns the address that called the current function: - -```rust -use stylus_sdk::msg; -use stylus_sdk::alloy_primitives::Address; - -pub fn only_owner(&self) -> Result<(), Vec> { - let caller = msg::sender(); - if caller != self.owner.get() { - return Err(b"Unauthorized".to_vec()); - } - Ok(()) -} -``` - -### msg::value() - -Returns the amount of ETH sent with the transaction: - -```rust -use stylus_sdk::msg; -use stylus_sdk::alloy_primitives::U256; - -pub fn deposit(&mut self) -> U256 { - let amount = msg::value(); - let current = self.balance.get(); - self.balance.set(current + amount); - amount -} -``` - -## Block context - -### block::timestamp() - -Returns the current block timestamp (seconds since Unix epoch): - -```rust -use stylus_sdk::block; - -pub fn is_expired(&self, deadline: u64) -> bool { - block::timestamp() > deadline -} -``` - -### block::number() - -Returns the current block number: - -```rust -pub fn get_block(&self) -> u64 { - block::number() -} -``` - -## Contract context - -### contract::address() - -Returns the address of the current contract: - -```rust -use stylus_sdk::contract; - -pub fn my_address(&self) -> Address { - contract::address() -} -``` - -### contract::balance() - -Returns the ETH balance of the current contract: - -```rust -pub fn get_balance(&self) -> U256 { - contract::balance() -} -``` - -## Transaction context - -### tx::gas_price() - -Returns the gas price of the current transaction: - -```rust -use stylus_sdk::tx; - -pub fn current_gas_price(&self) -> U256 { - tx::gas_price() -} -``` - -### tx::origin() - -Returns the original sender of the transaction (may differ from msg::sender() in delegate calls): - -```rust -pub fn original_caller(&self) -> Address { - tx::origin() -} -``` - -## Complete example - -```rust -use stylus_sdk::prelude::*; -use stylus_sdk::alloy_primitives::{Address, U256}; -use stylus_sdk::{block, contract, msg, tx}; - -#[storage] -pub struct ContextExample { - owner: StorageAddress, - deposits: StorageMap, -} - -#[external] -impl ContextExample { - pub fn deposit(&mut self) -> Result<(), Vec> { - let caller = msg::sender(); - let amount = msg::value(); - let timestamp = block::timestamp(); - - // Only accept deposits after certain time - if timestamp < 1700000000 { - return Err(b"Too early".to_vec()); - } - - // Update balance - let current = self.deposits.get(caller); - self.deposits.insert(caller, current + amount); - - Ok(()) - } - - pub fn get_context_info(&self) -> (Address, Address, u64, U256) { - ( - msg::sender(), - contract::address(), - block::number(), - tx::gas_price() - ) - } -} -``` - -## Comparison with Solidity - -| Solidity | Stylus (Rust) | -|----------|---------------| -| `msg.sender` | `msg::sender()` | -| `msg.value` | `msg::value()` | -| `block.timestamp` | `block::timestamp()` | -| `block.number` | `block::number()` | -| `address(this)` | `contract::address()` | -| `address(this).balance` | `contract::balance()` | -| `tx.gasprice` | `tx::gas_price()` | -| `tx.origin` | `tx::origin()` | - -## See also - -- [Contracts](/stylus/fundamentals/contracts) -- [Storage types](/stylus/fundamentals/data-types/storage) -- [Rust SDK reference](/stylus/reference/rust-sdk/) -``` - -#### Expand data types files - -Similar expansions needed for: -- `fundamentals/data-types/primitives.mdx` (1 word โ†’ ~200 words) -- `fundamentals/data-types/compound-types.mdx` (11 words โ†’ ~250 words) -- `fundamentals/data-types/storage.mdx` (20 words โ†’ ~200 words) -- `fundamentals/data-types/conversions-between-types.mdx` (1 word โ†’ ~200 words) - -[Templates provided - expand with examples and details] - -### Task 5.2: Create Redirect Configuration - -Create comprehensive redirects for all moved files: - -```javascript -// In docusaurus.config.js, add to module.exports: - -module.exports = { - // ... existing config - - presets: [ - [ - 'classic', - { - docs: { - // ... existing docs config - - async sidebarPath() { - return require.resolve('./sidebars.js'); - }, - - // Add redirects - beforeDefaultRemarkPlugins: [], - beforeDefaultRehypePlugins: [], - }, - }, - ], - ], - - plugins: [ - [ - '@docusaurus/plugin-client-redirects', - { - redirects: [ - // CLI tools redirects (high priority) - { - from: '/stylus/using-cli', - to: '/stylus/cli-tools/overview', - }, - { - from: '/stylus/how-tos/verifying-contracts', - to: '/stylus/cli-tools/verify-contracts', - }, - { - from: '/stylus/how-tos/verifying-contracts-arbiscan', - to: '/stylus/cli-tools/verify-contracts', - }, - { - from: '/stylus/how-tos/check-and-deploy', - to: '/stylus/cli-tools/check-and-deploy', - }, - { - from: '/stylus/how-tos/debugging-tx', - to: '/stylus/cli-tools/debugging-tx', - }, - - // Fundamentals redirects (high priority) - { - from: '/stylus/how-tos/testing-contracts', - to: '/stylus/fundamentals/testing-contracts', - }, - { - from: '/stylus/reference/project-structure', - to: '/stylus/fundamentals/project-structure', - }, - { - from: '/stylus/reference/contracts', - to: '/stylus/fundamentals/contracts', - }, - { - from: '/stylus/reference/global-variables-and-functions', - to: '/stylus/fundamentals/global-variables-and-functions', - }, - { - from: '/stylus/reference/data-types/primitives', - to: '/stylus/fundamentals/data-types/primitives', - }, - { - from: '/stylus/reference/data-types/compound-types', - to: '/stylus/fundamentals/data-types/compound-types', - }, - { - from: '/stylus/reference/data-types/storage', - to: '/stylus/fundamentals/data-types/storage', - }, - { - from: '/stylus/reference/data-types/conversions-between-types', - to: '/stylus/fundamentals/data-types/conversions-between-types', - }, - - // Reference redirects - { - from: '/stylus/reference/rust-sdk-guide', - to: '/stylus/reference/rust-sdk/index', - }, - - // Concepts redirects - { - from: '/stylus/concepts/evm-differences', - to: '/stylus/concepts/vm-differences', - }, - { - from: '/stylus/concepts/activation', - to: '/stylus/concepts/activation', // No change, but ensure old links work - }, - - // Advanced redirects - { - from: '/stylus/advanced/solidity-differences', - to: '/stylus/advanced/rust-to-solidity-differences', - }, - - // Troubleshooting redirects - { - from: '/stylus/troubleshooting-building-stylus', - to: '/stylus/troubleshooting/faq', - }, - - // How-tos โ†’ Guides (catch-all for remaining files) - { - from: '/stylus/how-tos/:slug', - to: '/stylus/guides/:slug', - }, - ], - }, - ], - ], - - // ... rest of config -}; -``` - -### Task 5.3: Add Polish Diagrams - -Add the final 3 diagrams: - -**Diagram #7: Storage Layout** (fundamentals/data-types/storage.mdx) - -```mermaid -flowchart TB - subgraph "Storage Slots (32 bytes each)" - Slot0["Slot 0
    Variable A (uint256)"] - Slot1["Slot 1
    Variable B (address) + C (uint96)"] - Slot2["Slot 2
    Mapping length"] - Slot3["Slot 3
    keccak256(key, 2)"] - end - - Mapping[Mapping key] -->|hash| Slot3 - - style Slot1 fill:#FFF3E0 - style Slot3 fill:#E3F2FD -``` - -**Diagram #10: Memory Model** (concepts/webassembly.mdx) - -```mermaid -graph TB - subgraph "WASM Linear Memory" - Stack["Stack
    32 KB
    (fixed)"] - Heap["Heap/Data
    (grows upward)"] - Page1["Page 1
    64 KB"] - Page2["Page 2
    64 KB"] - PageN["Page N
    64 KB"] - end - - Stack -.-> Page1 - Heap --> Page1 - Heap --> Page2 - Heap -.-> PageN - - style Stack fill:#FFEBEE - style Heap fill:#E8F5E9 - style Page1 fill:#E3F2FD -``` - -**Diagram #11: WASM Binary Structure** (concepts/webassembly.mdx) - -```mermaid -graph TB - WASM["WASM Module"] - - WASM --> Exports["Exports Section
    user_entrypoint"] - WASM --> Imports["Imports Section
    vm_hooks"] - WASM --> Memory["Memory Section
    Linear memory"] - WASM --> Custom["Custom Sections
    Metadata"] - WASM --> Code["Code Section
    Compiled bytecode"] - - Imports --> storage_load - Imports --> msg_sender - Imports --> emit_log - - style WASM fill:#E1BEE7 - style Exports fill:#C8E6C9 - style Imports fill:#BBDEFB -``` - -### Task 5.4: Comprehensive Terminology Audit - -Run final terminology check: - -```bash -./scripts/restructure/terminology-audit.sh - -# Fix any remaining violations -``` - -### Task 5.5: Comprehensive Frontmatter Audit - -```bash -./scripts/restructure/frontmatter-audit.sh - -# Complete any missing fields -``` - -### Task 5.6: Accessibility Audit - -Create accessibility validation script: - -```bash -cat > scripts/restructure/accessibility-audit.sh << 'EOF' -#!/bin/bash - -echo "=== Accessibility Audit ===" -echo "" - -issues=0 - -# Check heading hierarchy -echo "Checking heading hierarchy..." -for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do - # Check for H1 (should be only one, from frontmatter title) - h1_count=$(grep -c "^# " "$file" || true) - if [ "$h1_count" -gt 1 ]; then - echo "โš ๏ธ Multiple H1s in $file" - issues=$((issues + 1)) - fi - - # Check for heading skips (H2 โ†’ H4) - if grep -q "^## " "$file" && grep -q "^#### " "$file"; then - # Check if H3 exists between them - if ! grep -q "^### " "$file"; then - echo "โš ๏ธ Heading skip (H2 โ†’ H4) in $file" - issues=$((issues + 1)) - fi - fi -done - -# Check for alt text on images -echo "" -echo "Checking image alt text..." -for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do - # Find images without alt text - if grep -q "!\[\](" "$file"; then - echo "โš ๏ธ Image without alt text in $file" - issues=$((issues + 1)) - fi -done - -# Check diagram captions -echo "" -echo "Checking diagram captions..." -for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do - # If file has mermaid diagram, should have caption - if grep -q "```mermaid" "$file"; then - # Check for caption (line starting with *Figure or *Diagram) - if ! grep -A 5 "```mermaid" "$file" | grep -q "^\*Figure\|^\*Diagram"; then - echo "โš ๏ธ Mermaid diagram without caption in $file" - issues=$((issues + 1)) - fi - fi -done - -echo "" -echo "=== Audit Complete ===" -echo "Issues found: $issues" -echo "" - -if [ $issues -eq 0 ]; then - echo "โœ… All accessibility checks passed!" - exit 0 -else - echo "โŒ Accessibility issues found. Please fix." - exit 1 -fi -EOF - -chmod +x scripts/restructure/accessibility-audit.sh -./scripts/restructure/accessibility-audit.sh -``` - -### Task 5.7: Comprehensive Build Validation - -```bash -# Clean build -rm -rf build .docusaurus - -# Full build -yarn build - -# Check for warnings -yarn build 2>&1 | tee build.log - -# Check for broken links -grep -i "broken\|404\|not found" build.log - -# Check for missing files -grep -i "does not exist" build.log -``` - -### Task 5.8: Test All Diagrams - -Create diagram validation script: - -```bash -cat > scripts/restructure/diagram-validation.sh << 'EOF' -#!/bin/bash - -echo "=== Diagram Validation ===" -echo "" - -diagrams=0 -errors=0 - -for file in $(find docs/stylus -name "*.mdx" -o -name "*.md"); do - # Count mermaid diagrams - count=$(grep -c "```mermaid" "$file" || true) - if [ $count -gt 0 ]; then - diagrams=$((diagrams + count)) - echo "Found $count diagram(s) in $file" - - # Check for syntax errors (basic) - # Look for common issues - if grep -A 20 "```mermaid" "$file" | grep -q "```mermaid.*```mermaid"; then - echo " โš ๏ธ Possible nested mermaid blocks" - errors=$((errors + 1)) - fi - fi -done - -echo "" -echo "Total diagrams found: $diagrams" -echo "Expected diagrams: 13" -echo "" - -if [ $diagrams -eq 13 ]; then - echo "โœ… All 13 diagrams present!" -else - echo "โš ๏ธ Expected 13 diagrams, found $diagrams" -fi - -if [ $errors -gt 0 ]; then - echo "โŒ $errors diagram errors found" - exit 1 -fi - -exit 0 -EOF - -chmod +x scripts/restructure/diagram-validation.sh -./scripts/restructure/diagram-validation.sh -``` - -### Task 5.9: Mobile Responsiveness Test - -```bash -# Start dev server -yarn start --no-open - -# Use browser dev tools to test: -# - Mobile viewport (375px width) -# - Tablet viewport (768px width) -# - Test sidebar navigation -# - Test diagram rendering -# - Test touch targets (min 44x44px) -``` - -### Task 5.10: Lighthouse Audit - -```bash -# Build and serve -yarn build -yarn serve --no-open - -# Run Lighthouse (requires Chrome) -lighthouse http://localhost:3000/stylus \ - --only-categories=accessibility,performance,best-practices,seo \ - --output=html \ - --output-path=./lighthouse-report.html - -# Target scores: -# - Accessibility: โ‰ฅ95 -# - Performance: โ‰ฅ90 -# - Best Practices: โ‰ฅ90 -# - SEO: โ‰ฅ90 -``` - -### Task 5.11: Final Commit - -```bash -git add -A -git commit -m "docs(stylus): Phase 5 - Expansion & Validation - -- Expand stub files (contracts, global vars, data types) -- Add redirect configuration for all moved files -- Add final 3 polish diagrams (#7, #10, #11) -- Complete comprehensive validation (terminology, frontmatter, accessibility) -- Verify all 13 diagrams render correctly -- Achieve 100% terminology compliance -- Achieve โ‰ฅ95% accessibility score - -Files modified: 18 -Diagrams added: 3 -Validation: Complete" - -git tag phase-5-complete -git tag stylus-restructure-complete -``` - -## Phase 5 Success Criteria - -- [ ] โœ… All stub files expanded -- [ ] โœ… Redirects configured -- [ ] โœ… All 13 diagrams render -- [ ] โœ… Build passes with zero errors -- [ ] โœ… Zero broken links -- [ ] โœ… 100% terminology compliance -- [ ] โœ… 100% frontmatter completion -- [ ] โœ… Accessibility โ‰ฅ95% -- [ ] โœ… Lighthouse performance โ‰ฅ90% -- [ ] โœ… Mobile responsive -- [ ] โœ… Changes committed and tagged - -## Post-Restructure - -### Create Pull Request - -```bash -# Push to GitHub -git push origin stylus-docs-restructure - -# Create PR using gh CLI -gh pr create \ - --title "docs: Comprehensive Stylus documentation restructure" \ - --body "$(cat << 'EOF' -## Summary - -Complete 5-phase restructure of Stylus documentation addressing critical issues and creating best-in-class structure. - -## Changes - -### Structure -- Flattened sidebar from 4+ to max 3 levels -- Created 5 new top-level sections (fundamentals, guides, cli-tools, best-practices, troubleshooting) -- Moved 20+ files to better locations - -### Content -- Fixed 100% of terminology violations (CLAUDE.md compliance) -- Completed missing frontmatter on all files -- Merged duplicate content (verification docs, VM differences) -- Split oversized files (rust-sdk-guide โ†’ 8 focused files) -- Created 15 new documentation files - -### Visual Learning -- Added 13 strategic Mermaid diagrams -- Diagrams for lifecycle, deployment, architecture, call flows, storage, memory - -### Quality -- โœ… 100% terminology compliance -- โœ… 100% frontmatter completion -- โœ… 95%+ accessibility score -- โœ… Zero broken links -- โœ… All diagrams render correctly - -## Testing - -- [x] Build passes -- [x] All diagrams render -- [x] No broken links -- [x] Mobile responsive -- [x] Accessibility audit passed -- [x] Lighthouse scores โ‰ฅ90% - -## Impact - -- **Files modified**: ~58 -- **New files**: ~45 -- **Diagrams added**: 13 -- **Directories created**: 5 -- **Net improvement**: +39 focused, well-organized files - -## Rollback - -If needed, rollback with: -\`\`\`bash -git revert stylus-restructure-complete -\`\`\` - -Each phase is tagged for granular rollback if needed. -EOF -)" \ - --base master \ - --head stylus-docs-restructure -``` - -### Deploy Preview - -Netlify or Vercel will auto-deploy preview. Share with team for review. - -### Documentation - -Update CLAUDE.md: - -```bash -# After merge, update CLAUDE.md to reflect new structure -``` - -## Complete! ๐ŸŽ‰ - -The Stylus documentation restructure is now complete. You've successfully: - -โœ… Created a flatter, clearer directory structure -โœ… Fixed all terminology violations -โœ… Completed all missing frontmatter -โœ… Added 13 strategic diagrams -โœ… Created 15 new documentation files -โœ… Achieved 100% compliance and โ‰ฅ95% accessibility - -The documentation now provides: -- Clear learning paths for Rust-first and Solidity-first developers -- Comprehensive visual aids for complex concepts -- Better organization and discoverability -- Faster page loads and better SEO -- Mobile-friendly responsive design -- WCAG-compliant accessibility - -## Maintenance - -Going forward: -- Run terminology audit before commits -- Ensure all new files have complete frontmatter -- Add diagrams for complex concepts -- Maintain max 3-level sidebar depth -- Keep best practices updated diff --git a/docs/stylus/RESTRUCTURE_README.md b/docs/stylus/RESTRUCTURE_README.md deleted file mode 100644 index 10630835ca..0000000000 --- a/docs/stylus/RESTRUCTURE_README.md +++ /dev/null @@ -1,348 +0,0 @@ -# Stylus Documentation Restructure - Complete Guide - -This directory contains comprehensive, executable guides for restructuring the Stylus documentation. - -## ๐Ÿ“š Documentation - -- **[IMPLEMENTATION_GUIDE.md](./IMPLEMENTATION_GUIDE.md)** - Master guide with overview and Phases 1-2 -- **[IMPLEMENTATION_GUIDE_PHASE3.md](./IMPLEMENTATION_GUIDE_PHASE3.md)** - Phase 3: Content Consolidation -- **[IMPLEMENTATION_GUIDE_PHASE4.md](./IMPLEMENTATION_GUIDE_PHASE4.md)** - Phase 4: Create New Content -- **[IMPLEMENTATION_GUIDE_PHASE5.md](./IMPLEMENTATION_GUIDE_PHASE5.md)** - Phase 5: Expansion & Validation - -## ๐ŸŽฏ Quick Start - -```bash -# 1. Create backup -git checkout -b stylus-docs-restructure -git add -A -git commit -m "checkpoint: before restructure" - -# 2. Execute phases in order -# See IMPLEMENTATION_GUIDE.md for detailed steps - -# 3. Validate after each phase -yarn build -``` - -## ๐Ÿ“Š Overview - -| Phase | Focus | Duration | Files | Diagrams | -|-------|-------|----------|-------|----------| -| **1** | Foundation & Compliance | ~8h | ~28 modified | 3 added | -| **2** | Directory Restructure | ~10h | ~20 modified | 0 | -| **3** | Content Consolidation | ~12h | 4 modified, 12 new | 1 added | -| **4** | Create New Content | ~16h | 15 new | 6 added | -| **5** | Expansion & Validation | ~12h | ~18 modified | 3 added | -| **Total** | **5 weeks** | **~58h** | **~100 files** | **13 diagrams** | - -## ๐Ÿ—บ๏ธ Restructure Roadmap - -### Phase 1: Foundation & Compliance -- [x] Delete duplicate files -- [x] Create missing configs -- [x] Fix terminology violations -- [x] Complete frontmatter -- [x] Merge verification docs -- [x] Add quick-win diagrams (#3, #8, #12) - -**Success Criteria:** 100% terminology compliance, complete frontmatter, 3 diagrams rendering - -### Phase 2: Directory Restructure -- [ ] Create 5 new top-level directories -- [ ] Move files to fundamentals/ -- [ ] Rename how-tos/ to guides/ -- [ ] Create cli-tools/ section -- [ ] Update sidebars.js -- [ ] Fix all imports - -**Success Criteria:** Flatter structure (max 3 levels), all files moved, no broken links - -### Phase 3: Content Consolidation -- [ ] Merge VM differences -- [ ] Split rust-sdk-guide.md into 8 files -- [ ] Extract setup to partials -- [ ] Streamline quickstart -- [ ] Add journey diagram (#13) - -**Success Criteria:** No duplicate content, SDK properly organized, partials working - -### Phase 4: Create New Content -- [ ] Add fundamentals content (choose-path, dev-env) -- [ ] Create interop guides (Rust โ†” Solidity) -- [ ] Write best practices (security, performance, gas) -- [ ] Build troubleshooting section -- [ ] Add core concept diagrams (#1, #2, #4, #5, #6, #9) - -**Success Criteria:** All gaps filled, 6 diagrams added, comprehensive coverage - -### Phase 5: Expansion & Validation -- [ ] Expand all stub files -- [ ] Configure redirects -- [ ] Add polish diagrams (#7, #10, #11) -- [ ] Run comprehensive validation -- [ ] Achieve โ‰ฅ95% accessibility - -**Success Criteria:** All stubs expanded, all 13 diagrams working, 100% compliance, โ‰ฅ95% accessibility - -## ๐Ÿ“ New Directory Structure - -``` -docs/stylus/ -โ”œโ”€โ”€ gentle-introduction.mdx -โ”œโ”€โ”€ quickstart.mdx -โ”‚ -โ”œโ”€โ”€ fundamentals/ # NEW: SDK basics + prerequisites -โ”‚ โ”œโ”€โ”€ prerequisites.mdx -โ”‚ โ”œโ”€โ”€ choose-your-path.mdx # NEW -โ”‚ โ”œโ”€โ”€ development-environment.mdx # NEW -โ”‚ โ”œโ”€โ”€ project-structure.mdx # MOVED from reference/ -โ”‚ โ”œโ”€โ”€ contracts.mdx # MOVED + EXPANDED -โ”‚ โ”œโ”€โ”€ global-variables-and-functions.mdx # MOVED + EXPANDED -โ”‚ โ”œโ”€โ”€ testing-contracts.mdx # MOVED from how-tos/ -โ”‚ โ””โ”€โ”€ data-types/ # MOVED from reference/ -โ”‚ -โ”œโ”€โ”€ guides/ # RENAMED from how-tos, flattened -โ”‚ โ”œโ”€โ”€ create-project.mdx # NEW -โ”‚ โ”œโ”€โ”€ using-constructors.mdx -โ”‚ โ”œโ”€โ”€ using-inheritance.mdx -โ”‚ โ”œโ”€โ”€ importing-interfaces.mdx -โ”‚ โ”œโ”€โ”€ exporting-abi.mdx -โ”‚ โ”œโ”€โ”€ optimizing-binaries.mdx -โ”‚ โ”œโ”€โ”€ caching-contracts.mdx -โ”‚ โ”œโ”€โ”€ call-solidity-from-rust.mdx # NEW -โ”‚ โ”œโ”€โ”€ call-rust-from-solidity.mdx # NEW -โ”‚ โ”œโ”€โ”€ deploy-non-rust-contracts.mdx -โ”‚ โ””โ”€โ”€ add-language-support.mdx -โ”‚ -โ”œโ”€โ”€ cli-tools/ # NEW: Top-level CLI section -โ”‚ โ”œโ”€โ”€ overview.mdx -โ”‚ โ”œโ”€โ”€ check-and-deploy.mdx -โ”‚ โ”œโ”€โ”€ verify-contracts.mdx # MERGED -โ”‚ โ”œโ”€โ”€ debugging-tx.mdx -โ”‚ โ””โ”€โ”€ commands-reference.mdx # NEW -โ”‚ -โ”œโ”€โ”€ concepts/ -โ”‚ โ”œโ”€โ”€ webassembly.mdx -โ”‚ โ”œโ”€โ”€ activation.mdx -โ”‚ โ”œโ”€โ”€ gas-metering.mdx -โ”‚ โ”œโ”€โ”€ vm-differences.mdx # MERGED evm + solidity diffs -โ”‚ โ””โ”€โ”€ public-preview-expectations.mdx -โ”‚ -โ”œโ”€โ”€ best-practices/ # NEW -โ”‚ โ”œโ”€โ”€ security.mdx # NEW -โ”‚ โ”œโ”€โ”€ performance.mdx # NEW -โ”‚ โ””โ”€โ”€ gas-optimization.mdx # NEW -โ”‚ -โ”œโ”€โ”€ advanced/ -โ”‚ โ”œโ”€โ”€ rust-to-solidity-differences.mdx # RENAMED -โ”‚ โ”œโ”€โ”€ minimal-entrypoint-contracts.mdx -โ”‚ โ”œโ”€โ”€ hostio-exports.mdx -โ”‚ โ”œโ”€โ”€ recommended-libraries.mdx -โ”‚ โ””โ”€โ”€ memory-management.mdx # NEW -โ”‚ -โ”œโ”€โ”€ troubleshooting/ # NEW -โ”‚ โ”œโ”€โ”€ faq.mdx -โ”‚ โ”œโ”€โ”€ common-errors.mdx # NEW -โ”‚ โ””โ”€โ”€ debugging-guide.mdx # NEW -โ”‚ -โ”œโ”€โ”€ reference/ -โ”‚ โ”œโ”€โ”€ overview.mdx -โ”‚ โ”œโ”€โ”€ rust-sdk/ # NEW: Split from rust-sdk-guide.md -โ”‚ โ”‚ โ”œโ”€โ”€ index.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ storage.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ methods.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ events.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ errors.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ calls.mdx -โ”‚ โ”‚ โ”œโ”€โ”€ crypto.mdx -โ”‚ โ”‚ โ””โ”€โ”€ bytes-programming.mdx -โ”‚ โ””โ”€โ”€ opcode-hostio-pricing.mdx -โ”‚ -โ””โ”€โ”€ partials/ - โ”œโ”€โ”€ _stylus-faucets.mdx # MOVED - โ”œโ”€โ”€ _setup-rust-toolchain.mdx # NEW - โ”œโ”€โ”€ _setup-cargo-stylus.mdx # NEW - โ””โ”€โ”€ _setup-docker-nitro.mdx # NEW -``` - -## ๐ŸŽจ Mermaid Diagrams - -### High Priority (8 diagrams) - -1. **Contract Lifecycle** (gentle-introduction.mdx) - Flowchart showing Coding โ†’ Activation โ†’ Execution โ†’ Proving -2. **Deployment & Activation** (activation.mdx) - Sequence diagram of two-step deployment -3. **WASM Processing Pipeline** (activation.mdx) - Flowchart of binary processing โœ… Phase 1 -4. **EVM vs WASM Architecture** (vm-differences.mdx) - Side-by-side comparison -5. **Contract Call Flow** (importing-interfaces.mdx) - Sequence diagram for cross-language calls -6. **Ink to Gas Conversion** (gas-metering.mdx) - Flowchart explaining metering -7. **Storage Layout** (storage.mdx) - Memory layout diagram -8. **Call Config Decision Tree** (importing-interfaces.mdx) - Decision tree for Call constructors โœ… Phase 1 - -### Medium Priority (5 diagrams) - -9. **Deployment Workflows** (check-and-deploy.mdx) - Swimlanes for dev/testnet/prod -10. **Memory Model** (webassembly.mdx) - WASM memory structure -11. **WASM Binary Structure** (webassembly.mdx) - Component diagram -12. **Storage Type Hierarchy** (storage.mdx) - Type hierarchy tree โœ… Phase 1 -13. **Quickstart Journey** (quickstart.mdx) - Journey map โœ… Phase 3 - -## ๐Ÿ› ๏ธ Scripts - -All automation scripts are in `scripts/restructure/`: - -```bash -scripts/restructure/ -โ”œโ”€โ”€ terminology-audit.sh # Check CLAUDE.md compliance -โ”œโ”€โ”€ frontmatter-audit.sh # Verify frontmatter completion -โ”œโ”€โ”€ update-imports.sh # Fix imports for moved files -โ”œโ”€โ”€ accessibility-audit.sh # Check WCAG compliance -โ””โ”€โ”€ diagram-validation.sh # Verify all diagrams present -``` - -## โœ… Validation Checklist - -After each phase: - -- [ ] Run `yarn build` successfully -- [ ] Zero broken links -- [ ] All diagrams render -- [ ] Terminology audit passes -- [ ] Frontmatter audit passes -- [ ] Git commit with descriptive message -- [ ] Tag phase completion - -Final validation (Phase 5): - -- [ ] Accessibility โ‰ฅ95% -- [ ] Performance โ‰ฅ90% -- [ ] Mobile responsive -- [ ] All 13 diagrams working -- [ ] 100% CLAUDE.md compliance -- [ ] Comprehensive redirects configured - -## ๐Ÿ”„ Rollback Procedures - -### Rollback Individual Phase - -```bash -# Rollback to start of phase -git reset --hard phase-X-start - -# Or revert specific phase -git revert phase-X-complete -``` - -### Rollback All Changes - -```bash -# Reset to pre-restructure state -git reset --hard stylus-docs-restructure-start - -# Or delete branch and start over -git checkout master -git branch -D stylus-docs-restructure -``` - -### Git Tags - -Each phase creates two tags: -- `phase-X-start` - Before phase begins (for rollback) -- `phase-X-complete` - After phase commits (for reference) - -## ๐Ÿ“ˆ Success Metrics - -### Content Quality -- โœ… Zero duplicate files -- โœ… Complete navigation (no orphans) -- โœ… Clear learning paths -- โœ… Focused files (<300 lines except references) -- โœ… Single source of truth - -### CLAUDE.md Compliance -- โœ… 100% terminology standards -- โœ… 100% frontmatter completion -- โœ… Sentence case headers -- โœ… American English spelling -- โœ… Problem-solution troubleshooting format - -### Architecture -- โœ… Flattened navigation (max 3 levels) -- โœ… Better categorization -- โœ… Testing as fundamental -- โœ… CLI as top-level section - -### Technical Performance -- โœ… Improved SEO -- โœ… Faster page loads -- โœ… Accessibility โ‰ฅ95% -- โœ… Mobile usability โ‰ฅ90% - -### Maintainability -- โœ… Clear conventions -- โœ… Zero broken links -- โœ… Comprehensive redirects -- โœ… Visual learning support (13 diagrams) - -## ๐Ÿค Contributing - -When adding new content after restructure: - -1. **Choose correct directory:** - - SDK basics โ†’ `fundamentals/` - - Practical guides โ†’ `guides/` - - CLI commands โ†’ `cli-tools/` - - Conceptual โ†’ `concepts/` - - Patterns โ†’ `best-practices/` - - Complex internals โ†’ `advanced/` - - Problems โ†’ `troubleshooting/` - - API reference โ†’ `reference/` - -2. **Use complete frontmatter:** - ```yaml - --- - title: 'Your title' - description: 'SEO-friendly description' - user_story: 'As a , I want to ' - content_type: 'how-to | concept | reference | etc.' - author: github-username - sme: github-username - sidebar_position: N - --- - ``` - -3. **Follow terminology standards:** - - Run `./scripts/restructure/terminology-audit.sh` - - Fix violations before committing - -4. **Add diagrams for complex concepts:** - - Use Mermaid for consistency - - Include descriptive captions - - Test in both light/dark themes - -5. **Test before committing:** - ```bash - yarn build - ./scripts/restructure/terminology-audit.sh - ./scripts/restructure/frontmatter-audit.sh - ``` - -## ๐Ÿ“ž Support - -Questions during implementation: - -1. **Build errors:** Check `build.log` for specific errors -2. **Broken links:** Run `yarn build 2>&1 | grep broken` -3. **Import errors:** Run `./scripts/restructure/update-imports.sh` -4. **Diagram issues:** Run `./scripts/restructure/diagram-validation.sh` -5. **Rollback needed:** See rollback procedures above - -## ๐Ÿ“ License - -Same as parent project (MIT/Apache-2.0) - ---- - -**Last Updated:** 2025-12-12 -**Status:** Ready for implementation -**Estimated Total Time:** 5 weeks (~58 hours of focused work) -**Expected Impact:** Best-in-class documentation structure with comprehensive visual aids From 3619d053ac6948d6e65c3ed673dd6bb5ad9a8485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 12 Dec 2025 20:31:22 -0800 Subject: [PATCH 123/162] delete unnecessary dev docs --- docs/stylus/STRUCTURE.md | 238 --------------------------------------- 1 file changed, 238 deletions(-) delete mode 100644 docs/stylus/STRUCTURE.md diff --git a/docs/stylus/STRUCTURE.md b/docs/stylus/STRUCTURE.md deleted file mode 100644 index 536a5db2ee..0000000000 --- a/docs/stylus/STRUCTURE.md +++ /dev/null @@ -1,238 +0,0 @@ -# Stylus Documentation Structure - -This document provides a visual overview of the Stylus documentation structure after the v0.10 restructure. - -``` -docs/stylus/ -โ”‚ -โ”œโ”€โ”€ gentle-introduction.mdx -โ”œโ”€โ”€ quickstart.mdx -โ”œโ”€โ”€ using-cli.mdx (legacy) -โ”‚ -โ”œโ”€โ”€ fundamentals/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ choose-your-path.mdx [NEW - Phase 4] -โ”‚ โ”œโ”€โ”€ prerequisites.mdx [Phase 3] -โ”‚ โ”œโ”€โ”€ project-structure.mdx -โ”‚ โ”œโ”€โ”€ contracts.mdx [DIAGRAM: Lifecycle] -โ”‚ โ”œโ”€โ”€ global-variables-and-functions.mdx -โ”‚ โ”œโ”€โ”€ testing-contracts.mdx -โ”‚ โ””โ”€โ”€ data-types/ -โ”‚ โ”œโ”€โ”€ primitives.mdx -โ”‚ โ”œโ”€โ”€ compound-types.mdx -โ”‚ โ”œโ”€โ”€ storage.mdx [DIAGRAMS: Hierarchy + Layout] -โ”‚ โ””โ”€โ”€ conversions-between-types.mdx -โ”‚ -โ”œโ”€โ”€ guides/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ using-constructors.mdx -โ”‚ โ”œโ”€โ”€ using-inheritance.mdx -โ”‚ โ”œโ”€โ”€ importing-interfaces.mdx [DIAGRAM: Cross-Contract Calls] -โ”‚ โ”œโ”€โ”€ exporting-abi.mdx -โ”‚ โ”œโ”€โ”€ optimizing-binaries.mdx -โ”‚ โ”œโ”€โ”€ caching-contracts.mdx -โ”‚ โ”œโ”€โ”€ deploying-non-rust-wasm-contracts.mdx -โ”‚ โ””โ”€โ”€ adding-support-for-new-languages.mdx -โ”‚ -โ”œโ”€โ”€ cli-tools/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ overview.mdx -โ”‚ โ”œโ”€โ”€ check-and-deploy.mdx -โ”‚ โ”œโ”€โ”€ verify-contracts.mdx -โ”‚ โ”œโ”€โ”€ debugging-tx.mdx -โ”‚ โ””โ”€โ”€ commands-reference.mdx -โ”‚ -โ”œโ”€โ”€ best-practices/ [NEW - Phase 4] -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ security.mdx (501 lines) -โ”‚ โ””โ”€โ”€ gas-optimization.mdx [DIAGRAM: Performance Comparison] (548 lines) -โ”‚ -โ”œโ”€โ”€ troubleshooting/ [NEW - Phase 4] -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ common-issues.mdx (591 lines) -โ”‚ โ””โ”€โ”€ troubleshooting-building-stylus.md (legacy) -โ”‚ -โ”œโ”€โ”€ concepts/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ webassembly.mdx [DIAGRAMS: Pipeline + Binary + Memory] -โ”‚ โ”œโ”€โ”€ activation.mdx [DIAGRAM: Deployment] -โ”‚ โ”œโ”€โ”€ gas-metering.mdx -โ”‚ โ”œโ”€โ”€ vm-differences.mdx (renamed in Phase 3) -โ”‚ โ””โ”€โ”€ public-preview-expectations.mdx -โ”‚ -โ”œโ”€โ”€ advanced/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ rust-to-solidity-differences.mdx (renamed in Phase 3) -โ”‚ โ”œโ”€โ”€ minimal-entrypoint-contracts.mdx -โ”‚ โ”œโ”€โ”€ hostio-exports.mdx -โ”‚ โ””โ”€โ”€ recommended-libraries.mdx -โ”‚ -โ”œโ”€โ”€ reference/ -โ”‚ โ”œโ”€โ”€ _category_.yml -โ”‚ โ”œโ”€โ”€ overview.mdx -โ”‚ โ”œโ”€โ”€ opcode-hostio-pricing.mdx -โ”‚ โ””โ”€โ”€ rust-sdk-guide.md -โ”‚ -โ”œโ”€โ”€ partials/ (Reusable Content) -โ”‚ โ”œโ”€โ”€ _setup-rust-toolchain.mdx -โ”‚ โ”œโ”€โ”€ _setup-cargo-stylus.mdx -โ”‚ โ”œโ”€โ”€ _setup-docker-nitro.mdx -โ”‚ โ”œโ”€โ”€ _stylus-faucets.mdx -โ”‚ โ”œโ”€โ”€ _stylus-no-multi-inheritance-banner-partial.mdx -โ”‚ โ””โ”€โ”€ _stylus-public-preview-banner-partial.md -โ”‚ -โ””โ”€โ”€ planning/ (Phase Guides) - โ”œโ”€โ”€ RESTRUCTURE_README.md - โ”œโ”€โ”€ IMPLEMENTATION_GUIDE.md - โ”œโ”€โ”€ IMPLEMENTATION_GUIDE_PHASE3.md - โ”œโ”€โ”€ IMPLEMENTATION_GUIDE_PHASE4.md - โ””โ”€โ”€ IMPLEMENTATION_GUIDE_PHASE5.md -``` - -## Statistics - -### Diagrams: 11 total - -| File | Diagrams | Description | -| ----------------------------------- | -------- | ---------------------------------------------------- | -| fundamentals/choose-your-path.mdx | 1 | Learning path decision tree | -| fundamentals/contracts.mdx | 1 | Contract lifecycle flow | -| fundamentals/data-types/storage.mdx | 2 | Type hierarchy + Slot layout | -| guides/importing-interfaces.mdx | 1 | Cross-contract calls | -| best-practices/gas-optimization.mdx | 1 | Stylus vs Solidity performance | -| concepts/webassembly.mdx | 3 | Execution pipeline + Binary structure + Memory model | -| concepts/activation.mdx | 1 | WASM deployment process | -| quickstart.mdx | 1 | User journey through quickstart | - -### Directory Structure - -**10 top-level directories:** - -- `fundamentals/` - Core concepts and data types -- `guides/` - How-to guides for common tasks -- `cli-tools/` - CLI commands and usage -- `best-practices/` [NEW] - Security and optimization -- `troubleshooting/` [NEW] - Common issues and solutions -- `concepts/` - Deep-dive conceptual explanations -- `advanced/` - Advanced topics and low-level details -- `reference/` - API reference and SDK documentation -- `partials/` - Reusable content snippets -- `planning/` - Restructure implementation guides - -### File Inventory - -**Total:** ~58 documentation files - -**By Phase:** - -- **Phase 2:** Moved 19 files, created new directory structure -- **Phase 3:** Created 4 new files (prerequisites + 3 partials) -- **Phase 4:** Created 4 major files (choose-your-path, security, gas-optimization, common-issues) -- **Phase 5:** Added 3 diagrams to existing files - -**Major Content:** - -- Phase 4 new content: ~1,925 lines across 4 files -- Comprehensive security guide: 501 lines -- Complete gas optimization guide: 548 lines -- Troubleshooting FAQ: 591 lines -- Learning path guide: 285 lines - -### Navigation Improvements - -- **Before:** 4+ levels deep (confusing hierarchy) -- **After:** Maximum 3 levels (clear, scannable structure) -- **Sidebar categories:** 9 main sections (down from 15+ scattered sections) - -## Phase Highlights - -### Phase 1: Planning - -- Analyzed existing structure -- Identified pain points -- Created comprehensive restructure plan - -### Phase 2: Directory Restructure - -- Created 5 new top-level directories -- Moved 19 files to logical locations -- Flattened sidebar from 4+ to max 3 levels -- Updated 80+ navigation items - -### Phase 3: Content Consolidation - -- Created reusable setup partials (3 files) -- Renamed confusing files (evm->vm, solidity->rust-to-solidity) -- Added prerequisites guide -- Added journey diagram to quickstart -- Eliminated duplicate content - -### Phase 4: New Content Creation - -- Choose Your Path guide (4 learning paths) -- Security Best Practices (comprehensive) -- Gas Optimization Best Practices (Stylus-specific) -- Troubleshooting guide (common issues) -- 3 new diagrams added - -### Phase 5: Final Polish - -- Added 3 final diagrams (storage, WASM binary, memory) -- Completed comprehensive validation -- Verified all builds pass -- Tagged final milestone - -## Annotations Used - -| Marker | Meaning | -| --------- | --------------------------------------- | -| [NEW] | Added during restructure | -| [DIAGRAM] | Contains Mermaid diagram(s) | -| (legacy) | May be deprecated or consolidated | -| [Phase N] | Indicates which phase added/modified it | - -## Quick Navigation - -### For New Developers - -1. Start: `gentle-introduction.mdx` -2. Setup: `fundamentals/prerequisites.mdx` -3. Build: `quickstart.mdx` -4. Choose path: `fundamentals/choose-your-path.mdx` - -### For Solidity Developers - -1. Start: `advanced/rust-to-solidity-differences.mdx` -2. Quick start: `quickstart.mdx` -3. Best practices: `best-practices/security.mdx` - -### For Rust Developers - -1. Start: `quickstart.mdx` -2. Concepts: `concepts/webassembly.mdx` -3. Optimize: `best-practices/gas-optimization.mdx` - -### When Stuck - -1. Troubleshooting: `troubleshooting/common-issues.mdx` -2. CLI help: `cli-tools/commands-reference.mdx` -3. Debugging: `cli-tools/debugging-tx.mdx` - -## Tags Available - -Git tags for rollback if needed: - -- `phase-1-complete` - Planning phase -- `phase-2-complete` - Directory restructure -- `phase-3-complete` - Content consolidation -- `phase-4-complete` - New content creation -- `phase-5-complete` - Final diagrams -- `stylus-v0-10-restructure-complete` - Final milestone - ---- - -**Last Updated:** December 12, 2025 -**Restructure Status:** Complete (All 5 phases) -**Total Diagrams:** 11 -**Total Files:** ~58 -**Navigation Depth:** Max 3 levels From 418c26cb8d6ba14c30e960b72d71383415abc302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Sat, 13 Dec 2025 07:51:23 -0800 Subject: [PATCH 124/162] touch up --- docs/stylus/gentle-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index c583e2daab..82f1b8f1ce 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -1,7 +1,7 @@ --- id: gentle-introduction title: 'A gentle introduction to Stylus' -description: 'An introduction to Stylus, which enables writing EVM-compatible smart contracts in programming languages that compile to WASM, such as Rust, C, and C++.' +description: 'An introduction to Stylus, which enables writing EVM-compatible smart contracts in programming languages that compile to WASM, such as Rust, C, and C++' user_story: 'As a developer, I want to understand what Stylus is and why I should use it' content_type: concept author: amarrazza From 3c05ef71e6242f767b0d542ada32afa382f4f0ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 09:47:49 -0800 Subject: [PATCH 125/162] relink overview.mdx to fix build issues --- docs/stylus/reference/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/reference/overview.mdx b/docs/stylus/reference/overview.mdx index 9db6b602fa..21e7c35816 100644 --- a/docs/stylus/reference/overview.mdx +++ b/docs/stylus/reference/overview.mdx @@ -4,7 +4,7 @@ description: 'An overview of the features provided by the Stylus Rust SDK' author: jose-franco sme: jose-franco sidebar_position: 1 -sidebar_label: 'Overview' +sidebar_label: 'SDK Overview' user_story: 'As a developer, I want to understand the Stylus Rust SDK structure so I can navigate the documentation effectively.' content_type: 'reference' target_audience: Developers using the Stylus Rust SDK to write and deploy smart contracts. From bfbd1aca7666f3384a3d446bb2690eb7f5caa5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 09:54:14 -0800 Subject: [PATCH 126/162] fix fontmatter to BUILD SUCCESSFULLY --- docs/stylus/cli-tools/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/cli-tools/overview.mdx b/docs/stylus/cli-tools/overview.mdx index 333b53f92e..31e107cd81 100644 --- a/docs/stylus/cli-tools/overview.mdx +++ b/docs/stylus/cli-tools/overview.mdx @@ -1,5 +1,5 @@ --- -id: using-cli +id: 'overview' title: 'Using Stylus CLI' description: 'Get started with Stylus CLI, a Rust toolkit for developing Stylus contracts' author: 'anegg0' From 0137fe4ec209d79d7444dcfa6f3268fcc153a200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 10:44:58 -0800 Subject: [PATCH 127/162] fix: correct broken links in stylus reference overview - Fix audit reports link to use correct relative path - Update verify contracts link to correct CLI tools path - Fix VM differences link from evm-differences to vm-differences --- docs/stylus/reference/overview.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/stylus/reference/overview.mdx b/docs/stylus/reference/overview.mdx index 21e7c35816..7ff6e136f1 100644 --- a/docs/stylus/reference/overview.mdx +++ b/docs/stylus/reference/overview.mdx @@ -14,7 +14,7 @@ This section provides an in-depth overview of the features provided by the [Styl The Stylus Rust SDK is built on top of [Alloy](https://www.paradigm.xyz/2023/06/alloy), a collection of crates empowering the Rust Ethereum ecosystem. Because the SDK uses the same [Rust primitives for Ethereum types](https://docs.rs/alloy-primitives/latest/alloy_primitives/), Stylus is compatible with existing Rust libraries. -The Stylus Rust SDK has been audited in August 2024 at [commit #62bd831](https://github.com/OffchainLabs/stylus-sdk-rs/tree/62bd8318c7f3ab5be954cbc264f85bf2ba3f4b06) by Open Zeppelin which can be viewed [on our audits page](audit-reports.mdx). +The Stylus Rust SDK has been audited in August 2024 at [commit #62bd831](https://github.com/OffchainLabs/stylus-sdk-rs/tree/62bd8318c7f3ab5be954cbc264f85bf2ba3f4b06) by Open Zeppelin which can be viewed [on our audits page](../../audit-reports.mdx). ## Documentation index @@ -59,9 +59,9 @@ Master the `cargo stylus` command-line tool for contract development and deploym | Article | Description | | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -| [Verify contracts](/stylus/guides/verifying-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | +| [Verify contracts](/stylus/cli-tools/verify-contracts) | Verify your deployed contracts on block explorers for transparency and trust. | | [Exporting ABI](/stylus/guides/exporting-abi) | Generate Solidity-compatible ABI files for integration with frontend apps and tooling. | -| [Debugging with replay](/stylus/guides/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | +| [Debugging with replay](/stylus/cli-tools/debugging-tx) | Debug failed transactions by replaying them locally with detailed execution traces. | | [Optimizing WASM binary size](/stylus/guides/optimizing-binaries) | Reduce contract size for lower deployment costs and improved activation efficiency. | | [Deploying non-Rust WASM contracts](/stylus/guides/deploying-non-rust-wasm-contracts) | Deploy contracts written in C, C++, or other languages that compile to WebAssembly. | @@ -72,7 +72,7 @@ Understand how WebAssembly works within Arbitrum Nitro and its implications for | Article | Description | | ---------------------------------------------------- | ------------------------------------------------------------------------------------------ | | [WebAssembly](/stylus/concepts/webassembly) | Learn how WASM compilation, deployment, and execution work in Arbitrum Nitro. | -| [EVM differences](/stylus/concepts/evm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | +| [VM differences](/stylus/concepts/vm-differences) | Understand behavioral differences between Stylus WASM execution and traditional EVM. | | [Activation](/stylus/concepts/activation) | Learn about the contract activation process required before a Stylus contract can execute. | | [Caching strategy](/stylus/guides/caching-contracts) | Optimize contract performance by understanding and leveraging the WASM caching system. | From 544495acf2946cb7cda2bef5f6083b864d49525c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 10:50:25 -0800 Subject: [PATCH 128/162] fix: correct broken links in stylus CLI tools overview - Remove file extensions from internal documentation links - Update verify-contracts link to correct CLI tools path - Fix cargo-stylus repository URL --- docs/stylus/cli-tools/overview.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/stylus/cli-tools/overview.mdx b/docs/stylus/cli-tools/overview.mdx index 31e107cd81..5ef14950b9 100644 --- a/docs/stylus/cli-tools/overview.mdx +++ b/docs/stylus/cli-tools/overview.mdx @@ -117,15 +117,15 @@ Available for commands involving transactions: #### How-tos -| Topic | Description | -| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/guides/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/guides/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | -| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | +| Topic | Description | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | #### Additional resources -#### [Troubleshooting](/stylus/troubleshooting-building-stylus.md): solve the most common issues. +#### [Troubleshooting](/stylus/troubleshooting-building-stylus): solve the most common issues. -#### [cargo-stylus repository](https://github.com/OffchainLabs/stylus): consult cargo stylus' source code. +#### [cargo-stylus repository](https://github.com/OffchainLabs/cargo-stylus): consult cargo stylus' source code. From fde2aefafc510807d2c2f41417e378442925d869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 11:04:16 -0800 Subject: [PATCH 129/162] fix: remove broken links to missing guides in choose-your-path --- docs/stylus/fundamentals/choose-your-path.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/stylus/fundamentals/choose-your-path.mdx b/docs/stylus/fundamentals/choose-your-path.mdx index 30d90d3fa8..2a883e8dd6 100644 --- a/docs/stylus/fundamentals/choose-your-path.mdx +++ b/docs/stylus/fundamentals/choose-your-path.mdx @@ -137,7 +137,7 @@ _Figure: Choose your learning path based on your background and experience._ | `require(condition, "error")` | `ensure!(condition, Error)` | [Error handling](/stylus/fundamentals/contracts#error-handling) | | `msg.sender` | `msg::sender()` | [Global functions](/stylus/fundamentals/global-variables-and-functions) | | `constructor` | `impl` with initialization | [Contracts](/stylus/fundamentals/contracts) | -| Events | Derive `Erase` trait | [Events guide](/stylus/guides/events-and-logs) | +| Events | Derive `Erase` trait | See Stylus SDK documentation | ### Key resources @@ -179,7 +179,7 @@ _Figure: Choose your learning path based on your background and experience._ 4. **Advanced development** (ongoing) - Apply platform-specific optimizations - - Implement [cross-contract calls](/stylus/guides/cross-contract-calls) + - Implement cross-contract calls - Build production applications ### Key resources @@ -222,7 +222,7 @@ _Figure: Choose your learning path based on your background and experience._ 4. **Build applications** (ongoing) - Start with simple DeFi primitives - - Implement [events and logs](/stylus/guides/events-and-logs) + - Implement events and logs - Optimize for [gas efficiency](/stylus/best-practices/gas-optimization) ### Rust skills that transfer well From 9278ea2abe54af1e0a27241bc7c43fe59f9b1557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 11:04:25 -0800 Subject: [PATCH 130/162] fix: correct file extensions and paths in using-cli links --- docs/stylus/using-cli.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index 333b53f92e..4f61d1ba3b 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -117,15 +117,15 @@ Available for commands involving transactions: #### How-tos -| Topic | Description | -| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries.mdx) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/guides/debugging-tx.mdx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/guides/verifying-contracts.mdx) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | -| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation.mdx) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | +| Topic | Description | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | #### Additional resources -#### [Troubleshooting](/stylus/troubleshooting-building-stylus.md): solve the most common issues. +#### [Troubleshooting](/stylus/troubleshooting-building-stylus): solve the most common issues. -#### [cargo-stylus repository](https://github.com/OffchainLabs/stylus): consult cargo stylus' source code. +#### [cargo-stylus repository](https://github.com/OffchainLabs/cargo-stylus): consult cargo stylus' source code. From ed251941a5b2675b4d4cc9d8fe6489bb8757c415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 11:04:34 -0800 Subject: [PATCH 131/162] fix: correct dev node link path in debugging-tx --- docs/stylus/cli-tools/debugging-tx.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/cli-tools/debugging-tx.mdx b/docs/stylus/cli-tools/debugging-tx.mdx index aac7157564..a5e7c22d72 100644 --- a/docs/stylus/cli-tools/debugging-tx.mdx +++ b/docs/stylus/cli-tools/debugging-tx.mdx @@ -27,7 +27,7 @@ Cargo Stylus simplifies the development and debugging of Rust smart contracts fo - **Crate**: `cargo-stylus` - **GNU Debugger (GDB)** (Linux) or **LLDB** (MacOS) - **[Cast](https://book.getfoundry.sh/cast/)** (an Ethereum CLI tool) -- **[Arbitrum RPC Provider](#rpc-endpoint-compatibility)** with tracing endpoints enabled or a [local Stylus dev node](/run-arbitrum-node/run-nitro-dev-node) +- **[Arbitrum RPC Provider](#rpc-endpoint-compatibility)** with tracing endpoints enabled or a [local Stylus dev node](/run-arbitrum-node/05-run-nitro-dev-node) `cargo stylus replay` allows users to debug the execution of a Stylus transaction using [GDB](https://sourceware.org/gdb/) or [LLDB](https://lldb.llvm.org/) against the Rust source code. From f33cff6410520e47d075519633f31916e585265b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 11:04:42 -0800 Subject: [PATCH 132/162] fix: remove file extensions from all links in gentle-introduction --- docs/stylus/gentle-introduction.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/stylus/gentle-introduction.mdx b/docs/stylus/gentle-introduction.mdx index 82f1b8f1ce..85b08c7299 100644 --- a/docs/stylus/gentle-introduction.mdx +++ b/docs/stylus/gentle-introduction.mdx @@ -15,13 +15,13 @@ import ImageZoom from '@site/src/components/ImageZoom'; ### In a nutshell: -- Stylus lets you write smart contracts in programming languages that compile to WASM, such as Rust, C, C++, and others, allowing you to use their ecosystem of libraries and tools. Language and tooling support exists for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart.mdx). +- Stylus lets you write smart contracts in programming languages that compile to WASM, such as Rust, C, C++, and others, allowing you to use their ecosystem of libraries and tools. Language and tooling support exists for Rust. You can try the SDK and CLI with the [quickstart](/stylus/quickstart). - Solidity contracts and Stylus contracts are interoperable. In Solidity, you can call a Rust program and vice versa, thanks to a second, coequal WASM virtual machine. - Stylus contracts offer reduced gas costs for memory and compute-intensive operations because WASM programs execute more efficiently than EVM bytecode for these workloads. ### What's Stylus? -Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32.mdx), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. This paradigm is called MultiVM because it is additive to existing functionality. +Stylus is an upgrade to Arbitrum Nitro [(ArbOS 32)](/run-arbitrum-node/arbos-releases/arbos32), the tech stack powering Arbitrum One, Arbitrum Nova, and Arbitrum chains. This upgrade adds a second, coequal virtual machine to the EVM, where EVM contracts continue to behave exactly as they would in Ethereum. This paradigm is called MultiVM because it is additive to existing functionality. @@ -37,7 +37,7 @@ Bringing a Stylus program to life involves four stages: coding, activation, exec You write your smart contract in any programming language that compiles to WASM. Rust has the most developed support with an open-source SDK for smart contract development. C and C++ are also supported, so that you can deploy existing contracts in those languages onchain with minimal modifications. -The [Stylus SDK for Rust](/stylus/reference/rust-sdk-guide.md) provides the development framework and language features for smart contract development. It also provides access to EVM-specific functionality used by smart contract developers. +The [Stylus SDK for Rust](/stylus/reference/rust-sdk-guide) provides the development framework and language features for smart contract development. It also provides access to EVM-specific functionality used by smart contract developers. #### Activation @@ -74,7 +74,7 @@ Stylus can integrate into existing Solidity projects by calling a Stylus contrac ### Getting started -1. Follow the [quickstart](/stylus/quickstart.mdx) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview.mdx) documentation. +1. Follow the [quickstart](/stylus/quickstart) to deploy your first Stylus contract, and explore the [Rust SDK](/stylus/reference/overview) documentation. 2. Join the Stylus Developer [Telegram](https://t.me/arbitrum_stylus) group and [Arbitrum Discord](https://discord.gg/arbitrum) for community support. 3. Browse the [Awesome Stylus](https://github.com/OffchainLabs/awesome-stylus) repository for community-contributed projects, examples, and tools. 4. Subscribe to the [Stylus Saturdays](https://stylus-saturdays.com/) newsletter for tutorials and technical content. From 5d8025109446c679406d47cda7fc789fad6d8740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 11:12:35 -0800 Subject: [PATCH 133/162] fix link --- docs/run-arbitrum-node/arbos-releases/arbos32.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/run-arbitrum-node/arbos-releases/arbos32.mdx b/docs/run-arbitrum-node/arbos-releases/arbos32.mdx index a160818aae..3197778414 100644 --- a/docs/run-arbitrum-node/arbos-releases/arbos32.mdx +++ b/docs/run-arbitrum-node/arbos-releases/arbos32.mdx @@ -42,8 +42,7 @@ ArbOS 32 Bianca brings many features, improvements, and bug fixes to Arbitrum ch It is strongly recommended that teams upgrading to ArbOS 32 also spend the time following the instructions described below to deploy and enable the Stylus Cache Manager. Even if your team does not intend to build with Stylus in the immediate term, enabling the Cache Manager ensures that future usage of Arbitrum Stylus on your chain is smooth and provides a consistent UX with the developer experience of building with Arbitrum Stylus on Arbitrum One. ::: -Specific to Stylus and ArbOS 32 "Bianca", we have developed a caching strategy that stores frequently accessed contracts in memory to reduce the costs and time associated with contract execution from repeated initializations. Check out the [Stylus caching strategy docs](../../stylus/how-tos/caching-contracts.mdx) to learn more. - +Specific to Stylus and ArbOS 32 "Bianca", we have developed a caching strategy that stores frequently accessed contracts in memory to reduce the costs and time associated with contract execution from repeated initializations. Check out the [Stylus caching strategy docs](../../stylus/guides/caching-contracts.mdx) to learn more. In order to take advantage of this caching strategy, an additional step is required to deploy and enable it's use on your Arbitrum chain. ### Additional requirement for Arbitrum chains who wish to enable Fast Withdrawals From c19a230b5d3777bb38c4857b4c268adfbcb7cef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:08:59 -0800 Subject: [PATCH 134/162] fix: convert Mermaid diagrams to static PNG images Replace dynamic Mermaid rendering with static PNG images to resolve ColorMode context error during SSG build. Generated images using mermaid-cli. --- docs/stylus/guides/importing-interfaces.mdx | 22 +------------------- docs/stylus/quickstart.mdx | 15 +------------ static/img/stylus-call-decision-tree.png | Bin 0 -> 67385 bytes static/img/stylus-quickstart-journey.png | Bin 0 -> 27849 bytes 4 files changed, 2 insertions(+), 35 deletions(-) create mode 100644 static/img/stylus-call-decision-tree.png create mode 100644 static/img/stylus-quickstart-journey.png diff --git a/docs/stylus/guides/importing-interfaces.mdx b/docs/stylus/guides/importing-interfaces.mdx index 3baaed8ea3..1d93e808b7 100644 --- a/docs/stylus/guides/importing-interfaces.mdx +++ b/docs/stylus/guides/importing-interfaces.mdx @@ -169,27 +169,7 @@ The Stylus SDK provides three `Call` constructors for different types of externa Use this decision tree to choose the correct Call constructor: -```mermaid -flowchart TD - Start[Need to call
    external contract?] --> Modify{Does it
    modify state?} - Modify -->|No| View[Call::new
    view calls only] - Modify -->|Yes| ETH{Requires ETH
    payment?} - ETH -->|No| Mutating[Call::new_mutating self
    state changes, no value] - ETH -->|Yes| Payable[Call::new_payable self, value
    state changes + ETH] - - View --> Gas{Need custom
    gas limit?} - Mutating --> Gas - Payable --> Gas - - Gas -->|Yes| AddGas[Add .gas limit] - Gas -->|No| Done[Ready to call] - AddGas --> Done - - style View fill:#E3F2FD - style Mutating fill:#FFF3E0 - style Payable fill:#FFEBEE - style Done fill:#90EE90 -``` +![Call Decision Tree](/img/stylus-call-decision-tree.png) _Figure 2: Decision tree for selecting the appropriate Call constructor based on state modification and payment requirements._ diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index ad86f7f71c..5d0d923928 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -29,20 +29,7 @@ This guide will get you started with Stylus' This quickstart follows a simple path from project creation to successful contract interaction: -```mermaid -journey - title Quickstart Journey - section Setup - Create project: 5: Developer - Check validity: 3: Developer - section Deploy - Deploy contract: 4: Developer - Export ABI: 3: Developer - section Interact - Call contract: 5: Developer - Send transaction: 4: Developer - Verify results: 5: Developer -``` +![Quickstart Journey](/img/stylus-quickstart-journey.png) _Figure: Your path through this quickstart guide, from project creation to successful contract interaction._ diff --git a/static/img/stylus-call-decision-tree.png b/static/img/stylus-call-decision-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..e2c35e47ab3cbb9fd7890c934dadff86cfe8a552 GIT binary patch literal 67385 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 z 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 literal 0 HcmV?d00001 diff --git a/static/img/stylus-quickstart-journey.png b/static/img/stylus-quickstart-journey.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f34a691c8d2110c4ef88de35392521509346a9 GIT binary patch literal 27849 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

    w( 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 Date: Mon, 15 Dec 2025 12:12:00 -0800 Subject: [PATCH 135/162] fix: convert more Mermaid diagrams to PNG Convert Mermaid diagrams in contracts.mdx and storage.mdx to static PNG images to resolve SSG build errors. --- docs/stylus/fundamentals/contracts.mdx | 26 +---------- .../fundamentals/data-types/storage.mdx | 43 +----------------- static/img/stylus-contract-lifecycle.png | Bin 0 -> 54807 bytes static/img/stylus-storage-slots.png | Bin 0 -> 21043 bytes static/img/stylus-storage-types-hierarchy.png | Bin 0 -> 12349 bytes 5 files changed, 3 insertions(+), 66 deletions(-) create mode 100644 static/img/stylus-contract-lifecycle.png create mode 100644 static/img/stylus-storage-slots.png create mode 100644 static/img/stylus-storage-types-hierarchy.png diff --git a/docs/stylus/fundamentals/contracts.mdx b/docs/stylus/fundamentals/contracts.mdx index be84facf16..a75621da05 100644 --- a/docs/stylus/fundamentals/contracts.mdx +++ b/docs/stylus/fundamentals/contracts.mdx @@ -18,31 +18,7 @@ A Stylus contract consists of three main components: 2. **Entrypoint**: Marks the main contract struct that handles incoming calls 3. **Public Methods**: Functions exposed to external callers via the `#[public]` macro -```mermaid -graph TD - A[Write Rust Code] --> B[Compile to WASM] - B --> C[Deploy Bytecode] - C --> D[Activate Program] - D --> E[Contract Ready] - - E --> F{Incoming Call} - F -->|External call| G[user_entrypoint] - G --> H[Route to Method] - H --> I{Method Type} - - I -->|View| J[Read Storage] - I -->|Mutable| K[Modify Storage] - - J --> L[Return Result] - K --> L - - L --> M[ABI Encode Response] - M --> N[Return to Caller] - - style A fill:#FFE4B5 - style E fill:#90EE90 - style N fill:#87CEEB -``` +![Contract Lifecycle](/img/stylus-contract-lifecycle.png) _Figure: Contract lifecycle from development through execution, showing how calls are routed and processed._ diff --git a/docs/stylus/fundamentals/data-types/storage.mdx b/docs/stylus/fundamentals/data-types/storage.mdx index 4788a0ef93..d2ab17f1f6 100644 --- a/docs/stylus/fundamentals/data-types/storage.mdx +++ b/docs/stylus/fundamentals/data-types/storage.mdx @@ -21,31 +21,7 @@ Stylus contracts share the same persistent storage as Solidity contracts: The Stylus SDK provides a comprehensive hierarchy of storage types: -```mermaid -graph TB - Root[Storage Types] --> Primitives - Root --> Collections - Root --> Custom[Custom Structs] - - Primitives --> Bool[StorageBool] - Primitives --> Uint[StorageU256, U128, U64, etc.] - Primitives --> Int[StorageI256, I128, I64, etc.] - Primitives --> Addr[StorageAddress] - Primitives --> Bytes[StorageB256, B32, etc.] - - Collections --> Vec[StorageVec T] - Collections --> Array[StorageArray T, N] - Collections --> Map[StorageMap K, V] - Collections --> Str[StorageString] - Collections --> BytesCol[StorageBytes] - - Custom --> Struct[#[storage] annotated structs] - - style Root fill:#E1BEE7 - style Primitives fill:#BBDEFB - style Collections fill:#C8E6C9 - style Custom fill:#FFE0B2 -``` +![Storage Types Hierarchy](/img/stylus-storage-types-hierarchy.png) _Figure 3: Storage type hierarchy showing primitives, collections, and custom struct options._ @@ -975,22 +951,7 @@ Stylus uses the same storage layout as Solidity: - Variables are **packed** when possible to save space - Arrays and mappings use **computed slots** via hashing -```mermaid -flowchart TB - subgraph "Storage Slots (32 bytes each)" - Slot0["Slot 0
    uint256 value"] - Slot1["Slot 1
    address (20 bytes) + uint96 (12 bytes)"] - Slot2["Slot 2
    Mapping base slot"] - Slot3["Slot 3
    keccak256(key || slot)"] - end - - Mapping["Mapping[key]"] -->|"hash(key + 2)"| Slot3 - - style Slot0 fill:#E3F2FD - style Slot1 fill:#FFF3E0 - style Slot2 fill:#F3E5F5 - style Slot3 fill:#E8F5E9 -``` +![Storage Slots Layout](/img/stylus-storage-slots.png) _Figure: Storage slot layout showing how variables are packed into 32-byte slots and how mapping values are computed using keccak256 hashing._ diff --git a/static/img/stylus-contract-lifecycle.png b/static/img/stylus-contract-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..220986189a37da524e56c4188b60074eed8b7de9 GIT binary patch literal 54807 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%0A*1jiCEGXE8C?-C348w>EaoOzXK1;=x-8 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

    &EM-HIx0x}pU`$Qo)L);0Xo4ZET_Iz@T7 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 U3u;U|U`ODtuF35RZRf}T2IO_O_W%F@ literal 0 HcmV?d00001 diff --git a/static/img/stylus-storage-types-hierarchy.png b/static/img/stylus-storage-types-hierarchy.png new file mode 100644 index 0000000000000000000000000000000000000000..8487ba746314ea9a8e6ba32ba2e75740f0bc9708 GIT binary patch literal 12349 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 literal 0 HcmV?d00001 From 50050cfa170e5def041c39718da25b52edd07530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:14:49 -0800 Subject: [PATCH 136/162] fix: convert all remaining Mermaid diagrams to PNG Convert all Mermaid diagrams across stylus docs to static PNG images: - gas-optimization.mdx: gas comparison diagram - activation.mdx: activation process diagram - choose-your-path.mdx: learning paths diagram - webassembly.mdx: 3 diagrams (pipeline, structure, memory) This resolves all ColorMode context errors during SSG build. --- .../best-practices/gas-optimization.mdx | 12 +--- docs/stylus/concepts/activation.mdx | 13 +--- docs/stylus/concepts/webassembly.mdx | 68 +----------------- docs/stylus/fundamentals/choose-your-path.mdx | 32 +-------- static/img/stylus-activation-process.png | Bin 0 -> 9400 bytes static/img/stylus-gas-comparison.png | Bin 0 -> 20816 bytes static/img/stylus-learning-paths.png | Bin 0 -> 57025 bytes static/img/stylus-wasm-compile.png | Bin 0 -> 39397 bytes static/img/stylus-wasm-deploy.png | Bin 0 -> 25703 bytes static/img/stylus-wasm-execute.png | Bin 0 -> 32559 bytes 10 files changed, 6 insertions(+), 119 deletions(-) create mode 100644 static/img/stylus-activation-process.png create mode 100644 static/img/stylus-gas-comparison.png create mode 100644 static/img/stylus-learning-paths.png create mode 100644 static/img/stylus-wasm-compile.png create mode 100644 static/img/stylus-wasm-deploy.png create mode 100644 static/img/stylus-wasm-execute.png diff --git a/docs/stylus/best-practices/gas-optimization.mdx b/docs/stylus/best-practices/gas-optimization.mdx index 80a4a9eb84..4be460315f 100644 --- a/docs/stylus/best-practices/gas-optimization.mdx +++ b/docs/stylus/best-practices/gas-optimization.mdx @@ -15,17 +15,7 @@ Stylus contracts offer significant gas savings compared to Solidity (10-100x for ## Why Stylus is cheaper -```mermaid -graph LR - A[Solidity Contract] -->|Compiled to| B[EVM Bytecode] - C[Rust Contract] -->|Compiled to| D[WASM] - - B -->|Interpreted| E[Gas: Higher] - D -->|Native Execution| F[Gas: Lower] - - style E fill:#ffcccc - style F fill:#ccffcc -``` +![Gas Comparison](/img/stylus-gas-comparison.png) _Figure: Stylus WASM executes natively, avoiding EVM interpretation overhead._ diff --git a/docs/stylus/concepts/activation.mdx b/docs/stylus/concepts/activation.mdx index 4f3efd68fd..812565fdf0 100644 --- a/docs/stylus/concepts/activation.mdx +++ b/docs/stylus/concepts/activation.mdx @@ -75,18 +75,7 @@ This performs: **WASM Processing Pipeline**: -```mermaid -flowchart LR - A[Raw WASM Binary] --> B[Remove dangling
    references] - B --> C[Add project_hash
    metadata] - C --> D[Strip user
    custom sections] - D --> E[Brotli compress
    level 11] - E --> F[Add EOF prefix
    EFF00000] - F --> G[Final compressed code
    โ‰ค 24KB] - - style A fill:#FFE4B5 - style G fill:#90EE90 -``` +![Activation Process](/img/stylus-activation-process.png) _Figure 1: WASM binary processing pipeline showing transformation from raw binary to deployment-ready compressed code._ diff --git a/docs/stylus/concepts/webassembly.mdx b/docs/stylus/concepts/webassembly.mdx index 2b0755ac58..c1ead592ad 100644 --- a/docs/stylus/concepts/webassembly.mdx +++ b/docs/stylus/concepts/webassembly.mdx @@ -29,30 +29,7 @@ Nitro uses WebAssembly as its execution environment for several reasons: 4. **Language flexibility**: Developers can use Rust, C, C++, or any language that compiles to WASM 5. **Determinism**: Guaranteed identical execution across all validators -```mermaid -graph TB - subgraph "Developer Side" - A[Rust/C/C++ Code] --> B[Compiler] - B --> C[WASM Binary] - end - - subgraph "Arbitrum Nitro" - C --> D[Brotli Decompression] - D --> E[WASM Validation] - E --> F[JIT Compilation] - F --> G[Native Machine Code] - - subgraph "Execution Environment" - G --> H[Contract Execution] - H <--> I[Hostio Functions] - I <--> J[EVM State] - end - end - - style A fill:#FFE4B5 - style G fill:#90EE90 - style J fill:#87CEEB -``` +![WASM Execution Pipeline](/img/stylus-wasm-compile.png) _Figure: WebAssembly execution pipeline in Arbitrum Nitro, from source code to native execution with access to blockchain state._ @@ -85,26 +62,7 @@ rustflags = [ A Stylus WASM module consists of several sections: -```mermaid -graph TB - WASM["WASM Module"] - - WASM --> Exports["Exports Section
    user_entrypoint"] - WASM --> Imports["Imports Section
    vm_hooks"] - WASM --> Memory["Memory Section
    Linear memory"] - WASM --> Custom["Custom Sections
    Metadata"] - WASM --> Code["Code Section
    Compiled bytecode"] - - Imports --> storage_load["storage_load_bytes32"] - Imports --> msg_sender["msg_sender"] - Imports --> emit_log["emit_log"] - - style WASM fill:#E1BEE7 - style Exports fill:#C8E6C9 - style Imports fill:#BBDEFB - style Memory fill:#FFE0B2 - style Code fill:#F3E5F5 -``` +![WASM Module Structure](/img/stylus-wasm-deploy.png) _Figure: WASM module structure showing the main sections including exports, imports (hostio functions), memory, and code._ @@ -323,27 +281,7 @@ To stay within limits: ## Memory model -```mermaid -graph TB - subgraph "WASM Linear Memory" - Stack["Stack
    32 KB
    (fixed)"] - Heap["Heap/Data
    (grows upward)"] - Page1["Page 1
    64 KB"] - Page2["Page 2
    64 KB"] - PageN["Page N
    64 KB"] - end - - Stack -.fixed allocation.-> Page1 - Heap -->|grows into| Page1 - Heap -->|expands to| Page2 - Heap -.may grow to.-> PageN - - style Stack fill:#FFEBEE - style Heap fill:#E8F5E9 - style Page1 fill:#E3F2FD - style Page2 fill:#F3E5F5 - style PageN fill:#FFF3E0 -``` +![WASM Memory Model](/img/stylus-wasm-execute.png) _Figure: WASM linear memory model showing the fixed 32KB stack and growable heap organized in 64KB pages._ diff --git a/docs/stylus/fundamentals/choose-your-path.mdx b/docs/stylus/fundamentals/choose-your-path.mdx index 2a883e8dd6..fac1a9388e 100644 --- a/docs/stylus/fundamentals/choose-your-path.mdx +++ b/docs/stylus/fundamentals/choose-your-path.mdx @@ -17,37 +17,7 @@ Not sure where to start with Stylus? This guide helps you find the optimal learn ## Quick path selector -```mermaid -graph TD - A[Start Here] --> B{Do you have Rust experience?} - B -->|Yes| C{Have you written smart contracts?} - B -->|No| D[Path 1: Learn Rust First] - C -->|Yes, in Solidity| E[Path 2: Solidity to Stylus] - C -->|Yes, in other languages| F[Path 3: Smart Contract Developer] - C -->|No| G[Path 4: Rust Developer New to Web3] - - D --> D1[1. Rust Book Chapters 1-10] - D1 --> D2[2. Stylus Quickstart] - D2 --> D3[3. Fundamentals] - - E --> E1[1. Rust to Solidity Differences] - E1 --> E2[2. Quickstart] - E2 --> E3[3. Migration Patterns] - - F --> F1[1. Quickstart] - F1 --> F2[2. EVM Differences] - F2 --> F3[3. Advanced Topics] - - G --> G1[1. Web3 Concepts] - G1 --> G2[2. Quickstart] - G2 --> G3[3. Smart Contract Patterns] - - style A fill:#e1f5ff - style D fill:#fff4e1 - style E fill:#e8f5e9 - style F fill:#f3e5f5 - style G fill:#ffe0e0 -``` +![Learning Paths](/img/stylus-learning-paths.png) _Figure: Choose your learning path based on your background and experience._ diff --git a/static/img/stylus-activation-process.png b/static/img/stylus-activation-process.png new file mode 100644 index 0000000000000000000000000000000000000000..204af82a766da54c71b0bef0ff65a063e78c6da7 GIT binary patch literal 9400 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 o-6sD3?e;ZHo)$pjtBgpQknYd_0h7UQMgRZ+ literal 0 HcmV?d00001 diff --git a/static/img/stylus-gas-comparison.png b/static/img/stylus-gas-comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..40a958ffc2792b8d111efea472853978ed853f93 GIT binary patch literal 20816 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 HF?7OTSCT9f literal 0 HcmV?d00001 diff --git a/static/img/stylus-learning-paths.png b/static/img/stylus-learning-paths.png new file mode 100644 index 0000000000000000000000000000000000000000..c4038890762dac9570811fa79cf0032804de3bae GIT binary patch literal 57025 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

    V%h9cb2SxhZEy=gjbZ(} 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 literal 0 HcmV?d00001 diff --git a/static/img/stylus-wasm-deploy.png b/static/img/stylus-wasm-deploy.png new file mode 100644 index 0000000000000000000000000000000000000000..26a4644ec990782c07c84134c181966a383973c6 GIT binary patch literal 25703 zcmcG#Wl)_>&^CCZ2?PltK?4K{5IndA2=4Cg?(UFa!68`i5FCQLyIZi}?(S|odEWYJ zx4zolA6vCk)HxKKGxyAN_tjU+1j|Z`pd#ZTLlA^2CMqZoL2xg@@1xIQ!RvTW2RV3y zagZ0`hl+>a?m*BxNKEjvqHD_jf{Utx3O;m7S;%ja84%!pt}`juT)Rx!3dFEirr zUuCN*<)Z3I^{R;3j3Q@K3xY}YD?Xvmn(q`0BTL)+-ys>soIKdgd1A;a`unCVb#%nc z&!?PilGnK%acrf9j+rt;U*A0kKkl4xUeBP$Y|~Fn#Fd6)~|64a*p`kJs(5=!SMNy?24$!+}MiB z<9noQ^E%`-1(eSM*xd8}|IPA$nGV7v|M&c_KM7m^-=6ya>0>`tG6iNvcZxNM_ZoI* zJNccd8|H$N+@wgvJeHJDKmU0N|L@`M-TG4{(-(C14duY*`Z^6c-xI^)3sVN6lOjZ4IP zqMgeOzo+{jD)D#n^sm3Z%k%hmjCm%CjB#DXHtWm~R35@K?l2y;;c_C61F}li7%YKAqZ(N=(*Xb zgCK7W3%$v;*-iCNP0HXHt^Xb4&$Jagc$W_tm8Bga&&@A(;4Pl`lzx#)H zc}Jb!A4Taj`M7lzyVMZOew}#n`Q^F2Zae(vKMqJ2NFyJ-d-bP6jef~JW;%!y@=%Q! zOrvN1`0+;h%}>-nFUaZZqur!3M{8%8xKo>Wr>pjbjmw2IVIV~|hMjols~3k;t4WFgHhKG~J3(WS_YJx?Q?;*D?$zaX5zDStx zpGS=RJ#?+rh8OP7pSR?RKIMh=TvbSv^Lw?!KvPWLGhw@38?M25Crrhyl-4@EU>y$i z*t-gCIpDgXg?wjZS-8mae^)a%TxV1TSSj)`S7eCS94F-@y-a5aZ1PY(=@|SKmNk82 z#PXgbe_KyZ*mIpZDd58Y&-8g?B{=8V%_Q(&XJzL_x(<&p+#SwF`y+j4J8}#engaLv z1P!18Q@HN1IFWF1QZ#~ThkOo{ z`5%-EVmaQ=^u7}KrRPMdkU1J=i%wHWo2~Ze_n?_7&EIc^zgxneeg3l?_#X(O;*oO0 za=@Y?hQmPqH^MKG$ijtV?w7?q*DGHhF&G|Z`&g&e$9bLYJ`B(n4GmWp7jFJGGqbX* zwByf^1tM9b}{hx&>_MRZg zX*a{QG_~P~t9T9dwsMGUzM^?JUTB+nLf)i#ws>&I zV@n}gq7bHldHaNj5X(^K{oJ3pS}VeY1$-v70mZ8uLS!Q%-gncYSi%X z>3es^L`!pXaq<{B%GhR7fUZyfa8LW0c((kzm&Z4r8M3`wX9%1qC@7S#LojU5GH&;{ z2HT|a6|u0e%-CqYvl2VnB>(ua%_aZ*tM(`MK%}pTG1b+q2k6z-`ef0fQ92gL0s7zp z8M0AxhK#t8JuL+vB?Z)`K1#xV;iG)LyP4Cg6)igPAz*Bgg^_V=?uGBWJeTD~%&&-V z>okj{0y$Z*qeaQA#04{CQ&Li*e)mq}IM-aTkzv}~+HO~B7Af!L$Xc>CG&a6E$o7fza6QDY=ZIy*RwKlbZ09CLB~!NtM( zk@#;odF5qh3d~VCn+gZ>6Mp#IB?IrT9{#Uyjp6bOsCfW8-^w(xkul855*uWD=Th7nK{bI#l>Q) zfbz;ppk1?H6l`np;hWw9<|1n{`*Et?WQX)AJUl#_i15XW7X}6f2cnrU_Lni5bRuJ< z@ZrJ^j*gDDwzl^6tBMB8YW7XU%Y{NXa0V38PEIT_eU{eN&i3~9;4{w7;1@hogMkV2 zD%QFLQL=ieH2XTuyShm(7{#R`+yc|}vhIiHz=qCm$0O**_zzc4To>v>9iL)E$-G1s{OarLZ*Ol43JQ{v z@K6vlhob5UVElZM6zD(QsoP&%T+FTmyJLR{63@Q$$f8HbbzR(9mx>ncT(Omul*Ie`w8pou&xX0$TZ)V{7UBjd}+)_@_SVLu5lQDftrg(>vG&0o1dDeAqfs;jGu zi;Kalw6ydHM+vj!5BHrL`sRTR`{=>oku5eB7PFXK7{>jb4O6abM~4pw+n+d7Bf9jf zmT1@!5YN@YUYL6w&FRKi@rds%4(R6E+uJ)k{rNLc7D<-@9bR{-DJzQ}GTyta${5|= zqFhE|(A&-4lKJ5nEJ$KCpkQE-Sy92{*Y) z{+*wfyom&s?_9!JdpnvIB%JwqxSrozBwvwgED-4W#0VzKj+~K^k+^t&xzWHmfoMxX zVW9zIVsC?uzW(aU%IDni)YMd+JBur4U`gmfj!Xq$W^l}Hx|KR^2UA4DPH3p`VE?y% z^7(?!(ZFEdqKPy#ybczuSBtiG&pL{_due~l8`EdVn8?DyGW=xc=m>P;HbNR585#NX z^c0Im_2&`ac}{+QeseRSnOnPl866$n@bEBreT^)%lyN~#7Qi3zGfE5oyYz}J`@!%R z@oYSNd{UPc?&q>T{}h%gf71M580}_c?If!6d0l;cTwGj6Mh5FAJkB!=39?sN92w>1 z-v>5GysW^a5fKr$Xi`t*6&3h+csbIk1xI{{@Bmtrl)4NV3kwQlDPt=tDhdk=LqjEM zuygTAq82|HmXO4WCnqOI&-HRY*Fvw?9-xyJJ^H82Wb1~^gpompLPbSIknirUdBu~d zi=MHuu>i%#vG-V^iIT=fM(<<#UO$Hi&qhJ)XlrW&C%BY>N@Hebc5rZTa&mHuX4txN zb|ZSKsHT=bYN`o_*1w^1L_WPm5hu=t>MZz}oS66_PTcUxz}mWa0i&&unZF4JlRWPk zVQEOoL=BB233%EewiD0qG$>>9!qS#~K!L(q^EG|ZzSJlqmL2xXsN?N6u7HGIIw~CZ>w1wXAIw{(MDcFccNR8?ax18z6X8 zQBlDQ&pG;o807PK(=$8E$<3_^o{h&%h~Afyl$4}M^~SHw*1^Gm0ms(%yh1En-s+SL zD>OMN$(5UsF}z3(dvlYXH30s6)(>f1mMmc)+Vfk-3P3!FxOjMI2$f?#cYNnI!s3|2dH+XlZf;9UOEVm9Y*KPE@M!}B1JqPh zmX?-LgMBkIYD;#g%HpvaSxli=j~`ozG*)-Cs^19@_p^9u_X z1ie31fRw?pYinz3XzcCnS(un?t*q$j>17<%B2s7RL;{`t@EUe!YW$GDD*W&k4Qtnd zLC@W*vZjXgL-ZwY!hleQEbzba@$sT6O#uM`b#--RCj&CgZ18;>r{zz}wzYa4fvEVb zVQspN#!UP>qZtB0-QoBqHZ~a=o+PU+nFhe4}`&%JAf6Y04pjeph7|PtHhDZSG2N**ND_n_ww?x zv$Jz^b8~P2xXE{#mBC6c{WM)=F_mo7jMUS0g#qmBHXW>~uA!mBI9CNNQBJ6an8+;Q z7w~4U`uLy4i3g}nyhFgu`68XKNKz*!A@SlnG2jYS>QWDpV0YQs*>!asDIEuKlt468 zR8${6eEj(F(54WHMdwYv#{_u-OIG{JFqBH&ika8Q2!3si70ZcP>#3Kp=iN^U)N<=Sy>qZc71@G6`-Z1 z1w0I}CNRJ+$N}v@B8!WQz8rO^0YlqeaO^Zs&gWht@J{40eL#2stH3MRua*`;uwXgx z&}C&A<2zv6$M#AkF9CrG7}x-7BTn=-GRi*i*>DD!|Xb zOqmGtZOHiPW-Gl=rR1;6yFUt(6BFwIYBx57goTBLgxaV}Pz|{WO8|rE(kD*Ee~la< zNHQ}wH#ai_UON=1-Qmb3>3;*(1_to0zki2`l5w)LPtVN(TG(!(k3tDP2?S{C>6ayV^>$#%uJ$mEj!m>xP`EJl6B<>|9H&Dmpqo zn}dmQ)GE7NFSp%*HEe8cdAPZS6Y**KO#Sz6% z2rz!|!Le+K3xen8`o&re%JTAzcB_KyU&h}7_Y7DMU;`l`|BMBAAr}`D2ApGeL>V~D zoM8|$eE$4dP7W~c^Q$WtK;<1A{4%2vo4H&LUt?iK5b+YGz4%lMd|ggf7L7)=dg@jvP%!A-Cdg6_g01xR z0W8yFz)4F>JC>aNygtJF#QgDNBBxUU(06TBGqaskE*ISwlz;!G0e=14x96_J{=}&aRh5;R z^^QmZ{0ImLH`mwOTyM9HQn*}(fkP)F6Z|)6e%`-f3Zx4r-Hii!qvP{%(Sgo80ra>~ z1sr5T0uVp1+vz%x=?>T1Cfs_Y@gj{HVDGP9y;_b+Xrq4r9wA&}}c&4u-V^NYgM$i(FA=01}55yx1< zFF})zo{H-0%$RQOs3{9FQbN{b@0JXt*xzZBVc!F0f5pMT+iw<-~a{x_ZNZQ=kb^n(%W1wKY?#4$jM>6 zJw3%+wq>_1&z|y?&yVdh1Rrx}p`oDxG3f;X!bA;_yFWj1`pA^ay9X=NaJ`VoNQ!7t z;8^)HKopq5>!ZDd@tNMB@B4d@0U>(@6oQ-ZXnDERWQ5S`8A4NOI6hl^Y%HK90sMOA z<{=#`5rm%#j(+}3sPwwK1k#EVe;+3f__imTj*7$9@WJ->%jfWcfq|yXx9L8Qqb`CE zCZ<&k!1{s7A_cUAc#esQ$twu1DQkIo88~&cpmAVy6BEo{w~heYn!>kxZKf9s9l2|G`ugQpG7)twu zpI9;1+WL-%M|)|7kKU|13>RQduN5zEOEjs-KfN@%zPUko_KdU!(CDqf#LS~_KNGeN z4+*ib0_OpP3_KHTEZ!VW4GjyBEu4&wj=n|9)j=)t{{Ye{MyTH!>fsqYZFjxgJFMxc&nBCo)o14FU`2wgH;7|Xo zn-(2Cvb2=p#fwn23gaCvtUPqE>$%QOGAb(byzH(fg7YCOMNN)*T}zH1IdW#^mcK?# zDg8cURtQ4E-Ess?D0h`u+A*tR8RQ03)iM@t0kxWRU-+0Acjtyqkuy+b6%x*G5RjRQ zZIcRT?XH`Px8gv?h$PxHO6z+sgkO_2QX=8LrWz`k#h>|XC=D5U7uP>K>kl~iE!uk5 zG2TXn@*F10T{S|+adRnIMY!oXXQe_Va}CG~>Dl>hUajJSPHkYpo`N8*P zjwyc~q5t2iI{zw2|F@MXh6zmaaADFn5-fP(0A1ZBh!Z|=ah?+(oFn(H18*YkC312r zOBJVImX}WbCRB(jt{|N{p#J@<(AfU87TI>z&rA(lY3bWb1#hZy+mKAGoSM=Ny|7 zQCsx0QE9p94=pOB{Qk+oh5k(q(L&Q>1)GRX3ReLG>4jUr;)gh;0FK#)J2o0Rch@^5 z_&d(p1P#0EL4tMX&CCLwr^6Q7ak}{81t%)~!|Ku*orQi%@3dUXxPtw5^Mi$eJ#VQ2 znu7tHXPEhl^&VH)G2{W#={)W;fBzp+qg`>l9Tb% zw?2RqsH}Wh2cR!UDsHiYWbQ1@?&VsC#znRv8X*E}6Nw`7#n5C@3@l-3U? zge(S&c1q~h+lqeI-8z&h|os6^+%$`-);A*m_OZ;pW=t`^Wsaq0q2UWPI$v zHhts@sa-o1QR4X%6j)(Zia~TjE|!D+==uwF{`%lZ@-AXdq_5~IjOrUc}z|4j$6UTB1|?t zSXNe%i}kehfvcGKJLA>ekgk1iP*NM-;?XrYI=*>QHxzle_~Yi$efPFSXZ+T(tEF`Shrx2~AVl7DsE|Ffs%`F+1dQlZ*>5@NAm_|1h!fPDa1{!iJw z)7{Or1g6uFJ$+IyV`-Fv-v&#bvapb=qB0v7-MStOQ(>t)zyCz=5V4?`Kfz?+x0dN;f#>Ss(_(ERRp(t|DqfkMUDtPSMhXMnMJ!e_v!&tUhbhv= zeR%Fl6Ya}HhVh8H*(W~KD;%)#nYBgr9Q~435@)6pL%Ttv z_QubQ2gN-XLhe_cI>fS9pQGNJW}-l(O(D#fvYIDy<+e6AKTXi_Hn9Mj%D@JShHp9S zeZ{l8x~0cWnM1KhrmOaJg@pP*xSl7Uzd5YMPxgw5=_oetO&ZU`7JbXTmX6L@2RfIz zMd9jdj!asLskQXOYUm`Xu)k*Gbxq{Ra|(*73KJO|{A3!f`u@2&8I2M}s*j9}-MS1Y zffVIrq@)jniEFQdDann+HRl~s5FH+FyO>NOPHwn)TYd_K@>~P^l+Vwqth8P0F7dh9 zn2V3kN%!W|)77;-T|dI6f3&hWdQJ2s?0UT&L*auRDuhn7hyc-O)^amDDhdnNvtDm+ zBi+tT!;R*j<>JtVeJE3afl#m!%S+>x?ha%;3ik@uC^}`rQ;qek<&?DQu38tdoGZ%8 z$}0R`KtI2$x!tzse_j1*C%1-4{$AFRkv3RS-&{Wgq^}VcJzS5@Z(6!u$?ezHULz@h zBtH>_k4!`I?C5ATgIT>_)7r!DyRMD*6eEvSCIf6l-u3oBk{h-dWTI6oj}nfU>=^~% z_;Y$F7&URyy{p=WW)4m-B#Nbrk7zVEO^>p2hc0R0eo3G~vOlzH4JIQ93Y{mE{(c|o zBL=0sX5J*{k5$bD*6aS!_KCmaIwUl|vwMw(N%YXgy@}0_Ef8q%#^-X{UzLfU7i&Ia zuiztAP~@ho`K3|xWG&!2D2nbASvyl!=u!*=rF`-@T{QQmHi7wqM;|-wxBs)`>U&OVxZ2cTIp=p z{%c1#N7x`Ye4|VQ2HJXJH?cBlGM-9OW~IMbSAw91Xj*H`qM4hI(SnUG2gTZKMTFn{ zi#8$|jcMliTu#`lY$Wc#qOUD_J`H|3K(3P{vqYerxUb^!YVUq*HmFjZUsTnKcfO3| zD6EcD)nHsSz-rv=9Ua<;O&@g|j zm{8tgGlwn7)_b}Yn$@m0Sh9?g=(4eS?3?euOi!=QpWHR@_{-&i@cZ#{ecKqVEG_RN1GUE&vTj((YFN4(^$RR*Y>hinaO0mf6sV-I{8g zo)FC;a6ed0JSxa`+yBzYGKyE8xSz{k=*2p|{`Ec??apKRXf9T9y!Dg!2LTc#%_fB? zhQ+6ctTGLsdYs*@)3f*hZ0n6T%FKWkpn5!sg`m%s-G=)Vn=B1e#q_=55Mqg_#_Dlt zVIrSc8+maRCmzS2!5w%1XQ|_}hLh#Gtum9(BSi~Ilcg55QsJb9%M-!&!S%@1z)}*S zo{{zGVT$Q1jH{lAE=*F-O-W?A{E1ijjTX?W{MGJUuKECiBlw%&{&z~373Fxlu2-x_|1OSmd6i>@*m*{pL&xIZ7)DJw%#ESMZjd_h9mdohdEN;NAV%Cron5hl83U7^uGO z>JE```v;3s#uvR*tjGJF&mtZ@4_rQ$E6hY3H_xEu!X}M{g?Sg78G)KIIH>Z}jrwoP z(b`7CS?Ge(@A?+{`ywwo7#Y>rO4qJibhJl1J{k--sQj#=dG>5W!(mDN>~WR}`>D?@ zHpZF$LVL66g2?-J;gSgU!H-|qAO7YU?T;qirK!8Vob|+UW8#ji;stSI78cK%2M-mK z8v5o(6sXnQ5NXc;&gIe2)YNh3HrsnieZ=S|nWS__%4RdK%i*0vv~=aD!mm-B!5tlG zdhG^ynN~Qcchj(dWwK+5)YVZ|PFe3}&HfkhM@P*c;eJxGin89_prs@28xa9-lDU+S z!5>o^#Gsz&Fi{8^!O%8Kuy(+ku9lW@Z0H=0xU=mM5#k7FnA-m?o~34{2Kmk8 zbYq^pcYBY^#`KFk()q-(?5Emv!}QuQI|M}wwqhRRpmg_6;6U#%#E=Dceq4jt|-rLaCb!n1P?w1G)N5%&rHlS zGPsw&U&#NptT);**U{06I!uy5^)2+XfHH`W5jiYPvclyg^xJ1)7PYa| z{e{MT+(oRvm*JBe?hAPjpQ#i|-K?m$B4wKIuC=whVn03tzbj-Vp)FP~m< zsYTQ9{SgORmdvf^n)AN}y&diMnkm~85WR@;CyIvB?r(zMA}<}vYEp1kVv^KAbckVB zvBtm6%*2cC@e1bY_#@yGv;Fg(LnluUo7Kv(1`Uf5&uuj>Z=yr~IVONYH{lek55fHHG+UVA#j=7g6fb{j6;a7F##>oS3ej8H)G| zU;PPx`TDi@N_$^mAg7558z>pH>7KZLjgBr8op@YsJJ=bIv9#QdAs?!B+M|-!mHi|7 z;)Mh~eT!a4qZxDZw{IWczmMd4<9dC}QKjDG=_W5EwA18~Z^-zbh2>^qx_o?;W2NhR_@-7? z__!RPz^qP!v4^;nFlR3-?@0OF_3PnxXSutk!3G=2R5J@Jd|o^A{sVlaNu@!&&F^j! z1p99vyzXHj1R;c1`B}ezoln%okl5XYPwdsdA55=WzB}MG+%#;wI%&`kz8?1DGE}hd zKZuo>qQm<+>cTh{V?!>J&b-jm(GzIgVXFu7NHmC{J(ywPVIOf&W@5u)9nPHlV}ljm zZlfs}>pgOW}VJ>@;?+t zi*3MUYI^Yp!a@Aqf%0Y(>oF=~fvG*6d6P2!{`-P}3q!4tl`niz0O>Mk5ic_?j$=%c zft_oBWI>cznJafWe0Vn{*J}t`qYz;*Wj2Q(JU=&+fiGcuCf@UsAwS(Sdwrrg6#iQ{yO z876Xg=YrVDG4YQd_fLxUSs~h2Fl?`-Pd>8c!a^Y-ry^m`N3|Ar?sJR=l<#g4L8Mnv zP+)noie5?mZc7Q{xu7A@+(qznl$>NcIabzlsbpvC#m3FY2gN!~V*>+hOiXm>TW~NN zOLhwHQ$pD=%*c4Jq5Qp1%M}iaaE7cY5kIJaDQfuzRlYq)IW$>FPyUgm^-KN(3?v8( zV2G6u4oaGqGE_iD3mq>ejT;aZ9P2DA>($~$o64VF(Qf8F;QYbhV{WHbrb$;(RV}2P z#?BgVDX#sr!AY7qye8G)ZQm)6L>Tl8`YB5Z@dXWwdBVfWeUiPZgv$=d7Z@cr$0YU< z&pz$m*)y*)pKbR~Z{hrQp3q0em@Pk}xD=b3wt>&-`J;rZ;ft1r9QCUZ`=gE9z#Av3 zKb;e`#Rbxtqm*&t#z-+M9Y5HaF6D%q4>ibq)6= zL9_=bU?ugjI$n|m^@hBdf>T|_$3*@rR+bt=r8rft+E=21-G&ZVzR^Xrs0irR1+o1} z-$e+J5k{v4=ew~_r>RnF#wIDg%_;U2&|uUc5%SjVym>nrsbTcfbfwCzei{b{M-q1p zxDCfDJBL!L-=@cQ6>*|(Xd78wOf2Hmt!&PI!(_E}r0(Lmb;Y56Wwq;n__eKjB~9Ha ze48~--yC~OX`EGacp8Z1ZDbWHNJU?0O`aT8uZ*|3HT$PsrcNhIvEWo<_cd~M{>NbY zSl|rAQ-A06K!LD$Lx?-{YxXl27c9@v_E*j{b{vC#{qoF~PmFUSQY)&hZJlDXJ)G~l zI?RTJC|_5EguDtDHZU~YKR8H;cb1|{SZZ{8Pof`oxU$U@8;^DBs!13*H_^$+%uL9` z{S$os&!67WQKfuEb&WY;p|1IQr?|e~Q3D&1L|ZUWuc5e*P_TUd#6neIps=wC@A644 zSV&@`ivYi{Q&FM9aa8dK%-q-U+|AL>S|o8~OOnmD7u++kt7{zh#xA7!0PL1f&KarZ3&HlcWBi{7%t1EbT>hwX1x0q7I-YH zDBkmD;x80F8-M;hroMhTkN%yGprLZ7XXN*`^5FLZ%)5wZf{4shY$d68Wtvn(7$4gg zM&M*xM^wMpo@JJt2;S#S%Qa^-qq3mZBLvFexGfLBxfEy7&z&E3ObpI9)CuQwGsO@7 zDgL=HtIg?Lmh(H%@^c!aPY7wp=zRbE>B&Gk?F?B$e@9OcMUg8LH@Rjjrlp$;6IRd* zd~D+*b0Rjb!#~9WkZ(!kp`g40)CyvymIH3b+k|nLOxV>;$y*1kDYoed=N8i}jg7dBM$H}6w<;#P$>}&x4#=U_T^ku~?#6_n zg6b@;@We9N27axZHHVh{Sc&%?_Z{T4s=?j5ndc3isIPuy*~OdGIUo0cZjt%aBQFmzpo#)*K7U_g=$~{LI^3 z)m*@yOqjF$XCtT%zhI#5KzCDSJUBQw6_3KNMJ25u@;tG24>PqV*Dm~{lJU<-I^y)H4-KNy9V#` zzwja&q0({gwbT3BTzh{Kx%MtoE*-0G_M1KwqbVzNUw1V%O)bpaZWq@?yA)VJAjFwf zM?nef)Ifq%YpnMU7j($pcfml7jlgik4A-yE&tt`6_^WPu>KrJ>#ua)E`?-!h;h}Hg zQrGuq==55gO>Sq4H)jb}bJdTnUp{4u^fcaV&WS3-468KUHEDvZN1cNY*l=Vzx0^i) zR_KQPjKyD?H_xxFtq-|e9`_FqKbZ{wl1f$%=_0YQ;bmisjEa&2m7R3v56mC!wDnh8 zatS@$Za(6qIc!OTO19TgQ>2yUc0E_TwO^3q&CRvX{o`yCuh-cm8;FCCXw}gmRc4pb zO|9gshue-Hat7FgYND-}JP)R8D{DdC+~=A3!THG*$#4rRp;gI|sXVtgQ|ZxCA9Q@0 z9e(UFWVM1u4gnD#YC8IyB!z@wk2$}UHd{U0x|Fy*mFNDRfiKqPtd?Z(h7`#Q;p?w?MP*{|&p5JN`~3BWsE_~ArY)~G4xYXX_jtc2P~B<*Ut2<;Nx>Hw2v zmJefNbCQ02Ug`tcOD$a(-{cgw^h(*!G4a&`yLHq5PX3A-_+yGv-mFR9g~@ppQ=mu{ zASv!?zY9|*8PdUfvPrehm?E9qEJ@Oh@h$c8jw)NeNLkO$^|;`qxXgsM!fm6=`MX_y z-_UJYT|i^P22kp{Uw(f!NNJ<{#X7fU*~PQPvz6EE793|lh%J;(m_&g63Y(>IT!1Q0 zoNAAO(Nlk4XiD6PYXO4vgTq8yo!qI@G5F}U#GE5Naz`SAONgv+c>+Vat}eGFNTMM~ zleW~e5PO4 zTRN~$4En-Cy>`;e*F38axbnvdPddEcy`mlYIcf^e-<*%6c6ac{ zl-WK&)5SFg^h6gn|!mtat)Y84JXk}vO!CyM|@ z^=Ea`ah*LTIEyjd9Bj=pp~qt7Y>l!IwCOU8xFXa?^3cW+JLCS!N{({6o3{=H^-Ql= z+NStpt>&Owx~1&gPqQo<{AixRTFzBkQ~Qdc&UjxbLfUoz`0aX(ipWwbPFW(EeR3au z#el<%=y=A}V`i0HrtcFKIX=x0SsV#!Xrvv(BfIJ!R{GSED#u@P%RmC*)&>6Cv5-@J zC}>d>2?OodLKWG?2+mXr4O!!yS{2#Wq3)w^0@*=tp_@G-`D^6K4=$fGN3|5jtSjC_ zzH$jQ`FqKsJ!|Pru=?)|CFl)p?-^=c>xaG43yvs%s=VX2&Vex(y;9-N5zb=bZM6CP z5wvH3_H%k&TQW&ua$#X|nbd7uJi$SlyG9x0f0f`c1T=up2l?bzpwjYK$#k@Y&Q1W{h!YD7nZ9?M@=;`CXLqg4eMW4L8*`su@u{#X(6cf zk^a)-+G9|Ybq|#Mt^;nCTI_hqIDgCydfkn?K+p~PDbc51bX-jL|E)~Z{j(&!Io|ty zs&KB5bjUgCMT6(PytDh|z0!+y#v3N8q=&_~pRAU@Y}XV~3v^4Jp@kpHQeKwmFgx`n z;pckmp`g3Do_V%zixD8Z{T+HStW8QzuWDv)J!6HG>oea^(|-~AEs^0$iv}&-`B1dG z%7?~^K!9TK7&!toY^KJ)8v$=yJ_`X9xZUKmEq1#J`x@ANinEpPi8Q!SBB*h9M%!Y{ zKmow|Q8!63r`EY9YJ65(ttXA+qv^`|bBNDfdFDg{mn7J;AE#w!4KAs!o!+NWwcYaV z%1){0p(>k5A=8vY2o=8SkSAKp!;#IBka3>{rr6XW=bPOhZhynaY zhFR$x4w@twU7eD_p~>F&*Cmi|I6g1VM-s=bkc(XD2fN36F^Erd{yZz|J-A0xp}*8j z0NUBQyUBZ%)}44w^S~_A9N5$dH{kbb^I0#vSXyixAk26Y&ns+Xi>(f_Qv?KI` zT%Px(!O?b1xo+x~{GdFL>GR}9{jgcDgwKuhlr9uM)z9T{lfG9|jPT4~5@Z^>`jn>0 z?+=%2>JaLjtDUtn>l4%LPiBP_Fvqjc;)VSqZm-WK9Zbk>(1}3vFVB1}71_IU@4pYL zr{7~to^B1EFaTA**o>=47?~ZjB$r8fMfiGn!_J4hlDFpFR2aXTNn1l3=~u2M5{Peh zVPYxbF{DdR{-i;J(G?LIn$EDnLGL&%aciUZ>ePRg_2X%G1^%>o z)$RTY6RB{7YN>lhRg;sLcHfZ)noJUx8^}YB(`CnfqEhI6{U&mtXj^%&W$q7)#%?|E z-UD^XOlH#a-(}*{p4L3^b#P+XVW3jegH?Z_aTsVHku^850#pa=#(Q}CT_+Tm;33zj z)7Iz}%7i|3j>gXS!QOHy4Er7~-oV2HW2%yeJe(_fGa+$y1!ae2frSW%br}KOGl8evWf< z_&0svlu!|i+wwP^1lL_pijsy11-P_=(fhp-*`68e z;_fiea?FBHX!fa2v!-ZnqSwuMfJw=HM_KZ)^F+rS7Mq=a%OkkxD?8O|P*q8|SnawP zdt4cmJxPNGEw>kW+OTPO*$lw^i!>J(cOD;@$tz&h#^&dLBq!Gy^mGHBtX5~g2I%m{ z#-|hx2VzJUB+o%U9TsBetS{EQ+360~A>y$AnUO&Vl{##ZBX&64T|QJ-U-oK_fc6@V zYELdR`PHi>8<2gkfA8q^&wSp=Q@(ynNYTp1=c0#Du{ynznO^ij^5JACe2&M+VOl<) zdE+v?4|5eTS(B;e)Gv>pm#pp%&HLk4PxbQ^XWOl{o7eqZmejqsuQTSq&f}g0Q&ovm z#capl09p+02pv^F=}J^ARM}8K%hx*wRtN2=I{V1D7-K99fdi#}OZVKw?(N-H>EcH6 zL?bH+Hkyb~tWtcOO8ooI_y1?|9R})=CX%X4Ex(BwQqa$}y0%X(mAalQ)0s5CKz_3SMF1hr)`8!|px3T4Nu*-)Ko41PKd~(d^ zg@Q^NY2z5(LUm;s$~Tn8vvHm7obH*LiYSXuJnm6MZwbCqtcvtR9KV4VGyXzt8k-b*2Hv)}S+2Yftx zwwR5U>e(5s$;mi|QE0+-gnXOA-PEKM+?6@HIvH-Hi6M}t6d$5Ny>fB*r68j-F#Mqaqw=YNJ_4B# zYx`iLYCZ3#o*?XS#|(LI&*+@c9zcOpf%L1k@E92(6 z#^%rmhM#KN|AsJHVIbp9cx`D9W*hVC)cw=&fz>;gfq%CK ztTgF72I6f1Hv-Lu`uaJF%JIr7Dxg6zsxNk8!f>4t52Rxd5dz=5T^t7%db;vDBM1XOywgLw|KSl4?)~omZU%ddm-nzmc9V#6RYZ+qE#38;?pVEN3 zfb<$2D=pNSSV@-LS@k*a6A_7*9{uo+>>Yfl*DA88CSgtKdRahXmyU@vp= zK#TmT=K0dNm39U`+_z6#s=2NEmIuG{lpTx*n;akXjh%%h&;4g4jJ-=8yAJNmV!CC> zUp`kw!HT57!N-MzLSjGC*waKclX`K6*`1CJKgCQEtH>7R z6B`J?K;R`@Djb3POIiNO`0P@B@se!E7*7brOXgjlJ^8{XoqT7!lc>K>(OP0gc&b$UzXA^H35P;t-gK}tFTGA?HXc(4{vL%*x>8F zVB)n_ZM0n=1W87(V=5gVGFa)NzrC*soc|i1j5b5Q*QPol`6~-4r=TP|^C-8P$Jc#p zBTY)J5tVM?Z1Wb&Kv(x&3}A`f0d8Y7k}yy(ChU-8eO>vR@^blnMCj#-Dg@28g65z~ z*{JX*ul{w@rAX(L(yCvA@U@8w%Peqd1=aCpdV098Uq249C6A{4 zu(aFH@U~M_ljGz_=_uhkn;At1o5n}-z1*INqz|5-JjRS3CFrxkYnd5GL@l~ELES&+ zgcia|;`)pr-%(N#4f!Gn0?3GgB={xDM&I&u|F|-NAWLnGAC_PKXt6%Y-svufpf__? zSs+*u?^C~vp)EY5yE?79{y{kKX^F$pONg7NWPIaz-9E9X>Hws|MTs|!H%B54ltz6L zQUDuQvWt_?ry2er9M2%}1BIx&GqEg^@pPea;YYS4NwDdfZl-(zjVaa$-2ulGg+>&9 zftr>~hNHa;2`)zD5f>pN`D-nl{P{kH88pL52y8sJqghs-^-CAds8U}Z}lp=HaSe0x^1qC5tL!OQWvZZtM)~qsK_Mni zJX^N+85A4O)4g^A>UgGB8?X@Bt1@e(1s-H47LVJM7k$_v10e|fkLeVVuU~&cMn@az z_v*FSm@G3VGUR>!0@=qINk3mOU-9qXsrkm#uPEsJpiJ>9T2V{kgq5 zx|-X>$N679T4t=}_y0-(<5AuCxro1?Kg~u~HeNYWFjluRnttU8uCpH96_qiWt3>Cu zH2*W%yDszAk@XHga_(1u;FS1O`{cs$LaBpjl*0U72I-0uS9m^%tL=A{a7e%J!IXV|1|Np<_jX`t7{v7M1)+{G}g(k6YOh0dMM>567o<}Kb~#Bn2sD*Qp7yNRJ>MJa0thB z)$GkmA3vb^AdV`w9cl;Fu3ICN9dCF)L$iSqwTK$(RmXR6$`_~(4!M=2w7w8si(Eq8ftlXS9 zdK4ff4+SBfCpd_o+3GCC7VHLfLg?}F-Zo1q`Hp$rVhXQqbTq_WhewOGOiX5QRan*h z{1sh^H00NL?3?{Vs-5lJT#u|2_`QTGS5uFtsIdFjJ_>kXVQPb;u@G4c8o?&CUQ_2y z6BCvX6bn;Eb6woi^Ga=;4EG+%XXO>dhVke!L+SYQ1?f*!t7OmwuU!xNhvRt+f&>-XU`Zab9YhQ-^j^Y?`;?os%8jvXghNdZ8m zxaiwa?AI$h#wf=&br~Vl(O&O$eB4o>^^)h-aoqtv>JZ|r~Lm*{bX3jx`e56`B!|4IL7APH*;(QQii)1a; z`_NQ7R}`y}acJ!BOxxESi@D};sgi#lFWSJHdIm2O&%R89`d`xQekF3T-8 zRZvggCDd!V5X-zX6KiQP@}N~E>}9MX(?)2aZV(pccxy|6#&9z3oX66|R(4t;9)_6PY+k%>I8Wo|yqiwqF+(00^)vVbK=q=2}@1Bzmu2iwPAQ&R4T zlK@5u;7G$^?UQzMz^0+lKa+zcnjWK_hgPur6x(KU`{i5ho#OFj?(7e%vY93F_rf?# zqGOjgrw0LHY@k}J{t^+nvy*LCH&J}{JXSHIuOiJ>l`pP^sXFeo_pJ1O0V4?k(FhJh zk$;QX9&X>Sv9KSe=h>3RPfHR;=!(;nf1&c8)=gq|0uB$@-eB9RDl1?6u=QK}{Wg|> z&~Q(A_j$n`&qwN_jZ$H~Q4uK3k>WGOF2$Q&nRRq~ySq5LULmZq)l*}G>?G%|Cshs6 z9{F+;*jkq_ixbV8Qjh=an_K=qOrU-pm*uJX(O6eht1!~g_*^0;k#>|4{}}IFlOC_} zo$&7s$<+SDNOty<)fA=oOMjxYWyk`QmXm@Rl#kpsy>1R+x^LYpX0&&!Xk>{u@Rd&8 zTa@fzY{%Tdk;)vHFJ|Gq{<^}jd|)Cr{(8hL~uc9PUt5y&s(_BLAF~umwJj>b2%zBYRkfVZ%rVhdZ0?~PMs%7Ud6vyLyBxOq2 z|2Nb0>%X?KVat~(hT~2)NQ#9(1WC)rIQ9UlL?`4Twjc)_EC6GjQS8N~rHq?lsYoQa zg8g{-;raC8X}H&DL2N@=xi?!qvu?YCO|Py+tZl}d8S!((XJ_7J=+`ebH8qJ0dAP#G zMWQ*&%UY`~virx!fn~f!a?zfda;F`9L?C|NfB*4iO{jeOnf3$_)(P?P3=9lf`33>* zIV^2v+!nnth8h|r?gzH|`s09P{`~nfRMhDz0#Sm%AK>r*{aXXx2`DsG)tTjG^t^rQ zw{QH^Hwvb(*&P5|ee))k&&~+QVO7=sqn$-V1B3R5%m%bq5LDg&XoP(M2IrPzWoHMT z5}NB)3*~UGuB4Me^4IE%cH(`7P##cWLPCK4)&Y^UP}1O1O0w@+> za03oLB+_kfWl#h6iq$Nj+N-MyBvJs|8W~NY!jmvzNE4F`1Fhm|l69PG{KeHA@zwPV>?TcH)&L5qPwnkA%lS5sx~ z<*~M~Xmwveejq_$WmQ#OO+!u1q!iE3Xuo}#u-hX2c@ax>RTYO}6_4GNP!9G@vRQmb z!RW=F=fH3QGYFFa3#zHH5#Tf?CF-@k*t|XA;M?xf6f9X>H5nd8PY3_LwMl3<;qH}H zHZCqFb1vC`Jmk--cZH~_uX;z8oJl41p z8S)yqyiB#2^Ar7YTXQZd4P1%$fDZos`*&^4nvO1sMLoj>mK+T!;%9}=M>!CG$k~{z zZd=>|GX~@%%mpn3&chj2!f= zu*sNg?z6MkqA(&!z2$|4|MvFgw_IFs%Bwu~M=e=cSiV*}ye3*+Spi(Nv$vOzhi7+Z zCl26FTjCll#EVO0OjoN=m~-F`VH_a1fX-ZdW*;`TK3Z(q;C&^Ah7;b9gYTk6x6K07 zSyfs2-^gS9KFXc73oZ8~2-4Eh0;6_*etsxp>_AM-9}*Js2iz(r`c$~b4M11|f_V4t z-47o=IGr{!B7Vx!o2cCuNm5>r1NyKl{PkuSMLhqTOFId;2Xp9fKz3gZ=L2-_NP*rTxQot#QxA%luSQWD+vJsaekzaKA(>z>gMz7N83-k7L#-LY_YcXx4d z(b1v85y3+E65|hW@$&G@EiO`CzaG-t2opCnJe-NVZ@9ZRY%C}!=;!OJM$;Yxmcnso zp&Ja7v-3er3{_V&E`o~So?@>IJ;_9!XLWM27;9u$FHt;~$)!Q@hD*=Qj4gR5=|a~RiknHGKf_AQIp zEEj5vrvR!1O4i72nNdji2I7w{*SNF~Xg7dah>xefeLL>uK*rJWu^J7j&=aO`fQeOU zTBso0aS<}o)ErzNFMq_%4XCjz*bi9BK}aeSw+vWm&>bwWV%%ePs8fbZt@uAf4CfoJ zuB|D`%YQ?LY$ey#iQK)L3KY1A2yN<91Y$dc>*}AWT6gUNBXjQ9{{DV`n;?5&HG$3E zS?tY(F0=iqGL)P~0G0xKI5ae*;fIajVx>26lZShpt`H6H392Ta%4Ci*Ou-@wo zi0Oj5;~YOf+`%FQLIpp(E&xbKz)JV__n|ixC4DQkr{@`bjGR=ea#K@NST$d01Oat^ z=&+!e(*$X)AlgAJ6<~-RFz078Gc#=3`BG&(6#dJN_Y`lnm=+CzCC?lX#hg0iJiqws z4JJi!fWUnx4Qv60f#&hjRt~`HEsC?hn4W_80<`g>=eUFKVK|a9gV9U0O;;5+wXtTdT3?{)#%CrPIK@gb>3rRE%jh-FlCWD{}fzasro+cxibV zj+UI%z8fIQ5D*aH4%s;*$ZgsTRDR4(Ntqcbdahq)oq{A$xdvkr7ETZhVribY2SOjP z(`@3)2(j;u8;U!F+QxZ0Mcym-#cW>i=-JtE4yrCi`TP6BT!7X~4mK8|k9JZ%2KoRl z3l8Jp`*+A0UDGi>hlMTxc5_k@@CP*VF=pJOweANJl9F)g-vQF8MLO`iJ^_#ifrCf` zikOpykr7;)T3SHCo78n4-X#mjA{JjP99;t*73}JN??gt^L5oBpgMxyxzFc}1&&A7o z1Ml*Gof(l^9F>xO#56)Kg(zzldU{0f16sOE*w`m=g98IQzq8dfWYWl^9_XrRX~B$x zW`Yz03oGk4Bm>ly4g`>9R5~nz=*hO_PI{Oi&{E7#yr@U_d=M zv-D|sAT!)Gtgi07(T6ab7#AUS+mXS9Vbgnmch{^)Cy` zvgFegZET_Bw|>^d@bmcCKsTSD!apObgSkW*i7DB28LyT%R#r(>cl2Vi-*XN88`Yq#D78nd2m8`e@-g`)8a@CYTzKVLKdEYY~H%9D(Ts1nm&-~wL|L3Epp z3BDk1g#7n1>)l6ucqMk_p5nz%!7N@ly>kzy%SAWH@pzUjEOn zT=`@f8yg#6zjm199*)~xgT1-E$jb{1h!{=EnNkWvsBGH5^XGlumZkhb28NTVJw3!1 zOIPJlHJ3$M{rTQ9lnSVu*DF1p zjE#0yuLkezMZ5)hMo>`kVvncrwmk?^43d74&ebnJMTfUZ>e~NGL$40oogA-rwzN1G z7}wtq-9;jmj`zpA^7IdA1%A}0r_1d$e37Hdr((3|l1&tLe_wUH_hREW0@1Ow!k(Xz z!OH7oX=CGLz1CIfK$*b5rR!W?SQ1hHW)?L*GU9o>yfI#0EGfYd7EW1N?SMMns{Zlg z#K|dGPd~2Qc5-K{O|YX=;q=ryiWAi|I9OX$blx1$YdhWZ_Vw$sA3va=>lzztM^C&! z%OYiKYmcJ59%NUya=Fa7b@j%I=)CyX=jOs9O6Y}7eX6QtfK(6XG-e2mNA4X3i+ZiD ztUPR|pb@EY9xp>WI~SC`!dO^aA5XbsHj^-?Aa7PuROGd@P_LM9OOB+u^|Kv3YdAaV z-7GIFix-T3d$b*V=gy47Le1LBir3#}%bPbXZLHUZ@;!S82PY>J6i7Y>1Y|2R!C~gL zURrutoQq1)oBp@gx}D?LkNJe;p$1yx}!K{?qByh-ST_#q+D3olh1lYF14S-NCGdIT%IGLHF6{35F2M5=tJYBZU zde_G>(j-!rmhRH6qfq<3Ip*}PsR;iX%A_~(E~r~gdmb=~lVHvdD8YR=IY?StUVh^+ zE8;bA+#~qi!xOvQZrWH~-F2ZWTf7k%h6Zh8n#n?w#cxm8&d(2=fv{$Oz)vv0IDck8 z(+B`{d3st6x2)>E$AmrXHAn z20YV~{d#;K@5$rp=mS*ZyzA{M4`PqXvJaLw@0{qM`@tMl@&A z!M}fR9plr6GN{r4uv}fSdb@F&1{z0=KE)ugbFf2rzTMe$S)3YK!pCZLe7rXvpI})0 zBY&bQGV-fiQK}iqxZg*GLNX1sYWv|j`%@HRJ z&AN?E@X={wcO2&7bLnkLndF*0o z*;eP-Ha?bUP`RxxCgxvWZtQ+S?&Bpad(>fQl%oFX4OBi#%Xj042P=ztdG+kAQr6a< zfy=J*0JK|p9zO=j9f&Cc0#L6V<9XcQ%6od+n44b_CmG0SIXqD=Dl0QD9#vA}SnNeP z9N3<(kB?p!7xK_qnV+{bH=muEnH(EyUZi~MOxW4+ss3!=Oj~;~l1=m~Su1C~S!;7M zh@PCBD1-Z2?Zl=~dD_(#B;Y`SgX?z%*YB!YL||ZC>TKE#wy6pS=7RL}mqWQn%gdH{ z-tAqAsO5Csxqykjz7YuUN=uK<&jev|AYwIASJ&0j0^N?u$x4}EFH+A2VmmB9Bol(HE8$10Vy*qbEslSv4E5FOkEXZ4LZg1DI|E41= zdsyl4vb1y%mOhNWZ*Z__Y%HpcFsGnEljCFOJn3cFs#s8Z>P??-^pqLz@7icdeEe-3 z9N#(WTPO_6+qe7u{R7{>qsR%abg+y3(K~BP8*&aR1FwTrd_3dG{(# zlRipdg`*kpyt|0p+}-iL3k&~*pg?+NtkMC*$^<1PQ{S$+B+>iFK3b#`uBxx8nd^v5 z5;3t~C_voSq)p4dvpAXx3jtS##_lUM6~AoSn&K@UF2vEglKS8RR@L( zjEn82Ay`PF;*4y9zV(hWC4*YYSm1f6GQ)YFwkC0IxjOns?a~t#Ms6a$CWw=6^ z4HO?`PW-`m zn@dbc5Edta9kVgjtt{u7UR!J9Uq1HvIUMC@XPFOle{c&5hPRjsAeFcuKX!#P3XSGu zzX%9aX054Xhiwjb zpm-lY&dze74@XB-*GOb)9pHdt5%QHhqoyXVpuTP?uUxAuslNGF82PP>Acc&)=?m?d zS!<90%qA1FOrj{J8|>ose6g06?u8vf?fiJmoE)3q^MoXnI{gyJ2@5&Zg+Bc8RBG4-LMP4N%U;FfSeh5KbnqC zw5_MdWb{WfyZ)5x(8AK{DxIhomw>=_oSjmxPEph;7poOgoTRAe5!yJK!?4z2(YLvo z>wWU8&M1_YHs-OVQgfVLua#H>k8*wxo^ zGcrb@&1z4#Kb4g+pX{&S!!sSsiSQxJ+?=QsueEuITwYy0;HyoXQumuan8vuDpHhPA zRfYBF3M36PGLGS_r$v@5u9s`Wb3z|`ud`BX@Iku1-dLG$A;b^RDYZ%n5AUSI@Gs6s z&-NrJ+?CSqFP`)sK*n7u^PqQe zX=B5pc=XJY=ICh@DCT;4&hP}-WBbZWSxx4q^G^=_XSU@P)!)XCm6Ez;q+ z_4FQ@rj`f@`axPqQ7*vqWF5mv5jYo3gdb2?ns6WRfyEDOJk7;9Dlrlw5v7U4oYRBM zd9Kk5GZ8rRT&cvnY-nSn9O3@Czz*Tskg(>v-G+Mp{OnzV8#4_GoMI4@Uc%_ln}}WEY+o$Z-h@p1=xV)2*TL{r z$Hw|J<`UZPof|xzsmW5QYvcxTw}}ZgFIP#)yWI9ihxLaHdwz6Ec4NDtr%V14PYA~E zW4@0mcg-qd5^LP~Py-oGa6*ao-Js+fZ)wRZDl+ndKn*;<>-#m^-HsnLwhUf!L8rlgo-~*Z2fXNBFjuy!{&;v>uzq~JfwXcMsMLUUd+7FenNLJIW)8Hg ze0?FKbuyFClg(Qu9aAD_m~iW^A|ly5b)%WHx2tQSt1Euxexihk5`GEbOs_-y7#gW~ z2?Ti&KUIRhM{i!lMi+^<|2+!&{|TV38-M`~J6AJ;3ukwSX0i`G2#Q0xA`cqTW zGi9;@G5fpzX&QbAMAegrCic5rFS03At`iX@#on0wsWZ!IQd(&8Sd?rQPZjO(DS*N% zw(F5q*2=~&iKnT-AF8pYY6uZyQlOx#(RMLVuAJq+&qUyxpAO>x&p7V?`UIz(v63gh Tq9IFu(Od3`l2pFLGw=Ta&MS(~ literal 0 HcmV?d00001 diff --git a/static/img/stylus-wasm-execute.png b/static/img/stylus-wasm-execute.png new file mode 100644 index 0000000000000000000000000000000000000000..0910637ab13d237f9ffcefb7c9f558483dd5c106 GIT binary patch literal 32559 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 NFD@@uBJ%0m{{cMBnHvBA literal 0 HcmV?d00001 From 761457ee1b043d6210b0eb0a04130fd465e085da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:28:10 -0800 Subject: [PATCH 137/162] fix: correct broken link to debugging-tx documentation Update link from /stylus/how-tos/debugging-tx to /stylus/cli-tools/debugging-tx --- .../arbitrum-vs-ethereum/03-rpc-methods.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx index 91fdf6f8ed..b70fb3de78 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx @@ -142,7 +142,7 @@ If the sync process encounters an error while trying to collect the data above t :::info The `cargo-stylus` command-line tool uses the `stylusTracer` to replay transactions locally inside a debugger. -More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/how-tos/debugging-tx). +More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/cli-tools/debugging-tx). ::: From 0f0f9c3ab930b810b49948abc6f48f1172e756bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:30:41 -0800 Subject: [PATCH 138/162] Revert "fix: correct broken link to debugging-tx documentation" This reverts commit 761457ee1b043d6210b0eb0a04130fd465e085da. --- .../arbitrum-vs-ethereum/03-rpc-methods.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx index b70fb3de78..91fdf6f8ed 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx @@ -142,7 +142,7 @@ If the sync process encounters an error while trying to collect the data above t :::info The `cargo-stylus` command-line tool uses the `stylusTracer` to replay transactions locally inside a debugger. -More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/cli-tools/debugging-tx). +More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/how-tos/debugging-tx). ::: From 878c1d957ff488f23887f338e0ca5585670da147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:31:24 -0800 Subject: [PATCH 139/162] fix: correct run-arbitrum-node link paths in stylus docs Remove number prefixes from URLs as Docusaurus strips them from filenames --- docs/stylus/cli-tools/debugging-tx.mdx | 2 +- docs/stylus/cli-tools/overview.mdx | 12 ++++++------ docs/stylus/using-cli.mdx | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/stylus/cli-tools/debugging-tx.mdx b/docs/stylus/cli-tools/debugging-tx.mdx index a5e7c22d72..aac7157564 100644 --- a/docs/stylus/cli-tools/debugging-tx.mdx +++ b/docs/stylus/cli-tools/debugging-tx.mdx @@ -27,7 +27,7 @@ Cargo Stylus simplifies the development and debugging of Rust smart contracts fo - **Crate**: `cargo-stylus` - **GNU Debugger (GDB)** (Linux) or **LLDB** (MacOS) - **[Cast](https://book.getfoundry.sh/cast/)** (an Ethereum CLI tool) -- **[Arbitrum RPC Provider](#rpc-endpoint-compatibility)** with tracing endpoints enabled or a [local Stylus dev node](/run-arbitrum-node/05-run-nitro-dev-node) +- **[Arbitrum RPC Provider](#rpc-endpoint-compatibility)** with tracing endpoints enabled or a [local Stylus dev node](/run-arbitrum-node/run-nitro-dev-node) `cargo stylus replay` allows users to debug the execution of a Stylus transaction using [GDB](https://sourceware.org/gdb/) or [LLDB](https://lldb.llvm.org/) against the Rust source code. diff --git a/docs/stylus/cli-tools/overview.mdx b/docs/stylus/cli-tools/overview.mdx index 5ef14950b9..bcd8207d4b 100644 --- a/docs/stylus/cli-tools/overview.mdx +++ b/docs/stylus/cli-tools/overview.mdx @@ -117,12 +117,12 @@ Available for commands involving transactions: #### How-tos -| Topic | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | -| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | +| Topic | Description | +| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | #### Additional resources diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index 4f61d1ba3b..615372c72e 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -117,12 +117,12 @@ Available for commands involving transactions: #### How-tos -| Topic | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | -| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | -| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | -| [Run a Stylus dev node](/run-arbitrum-node/03-run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | +| Topic | Description | +| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| [Learn how to optimize WASM binaries](/stylus/guides/optimizing-binaries) | The `cargo-stylus` tool allows you to optimize WebAssembly (WASM) binaries, ensuring that your contracts are as efficient as possible. | +| [Debug Stylus transactions](/stylus/cli-tools/debugging-tx) | A guide to debugging transactions, helping you identify and fix issues. Gain insights into your Stylus contracts by debugging transactions. | +| [Verify contracts](/stylus/cli-tools/verify-contracts) | Ensure that your Stylus contracts are correctly verified. Step-by-step instructions on how to verify your contracts using `cargo-stylus`. | +| [Run a Stylus dev node](/run-arbitrum-node/run-local-full-chain-simulation) | Learn how to run a local Arbitrum dev node to test your Stylus contracts. | #### Additional resources From abb85ca8a5d26c24b06bbdbe8d486c31a326d5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:35:51 -0800 Subject: [PATCH 140/162] fix: update debugging-tx link in rpc-methods Correct path from /stylus/how-tos/debugging-tx to /stylus/cli-tools/debugging-tx --- .../arbitrum-vs-ethereum/03-rpc-methods.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx index 91fdf6f8ed..b70fb3de78 100644 --- a/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx +++ b/docs/build-decentralized-apps/arbitrum-vs-ethereum/03-rpc-methods.mdx @@ -142,7 +142,7 @@ If the sync process encounters an error while trying to collect the data above t :::info The `cargo-stylus` command-line tool uses the `stylusTracer` to replay transactions locally inside a debugger. -More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/how-tos/debugging-tx). +More information can be found on [How to debug Stylus transactions using Cargo Stylus Replay](/stylus/cli-tools/debugging-tx). ::: From c836b88daf481a0cf9dad3bf5550167b91629987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:48:45 -0800 Subject: [PATCH 141/162] remove truffle from framework list --- .../reference/04-development-frameworks.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx index 9d59cbec03..a6a5475711 100644 --- a/docs/build-decentralized-apps/reference/04-development-frameworks.mdx +++ b/docs/build-decentralized-apps/reference/04-development-frameworks.mdx @@ -20,10 +20,6 @@ The following tools will help you develop and test your decentralized apps (dApp [Foundry](https://github.com/foundry-rs/foundry) is a high-performance, portable, and modular toolkit designed for EVM application development, leveraging the Rust programming language. It offers a comprehensive suite of tools to streamline the process of creating, testing, and deploying smart contracts on the Ethereum, Arbitrum and, in general, any EVM network. Foundry facilitates seamless interaction with EVM smart contracts, transactions, and chain data, while also providing a local node and a user-friendly Solidity REPL environment for efficient development. -## Truffle - -[Truffle](https://trufflesuite.com/) is a comprehensive suite of tools for smart contract development, providing an end-to-end solution for building, testing, debugging, and deploying on Ethereum, Arbitrum and other EVM-compatible chains. It features advanced debugging capabilities, fast EVM simulation with Ganache, a user-centric design with a VS Code extension, and robust parent and child chain support. Truffle prioritizes security and partners with ConsenSys Diligence to bring continuous security to projects, providing a seamless and secure developer experience. - ## thirdweb [thirdweb SDK](https://portal.thirdweb.com/sdk) covers all aspects of the Web3 development stack, including connecting to userโ€™s wallets, interacting with the blockchain and smart contracts, decentralized storage, authentication, and more; enabling you to build scalable and performant Web3 applications on any EVM-compatible blockchain. Out of the box, infrastructure is provided for everything required to create decentralized applications, including connection to the blockchain (RPC), decentralized storage (IPFS + pinning services), and tools to create powerful user experiences; such as gasless transactions, wallet connection components, FIAT on-ramps, data APIs, and more. From 86f858bab0bf8bb9644fed6905b25b0d22302492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:53:54 -0800 Subject: [PATCH 142/162] Update docs/stylus/using-cli.mdx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/stylus/using-cli.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/using-cli.mdx b/docs/stylus/using-cli.mdx index 615372c72e..6b4cf6aac4 100644 --- a/docs/stylus/using-cli.mdx +++ b/docs/stylus/using-cli.mdx @@ -126,6 +126,6 @@ Available for commands involving transactions: #### Additional resources -#### [Troubleshooting](/stylus/troubleshooting-building-stylus): solve the most common issues. +#### [Troubleshooting](/stylus/troubleshooting/common-issues): solve the most common issues. #### [cargo-stylus repository](https://github.com/OffchainLabs/cargo-stylus): consult cargo stylus' source code. From 05beb5119b57c0de83ad857a787a7b13dac5c891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:54:53 -0800 Subject: [PATCH 143/162] Update docs/stylus/quickstart.mdx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/stylus/quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 5d0d923928..87cfbbb50a 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -198,7 +198,7 @@ Location: prover/src/binary.rs:493:9, data: None ``` -The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/main/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. +The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/stylus-sdk-rs/blob/main/cargo-stylus/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. If your contract succeeds, you'll see something like this: From a37b310e0223057b0a7f10f9491b3da6c07bdc5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 12:55:04 -0800 Subject: [PATCH 144/162] Update docs/stylus/quickstart.mdx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/stylus/quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 87cfbbb50a..58a68f60b8 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -94,7 +94,7 @@ cd nitro-devnode ## Creating a Stylus project with cargo stylus -[cargo stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus/blob/main/main/VALID_WASM.md) is a CLI toolkit built to facilitate the development of Stylus contracts. +[cargo stylus](https://github.com/OffchainLabs/stylus-sdk-rs/tree/main/cargo-stylus) is a CLI toolkit built to facilitate the development of Stylus contracts. It is available as a plugin to the standard cargo tool used for developing Rust programs. From e8c12b293569aef6d8f68f0bef66b3e485a089cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 15 Dec 2025 13:40:28 -0800 Subject: [PATCH 145/162] remove unnecessary diagram --- docs/stylus/quickstart.mdx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 58a68f60b8..510bbb498a 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -25,16 +25,6 @@ This guide will get you started with Stylus' 6. [Calling your contract](./quickstart#calling-your-contract) 7. [Sending a transaction to your contract](./quickstart#sending-a-transaction-to-your-contract) -## Your journey - -This quickstart follows a simple path from project creation to successful contract interaction: - -![Quickstart Journey](/img/stylus-quickstart-journey.png) - -_Figure: Your path through this quickstart guide, from project creation to successful contract interaction._ - -Let's get started! - ## Setting up your development environment ### Prerequisites From de4c359a678ace28cba99146ad03336791d0963e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 16 Dec 2025 17:21:28 -0800 Subject: [PATCH 146/162] reformat --- .../04-stake-and-validator-configurations.mdx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx index 77b4b678cf..699a81a7c1 100644 --- a/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx +++ b/docs/launch-arbitrum-chain/02-configure-your-chain/common-configurations/04-stake-and-validator-configurations.mdx @@ -11,16 +11,16 @@ unlisted: true - **Base Stake**: Minimum bond required for validators. - **Stake Token**: Token used for staking. - **Loser Stake Escrow**: Address for escrowed funds from losing validators. -Arbitrum chains are customizable Layer 3 (L3) chains that settle -to an Arbitrum Layer 2 (L2) chain, such as Arbitrum One. They support - validator - configurations to ensure chain security through bonding and - assertion - challenges. Validators post assertions about the chain's state on the parent L2 chain and can - challenge - incorrect assertions. Arbitrum chains can be permissioned, meaning validators must be allowlisted. -For chains that use that elect to use the BoLD protocol, permissionless validation is an option (BoLD -also supports permissioned validation). + Arbitrum chains are customizable Layer 3 (L3) chains that settle + to an Arbitrum Layer 2 (L2) chain, such as Arbitrum One. They support + validator + configurations to ensure chain security through bonding and + assertion + challenges. Validators post assertions about the chain's state on the parent L2 chain and can + challenge + incorrect assertions. Arbitrum chains can be permissioned, meaning validators must be allowlisted. + For chains that use that elect to use the BoLD protocol, permissionless validation is an option (BoLD + also supports permissioned validation). Bonding is required for active validation, where validators place bond funds to participate. If a validator loses a challenge (e.g., due to a faulty assertion), their bond is escrowed or burned. Configurations such as the `stakeToken`, `baseStake`, and `loserStakeEscrow` are configurable during chain deployment or post-deployment via contract calls. From fba9baa831635b1fe98759cd0f4fad2a1332dc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 17:15:11 -0800 Subject: [PATCH 147/162] remove inheritance pattern --- docs/stylus/fundamentals/contracts.mdx | 184 +------------------------ 1 file changed, 2 insertions(+), 182 deletions(-) diff --git a/docs/stylus/fundamentals/contracts.mdx b/docs/stylus/fundamentals/contracts.mdx index a75621da05..d0ea140433 100644 --- a/docs/stylus/fundamentals/contracts.mdx +++ b/docs/stylus/fundamentals/contracts.mdx @@ -402,11 +402,9 @@ This is useful for: - Avoiding naming conflicts - Implementing multiple methods with the same name but different selectors -## Contract Composition and Inheritance +## Contract trait-based composition -Stylus supports two patterns for code reuse: trait-based composition (new, preferred) and struct inheritance (legacy). - -### Trait-Based Composition (Preferred) +Stylus supports code reuse via trait-based composition. Define reusable functionality as traits and implement them on your contract: @@ -1652,184 +1650,6 @@ impl Vault { } ``` -## Struct inheritance with `#[inherit]` (legacy pattern - subject to change) - -:::note -This section covers the legacy `#[inherit]` pattern. The trait-based composition pattern described in the [Contract composition and inheritance](#contract-composition-and-inheritance) section is the preferred approach for new contracts. -::: - -The Stylus Rust SDK provides an `#[inherit]` macro that replicates Solidity's composition pattern. The `#[public]` macro provides the `Router` trait, which can be used to connect types via inheritance. - -### Basic inheritance - -Use `#[inherit]` to include methods from another type: - -```rust -#[public] -#[inherit(Erc20)] -impl Token { - pub fn mint(&mut self, amount: U256) -> Result<(), Vec> { - // Token-specific logic - Ok(()) - } -} - -#[public] -impl Erc20 { - pub fn balance_of(&self, account: Address) -> U256 { - self.balances.get(account) - } -} -``` - -In this example, `Token` inherits the public methods from `Erc20`. If someone calls the `Token` contract with the `balanceOf` selector, the function `Erc20::balance_of()` executes. - -### Using `#[borrow]` for storage access - -The inheriting type must implement the `Borrow` trait for borrowing data from the inherited type. The `#[borrow]` annotation simplifies this: - -```rust -sol_storage! { - #[entrypoint] - pub struct Token { - #[borrow] - Erc20 erc20; - uint256 cap; - } - - pub struct Erc20 { - mapping(address => uint256) balances; - uint256 total_supply; - } -} -``` - -### Method resolution order - -When a method is called, Stylus searches for it in this order: - -1. The entrypoint struct itself -2. Inherited types, in order of declaration -3. Types inherited by those types (depth-first search) - -```rust -#[public] -#[inherit(B, C)] -impl A { - pub fn foo() -> Result<(), Vec> { /* ... */ } -} - -#[public] -impl B { - pub fn bar() -> Result<(), Vec> { /* ... */ } -} - -#[public] -impl C { - pub fn bar() -> Result<(), Vec> { /* ... */ } - pub fn baz() -> Result<(), Vec> { /* ... */ } -} -``` - -In this example: - -- Calling `foo()` executes `A::foo()` (found in A) -- Calling `bar()` executes `B::bar()` (found in B first, C's version is never reached) -- Calling `baz()` executes `C::baz()` (not found in A or B, found in C) - -### Method overriding - -Because methods are checked in inheritance order, a method in the higher-level type overrides methods with the same name in lower levels: - -```rust -#[public] -#[inherit(B)] -impl A { - pub fn foo() -> Result<(), Vec> { - // This version will be called - Ok(()) - } -} - -#[public] -impl B { - pub fn foo() -> Result<(), Vec> { - // This version is never reached - Ok(()) - } -} -``` - -:::caution -The Stylus Rust SDK does not currently contain explicit `override` or `virtual` keywords. Carefully ensure your contracts only override the intended functions. Unintentional method shadowing can lead to unexpected behavior. -::: - -### Limitations - -- **No multi-inheritance**: A single contract cannot inherit from multiple unrelated types that both need storage access -- **No explicit override/virtual**: Method overriding is implicit based on declaration order -- **Subject to change**: This pattern may evolve in future SDK versions - -### Complete inheritance example - -```rust -#![cfg_attr(not(any(test, feature = "export-abi")), no_main)] -extern crate alloc; - -use alloy_primitives::{Address, U256}; -use stylus_sdk::prelude::*; - -sol_storage! { - #[entrypoint] - pub struct Token { - #[borrow] - Erc20 erc20; - address owner; - } - - pub struct Erc20 { - mapping(address => uint256) balances; - uint256 total_supply; - } -} - -#[public] -#[inherit(Erc20)] -impl Token { - pub fn mint(&mut self, to: Address, amount: U256) -> Result<(), Vec> { - // Token adds minting capability - let current = self.erc20.balances.get(to); - self.erc20.balances.setter(to).set(current + amount); - let supply = self.erc20.total_supply.get(); - self.erc20.total_supply.set(supply + amount); - Ok(()) - } -} - -#[public] -impl Erc20 { - pub fn balance_of(&self, account: Address) -> U256 { - self.balances.get(account) - } - - pub fn total_supply(&self) -> U256 { - self.total_supply.get() - } - - pub fn transfer(&mut self, to: Address, amount: U256) -> Result> { - let from = self.vm().msg_sender(); - let from_balance = self.balances.get(from); - if from_balance < amount { - return Ok(false); - } - self.balances.setter(from).set(from_balance - amount); - let to_balance = self.balances.get(to); - self.balances.setter(to).set(to_balance + amount); - Ok(true) - } -} -``` - ## See Also - [Primitives](./data-types/primitives.mdx) - Basic data types From 46a74d2ce8e43f1b44ed01939b2c31cbc4b16f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 17:26:48 -0800 Subject: [PATCH 148/162] remove stylus-by-example submodule --- .gitmodules | 3 --- submodules/stylus-by-example | 1 - 2 files changed, 4 deletions(-) delete mode 160000 submodules/stylus-by-example diff --git a/.gitmodules b/.gitmodules index eea44da8c8..ad4d5dd0e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,6 +3,3 @@ url = https://github.com/OffchainLabs/arbitrum-sdk branch = main -[submodule "stylus-by-example"] - path = submodules/stylus-by-example - url = https://github.com/offchainlabs/stylus-by-example.git diff --git a/submodules/stylus-by-example b/submodules/stylus-by-example deleted file mode 160000 index 24eb919c99..0000000000 --- a/submodules/stylus-by-example +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 24eb919c99079bada64c30db1cb2896fbada8a1f From 83e3c7a52baa7c2fef57a1268992be85f719d80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 17:38:36 -0800 Subject: [PATCH 149/162] fix: resolve useDocsVersion context error in FloatingHoverModal The FloatingHoverModal component was wrapping pre-compiled MDX components in an MDXProvider, which caused React hook violations. The MDXProvider tried to establish new context outside the Docusaurus DocsVersionProvider hierarchy, resulting in "Hook useDocsVersion is called outside the " error. Fixed by: - Removing the unnecessary MDXProvider wrapper - Removing the mdxComponents object mapping (not needed for pre-compiled MDX) - Rendering ContentComponent directly, which preserves Docusaurus context Root cause: Pre-compiled MDX components don't need MDXProvider re-wrapping, and doing so breaks context inheritance from Docusaurus theme providers. --- src/components/FloatingHoverModal/index.js | 28 +--------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/src/components/FloatingHoverModal/index.js b/src/components/FloatingHoverModal/index.js index 4ac622555b..249e17aaf7 100644 --- a/src/components/FloatingHoverModal/index.js +++ b/src/components/FloatingHoverModal/index.js @@ -13,7 +13,6 @@ import { autoUpdate, useMergeRefs, } from '@floating-ui/react'; -import { MDXProvider } from '@mdx-js/react'; // Remove Link import - we'll use a span instead to avoid Docusaurus broken link detection (Docusaurus's build will fail if a points to a non-existent page) import './styles.css'; @@ -61,29 +60,6 @@ const contentMap = { 'config-other-language-support': ConfigOtherLanguageSupport, }; -// MDX components for proper rendering -const mdxComponents = { - h1: ({ children }) =>

    {children}

    , - h2: ({ children }) =>

    {children}

    , - p: ({ children }) =>

    {children}

    , - ul: ({ children }) =>
      {children}
    , - ol: ({ children }) =>
      {children}
    , - li: ({ children }) =>
  1. {children}
  2. , - strong: ({ children }) => {children}, - code: ({ children }) => {children}, - table: ({ children }) => {children}
    , - thead: ({ children }) => {children}, - tbody: ({ children }) => {children}, - tr: ({ children }) => {children}, - th: ({ children }) => {children}, - td: ({ children }) => {children}, - a: ({ children, href }) => ( - - {children} - - ), -}; - export function FloatingHoverModal({ href, children }) { const [isOpen, setIsOpen] = useState(false); @@ -151,9 +127,7 @@ export function FloatingHoverModal({ href, children }) {
    {ContentComponent ? ( - - - + ) : (

    Content Not Available

    From 0f15837c69deae48962304862cde8403d5fd9d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:17:50 -0800 Subject: [PATCH 150/162] fix: remove BrowserOnly wrapper from HeaderBadges to preserve React context chain HeaderBadges was wrapped in BrowserOnly which created a context boundary during hydration, breaking the DocsVersionProvider context for all doc pages. This caused 'Hook useDocsVersion is called outside provider' errors. Fixed by using useEffect to set href client-side while always rendering the same DOM structure, preventing hydration mismatches and preserving context. --- src/components/HeaderBadges/index.tsx | 42 +++++++++++++++------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/components/HeaderBadges/index.tsx b/src/components/HeaderBadges/index.tsx index 92aedce7ac..fb3f9695b4 100644 --- a/src/components/HeaderBadges/index.tsx +++ b/src/components/HeaderBadges/index.tsx @@ -1,25 +1,31 @@ import React from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; export const HeaderBadges = () => { + const [href, setHref] = React.useState(''); + + React.useEffect(() => { + // Client-side only: build the GitHub issue URL + const pathname = new URL(window.location.href).pathname; + const url = window.location.href; + setHref( + `https://github.com/OffchainLabs/arbitrum-docs/issues/new?title=Docs update request: ${pathname}&body=Source: ${url}%0A%0ARequest: (how can we help?)%0A%0APsst, this issue will be closed with a templated response if it isn't a documentation update request.`, + ); + }, []); + + // Always render the structure, just update href on client return ( - - {() => ( - - )} - + ); }; From 318b588d692f5ebbeb60bd8bbfe4751771f4f2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:18:05 -0800 Subject: [PATCH 151/162] fix: replace BrowserOnly with useEffect in GenerateTroubleshootingReportWidget The BrowserOnly callback had no return statement, causing hydration mismatches. Replaced with useEffect hook for proper side-effect handling. --- .../GenerateTroubleshootingReportWidget.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/GenerateTroubleshootingReportWidget.js b/src/components/GenerateTroubleshootingReportWidget.js index 8490afee01..799813f486 100644 --- a/src/components/GenerateTroubleshootingReportWidget.js +++ b/src/components/GenerateTroubleshootingReportWidget.js @@ -1,5 +1,4 @@ import React from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; export const GenerateTroubleshootingReportWidget = () => { let appendConfigDetailsToOutput = function (output) { @@ -87,11 +86,9 @@ export const GenerateTroubleshootingReportWidget = () => { }, 100); }; - return ( - - {() => { - bindButton(); - }} - - ); + React.useEffect(() => { + bindButton(); + }, []); + + return null; }; From c8edb76c28b8a1ebd09a3201ab8a2a3bd638d509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:18:12 -0800 Subject: [PATCH 152/162] fix: replace BrowserOnly with useEffect in MultiDimensionalContentWidget The BrowserOnly callback had no return statement, causing hydration mismatches. Replaced with useEffect hook for proper side-effect handling. --- src/components/MultiDimensionalContentWidget.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/MultiDimensionalContentWidget.js b/src/components/MultiDimensionalContentWidget.js index 3ae518ea84..0ad799bdbf 100644 --- a/src/components/MultiDimensionalContentWidget.js +++ b/src/components/MultiDimensionalContentWidget.js @@ -1,5 +1,4 @@ import React from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; export const MultiDimensionalContentWidget = () => { let getAllTabElements = function () { @@ -99,11 +98,9 @@ export const MultiDimensionalContentWidget = () => { }, 100); }; - return ( - - {() => { - bindTabs(); - }} - - ); + React.useEffect(() => { + bindTabs(); + }, []); + + return null; }; From 5ade58b4f8439207cbf9a6409485b3d300a3040f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:18:20 -0800 Subject: [PATCH 153/162] fix: remove MDXProvider wrapper from Timeboost Modal Pre-compiled MDX components don't need MDXProvider re-wrapping. Removed unnecessary wrapper and components object to prevent context chain interruption. --- .../Timeboost/CentralizedAuction/Modal.tsx | 41 +------------------ 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/src/components/InteractiveDiagrams/Timeboost/CentralizedAuction/Modal.tsx b/src/components/InteractiveDiagrams/Timeboost/CentralizedAuction/Modal.tsx index fe521afb9d..08108438c9 100644 --- a/src/components/InteractiveDiagrams/Timeboost/CentralizedAuction/Modal.tsx +++ b/src/components/InteractiveDiagrams/Timeboost/CentralizedAuction/Modal.tsx @@ -8,8 +8,6 @@ import step4Content from './modal-centralized-auction-step-4.mdx'; import step5Content from './modal-centralized-auction-step-5.mdx'; import { createPortal } from 'react-dom'; import { NumberComponent } from './NumberComponent'; -import { MDXProvider } from '@mdx-js/react'; -import type { MDXComponents } from '@mdx-js/react/lib'; import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter'; import { oneDark, oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import javascript from 'react-syntax-highlighter/dist/cjs/languages/prism/javascript'; @@ -25,41 +23,6 @@ interface CodeBlock { SyntaxHighlighter.registerLanguage('javascript', javascript); SyntaxHighlighter.registerLanguage('solidity', solidity); -const components = { - h1: ({ children }) =>

    {children}

    , - p: ({ children }) =>

    {children}

    , - ol: ({ children }) =>
      {children}
    , - li: ({ children }) =>
  3. {children}
  4. , - pre: ({ children }) => children, - code: ({ children, className }) => { - const language = className?.replace('language-', '') || 'text'; - - // Safe check for SSG - default to false when context is not available - let isDarkTheme = false; - try { - const colorMode = useColorMode(); - isDarkTheme = colorMode.isDarkTheme; - } catch (e) { - // During SSG, useColorMode throws an error - use default - } - - return ( - - {children} - - ); - }, -}; - export function Modal({ number }: { number: number }) { const [isOpen, setIsOpen] = useState(false); @@ -150,9 +113,7 @@ export function Modal({ number }: { number: number }) { - - - +
    ), From 36eeb9738065cf46598ca9dd0e1ac8117c791155 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:27:30 -0800 Subject: [PATCH 154/162] fix: remove sync-stylus-content script after submodule removal Removed reference to deleted sync-stylus-content.js script from package.json build command --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 480232ce9c..6897ab17e3 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,11 @@ "generate-precompiles-ref-tables": "tsx scripts/precompile-reference-generator.ts", "update-variable-refs": "tsx scripts/update-variable-references.ts", "prepare": "husky || true", - "start": "yarn clear && yarn sync-stylus-content && docusaurus start", + "start": "yarn clear && yarn docusaurus start", "generate-sdk-docs": "npx docusaurus generate-typedoc", - "sync-stylus-content": "node scripts/sync-stylus-content.js", "build-glossary": "tsx scripts/build-glossary.ts", "build-translation": "yarn tsx ./scripts/move-untranslated-files.ts", - "build": "yarn install-sdk-dependencies && yarn sync-stylus-content && docusaurus build", + "build": "yarn install-sdk-dependencies && docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", From 198b42747c4fa11d21df800121222ab5bdb23530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:44:15 -0800 Subject: [PATCH 155/162] chore: upgrade Docusaurus to 3.9.2 Upgraded from 3.6.3 to address potential context provider bugs --- package.json | 12 +- yarn.lock | 3197 +++++++++++++++++++++++++------------------------- 2 files changed, 1581 insertions(+), 1628 deletions(-) diff --git a/package.json b/package.json index 6897ab17e3..6b107f257e 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,11 @@ }, "dependencies": { "@arbitrum/sdk": "^3.0.0", - "@docusaurus/core": "^3.6.3", - "@docusaurus/preset-classic": "^3.6.3", - "@docusaurus/theme-common": "^3.6.3", - "@docusaurus/theme-live-codeblock": "^3.6.3", - "@docusaurus/theme-mermaid": "^3.6.3", + "@docusaurus/core": "^3.9.2", + "@docusaurus/preset-classic": "^3.9.2", + "@docusaurus/theme-common": "^3.9.2", + "@docusaurus/theme-live-codeblock": "^3.9.2", + "@docusaurus/theme-mermaid": "^3.9.2", "@ethersproject/address": "^5.7.0", "@floating-ui/react": "^0.27.15", "@inkeep/cxkit-docusaurus": "^0.5.91", @@ -75,7 +75,7 @@ "devDependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", - "@docusaurus/module-type-aliases": "^3.3.2", + "@docusaurus/module-type-aliases": "^3.9.2", "@offchainlabs/notion-docs-generator": "^0.1.0", "@offchainlabs/prettier-config": "0.2.1", "@tsconfig/docusaurus": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index da65ff6989..f798f1af15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -43,158 +43,191 @@ resolved "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz" integrity sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q== -"@algolia/autocomplete-core@1.9.3": - version "1.9.3" - resolved "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz" - integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== +"@ai-sdk/gateway@2.0.22": + version "2.0.22" + resolved "https://registry.yarnpkg.com/@ai-sdk/gateway/-/gateway-2.0.22.tgz#045ba030ad47728748efb60e213e9b1d6aa89ff6" + integrity sha512-6fHjDfCbjfj4vyMExuLei7ir2///E5sNwNZaobdJsJIxJjDSsjzSLGO/aUI7p9eOnB8XctDrDSF5ilwDGpi6eg== dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" - "@algolia/autocomplete-shared" "1.9.3" + "@ai-sdk/provider" "2.0.0" + "@ai-sdk/provider-utils" "3.0.19" + "@vercel/oidc" "3.0.5" -"@algolia/autocomplete-plugin-algolia-insights@1.9.3": - version "1.9.3" - resolved "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz" - integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== +"@ai-sdk/provider-utils@3.0.19": + version "3.0.19" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider-utils/-/provider-utils-3.0.19.tgz#065e4ffe287ec536b882fdcdff0bd38c250a4873" + integrity sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA== dependencies: - "@algolia/autocomplete-shared" "1.9.3" + "@ai-sdk/provider" "2.0.0" + "@standard-schema/spec" "^1.0.0" + eventsource-parser "^3.0.6" -"@algolia/autocomplete-preset-algolia@1.9.3": - version "1.9.3" - resolved "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz" - integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== +"@ai-sdk/provider@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider/-/provider-2.0.0.tgz#b853c739d523b33675bc74b6c506b2c690bc602b" + integrity sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA== dependencies: - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-shared@1.9.3": - version "1.9.3" - resolved "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz" - integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== + json-schema "^0.4.0" -"@algolia/cache-browser-local-storage@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.23.3.tgz" - integrity sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg== +"@ai-sdk/react@^2.0.30": + version "2.0.117" + resolved "https://registry.yarnpkg.com/@ai-sdk/react/-/react-2.0.117.tgz#383428aebacf899d61daa84031a1068465afac65" + integrity sha512-qfwz4p1ev+i/M9rsOUEe53UgzxMUz7e4wrImWdkuFrpD78MBIj53eE/LtyCeAYSCFVSz3JfIDvtdk5MjTrNcbA== dependencies: - "@algolia/cache-common" "4.23.3" + "@ai-sdk/provider-utils" "3.0.19" + ai "5.0.115" + swr "^2.2.5" + throttleit "2.1.0" -"@algolia/cache-common@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.23.3.tgz" - integrity sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A== +"@algolia/abtesting@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@algolia/abtesting/-/abtesting-1.12.1.tgz#180474d468b09edb8be25d62f61b3c498e3a7482" + integrity sha512-Y+7e2uPe376OH5O73OB1+vR40ZhbV2kzGh/AR/dPCWguoBOp1IK0o+uZQLX+7i32RMMBEKl3pj6KVEav100Kvg== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/autocomplete-core@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz#702df67a08cb3cfe8c33ee1111ef136ec1a9e232" + integrity sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.19.2" + "@algolia/autocomplete-shared" "1.19.2" + +"@algolia/autocomplete-plugin-algolia-insights@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz#3584b625b9317e333d1ae43664d02358e175c52d" + integrity sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg== + dependencies: + "@algolia/autocomplete-shared" "1.19.2" + +"@algolia/autocomplete-shared@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz#c0b7b8dc30a5c65b70501640e62b009535e4578f" + integrity sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w== + +"@algolia/client-abtesting@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.46.1.tgz#5682c0e6cd14b97b9f0de3bbd3b29b651d41b650" + integrity sha512-5SWfl0UGuKxMBYlU2Y9BnlIKKEyhFU5jHE9F9jAd8nbhxZNLk0y7fXE+AZeFtyK1lkVw6O4B/e6c3XIVVCkmqw== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/client-analytics@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.46.1.tgz#3db582ad78bed7c98ed72ddff440c0d5eb09d4fe" + integrity sha512-496K6B1l/0Jvyp3MbW/YIgmm1a6nkTrKXBM7DoEy9YAOJ8GywGpa2UYjNCW1UrOTt+em1ECzDjRx7PIzTR9YvA== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/client-common@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.46.1.tgz#e6b2604e8e9f674a90d0155cbe93111fbb5e6f52" + integrity sha512-3u6AuZ1Kiss6V5JPuZfVIUYfPi8im06QBCgKqLg82GUBJ3SwhiTdSZFIEgz2mzFuitFdW1PQi3c/65zE/3FgIw== + +"@algolia/client-insights@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.46.1.tgz#0d8d20890cf7e962422da19606e1038cab3de591" + integrity sha512-LwuWjdO35HHl1rxtdn48t920Xl26Dl0SMxjxjFeAK/OwK/pIVfYjOZl/f3Pnm7Kixze+6HjpByVxEaqhTuAFaw== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/client-personalization@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.46.1.tgz#46f686159967f45bff2041ce081bcdd078f04365" + integrity sha512-6LvJAlfEsn9SVq63MYAFX2iUxztUK2Q7BVZtI1vN87lDiJ/tSVFKgKS/jBVO03A39ePxJQiFv6EKv7lmoGlWtQ== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/client-query-suggestions@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.1.tgz#b2ab960012b72473d9b8b80cf7021d8292fde2c4" + integrity sha512-9GLUCyGGo7YOXHcNqbzca82XYHJTbuiI6iT0FTGc0BrnV2N4OcrznUuVKic/duiLSun5gcy/G2Bciw5Sav9f9w== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" + +"@algolia/client-search@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.46.1.tgz#8c41371a2351080ae2cb3473fd26c572d8d077aa" + integrity sha512-NL76o/BoEgU4ObY5oBEC3o6KSPpuXsnSta00tAxTm1iKUWOGR34DQEKhUt8xMHhMKleUNPM/rLPFiIVtfsGU8w== + dependencies: + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" -"@algolia/cache-in-memory@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.23.3.tgz" - integrity sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg== - dependencies: - "@algolia/cache-common" "4.23.3" +"@algolia/events@^4.0.1": + version "4.0.1" + resolved "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz" + integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== -"@algolia/client-account@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.23.3.tgz" - integrity sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA== +"@algolia/ingestion@1.46.1": + version "1.46.1" + resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.46.1.tgz#f0a5e9517784be36411866b2093d1cc6e87b6dbd" + integrity sha512-52Nc8WKC1FFXsdlXlTMl1Re/pTAbd2DiJiNdYmgHiikZcfF96G+Opx4qKiLUG1q7zp9e+ahNwXF6ED0XChMywg== dependencies: - "@algolia/client-common" "4.23.3" - "@algolia/client-search" "4.23.3" - "@algolia/transporter" "4.23.3" + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" -"@algolia/client-analytics@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.23.3.tgz" - integrity sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA== +"@algolia/monitoring@1.46.1": + version "1.46.1" + resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.46.1.tgz#3883c6ef5807e865aaaf5d239055f5b257dcafb0" + integrity sha512-1x2/2Y/eqz6l3QcEZ8u/zMhSCpjlhePyizJd3sXrmg031HjayYT5+IxikjpqkdF7TU/deCTd/TFUcxLJ2ZHXiQ== dependencies: - "@algolia/client-common" "4.23.3" - "@algolia/client-search" "4.23.3" - "@algolia/requester-common" "4.23.3" - "@algolia/transporter" "4.23.3" + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" -"@algolia/client-common@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.23.3.tgz" - integrity sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw== +"@algolia/recommend@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.46.1.tgz#f47050a465b5b9b8491becaa850b4ce772eef090" + integrity sha512-SSd3KlQuplxV3aRs5+Z09XilFesgpPjtCG7BGRxLTVje5hn9BLmhjO4W3gKw01INUt44Z1r0Fwx5uqnhAouunA== dependencies: - "@algolia/requester-common" "4.23.3" - "@algolia/transporter" "4.23.3" + "@algolia/client-common" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" -"@algolia/client-personalization@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.23.3.tgz" - integrity sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g== +"@algolia/requester-browser-xhr@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.1.tgz#b22946a4f4ffee6ccbbbddc89ba404065db299be" + integrity sha512-3GfCwudeW6/3caKSdmOP6RXZEL4F3GiemCaXEStkTt2Re8f7NcGYAAZnGlHsCzvhlNEuDzPYdYxh4UweY8l/2w== dependencies: - "@algolia/client-common" "4.23.3" - "@algolia/requester-common" "4.23.3" - "@algolia/transporter" "4.23.3" + "@algolia/client-common" "5.46.1" -"@algolia/client-search@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.23.3.tgz" - integrity sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw== +"@algolia/requester-fetch@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.46.1.tgz#eaaad8935b416d2e4889b6a50524d8d58979188d" + integrity sha512-JUAxYfmnLYTVtAOFxVvXJ4GDHIhMuaP7JGyZXa/nCk3P8RrN5FCNTdRyftSnxyzwSIAd8qH3CjdBS9WwxxqcHQ== dependencies: - "@algolia/client-common" "4.23.3" - "@algolia/requester-common" "4.23.3" - "@algolia/transporter" "4.23.3" + "@algolia/client-common" "5.46.1" -"@algolia/events@^4.0.1": - version "4.0.1" - resolved "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz" - integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== - -"@algolia/logger-common@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.23.3.tgz" - integrity sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g== - -"@algolia/logger-console@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.23.3.tgz" - integrity sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A== - dependencies: - "@algolia/logger-common" "4.23.3" - -"@algolia/recommend@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.23.3.tgz" - integrity sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w== - dependencies: - "@algolia/cache-browser-local-storage" "4.23.3" - "@algolia/cache-common" "4.23.3" - "@algolia/cache-in-memory" "4.23.3" - "@algolia/client-common" "4.23.3" - "@algolia/client-search" "4.23.3" - "@algolia/logger-common" "4.23.3" - "@algolia/logger-console" "4.23.3" - "@algolia/requester-browser-xhr" "4.23.3" - "@algolia/requester-common" "4.23.3" - "@algolia/requester-node-http" "4.23.3" - "@algolia/transporter" "4.23.3" - -"@algolia/requester-browser-xhr@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.23.3.tgz" - integrity sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw== - dependencies: - "@algolia/requester-common" "4.23.3" - -"@algolia/requester-common@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.23.3.tgz" - integrity sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw== - -"@algolia/requester-node-http@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.23.3.tgz" - integrity sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA== - dependencies: - "@algolia/requester-common" "4.23.3" - -"@algolia/transporter@4.23.3": - version "4.23.3" - resolved "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.23.3.tgz" - integrity sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ== - dependencies: - "@algolia/cache-common" "4.23.3" - "@algolia/logger-common" "4.23.3" - "@algolia/requester-common" "4.23.3" +"@algolia/requester-node-http@5.46.1": + version "5.46.1" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.46.1.tgz#ea2399481671c5401f0493628367d3cd43c0ab7f" + integrity sha512-VwbhV1xvTGiek3d2pOS6vNBC4dtbNadyRT+i1niZpGhOJWz1XnfhxNboVbXPGAyMJYz7kDrolbDvEzIDT93uUA== + dependencies: + "@algolia/client-common" "5.46.1" "@ampproject/remapping@^2.2.0": version "2.3.0" @@ -204,18 +237,13 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@antfu/install-pkg@^0.4.1": - version "0.4.1" - resolved "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz" - integrity sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw== +"@antfu/install-pkg@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@antfu/install-pkg/-/install-pkg-1.1.0.tgz#78fa036be1a6081b5a77a5cf59f50c7752b6ba26" + integrity sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ== dependencies: - package-manager-detector "^0.2.0" - tinyexec "^0.3.0" - -"@antfu/utils@^0.7.10": - version "0.7.10" - resolved "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz" - integrity sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww== + package-manager-detector "^1.3.0" + tinyexec "^1.0.1" "@arbitrum/sdk@^3.0.0": version "3.4.0" @@ -228,7 +256,7 @@ async-mutex "^0.4.0" ethers "^5.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2": version "7.24.2" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz" integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== @@ -2114,10 +2142,10 @@ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783" integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== -"@braintree/sanitize-url@^7.0.1": - version "7.1.0" - resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz" - integrity sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg== +"@braintree/sanitize-url@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz#15e19737d946559289b915e5dad3b4c28407735e" + integrity sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw== "@chevrotain/cst-dts-gen@11.0.3": version "11.0.3" @@ -2156,92 +2184,136 @@ resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@csstools/cascade-layer-name-parser@^2.0.4": - version "2.0.4" - resolved "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.4.tgz" - integrity sha512-7DFHlPuIxviKYZrOiwVU/PiHLm3lLUR23OMuEEtfEOQTOp9hzQ2JjdY6X5H18RVuUPJqSCI+qNnD5iOLMVE0bA== +"@csstools/cascade-layer-name-parser@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz#43f962bebead0052a9fed1a2deeb11f85efcbc72" + integrity sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A== -"@csstools/color-helpers@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz" - integrity sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA== +"@csstools/color-helpers@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz#106c54c808cabfd1ab4c602d8505ee584c2996ef" + integrity sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA== -"@csstools/css-calc@^2.1.0": - version "2.1.0" - resolved "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.0.tgz" - integrity sha512-X69PmFOrjTZfN5ijxtI8hZ9kRADFSLrmmQ6hgDJ272Il049WGKpDY64KhrFm/7rbWve0z81QepawzjkKlqkNGw== +"@csstools/css-calc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.4.tgz#8473f63e2fcd6e459838dd412401d5948f224c65" + integrity sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== -"@csstools/css-color-parser@^3.0.6": - version "3.0.6" - resolved "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.6.tgz" - integrity sha512-S/IjXqTHdpI4EtzGoNCHfqraXF37x12ZZHA1Lk7zoT5pm2lMjFuqhX/89L7dqX4CcMacKK+6ZCs5TmEGb/+wKw== +"@csstools/css-color-parser@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz#4e386af3a99dd36c46fef013cfe4c1c341eed6f0" + integrity sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA== dependencies: - "@csstools/color-helpers" "^5.0.1" - "@csstools/css-calc" "^2.1.0" + "@csstools/color-helpers" "^5.1.0" + "@csstools/css-calc" "^2.1.4" + +"@csstools/css-parser-algorithms@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076" + integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== -"@csstools/css-parser-algorithms@^3.0.4": +"@csstools/css-tokenizer@^3.0.4": version "3.0.4" - resolved "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz" - integrity sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A== + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3" + integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== -"@csstools/css-tokenizer@^3.0.3": - version "3.0.3" - resolved "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz" - integrity sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw== +"@csstools/media-query-list-parser@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz#7aec77bcb89c2da80ef207e73f474ef9e1b3cdf1" + integrity sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ== -"@csstools/media-query-list-parser@^4.0.2": - version "4.0.2" - resolved "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz" - integrity sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A== +"@csstools/postcss-alpha-function@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz#7989605711de7831bc7cd75b94c9b5bac9c3728e" + integrity sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" -"@csstools/postcss-cascade-layers@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.1.tgz" - integrity sha512-XOfhI7GShVcKiKwmPAnWSqd2tBR0uxt+runAxttbSp/LY2U16yAVPmAf7e9q4JJ0d+xMNmpwNDLBXnmRCl3HMQ== +"@csstools/postcss-cascade-layers@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz#dd2c70db3867b88975f2922da3bfbae7d7a2cae7" + integrity sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg== dependencies: "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" -"@csstools/postcss-color-function@^4.0.6": - version "4.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.6.tgz" - integrity sha512-EcvXfC60cTIumzpsxWuvVjb7rsJEHPvqn3jeMEBUaE3JSc4FRuP7mEQ+1eicxWmIrs3FtzMH9gR3sgA5TH+ebQ== +"@csstools/postcss-color-function-display-p3-linear@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz#3017ff5e1f65307d6083e58e93d76724fb1ebf9f" + integrity sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-color-mix-function@^3.0.6": - version "3.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.6.tgz" - integrity sha512-jVKdJn4+JkASYGhyPO+Wa5WXSx1+oUgaXb3JsjJn/BlrtFh5zjocCY7pwWi0nuP24V1fY7glQsxEYcYNy0dMFg== +"@csstools/postcss-color-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz#a7c85a98c77b522a194a1bbb00dd207f40c7a771" + integrity sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-content-alt-text@^2.0.4": - version "2.0.4" - resolved "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.4.tgz" - integrity sha512-YItlZUOuZJCBlRaCf8Aucc1lgN41qYGALMly0qQllrxYJhiyzlI6RxOTMUvtWk+KhS8GphMDsDhKQ7KTPfEMSw== +"@csstools/postcss-color-mix-function@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz#2f1ee9f8208077af069545c9bd79bb9733382c2a" + integrity sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-exponential-functions@^2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.5.tgz" - integrity sha512-mi8R6dVfA2nDoKM3wcEi64I8vOYEgQVtVKCfmLHXupeLpACfGAided5ddMt5f+CnEodNu4DifuVwb0I6fQDGGQ== +"@csstools/postcss-color-mix-variadic-function-arguments@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz#b4012b62a4eaa24d694172bb7137f9d2319cb8f2" + integrity sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-content-alt-text@^2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz#1d52da1762893c32999ff76839e48d6ec7c7a4cb" + integrity sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-contrast-color-function@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz#ca46986d095c60f208d9e3f24704d199c9172637" + integrity sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-exponential-functions@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz#fc03d1272888cb77e64cc1a7d8a33016e4f05c69" + integrity sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw== + dependencies: + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/postcss-font-format-keywords@^4.0.0": version "4.0.0" @@ -2251,67 +2323,67 @@ "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-gamut-mapping@^2.0.6": - version "2.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.6.tgz" - integrity sha512-0ke7fmXfc8H+kysZz246yjirAH6JFhyX9GTlyRnM0exHO80XcA9zeJpy5pOp5zo/AZiC/q5Pf+Hw7Pd6/uAoYA== - dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - -"@csstools/postcss-gradients-interpolation-method@^5.0.6": - version "5.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.6.tgz" - integrity sha512-Itrbx6SLUzsZ6Mz3VuOlxhbfuyLTogG5DwEF1V8dAi24iMuvQPIHd7Ti+pNDp7j6WixndJGZaoNR0f9VSzwuTg== - dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" +"@csstools/postcss-gamut-mapping@^2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz#be0e34c9f0142852cccfc02b917511f0d677db8b" + integrity sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + +"@csstools/postcss-gradients-interpolation-method@^5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz#0955cce4d97203b861bf66742bbec611b2f3661c" + integrity sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-hwb-function@^4.0.6": - version "4.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.6.tgz" - integrity sha512-927Pqy3a1uBP7U8sTfaNdZVB0mNXzIrJO/GZ8us9219q9n06gOqCdfZ0E6d1P66Fm0fYHvxfDbfcUuwAn5UwhQ== +"@csstools/postcss-hwb-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz#07f7ecb08c50e094673bd20eaf7757db0162beee" + integrity sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-ic-unit@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.0.tgz" - integrity sha512-9QT5TDGgx7wD3EEMN3BSUG6ckb6Eh5gSPT5kZoVtUuAonfPmLDJyPhqR4ntPpMYhUKAMVKAg3I/AgzqHMSeLhA== +"@csstools/postcss-ic-unit@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz#2ee2da0690db7edfbc469279711b9e69495659d2" + integrity sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg== dependencies: - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-initial@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.0.tgz" - integrity sha512-dv2lNUKR+JV+OOhZm9paWzYBXOCi+rJPqJ2cJuhh9xd8USVrd0cBEPczla81HNOyThMQWeCcdln3gZkQV2kYxA== +"@csstools/postcss-initial@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz#c385bd9d8ad31ad159edd7992069e97ceea4d09a" + integrity sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg== -"@csstools/postcss-is-pseudo-class@^5.0.1": - version "5.0.1" - resolved "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.1.tgz" - integrity sha512-JLp3POui4S1auhDR0n8wHd/zTOWmMsmK3nQd3hhL6FhWPaox5W7j1se6zXOG/aP07wV2ww0lxbKYGwbBszOtfQ== +"@csstools/postcss-is-pseudo-class@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz#d34e850bcad4013c2ed7abe948bfa0448aa8eb74" + integrity sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ== dependencies: "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" -"@csstools/postcss-light-dark-function@^2.0.7": - version "2.0.7" - resolved "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.7.tgz" - integrity sha512-ZZ0rwlanYKOHekyIPaU+sVm3BEHCe+Ha0/px+bmHe62n0Uc1lL34vbwrLYn6ote8PHlsqzKeTQdIejQCJ05tfw== +"@csstools/postcss-light-dark-function@^2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz#0df448aab9a33cb9a085264ff1f396fb80c4437d" + integrity sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" "@csstools/postcss-logical-float-and-clear@^3.0.0": @@ -2336,32 +2408,32 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-logical-viewport-units@^3.0.3": - version "3.0.3" - resolved "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.3.tgz" - integrity sha512-OC1IlG/yoGJdi0Y+7duz/kU/beCwO+Gua01sD6GtOtLi7ByQUpcIqs7UE/xuRPay4cHgOMatWdnDdsIDjnWpPw== +"@csstools/postcss-logical-viewport-units@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz#016d98a8b7b5f969e58eb8413447eb801add16fc" + integrity sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ== dependencies: - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-media-minmax@^2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.5.tgz" - integrity sha512-sdh5i5GToZOIAiwhdntRWv77QDtsxP2r2gXW/WbLSCoLr00KTq/yiF1qlQ5XX2+lmiFa8rATKMcbwl3oXDMNew== +"@csstools/postcss-media-minmax@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz#184252d5b93155ae526689328af6bdf3fc113987" + integrity sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" -"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.4": - version "3.0.4" - resolved "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.4.tgz" - integrity sha512-AnGjVslHMm5xw9keusQYvjVWvuS7KWK+OJagaG0+m9QnIjZsrysD2kJP/tr/UJIyYtMCtu8OkUd+Rajb4DqtIQ== +"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz#f485c31ec13d6b0fb5c528a3474334a40eff5f11" + integrity sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg== dependencies: - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" "@csstools/postcss-nested-calc@^4.0.0": version "4.0.0" @@ -2378,42 +2450,47 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-oklab-function@^4.0.6": - version "4.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.6.tgz" - integrity sha512-Hptoa0uX+XsNacFBCIQKTUBrFKDiplHan42X73EklG6XmQLG7/aIvxoNhvZ7PvOWMt67Pw3bIlUY2nD6p5vL8A== +"@csstools/postcss-oklab-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz#416640ef10227eea1375b47b72d141495950971d" + integrity sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -"@csstools/postcss-progressive-custom-properties@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.0.0.tgz" - integrity sha512-XQPtROaQjomnvLUSy/bALTR5VCtTVUFwYs1SblvYgLSeTo2a/bMNwUwo2piXw5rTv/FEYiy5yPSXBqg9OKUx7Q== - dependencies: - postcss-value-parser "^4.2.0" +"@csstools/postcss-position-area-property@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-position-area-property/-/postcss-position-area-property-1.0.0.tgz#41f0cbc737a81a42890d5ec035fa26a45f4f4ad4" + integrity sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q== -"@csstools/postcss-random-function@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-1.0.1.tgz" - integrity sha512-Ab/tF8/RXktQlFwVhiC70UNfpFQRhtE5fQQoP2pO+KCPGLsLdWFiOuHgSRtBOqEshCVAzR4H6o38nhvRZq8deA== +"@csstools/postcss-progressive-custom-properties@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz#c39780b9ff0d554efb842b6bd75276aa6f1705db" + integrity sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + postcss-value-parser "^4.2.0" -"@csstools/postcss-relative-color-syntax@^3.0.6": - version "3.0.6" - resolved "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.6.tgz" - integrity sha512-yxP618Xb+ji1I624jILaYM62uEmZcmbdmFoZHoaThw896sq0vU39kqTTF+ZNic9XyPtPMvq0vyvbgmHaszq8xg== - dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" +"@csstools/postcss-random-function@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz#3191f32fe72936e361dadf7dbfb55a0209e2691e" + integrity sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w== + dependencies: + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + +"@csstools/postcss-relative-color-syntax@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz#ced792450102441f7c160e1d106f33e4b44181f8" + integrity sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" "@csstools/postcss-scope-pseudo-class@^4.0.1": @@ -2423,50 +2500,58 @@ dependencies: postcss-selector-parser "^7.0.0" -"@csstools/postcss-sign-functions@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.0.tgz" - integrity sha512-SLcc20Nujx/kqbSwDmj6oaXgpy3UjFhBy1sfcqPgDkHfOIfUtUVH7OXO+j7BU4v/At5s61N5ZX6shvgPwluhsA== +"@csstools/postcss-sign-functions@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz#a9ac56954014ae4c513475b3f1b3e3424a1e0c12" + integrity sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@csstools/postcss-stepped-value-functions@^4.0.5": - version "4.0.5" - resolved "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.5.tgz" - integrity sha512-G6SJ6hZJkhxo6UZojVlLo14MohH4J5J7z8CRBrxxUYy9JuZiIqUo5TBYyDGcE0PLdzpg63a7mHSJz3VD+gMwqw== +"@csstools/postcss-stepped-value-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz#36036f1a0e5e5ee2308e72f3c9cb433567c387b9" + integrity sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@csstools/postcss-text-decoration-shorthand@^4.0.1": - version "4.0.1" - resolved "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.1.tgz" - integrity sha512-xPZIikbx6jyzWvhms27uugIc0I4ykH4keRvoa3rxX5K7lEhkbd54rjj/dv60qOCTisoS+3bmwJTeyV1VNBrXaw== +"@csstools/postcss-system-ui-font-family@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-system-ui-font-family/-/postcss-system-ui-font-family-1.0.0.tgz#bd65b79078debf6f67b318dc9b71a8f9fa16f8c8" + integrity sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ== dependencies: - "@csstools/color-helpers" "^5.0.1" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + +"@csstools/postcss-text-decoration-shorthand@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz#fae1b70f07d1b7beb4c841c86d69e41ecc6f743c" + integrity sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA== + dependencies: + "@csstools/color-helpers" "^5.1.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-trigonometric-functions@^4.0.5": - version "4.0.5" - resolved "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.5.tgz" - integrity sha512-/YQThYkt5MLvAmVu7zxjhceCYlKrYddK6LEmK5I4ojlS6BmO9u2yO4+xjXzu2+NPYmHSTtP4NFSamBCMmJ1NJA== +"@csstools/postcss-trigonometric-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz#3f94ed2e319b57f2c59720b64e4d0a8a6fb8c3b2" + integrity sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A== dependencies: - "@csstools/css-calc" "^2.1.0" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/postcss-unset-value@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz" integrity sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA== -"@csstools/selector-resolve-nested@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz" - integrity sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ== +"@csstools/selector-resolve-nested@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz#848c6f44cb65e3733e478319b9342b7aa436fac7" + integrity sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g== "@csstools/selector-specificity@^5.0.0": version "5.0.0" @@ -2483,25 +2568,34 @@ resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@docsearch/css@3.6.0": - version "3.6.0" - resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.6.0.tgz" - integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ== +"@docsearch/core@4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@docsearch/core/-/core-4.3.1.tgz#88a97a6fe4d4025269b6dee8b9d070b76758ad82" + integrity sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ== -"@docsearch/react@^3.5.2": - version "3.6.0" - resolved "https://registry.npmjs.org/@docsearch/react/-/react-3.6.0.tgz" - integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w== - dependencies: - "@algolia/autocomplete-core" "1.9.3" - "@algolia/autocomplete-preset-algolia" "1.9.3" - "@docsearch/css" "3.6.0" - algoliasearch "^4.19.1" +"@docsearch/css@4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-4.3.2.tgz#d47d25336c9516b419245fa74e8dd5ae84a17492" + integrity sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ== -"@docusaurus/babel@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.3.tgz" - integrity sha512-7dW9Hat9EHYCVicFXYA4hjxBY38+hPuCURL8oRF9fySRm7vzNWuEOghA1TXcykuXZp0HLG2td4RhDxCvGG7tNw== +"@docsearch/react@^3.9.0 || ^4.1.0": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-4.3.2.tgz#450b8341cb5cca03737a00075d4dfd3a904a3e3e" + integrity sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ== + dependencies: + "@ai-sdk/react" "^2.0.30" + "@algolia/autocomplete-core" "1.19.2" + "@docsearch/core" "4.3.1" + "@docsearch/css" "4.3.2" + ai "^5.0.30" + algoliasearch "^5.28.0" + marked "^16.3.0" + zod "^4.1.8" + +"@docusaurus/babel@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.9.2.tgz#f956c638baeccf2040e482c71a742bc7e35fdb22" + integrity sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA== dependencies: "@babel/core" "^7.25.9" "@babel/generator" "^7.25.9" @@ -2513,55 +2607,54 @@ "@babel/runtime" "^7.25.9" "@babel/runtime-corejs3" "^7.25.9" "@babel/traverse" "^7.25.9" - "@docusaurus/logger" "3.6.3" - "@docusaurus/utils" "3.6.3" + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" babel-plugin-dynamic-import-node "^2.3.3" fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/bundler@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.3.tgz" - integrity sha512-47JLuc8D4wA+6VOvmMd5fUC9rFppBQpQOnxDYiVXffm/DeV/wmm3sbpNd5Y+O+G2+nevLTRnvCm/qyancv0Y3A== +"@docusaurus/bundler@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.9.2.tgz#0ca82cda4acf13a493e3f66061aea351e9d356cf" + integrity sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA== dependencies: "@babel/core" "^7.25.9" - "@docusaurus/babel" "3.6.3" - "@docusaurus/cssnano-preset" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" + "@docusaurus/babel" "3.9.2" + "@docusaurus/cssnano-preset" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" babel-loader "^9.2.1" - clean-css "^5.3.2" + clean-css "^5.3.3" copy-webpack-plugin "^11.0.0" - css-loader "^6.8.1" + css-loader "^6.11.0" css-minimizer-webpack-plugin "^5.0.1" cssnano "^6.1.2" file-loader "^6.2.0" html-minifier-terser "^7.2.0" - mini-css-extract-plugin "^2.9.1" + mini-css-extract-plugin "^2.9.2" null-loader "^4.0.1" - postcss "^8.4.26" - postcss-loader "^7.3.3" - postcss-preset-env "^10.1.0" - react-dev-utils "^12.0.1" + postcss "^8.5.4" + postcss-loader "^7.3.4" + postcss-preset-env "^10.2.1" terser-webpack-plugin "^5.3.9" tslib "^2.6.0" url-loader "^4.1.1" webpack "^5.95.0" webpackbar "^6.0.1" -"@docusaurus/core@3.6.3", "@docusaurus/core@^3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.3.tgz" - integrity sha512-xL7FRY9Jr5DWqB6pEnqgKqcMPJOX5V0pgWXi5lCiih11sUBmcFKM7c3+GyxcVeeWFxyYSDP3grLTWqJoP4P9Vw== - dependencies: - "@docusaurus/babel" "3.6.3" - "@docusaurus/bundler" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" +"@docusaurus/core@3.9.2", "@docusaurus/core@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.9.2.tgz#cc970f29b85a8926d63c84f8cffdcda43ed266ff" + integrity sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw== + dependencies: + "@docusaurus/babel" "3.9.2" + "@docusaurus/bundler" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" boxen "^6.2.1" chalk "^4.1.2" chokidar "^3.5.3" @@ -2569,100 +2662,61 @@ combine-promises "^1.1.0" commander "^5.1.0" core-js "^3.31.1" - del "^6.1.1" detect-port "^1.5.1" escape-html "^1.0.3" eta "^2.2.0" eval "^0.1.8" + execa "5.1.1" fs-extra "^11.1.1" html-tags "^3.3.1" html-webpack-plugin "^5.6.0" leven "^3.1.0" lodash "^4.17.21" + open "^8.4.0" p-map "^4.0.0" prompts "^2.4.2" - react-dev-utils "^12.0.1" - react-helmet-async "^1.3.0" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber "^1.0.1" react-router "^5.3.4" react-router-config "^5.1.1" react-router-dom "^5.3.4" - rtl-detect "^1.0.4" semver "^7.5.4" serve-handler "^6.1.6" - shelljs "^0.8.5" + tinypool "^1.0.2" tslib "^2.6.0" update-notifier "^6.0.2" webpack "^5.95.0" webpack-bundle-analyzer "^4.10.2" - webpack-dev-server "^4.15.2" + webpack-dev-server "^5.2.2" webpack-merge "^6.0.1" -"@docusaurus/cssnano-preset@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.3.tgz" - integrity sha512-qP7SXrwZ+23GFJdPN4aIHQrZW+oH/7tzwEuc/RNL0+BdZdmIjYQqUxdXsjE4lFxLNZjj0eUrSNYIS6xwfij+5Q== +"@docusaurus/cssnano-preset@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz#523aab65349db3c51a77f2489048d28527759428" + integrity sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ== dependencies: cssnano-preset-advanced "^6.1.2" - postcss "^8.4.38" + postcss "^8.5.4" postcss-sort-media-queries "^5.2.0" tslib "^2.6.0" -"@docusaurus/logger@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.3.tgz" - integrity sha512-xSubJixcNyMV9wMV4q0s47CBz3Rlc5jbcCCuij8pfQP8qn/DIpt0ks8W6hQWzHAedg/J/EwxxUOUrnEoKzJo8g== +"@docusaurus/logger@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.9.2.tgz#6ec6364b90f5a618a438cc9fd01ac7376869f92a" + integrity sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA== dependencies: chalk "^4.1.2" tslib "^2.6.0" -"@docusaurus/logger@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.8.1.tgz#45321b2e2e14695d0dbd8b4104ea7b0fbaa98700" - integrity sha512-2wjeGDhKcExEmjX8k1N/MRDiPKXGF2Pg+df/bDDPnnJWHXnVEZxXj80d6jcxp1Gpnksl0hF8t/ZQw9elqj2+ww== - dependencies: - chalk "^4.1.2" - tslib "^2.6.0" - -"@docusaurus/mdx-loader@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.3.tgz" - integrity sha512-3iJdiDz9540ppBseeI93tWTDtUGVkxzh59nMq4ignylxMuXBLK8dFqVeaEor23v1vx6TrGKZ2FuLaTB+U7C0QQ== - dependencies: - "@docusaurus/logger" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" - "@mdx-js/mdx" "^3.0.0" - "@slorber/remark-comment" "^1.0.0" - escape-html "^1.0.3" - estree-util-value-to-estree "^3.0.1" - file-loader "^6.2.0" - fs-extra "^11.1.1" - image-size "^1.0.2" - mdast-util-mdx "^3.0.0" - mdast-util-to-string "^4.0.0" - rehype-raw "^7.0.0" - remark-directive "^3.0.0" - remark-emoji "^4.0.0" - remark-frontmatter "^5.0.0" - remark-gfm "^4.0.0" - stringify-object "^3.3.0" - tslib "^2.6.0" - unified "^11.0.3" - unist-util-visit "^5.0.0" - url-loader "^4.1.1" - vfile "^6.0.1" - webpack "^5.88.1" - -"@docusaurus/mdx-loader@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.8.1.tgz#74309b3614bbcef1d55fb13e6cc339b7fb000b5f" - integrity sha512-DZRhagSFRcEq1cUtBMo4TKxSNo/W6/s44yhr8X+eoXqCLycFQUylebOMPseHi5tc4fkGJqwqpWJLz6JStU9L4w== +"@docusaurus/mdx-loader@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz#78d238de6c6203fa811cc2a7e90b9b79e111408c" + integrity sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ== dependencies: - "@docusaurus/logger" "3.8.1" - "@docusaurus/utils" "3.8.1" - "@docusaurus/utils-validation" "3.8.1" + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" "@mdx-js/mdx" "^3.0.0" "@slorber/remark-comment" "^1.0.0" escape-html "^1.0.3" @@ -2685,25 +2739,12 @@ vfile "^6.0.1" webpack "^5.88.1" -"@docusaurus/module-type-aliases@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.3.tgz" - integrity sha512-MjaXX9PN/k5ugNvfRZdWyKWq4FsrhN4LEXaj0pEmMebJuBNlFeGyKQUa9DRhJHpadNaiMLrbo9m3U7Ig5YlsZg== - dependencies: - "@docusaurus/types" "3.6.3" - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router-config" "*" - "@types/react-router-dom" "*" - react-helmet-async "*" - react-loadable "npm:@docusaurus/react-loadable@6.0.0" - -"@docusaurus/module-type-aliases@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.8.1.tgz#454de577bd7f50b5eae16db0f76b49ca5e4e281a" - integrity sha512-6xhvAJiXzsaq3JdosS7wbRt/PwEPWHr9eM4YNYqVlbgG1hSK3uQDXTVvQktasp3VO6BmfYWPozueLWuj4gB+vg== +"@docusaurus/module-type-aliases@3.9.2", "@docusaurus/module-type-aliases@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz#993c7cb0114363dea5ef6855e989b3ad4b843a34" + integrity sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew== dependencies: - "@docusaurus/types" "3.8.1" + "@docusaurus/types" "3.9.2" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -2711,182 +2752,196 @@ react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" react-loadable "npm:@docusaurus/react-loadable@6.0.0" -"@docusaurus/module-type-aliases@^3.3.2": - version "3.3.2" - resolved "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.3.2.tgz" - integrity sha512-b/XB0TBJah5yKb4LYuJT4buFvL0MGAb0+vJDrJtlYMguRtsEBkf2nWl5xP7h4Dlw6ol0hsHrCYzJ50kNIOEclw== - dependencies: - "@docusaurus/types" "3.3.2" - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router-config" "*" - "@types/react-router-dom" "*" - react-helmet-async "*" - react-loadable "npm:@docusaurus/react-loadable@6.0.0" - -"@docusaurus/plugin-content-blog@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.3.tgz" - integrity sha512-k0ogWwwJU3pFRFfvW1kRVHxzf2DutLGaaLjAnHVEU6ju+aRP0Z5ap/13DHyPOfHeE4WKpn/M0TqjdwZAcY3kAw== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" +"@docusaurus/plugin-content-blog@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz#d5ce51eb7757bdab0515e2dd26a793ed4e119df9" + integrity sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" cheerio "1.0.0-rc.12" feed "^4.2.2" fs-extra "^11.1.1" lodash "^4.17.21" - reading-time "^1.5.0" + schema-dts "^1.1.2" srcset "^4.0.0" tslib "^2.6.0" unist-util-visit "^5.0.0" utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-docs@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.3.tgz" - integrity sha512-r2wS8y/fsaDcxkm20W5bbYJFPzdWdEaTWVYjNxlHlcmX086eqQR1Fomlg9BHTJ0dLXPzAlbC8EN4XqMr3QzNCQ== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/module-type-aliases" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" +"@docusaurus/plugin-content-docs@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz#cd8f2d1c06e53c3fa3d24bdfcb48d237bf2d6b2e" + integrity sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" "@types/react-router-config" "^5.0.7" combine-promises "^1.1.0" fs-extra "^11.1.1" js-yaml "^4.1.0" lodash "^4.17.21" + schema-dts "^1.1.2" tslib "^2.6.0" utility-types "^3.10.0" webpack "^5.88.1" -"@docusaurus/plugin-content-pages@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.3.tgz" - integrity sha512-eHrmTgjgLZsuqfsYr5X2xEwyIcck0wseSofWrjTwT9FLOWp+KDmMAuVK+wRo7sFImWXZk3oV/xX/g9aZrhD7OA== +"@docusaurus/plugin-content-pages@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz#22db6c88ade91cec0a9e87a00b8089898051b08d" + integrity sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" fs-extra "^11.1.1" tslib "^2.6.0" webpack "^5.88.1" -"@docusaurus/plugin-debug@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.3.tgz" - integrity sha512-zB9GXfIZNPRfzKnNjU6xGVrqn9bPXuGhpjgsuc/YtcTDjnjhasg38NdYd5LEqXex5G/zIorQgWB3n6x/Ut62vQ== +"@docusaurus/plugin-css-cascade-layers@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz#358c85f63f1c6a11f611f1b8889d9435c11b22f8" + integrity sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + tslib "^2.6.0" + +"@docusaurus/plugin-debug@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz#b5df4db115583f5404a252dbf66f379ff933e53c" + integrity sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" fs-extra "^11.1.1" - react-json-view-lite "^1.2.0" + react-json-view-lite "^2.3.0" tslib "^2.6.0" -"@docusaurus/plugin-google-analytics@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.3.tgz" - integrity sha512-rCDNy1QW8Dag7nZq67pcum0bpFLrwvxJhYuVprhFh8BMBDxV0bY+bAkGHbSf68P3Bk9C3hNOAXX1srGLIDvcTA== +"@docusaurus/plugin-google-analytics@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz#857fe075fdeccdf6959e62954d9efe39769fa247" + integrity sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" tslib "^2.6.0" -"@docusaurus/plugin-google-gtag@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.3.tgz" - integrity sha512-+OyDvhM6rqVkQOmLVkQWVJAizEEfkPzVWtIHXlWPOCFGK9X4/AWeBSrU0WG4iMg9Z4zD4YDRrU+lvI4s6DSC+w== +"@docusaurus/plugin-google-gtag@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz#df75b1a90ae9266b0471909ba0265f46d5dcae62" + integrity sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" "@types/gtag.js" "^0.0.12" tslib "^2.6.0" -"@docusaurus/plugin-google-tag-manager@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.3.tgz" - integrity sha512-1M6UPB13gWUtN2UHX083/beTn85PlRI9ABItTl/JL1FJ5dJTWWFXXsHf9WW/6hrVwthwTeV/AGbGKvLKV+IlCA== +"@docusaurus/plugin-google-tag-manager@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz#d1a3cf935acb7d31b84685e92d70a1d342946677" + integrity sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" tslib "^2.6.0" -"@docusaurus/plugin-sitemap@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.3.tgz" - integrity sha512-94qOO4M9Fwv9KfVQJsgbe91k+fPJ4byf1L3Ez8TUa6TAFPo/BrLwQ80zclHkENlL1824TuxkcMKv33u6eydQCg== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" +"@docusaurus/plugin-sitemap@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz#e1d9f7012942562cc0c6543d3cb2cdc4ae713dc4" + integrity sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" fs-extra "^11.1.1" sitemap "^7.1.1" tslib "^2.6.0" -"@docusaurus/preset-classic@^3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.3.tgz" - integrity sha512-VHSYWROT3flvNNI1SrnMOtW1EsjeHNK9dhU6s9eY5hryZe79lUqnZJyze/ymDe2LXAqzyj6y5oYvyBoZZk6ErA== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/plugin-content-blog" "3.6.3" - "@docusaurus/plugin-content-docs" "3.6.3" - "@docusaurus/plugin-content-pages" "3.6.3" - "@docusaurus/plugin-debug" "3.6.3" - "@docusaurus/plugin-google-analytics" "3.6.3" - "@docusaurus/plugin-google-gtag" "3.6.3" - "@docusaurus/plugin-google-tag-manager" "3.6.3" - "@docusaurus/plugin-sitemap" "3.6.3" - "@docusaurus/theme-classic" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/theme-search-algolia" "3.6.3" - "@docusaurus/types" "3.6.3" - -"@docusaurus/theme-classic@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.3.tgz" - integrity sha512-1RRLK1tSArI2c00qugWYO3jRocjOZwGF1mBzPPylDVRwWCS/rnWWR91ChdbbaxIupRJ+hX8ZBYrwr5bbU0oztQ== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/module-type-aliases" "3.6.3" - "@docusaurus/plugin-content-blog" "3.6.3" - "@docusaurus/plugin-content-docs" "3.6.3" - "@docusaurus/plugin-content-pages" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/theme-translations" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" +"@docusaurus/plugin-svgr@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz#62857ed79d97c0150d25f7e7380fdee65671163a" + integrity sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@svgr/core" "8.1.0" + "@svgr/webpack" "^8.1.0" + tslib "^2.6.0" + webpack "^5.88.1" + +"@docusaurus/preset-classic@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz#85cc4f91baf177f8146c9ce896dfa1f0fd377050" + integrity sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/plugin-content-blog" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/plugin-content-pages" "3.9.2" + "@docusaurus/plugin-css-cascade-layers" "3.9.2" + "@docusaurus/plugin-debug" "3.9.2" + "@docusaurus/plugin-google-analytics" "3.9.2" + "@docusaurus/plugin-google-gtag" "3.9.2" + "@docusaurus/plugin-google-tag-manager" "3.9.2" + "@docusaurus/plugin-sitemap" "3.9.2" + "@docusaurus/plugin-svgr" "3.9.2" + "@docusaurus/theme-classic" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-search-algolia" "3.9.2" + "@docusaurus/types" "3.9.2" + +"@docusaurus/theme-classic@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz#6e514f99a0ff42b80afcf42d5e5d042618311ce0" + integrity sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/plugin-content-blog" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/plugin-content-pages" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-translations" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" "@mdx-js/react" "^3.0.0" clsx "^2.0.0" - copy-text-to-clipboard "^3.2.0" infima "0.2.0-alpha.45" lodash "^4.17.21" nprogress "^0.2.0" - postcss "^8.4.26" + postcss "^8.5.4" prism-react-renderer "^2.3.0" prismjs "^1.29.0" react-router-dom "^5.3.4" @@ -2894,33 +2949,15 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-common@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.3.tgz" - integrity sha512-b8ZkhczXHDxWWyvz+YJy4t/PlPbEogTTbgnHoflYnH7rmRtyoodTsu8WVM12la5LmlMJBclBXFl29OH8kPE7gg== - dependencies: - "@docusaurus/mdx-loader" "3.6.3" - "@docusaurus/module-type-aliases" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@types/history" "^4.7.11" - "@types/react" "*" - "@types/react-router-config" "*" - clsx "^2.0.0" - parse-numeric-range "^1.3.0" - prism-react-renderer "^2.3.0" - tslib "^2.6.0" - utility-types "^3.10.0" - -"@docusaurus/theme-common@^3.6.3": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.8.1.tgz#17c23316fbe3ee3f7e707c7298cb59a0fff38b4b" - integrity sha512-UswMOyTnPEVRvN5Qzbo+l8k4xrd5fTFu2VPPfD6FcW/6qUtVLmJTQCktbAL3KJ0BVXGm5aJXz/ZrzqFuZERGPw== +"@docusaurus/theme-common@3.9.2", "@docusaurus/theme-common@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.9.2.tgz#487172c6fef9815c2746ef62a71e4f5b326f9ba5" + integrity sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag== dependencies: - "@docusaurus/mdx-loader" "3.8.1" - "@docusaurus/module-type-aliases" "3.8.1" - "@docusaurus/utils" "3.8.1" - "@docusaurus/utils-common" "3.8.1" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" @@ -2930,49 +2967,49 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-live-codeblock@^3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.6.3.tgz" - integrity sha512-l6T+rpfiG5FT3kSWEtW7no2VMU7J0hqwNOXC2iubfzkQCLB+A5asP7kGTzBxSn6OKKsj9FY7p26A6CVvy4dvWQ== +"@docusaurus/theme-live-codeblock@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.9.2.tgz#43f0968fb737fda1dae2222a2ab7caa25c5668d0" + integrity sha512-cgxxZh18dI5Q4iV0GLmwqXtgZbTLOnb0TYgZRiUh0mnIGbuNWFUhUYXXl5owKbDfIXFdFAiI/owJKM83howEAw== dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/theme-translations" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" + "@docusaurus/core" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-translations" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" "@philpl/buble" "^0.19.7" clsx "^2.0.0" fs-extra "^11.1.1" react-live "^4.1.6" tslib "^2.6.0" -"@docusaurus/theme-mermaid@^3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.6.3.tgz" - integrity sha512-kIqpjNCP/9R2GGf8UmiDxD3CkOAEJuJIEFlaKMgQtjVxa/vH+9PLI1+DFbArGoG4+0ENTYUq8phHPW7SeL36uQ== - dependencies: - "@docusaurus/core" "3.6.3" - "@docusaurus/module-type-aliases" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" - mermaid ">=10.4" +"@docusaurus/theme-mermaid@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-mermaid/-/theme-mermaid-3.9.2.tgz#f065e4b4b319560ddd8c3be65ce9dd19ce1d5cc8" + integrity sha512-5vhShRDq/ntLzdInsQkTdoKWSzw8d1jB17sNPYhA/KvYYFXfuVEGHLM6nrf8MFbV8TruAHDG21Fn3W4lO8GaDw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + mermaid ">=11.6.0" tslib "^2.6.0" -"@docusaurus/theme-search-algolia@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.3.tgz" - integrity sha512-rt+MGCCpYgPyWCGXtbxlwFbTSobu15jWBTPI2LHsHNa5B0zSmOISX6FWYAPt5X1rNDOqMGM0FATnh7TBHRohVA== - dependencies: - "@docsearch/react" "^3.5.2" - "@docusaurus/core" "3.6.3" - "@docusaurus/logger" "3.6.3" - "@docusaurus/plugin-content-docs" "3.6.3" - "@docusaurus/theme-common" "3.6.3" - "@docusaurus/theme-translations" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-validation" "3.6.3" - algoliasearch "^4.18.0" - algoliasearch-helper "^3.13.3" +"@docusaurus/theme-search-algolia@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz#420fd5b27fc1673b48151fdc9fe7167ba135ed50" + integrity sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw== + dependencies: + "@docsearch/react" "^3.9.0 || ^4.1.0" + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-translations" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + algoliasearch "^5.37.0" + algoliasearch-helper "^3.26.0" clsx "^2.0.0" eta "^2.2.0" fs-extra "^11.1.1" @@ -2980,51 +3017,22 @@ tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.3.tgz" - integrity sha512-Gb0regclToVlngSIIwUCtBMQBq48qVUaN1XQNKW4XwlsgUyk0vP01LULdqbem7czSwIeBAFXFoORJ0RPX7ht/w== +"@docusaurus/theme-translations@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz#238cd69c2da92d612be3d3b4f95944c1d0f1e041" + integrity sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA== dependencies: fs-extra "^11.1.1" tslib "^2.6.0" -"@docusaurus/types@3.3.2": - version "3.3.2" - resolved "https://registry.npmjs.org/@docusaurus/types/-/types-3.3.2.tgz" - integrity sha512-5p201S7AZhliRxTU7uMKtSsoC8mgPA9bs9b5NQg1IRdRxJfflursXNVsgc3PcMqiUTul/v1s3k3rXXFlRE890w== - dependencies: - "@mdx-js/mdx" "^3.0.0" - "@types/history" "^4.7.11" - "@types/react" "*" - commander "^5.1.0" - joi "^17.9.2" - react-helmet-async "^1.3.0" - utility-types "^3.10.0" - webpack "^5.88.1" - webpack-merge "^5.9.0" - -"@docusaurus/types@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.3.tgz" - integrity sha512-xD9oTGDrouWzefkhe9ogB2fDV96/82cRpNGx2HIvI5L87JHNhQVIWimQ/3JIiiX/TEd5S9s+VO6FFguwKNRVow== - dependencies: - "@mdx-js/mdx" "^3.0.0" - "@types/history" "^4.7.11" - "@types/react" "*" - commander "^5.1.0" - joi "^17.9.2" - react-helmet-async "^1.3.0" - utility-types "^3.10.0" - webpack "^5.95.0" - webpack-merge "^5.9.0" - -"@docusaurus/types@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.8.1.tgz#83ab66c345464e003b576a49f78897482061fc26" - integrity sha512-ZPdW5AB+pBjiVrcLuw3dOS6BFlrG0XkS2lDGsj8TizcnREQg3J8cjsgfDviszOk4CweNfwo1AEELJkYaMUuOPg== +"@docusaurus/types@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.9.2.tgz#e482cf18faea0d1fa5ce0e3f1e28e0f32d2593eb" + integrity sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q== dependencies: "@mdx-js/mdx" "^3.0.0" "@types/history" "^4.7.11" + "@types/mdast" "^4.0.2" "@types/react" "*" commander "^5.1.0" joi "^17.9.2" @@ -3033,85 +3041,36 @@ webpack "^5.95.0" webpack-merge "^5.9.0" -"@docusaurus/utils-common@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.3.tgz" - integrity sha512-v4nKDaANLgT3pMBewHYEMAl/ufY0LkXao1QkFWzI5huWFOmNQ2UFzv2BiKeHX5Ownis0/w6cAyoxPhVdDonlSQ== - dependencies: - "@docusaurus/types" "3.6.3" - tslib "^2.6.0" - -"@docusaurus/utils-common@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.8.1.tgz#c369b8c3041afb7dcd595d4172beb1cc1015c85f" - integrity sha512-zTZiDlvpvoJIrQEEd71c154DkcriBecm4z94OzEE9kz7ikS3J+iSlABhFXM45mZ0eN5pVqqr7cs60+ZlYLewtg== +"@docusaurus/utils-common@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.9.2.tgz#e89bfcf43d66359f43df45293fcdf22814847460" + integrity sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw== dependencies: - "@docusaurus/types" "3.8.1" + "@docusaurus/types" "3.9.2" tslib "^2.6.0" -"@docusaurus/utils-validation@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.3.tgz" - integrity sha512-bhEGGiN5BE38h21vjqD70Gxg++j+PfYVddDUE5UFvLDup68QOcpD33CLr+2knPorlxRbEaNfz6HQDUMQ3HuqKw== +"@docusaurus/utils-validation@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz#04aec285604790806e2fc5aa90aa950dc7ba75ae" + integrity sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A== dependencies: - "@docusaurus/logger" "3.6.3" - "@docusaurus/utils" "3.6.3" - "@docusaurus/utils-common" "3.6.3" + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" fs-extra "^11.2.0" joi "^17.9.2" js-yaml "^4.1.0" lodash "^4.17.21" tslib "^2.6.0" -"@docusaurus/utils-validation@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.8.1.tgz#0499c0d151a4098a0963237057993282cfbd538e" - integrity sha512-gs5bXIccxzEbyVecvxg6upTwaUbfa0KMmTj7HhHzc016AGyxH2o73k1/aOD0IFrdCsfJNt37MqNI47s2MgRZMA== +"@docusaurus/utils@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.9.2.tgz#ffab7922631c7e0febcb54e6d499f648bf8a89eb" + integrity sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ== dependencies: - "@docusaurus/logger" "3.8.1" - "@docusaurus/utils" "3.8.1" - "@docusaurus/utils-common" "3.8.1" - fs-extra "^11.2.0" - joi "^17.9.2" - js-yaml "^4.1.0" - lodash "^4.17.21" - tslib "^2.6.0" - -"@docusaurus/utils@3.6.3": - version "3.6.3" - resolved "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.3.tgz" - integrity sha512-0R/FR3bKVl4yl8QwbL4TYFfR+OXBRpVUaTJdENapBGR3YMwfM6/JnhGilWQO8AOwPJGtGoDK7ib8+8UF9f3OZQ== - dependencies: - "@docusaurus/logger" "3.6.3" - "@docusaurus/types" "3.6.3" - "@docusaurus/utils-common" "3.6.3" - "@svgr/webpack" "^8.1.0" - escape-string-regexp "^4.0.0" - file-loader "^6.2.0" - fs-extra "^11.1.1" - github-slugger "^1.5.0" - globby "^11.1.0" - gray-matter "^4.0.3" - jiti "^1.20.0" - js-yaml "^4.1.0" - lodash "^4.17.21" - micromatch "^4.0.5" - prompts "^2.4.2" - resolve-pathname "^3.0.0" - shelljs "^0.8.5" - tslib "^2.6.0" - url-loader "^4.1.1" - utility-types "^3.10.0" - webpack "^5.88.1" - -"@docusaurus/utils@3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.8.1.tgz#2ac1e734106e2f73dbd0f6a8824d525f9064e9f0" - integrity sha512-P1ml0nvOmEFdmu0smSXOqTS1sxU5tqvnc0dA4MTKV39kye+bhQnjkIKEE18fNOvxjyB86k8esoCIFM3x4RykOQ== - dependencies: - "@docusaurus/logger" "3.8.1" - "@docusaurus/types" "3.8.1" - "@docusaurus/utils-common" "3.8.1" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-common" "3.9.2" escape-string-regexp "^4.0.0" execa "5.1.1" file-loader "^6.2.0" @@ -3820,19 +3779,14 @@ resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz" integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== -"@iconify/utils@^2.1.32": - version "2.2.0" - resolved "https://registry.npmjs.org/@iconify/utils/-/utils-2.2.0.tgz" - integrity sha512-9A5eZQV9eKlNCXlI/SgYsGRS7YmGmB1oAsRpNVIYBmIzGJRgH+hfG+lo4069s+GFWFNnBAtDg10c53vQZBLfnA== +"@iconify/utils@^3.0.1": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@iconify/utils/-/utils-3.1.0.tgz#fb41882915f97fee6f91a2fbb8263e8772ca0438" + integrity sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw== dependencies: - "@antfu/install-pkg" "^0.4.1" - "@antfu/utils" "^0.7.10" + "@antfu/install-pkg" "^1.1.0" "@iconify/types" "^2.0.0" - debug "^4.4.0" - globals "^15.13.0" - kolorist "^1.8.0" - local-pkg "^0.5.1" - mlly "^1.7.3" + mlly "^1.8.0" "@inkeep/cxkit-color-mode@0.5.91": version "0.5.91" @@ -4020,6 +3974,51 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jsonjoy.com/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578" + integrity sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA== + +"@jsonjoy.com/buffers@^1.0.0", "@jsonjoy.com/buffers@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz#8d99c7f67eaf724d3428dfd9826c6455266a5c83" + integrity sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA== + +"@jsonjoy.com/codegen@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz#5c23f796c47675f166d23b948cdb889184b93207" + integrity sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g== + +"@jsonjoy.com/json-pack@^1.11.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz#93f8dd57fe3a3a92132b33d1eb182dcd9e7629fa" + integrity sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg== + dependencies: + "@jsonjoy.com/base64" "^1.1.2" + "@jsonjoy.com/buffers" "^1.2.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/json-pointer" "^1.0.2" + "@jsonjoy.com/util" "^1.9.0" + hyperdyperid "^1.2.0" + thingies "^2.5.0" + tree-dump "^1.1.0" + +"@jsonjoy.com/json-pointer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz#049cb530ac24e84cba08590c5e36b431c4843408" + integrity sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg== + dependencies: + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/util" "^1.9.0" + +"@jsonjoy.com/util@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-1.9.0.tgz#7ee95586aed0a766b746cd8d8363e336c3c47c46" + integrity sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ== + dependencies: + "@jsonjoy.com/buffers" "^1.0.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.5" resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz" @@ -4061,12 +4060,12 @@ dependencies: "@types/mdx" "^2.0.0" -"@mermaid-js/parser@^0.3.0": - version "0.3.0" - resolved "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz" - integrity sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA== +"@mermaid-js/parser@^0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@mermaid-js/parser/-/parser-0.6.3.tgz#3ce92dad2c5d696d29e11e21109c66a7886c824e" + integrity sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA== dependencies: - langium "3.0.0" + langium "3.3.1" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -4204,6 +4203,11 @@ resolved "https://registry.npmjs.org/@offchainlabs/prettier-config/-/prettier-config-0.2.1.tgz" integrity sha512-VjE4Hahx9ipTheXJVlt7tFtHeMVvlYUkKNT4uxnAK4i4qrLcqhlm/4GE9mueOS/Syi2/gzDKvNH0nk6+ts2IrA== +"@opentelemetry/api@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" + integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== + "@philpl/buble@^0.19.7": version "0.19.7" resolved "https://registry.npmjs.org/@philpl/buble/-/buble-0.19.7.tgz" @@ -5009,6 +5013,11 @@ micromark-util-character "^1.1.0" micromark-util-symbol "^1.0.1" +"@standard-schema/spec@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" + integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== + "@svgr/babel-plugin-add-jsx-attribute@8.0.0": version "8.0.0" resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz" @@ -5163,9 +5172,9 @@ "@types/connect" "*" "@types/node" "*" -"@types/bonjour@^3.5.9": +"@types/bonjour@^3.5.13": version "3.5.13" - resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" @@ -5180,9 +5189,9 @@ "@types/node" "*" "@types/responselike" "^1.0.0" -"@types/connect-history-api-fallback@^1.3.5": +"@types/connect-history-api-fallback@^1.5.4": version "1.5.4" - resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" @@ -5462,7 +5471,17 @@ "@types/range-parser" "*" "@types/send" "*" -"@types/express@*", "@types/express@^4.17.13": +"@types/express-serve-static-core@^4.17.21": + version "4.19.7" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz#f1d306dcc03b1aafbfb6b4fe684cce8a31cffc10" + integrity sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": version "4.17.21" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== @@ -5472,6 +5491,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.21": + version "4.17.25" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" + integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "^1" + "@types/geojson@*": version "7946.0.15" resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz" @@ -5542,7 +5571,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -5622,11 +5651,6 @@ dependencies: undici-types "~5.26.4" -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - "@types/prismjs@^1.26.0": version "1.26.3" resolved "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz" @@ -5712,10 +5736,10 @@ dependencies: "@types/node" "*" -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== +"@types/retry@0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" + integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== "@types/sax@^1.2.1": version "1.2.7" @@ -5737,14 +5761,22 @@ "@types/mime" "^1" "@types/node" "*" -"@types/serve-index@^1.9.1": +"@types/send@<1": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" + integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.4": version "1.9.4" - resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" -"@types/serve-static@*", "@types/serve-static@^1.13.10": +"@types/serve-static@*": version "1.15.7" resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz" integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== @@ -5753,9 +5785,18 @@ "@types/node" "*" "@types/send" "*" -"@types/sockjs@^0.3.33": +"@types/serve-static@^1", "@types/serve-static@^1.15.5": + version "1.15.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" + integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "<1" + +"@types/sockjs@^0.3.36": version "0.3.36" - resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" @@ -5780,10 +5821,10 @@ resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz" integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== -"@types/ws@^8.5.5": - version "8.5.10" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" - integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== +"@types/ws@^8.5.10": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: "@types/node" "*" @@ -5804,6 +5845,11 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@vercel/oidc@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vercel/oidc/-/oidc-3.0.5.tgz#bd8db7ee777255c686443413492db4d98ef49657" + integrity sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw== + "@vitest/expect@3.0.7": version "3.0.7" resolved "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.7.tgz" @@ -6230,7 +6276,12 @@ acorn@^8.14.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz" integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== -address@^1.0.1, address@^1.1.2: +acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +address@^1.0.1: version "1.2.2" resolved "https://registry.npmjs.org/address/-/address-1.2.2.tgz" integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== @@ -6255,6 +6306,16 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ai@5.0.115, ai@^5.0.30: + version "5.0.115" + resolved "https://registry.yarnpkg.com/ai/-/ai-5.0.115.tgz#a04ff38a340bc4e3cd7e7f444577fa4eb36d129a" + integrity sha512-aVuHx0orGxXvhyL7oXUyW8TnWQE6Al8f3Bl6VZjz0WHMV+WaACHPkSyvQ3wje2QCUGzdl5DBF5d+OaXyghPQyg== + dependencies: + "@ai-sdk/gateway" "2.0.22" + "@ai-sdk/provider" "2.0.0" + "@ai-sdk/provider-utils" "3.0.19" + "@opentelemetry/api" "1.9.0" + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" @@ -6262,7 +6323,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -6274,7 +6335,7 @@ ajv-keywords@^5.1.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.2, ajv@^6.12.5: +ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -6294,33 +6355,32 @@ ajv@^8.0.0, ajv@^8.9.0: require-from-string "^2.0.2" uri-js "^4.4.1" -algoliasearch-helper@^3.13.3: - version "3.19.0" - resolved "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.19.0.tgz" - integrity sha512-AaSb5DZDMZmDQyIy6lf4aL0OZGgyIdqvLIIvSuVQOIOqfhrYSY7TvotIFI2x0Q3cP3xUpTd7lI1astUC4aXBJw== +algoliasearch-helper@^3.26.0: + version "3.26.1" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz#5b7f0874a2751c3d6de675d5403d8fa2f015023f" + integrity sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw== dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.18.0, algoliasearch@^4.19.1: - version "4.23.3" - resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.23.3.tgz" - integrity sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg== - dependencies: - "@algolia/cache-browser-local-storage" "4.23.3" - "@algolia/cache-common" "4.23.3" - "@algolia/cache-in-memory" "4.23.3" - "@algolia/client-account" "4.23.3" - "@algolia/client-analytics" "4.23.3" - "@algolia/client-common" "4.23.3" - "@algolia/client-personalization" "4.23.3" - "@algolia/client-search" "4.23.3" - "@algolia/logger-common" "4.23.3" - "@algolia/logger-console" "4.23.3" - "@algolia/recommend" "4.23.3" - "@algolia/requester-browser-xhr" "4.23.3" - "@algolia/requester-common" "4.23.3" - "@algolia/requester-node-http" "4.23.3" - "@algolia/transporter" "4.23.3" +algoliasearch@^5.28.0, algoliasearch@^5.37.0: + version "5.46.1" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.46.1.tgz#3b3de480398f3b559632489a1778d5c581183794" + integrity sha512-39ol8Ulqb3MntofkXHlrcXKyU8BU0PXvQrXPBIX6eXj/EO4VT7651mhGVORI2oF8ydya9nFzT3fYDoqme/KL6w== + dependencies: + "@algolia/abtesting" "1.12.1" + "@algolia/client-abtesting" "5.46.1" + "@algolia/client-analytics" "5.46.1" + "@algolia/client-common" "5.46.1" + "@algolia/client-insights" "5.46.1" + "@algolia/client-personalization" "5.46.1" + "@algolia/client-query-suggestions" "5.46.1" + "@algolia/client-search" "5.46.1" + "@algolia/ingestion" "1.46.1" + "@algolia/monitoring" "1.46.1" + "@algolia/recommend" "5.46.1" + "@algolia/requester-browser-xhr" "5.46.1" + "@algolia/requester-fetch" "5.46.1" + "@algolia/requester-node-http" "5.46.1" altcha-lib@^1.2.0: version "1.3.0" @@ -6449,11 +6509,6 @@ asynckit@^0.4.0: resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - autoprefixer@^10.4.19: version "10.4.19" resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz" @@ -6466,6 +6521,17 @@ autoprefixer@^10.4.19: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +autoprefixer@^10.4.22: + version "10.4.23" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.23.tgz#c6aa6db8e7376fcd900f9fd79d143ceebad8c4e6" + integrity sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA== + dependencies: + browserslist "^4.28.1" + caniuse-lite "^1.0.30001760" + fraction.js "^5.3.4" + picocolors "^1.1.1" + postcss-value-parser "^4.2.0" + babel-loader@^9.2.1: version "9.2.1" resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz" @@ -6523,6 +6589,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +baseline-browser-mapping@^2.9.0: + version "2.9.9" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.9.tgz#68c17013c33ba9e8264c5f2ae107d506228428ee" + integrity sha512-V8fbOCSeOFvlDj7LLChUcqbZrdKD9RU/VR260piF1790vT0mfLSwGc/Qzxv3IqiTukOpNtItePa0HBpMAj7MDg== + batch@0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" @@ -6558,28 +6629,28 @@ bn.js@^5.2.1: resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== +body-parser@~1.20.3: + version "1.20.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" + integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== dependencies: - bytes "3.1.2" + bytes "~3.1.2" content-type "~1.0.5" debug "2.6.9" depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.14.0" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" -bonjour-service@^1.0.11: - version "1.2.1" - resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz" - integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== +bonjour-service@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" + integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== dependencies: fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" @@ -6644,7 +6715,7 @@ brorand@^1.1.0: resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: +browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -6654,7 +6725,7 @@ browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^ node-releases "^2.0.14" update-browserslist-db "^1.0.13" -browserslist@^4.23.1, browserslist@^4.24.0, browserslist@^4.24.2: +browserslist@^4.24.0, browserslist@^4.24.2: version "4.24.2" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz" integrity sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg== @@ -6664,19 +6735,37 @@ browserslist@^4.23.1, browserslist@^4.24.0, browserslist@^4.24.2: node-releases "^2.0.18" update-browserslist-db "^1.1.1" +browserslist@^4.28.0, browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== + dependencies: + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +bundle-name@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" + integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== + dependencies: + run-applescript "^7.0.0" + bytes@3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2: +bytes@~3.1.2: version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cac@^6.7.14: @@ -6728,7 +6817,7 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.5, call-bind@^1.0.7: +call-bind@^1.0.5: version "1.0.7" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -6739,6 +6828,14 @@ call-bind@^1.0.5, call-bind@^1.0.7: get-intrinsic "^1.2.4" set-function-length "^1.2.1" +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" @@ -6782,6 +6879,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599, can resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz" integrity sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg== +caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001760: + version "1.0.30001760" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz#bdd1960fafedf8d5f04ff16e81460506ff9b798f" + integrity sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw== + ccount@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" @@ -6807,7 +6909,7 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -6909,7 +7011,7 @@ chevrotain@~11.0.3: "@chevrotain/utils" "11.0.3" lodash-es "4.17.21" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.3: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -6946,7 +7048,7 @@ classnames@^2.5.1: resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== -clean-css@^5.2.2, clean-css@^5.3.2, clean-css@~5.3.2: +clean-css@^5.2.2, clean-css@^5.3.3, clean-css@~5.3.2: version "5.3.3" resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz" integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== @@ -7168,9 +7270,9 @@ content-disposition@0.5.2: resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz" integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== -content-disposition@0.5.4: +content-disposition@~0.5.4: version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: safe-buffer "5.2.1" @@ -7185,20 +7287,15 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +cookie-signature@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" + integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -copy-text-to-clipboard@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz" - integrity sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q== +cookie@~0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -7260,17 +7357,6 @@ cose-base@^2.2.0: dependencies: layout-base "^2.0.0" -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: version "8.3.6" resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz" @@ -7323,18 +7409,18 @@ css-declaration-sorter@^7.2.0: resolved "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz" integrity sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow== -css-has-pseudo@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.1.tgz" - integrity sha512-EOcoyJt+OsuKfCADgLT7gADZI5jMzIe/AeI6MeAYKiFBDmNmM7kk46DtSfMj5AohUJisqVzopBpnQTlvbyaBWg== +css-has-pseudo@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz#a5ee2daf5f70a2032f3cefdf1e36e7f52a243873" + integrity sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA== dependencies: "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" -css-loader@^6.8.1: +css-loader@^6.11.0: version "6.11.0" - resolved "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" @@ -7415,10 +7501,10 @@ css-what@^6.0.1, css-what@^6.1.0: resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== -cssdb@^8.2.1: - version "8.2.3" - resolved "https://registry.npmjs.org/cssdb/-/cssdb-8.2.3.tgz" - integrity sha512-9BDG5XmJrJQQnJ51VFxXCAtpZ5ebDlAREmO8sxMOVU0aSxN/gocbctjIG5LMh3WBUq+xTlb/jw2LoljBEqraTA== +cssdb@^8.5.2: + version "8.5.2" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.5.2.tgz#8a8c16c43785e32749453e589f18debcd936c7d1" + integrity sha512-Pmoj9RmD8RIoIzA2EQWO4D4RMeDts0tgAH0VXdlNdxjuBGI3a9wMOIcUwaPNmD4r2qtIa06gqkIf7sECl+cBCg== cssesc@^3.0.0: version "3.0.0" @@ -7513,16 +7599,11 @@ cytoscape-fcose@^2.2.0: dependencies: cose-base "^2.2.0" -cytoscape@^3.28.1: +cytoscape@^3.28.1, cytoscape@^3.29.3: version "3.33.1" resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.33.1.tgz#449e05d104b760af2912ab76482d24c01cdd4c97" integrity sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ== -cytoscape@^3.29.2: - version "3.30.4" - resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.4.tgz" - integrity sha512-OxtlZwQl1WbwMmLiyPSEBuzeTIQnwZhJYYWFzZ2PhEHVFwpeaqNIkUzSiso00D98qk60l8Gwon2RP304d3BJ1A== - "d3-array@1 - 2": version "2.12.1" resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" @@ -7802,15 +7883,20 @@ dagre-d3-es@7.0.10: d3 "^7.8.2" lodash-es "^4.17.21" -dagre-d3-es@7.0.11: - version "7.0.11" - resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz" - integrity sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw== +dagre-d3-es@7.0.13: + version "7.0.13" + resolved "https://registry.yarnpkg.com/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz#acfb4b449f6dcdd48d8ea8081a6d8c59bc8128c3" + integrity sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q== dependencies: d3 "^7.9.0" lodash-es "^4.17.21" -dayjs@^1.11.10, dayjs@^1.11.7: +dayjs@^1.11.18: + version "1.11.19" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.19.tgz#15dc98e854bb43917f12021806af897c58ae2938" + integrity sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw== + +dayjs@^1.11.7: version "1.11.13" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== @@ -7820,7 +7906,7 @@ debounce@^1.2.1: resolved "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@2.6.9, debug@^2.6.0: +debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -7865,17 +7951,23 @@ deep-extend@^0.6.0: resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deepmerge@^4.2.2, deepmerge@^4.3.1: +deepmerge@^4.3.1: 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== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== +default-browser-id@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.1.tgz#f7a7ccb8f5104bf8e0f71ba3b1ccfa5eafdb21e8" + integrity sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q== + +default-browser@^5.2.1: + version "5.4.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.4.0.tgz#b55cf335bb0b465dd7c961a02cd24246aa434287" + integrity sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg== dependencies: - execa "^5.0.0" + bundle-name "^4.1.0" + default-browser-id "^5.0.0" defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: version "2.0.1" @@ -7896,6 +7988,11 @@ define-lazy-prop@^2.0.0: resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + define-properties@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" @@ -7905,20 +8002,6 @@ define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -del@^6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/del/-/del-6.1.1.tgz" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" - delaunator@5: version "5.0.1" resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz" @@ -7931,7 +8014,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -7951,7 +8034,7 @@ dequal@^2.0.0, dequal@^2.0.3: resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -destroy@1.2.0: +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -7966,14 +8049,6 @@ detect-node@^2.0.4: resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -detect-port-alt@^1.1.6: - version "1.1.6" - resolved "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz" - integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== - dependencies: - address "^1.0.1" - debug "^2.6.0" - detect-port@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz" @@ -8074,10 +8149,10 @@ domhandler@^5.0.2, domhandler@^5.0.3: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.6.tgz#43c714a94c6a7b8801850f82e756685300a027e2" integrity sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ== -dompurify@^3.2.1: - version "3.2.3" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.2.3.tgz" - integrity sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA== +dompurify@^3.2.5: + version "3.3.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.3.1.tgz#c7e1ddebfe3301eacd6c0c12a4af284936dbbb86" + integrity sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -8153,6 +8228,11 @@ electron-to-chromium@^1.4.668: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.754.tgz" integrity sha512-7Kr5jUdns5rL/M9wFFmMZAgFDuL2YOnanFH4OI4iFzUqyh3XOL7nAGbSlSMZdzKMIyyTpNSbqZsWG9odwLeKvA== +electron-to-chromium@^1.5.263: + version "1.5.267" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz#5d84f2df8cdb6bfe7e873706bb21bd4bfb574dc7" + integrity sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw== + electron-to-chromium@^1.5.41: version "1.5.72" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.72.tgz" @@ -8201,10 +8281,10 @@ emoticon@^4.0.1: resolved "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz" integrity sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== end-of-stream@^1.1.0: version "1.4.4" @@ -8538,7 +8618,12 @@ events@^3.2.0: resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@5.1.1, execa@^5.0.0: +eventsource-parser@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" + integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== + +execa@5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -8558,39 +8643,39 @@ expect-type@^1.1.0: resolved "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz" integrity sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA== -express@^4.17.3: - version "4.19.2" - resolved "https://registry.npmjs.org/express/-/express-4.19.2.tgz" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== +express@^4.21.2: + version "4.22.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" + integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" - content-disposition "0.5.4" + body-parser "~1.20.3" + content-disposition "~0.5.4" content-type "~1.0.4" - cookie "0.6.0" - cookie-signature "1.0.6" + cookie "~0.7.1" + cookie-signature "~1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" + finalhandler "~1.3.1" + fresh "~0.5.2" + http-errors "~2.0.0" + merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "~0.1.12" proxy-addr "~2.0.7" - qs "6.11.0" + qs "~6.14.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "~0.19.0" + serve-static "~1.16.2" setprototypeof "1.2.0" - statuses "2.0.1" + statuses "~2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -8683,11 +8768,6 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -filesize@^8.0.6: - version "8.0.7" - resolved "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz" - integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -8695,17 +8775,17 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" + integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - statuses "2.0.1" + statuses "~2.0.2" unpipe "~1.0.0" find-cache-dir@^4.0.0: @@ -8716,21 +8796,6 @@ find-cache-dir@^4.0.0: common-path-prefix "^3.0.0" pkg-dir "^7.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - find-up@^6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz" @@ -8765,25 +8830,6 @@ foreground-child@^3.3.1: cross-spawn "^7.0.6" signal-exit "^4.0.1" -fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.3" - resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" - form-data-encoder@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" @@ -8827,9 +8873,14 @@ fraction.js@^4.3.7: resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== -fresh@0.5.2: +fraction.js@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" + integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== + +fresh@~0.5.2: version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== fs-extra@^11.1.1, fs-extra@^11.2.0: @@ -8841,21 +8892,6 @@ fs-extra@^11.1.1, fs-extra@^11.2.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-monkey@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz" - integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -8876,7 +8912,7 @@ gensync@^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== -get-intrinsic@^1.2.4, get-intrinsic@^1.2.6: +get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== @@ -8948,6 +8984,11 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" +glob-to-regex.js@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz#2b323728271d133830850e32311f40766c5f6413" + integrity sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ== + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" @@ -8964,7 +9005,7 @@ glob@^10.3.10: minipass "^7.0.4" path-scurry "^1.10.2" -glob@^7.0.0, glob@^7.1.3, glob@^7.1.6, glob@^7.2.0: +glob@^7.2.0: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -8988,40 +9029,19 @@ glob@~11.0.2: package-json-from-dist "^1.0.0" path-scurry "^2.0.0" -global-dirs@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz" - integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== - dependencies: - ini "2.0.0" - -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== +global-dirs@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz" + integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" + ini "2.0.0" globals@^11.1.0: version "11.12.0" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^15.13.0: - version "15.13.0" - resolved "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz" - integrity sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g== - -globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: +globby@^11.1.0: version "11.1.0" resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -9411,11 +9431,6 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" -html-entities@^2.3.2: - version "2.5.2" - resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz" - integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== - html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" @@ -9510,17 +9525,6 @@ http-deceiver@^1.2.7: resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - http-errors@~1.6.2: version "1.6.3" resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" @@ -9531,15 +9535,26 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@~2.0.0, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== +http-proxy-middleware@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" + integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -9594,12 +9609,10 @@ husky@^9.1.7: resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d" integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA== -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" +hyperdyperid@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b" + integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== iconv-lite@0.6: version "0.6.3" @@ -9608,6 +9621,13 @@ iconv-lite@0.6: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@~0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz" @@ -9623,29 +9643,17 @@ ignore@~7.0.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== -image-size@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" - integrity sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg== - dependencies: - queue "6.0.2" - image-size@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/image-size/-/image-size-2.0.2.tgz#84a7b43704db5736f364bf0d1b029821299b4bdc" integrity sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w== -immer@^9.0.7: - version "9.0.21" - resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - immutable@^4.0.0: version "4.3.5" resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz" integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== -import-fresh@^3.1.0, import-fresh@^3.3.0: +import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -9681,7 +9689,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -9696,7 +9704,7 @@ ini@2.0.0: resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -9726,11 +9734,6 @@ internmap@^1.0.0: resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - invariant@^2.2.4: version "2.2.4" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" @@ -9743,10 +9746,10 @@ ipaddr.js@1.9.1: resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -ipaddr.js@^2.0.1: - version "2.2.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== +ipaddr.js@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz#71dce70e1398122208996d1c22f2ba46a24b1abc" + integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== is-alphabetical@^1.0.0: version "1.0.4" @@ -9815,6 +9818,11 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz" @@ -9847,6 +9855,13 @@ is-hexadecimal@^2.0.0: resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz" integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-installed-globally@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz" @@ -9855,6 +9870,11 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" +is-network-error@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.3.0.tgz#2ce62cbca444abd506f8a900f39d20b898d37512" + integrity sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw== + is-npm@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz" @@ -9875,11 +9895,6 @@ is-obj@^2.0.0: resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - is-path-inside@^3.0.2: version "3.0.3" resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" @@ -9914,11 +9929,6 @@ is-regexp@^1.0.0: resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== -is-root@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz" - integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" @@ -9941,6 +9951,13 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +is-wsl@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" + integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== + dependencies: + is-inside-container "^1.0.0" + is-yarn-global@^0.4.0: version "0.4.1" resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz" @@ -10096,6 +10113,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + json5@^2.1.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" @@ -10132,6 +10154,13 @@ katex@^0.16.0: dependencies: commander "^8.3.0" +katex@^0.16.22: + version "0.16.27" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.27.tgz#4ecf6f620e0ca1c1a5de722e85fcdcec49086a48" + integrity sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw== + dependencies: + commander "^8.3.0" + katex@^0.16.9: version "0.16.10" resolved "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz" @@ -10171,15 +10200,10 @@ klona@^2.0.4: resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== -kolorist@^1.8.0: - version "1.8.0" - resolved "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz" - integrity sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ== - -langium@3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz" - integrity sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg== +langium@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/langium/-/langium-3.3.1.tgz#da745a40d5ad8ee565090fed52eaee643be4e591" + integrity sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w== dependencies: chevrotain "~11.0.3" chevrotain-allstar "~0.3.0" @@ -10194,13 +10218,13 @@ latest-version@^7.0.0: dependencies: package-json "^8.1.0" -launch-editor@^2.6.0: - version "2.6.1" - resolved "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz" - integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== +launch-editor@^2.6.1: + version "2.12.0" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.12.0.tgz#cc740f4e0263a6b62ead2485f9896e545321f817" + integrity sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg== dependencies: - picocolors "^1.0.0" - shell-quote "^1.8.1" + picocolors "^1.1.1" + shell-quote "^1.8.3" layout-base@^1.0.0: version "1.0.2" @@ -10248,34 +10272,6 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^3.2.0: - version "3.2.1" - resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz" - integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== - -local-pkg@^0.5.1: - version "0.5.1" - resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz" - integrity sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ== - dependencies: - mlly "^1.7.3" - pkg-types "^1.2.1" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - locate-path@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz" @@ -10459,11 +10455,6 @@ markdownlint@~0.38.0: micromark-extension-math "3.1.0" micromark-util-types "2.0.2" -marked@^13.0.2: - version "13.0.3" - resolved "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz" - integrity sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA== - marked@^15.0.7: version "15.0.11" resolved "https://registry.npmjs.org/marked/-/marked-15.0.11.tgz" @@ -10474,6 +10465,11 @@ marked@^15.0.9: resolved "https://registry.yarnpkg.com/marked/-/marked-15.0.12.tgz#30722c7346e12d0a2d0207ab9b0c4f0102d86c4e" integrity sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA== +marked@^16.2.1, marked@^16.3.0: + version "16.4.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3" + integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA== + marked@^4.1.0, marked@^4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz" @@ -10774,12 +10770,17 @@ media-typer@0.3.0: resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.1.2, memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.npmjs.org/memfs/-/memfs-3.6.0.tgz" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== +memfs@^4.43.1: + version "4.51.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.51.1.tgz#25945de4a90d1573945105e187daa9385e1bca73" + integrity sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ== dependencies: - fs-monkey "^1.0.4" + "@jsonjoy.com/json-pack" "^1.11.0" + "@jsonjoy.com/util" "^1.9.0" + glob-to-regex.js "^1.0.1" + thingies "^2.5.0" + tree-dump "^1.0.3" + tslib "^2.0.0" merge-anything@5.1.7: version "5.1.7" @@ -10788,10 +10789,10 @@ merge-anything@5.1.7: dependencies: is-what "^4.1.8" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" @@ -10803,31 +10804,31 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -mermaid@>=10.4: - version "11.4.1" - resolved "https://registry.npmjs.org/mermaid/-/mermaid-11.4.1.tgz" - integrity sha512-Mb01JT/x6CKDWaxigwfZYuYmDZ6xtrNwNlidKZwkSrDaY9n90tdrJTV5Umk+wP1fZscGptmKFXHsXMDEVZ+Q6A== +mermaid@>=11.6.0: + version "11.12.2" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-11.12.2.tgz#48bbdb9f724bc2191e2128e1403bf964fff2bc3d" + integrity sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w== dependencies: - "@braintree/sanitize-url" "^7.0.1" - "@iconify/utils" "^2.1.32" - "@mermaid-js/parser" "^0.3.0" + "@braintree/sanitize-url" "^7.1.1" + "@iconify/utils" "^3.0.1" + "@mermaid-js/parser" "^0.6.3" "@types/d3" "^7.4.3" - cytoscape "^3.29.2" + cytoscape "^3.29.3" cytoscape-cose-bilkent "^4.1.0" cytoscape-fcose "^2.2.0" d3 "^7.9.0" d3-sankey "^0.12.3" - dagre-d3-es "7.0.11" - dayjs "^1.11.10" - dompurify "^3.2.1" - katex "^0.16.9" + dagre-d3-es "7.0.13" + dayjs "^1.11.18" + dompurify "^3.2.5" + katex "^0.16.22" khroma "^2.1.0" lodash-es "^4.17.21" - marked "^13.0.2" + marked "^16.2.1" roughjs "^4.6.6" - stylis "^4.3.1" + stylis "^4.3.6" ts-dedent "^2.2.0" - uuid "^9.0.1" + uuid "^11.1.0" mermaid@^10.0.0: version "10.9.4" @@ -11568,6 +11569,11 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-db@~1.33.0: version "1.33.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz" @@ -11580,13 +11586,20 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime-types@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" @@ -11612,10 +11625,10 @@ mimic-response@^4.0.0: resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz" integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== -mini-css-extract-plugin@^2.9.1: - version "2.9.2" - resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz" - integrity sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w== +mini-css-extract-plugin@^2.9.2: + version "2.9.4" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz#cafa1a42f8c71357f49cd1566810d74ff1cb0200" + integrity sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ== dependencies: schema-utils "^4.0.0" tapable "^2.2.1" @@ -11630,7 +11643,7 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== -minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: +minimatch@3.1.2, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -11673,15 +11686,15 @@ minipass@^7.1.2: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -mlly@^1.7.2, mlly@^1.7.3: - version "1.7.3" - resolved "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz" - integrity sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A== +mlly@^1.7.4, mlly@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.8.0.tgz#e074612b938af8eba1eaf43299cbc89cb72d824e" + integrity sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g== dependencies: - acorn "^8.14.0" - pathe "^1.1.2" - pkg-types "^1.2.1" - ufo "^1.5.4" + acorn "^8.15.0" + pathe "^2.0.3" + pkg-types "^1.3.1" + ufo "^1.6.1" mri@^1.1.0: version "1.2.0" @@ -11725,6 +11738,11 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + nanoid@^3.3.7: version "3.3.7" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" @@ -11790,6 +11808,11 @@ node-releases@^2.0.18: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + non-layered-tidy-tree-layout@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz#57d35d13c356643fc296a55fb11ac15e74da7804" @@ -11847,10 +11870,10 @@ object-assign@^4.0.1, object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-keys@^1.1.1: version "1.1.1" @@ -11872,9 +11895,9 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@2.4.1: +on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" @@ -11898,7 +11921,17 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@^8.0.9, open@^8.4.0: +open@^10.0.3: + version "10.2.0" + resolved "https://registry.yarnpkg.com/open/-/open-10.2.0.tgz#b9d855be007620e80b6fb05fac98141fe62db73c" + integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== + dependencies: + default-browser "^5.2.1" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + wsl-utils "^0.1.0" + +open@^8.4.0: version "8.4.2" resolved "https://registry.npmjs.org/open/-/open-8.4.2.tgz" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -11945,20 +11978,6 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== -p-limit@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - p-limit@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz" @@ -11966,20 +11985,6 @@ p-limit@^4.0.0: dependencies: yocto-queue "^1.0.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^5.0.0: - 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== - dependencies: - p-limit "^3.0.2" - p-locate@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz" @@ -12002,12 +12007,13 @@ p-queue@^6.6.2: eventemitter3 "^4.0.4" p-timeout "^3.2.0" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== +p-retry@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.1.tgz#81828f8dc61c6ef5a800585491572cc9892703af" + integrity sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ== dependencies: - "@types/retry" "0.12.0" + "@types/retry" "0.12.2" + is-network-error "^1.0.0" retry "^0.13.1" p-timeout@^3.2.0: @@ -12017,11 +12023,6 @@ p-timeout@^3.2.0: dependencies: p-finally "^1.0.0" -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - package-json-from-dist@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" @@ -12037,10 +12038,10 @@ package-json@^8.1.0: registry-url "^6.0.0" semver "^7.3.7" -package-manager-detector@^0.2.0: - version "0.2.7" - resolved "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.7.tgz" - integrity sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ== +package-manager-detector@^1.3.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/package-manager-detector/-/package-manager-detector-1.6.0.tgz#70d0cf0aa02c877eeaf66c4d984ede0be9130734" + integrity sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA== param-case@^3.0.4: version "3.0.4" @@ -12083,7 +12084,7 @@ parse-entities@^4.0.0: is-decimal "^2.0.0" is-hexadecimal "^2.0.0" -parse-json@^5.0.0, parse-json@^5.2.0: +parse-json@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -12131,16 +12132,6 @@ path-data-parser@0.1.0, path-data-parser@^0.1.0: resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz" integrity sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w== -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - path-exists@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz" @@ -12182,11 +12173,6 @@ path-scurry@^2.0.0: lru-cache "^11.0.0" minipass "^7.1.2" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - path-to-regexp@3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz" @@ -12199,6 +12185,11 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" +path-to-regexp@~0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" @@ -12212,12 +12203,7 @@ path@^0.12.7: process "^0.11.1" util "^0.10.3" -pathe@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz" - integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== - -pathe@^2.0.3: +pathe@^2.0.1, pathe@^2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz" integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== @@ -12263,21 +12249,14 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.0" -pkg-types@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz" - integrity sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw== +pkg-types@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df" + integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ== dependencies: confbox "^0.1.8" - mlly "^1.7.2" - pathe "^1.1.2" - -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== - dependencies: - find-up "^3.0.0" + mlly "^1.7.4" + pathe "^2.0.1" points-on-curve@0.2.0, points-on-curve@^0.2.0: version "0.2.0" @@ -12314,15 +12293,15 @@ postcss-clamp@^4.1.0: dependencies: postcss-value-parser "^4.2.0" -postcss-color-functional-notation@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.6.tgz" - integrity sha512-wLXvm8RmLs14Z2nVpB4CWlnvaWPRcOZFltJSlcbYwSJ1EDZKsKDhPKIMecCnuU054KSmlmubkqczmm6qBPCBhA== +postcss-color-functional-notation@^7.0.12: + version "7.0.12" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz#9a3df2296889e629fde18b873bb1f50a4ecf4b83" + integrity sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" postcss-color-hex-alpha@^10.0.0: @@ -12359,35 +12338,35 @@ postcss-convert-values@^6.1.0: browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-custom-media@^11.0.5: - version "11.0.5" - resolved "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.5.tgz" - integrity sha512-SQHhayVNgDvSAdX9NQ/ygcDQGEY+aSF4b/96z7QUX6mqL5yl/JgG/DywcF6fW9XbnCRE+aVYk+9/nqGuzOPWeQ== +postcss-custom-media@^11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz#6b450e5bfa209efb736830066682e6567bd04967" + integrity sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/media-query-list-parser" "^4.0.2" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" -postcss-custom-properties@^14.0.4: - version "14.0.4" - resolved "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.4.tgz" - integrity sha512-QnW8FCCK6q+4ierwjnmXF9Y9KF8q0JkbgVfvQEMa93x1GT8FvOiUevWCN2YLaOWyByeDX8S6VFbZEeWoAoXs2A== +postcss-custom-properties@^14.0.6: + version "14.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz#1af73a650bf115ba052cf915287c9982825fc90e" + integrity sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-custom-selectors@^8.0.4: - version "8.0.4" - resolved "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.4.tgz" - integrity sha512-ASOXqNvDCE0dAJ/5qixxPeL1aOVGHGW2JwSy7HyjWNbnWTQCl+fDc968HY1jCmZI0+BaYT5CxsOiUhavpG/7eg== +postcss-custom-selectors@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz#9448ed37a12271d7ab6cb364b6f76a46a4a323e8" + integrity sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg== dependencies: - "@csstools/cascade-layer-name-parser" "^2.0.4" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" postcss-selector-parser "^7.0.0" postcss-dir-pseudo-class@^9.0.1: @@ -12424,12 +12403,12 @@ postcss-discard-unused@^6.0.5: dependencies: postcss-selector-parser "^6.0.16" -postcss-double-position-gradients@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.0.tgz" - integrity sha512-JkIGah3RVbdSEIrcobqj4Gzq0h53GG4uqDPsho88SgY84WnpkTpI0k50MFK/sX7XqVisZ6OqUfFnoUO6m1WWdg== +postcss-double-position-gradients@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz#b482d08b5ced092b393eb297d07976ab482d4cad" + integrity sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g== dependencies: - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" @@ -12465,30 +12444,30 @@ postcss-image-set-function@^7.0.0: "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-lab-function@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.6.tgz" - integrity sha512-HPwvsoK7C949vBZ+eMyvH2cQeMr3UREoHvbtra76/UhDuiViZH6pir+z71UaJQohd7VDSVUdR6TkWYKExEc9aQ== +postcss-lab-function@^7.0.12: + version "7.0.12" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz#eb555ac542607730eb0a87555074e4a5c6eef6e4" + integrity sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w== dependencies: - "@csstools/css-color-parser" "^3.0.6" - "@csstools/css-parser-algorithms" "^3.0.4" - "@csstools/css-tokenizer" "^3.0.3" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" "@csstools/utilities" "^2.0.0" -postcss-loader@^7.3.3: +postcss-loader@^7.3.4: version "7.3.4" - resolved "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.4.tgz#aed9b79ce4ed7e9e89e56199d25ad1ec8f606209" integrity sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A== dependencies: cosmiconfig "^8.3.5" jiti "^1.20.0" semver "^7.5.4" -postcss-logical@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.0.0.tgz" - integrity sha512-HpIdsdieClTjXLOyYdUPAX/XQASNIwdKt5hoZW08ZOAiI+tbV0ta1oclkpVkW5ANU+xJvk3KkA0FejkjGLXUkg== +postcss-logical@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-8.1.0.tgz#4092b16b49e3ecda70c4d8945257da403d167228" + integrity sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA== dependencies: postcss-value-parser "^4.2.0" @@ -12578,12 +12557,12 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^13.0.1: - version "13.0.1" - resolved "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz" - integrity sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ== +postcss-nesting@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.2.tgz#fde0d4df772b76d03b52eccc84372e8d1ca1402e" + integrity sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ== dependencies: - "@csstools/selector-resolve-nested" "^3.0.0" + "@csstools/selector-resolve-nested" "^3.1.0" "@csstools/selector-specificity" "^5.0.0" postcss-selector-parser "^7.0.0" @@ -12681,67 +12660,73 @@ postcss-place@^10.0.0: dependencies: postcss-value-parser "^4.2.0" -postcss-preset-env@^10.1.0: - version "10.1.1" - resolved "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.1.1.tgz" - integrity sha512-wqqsnBFD6VIwcHHRbhjTOcOi4qRVlB26RwSr0ordPj7OubRRxdWebv/aLjKLRR8zkZrbxZyuus03nOIgC5elMQ== - dependencies: - "@csstools/postcss-cascade-layers" "^5.0.1" - "@csstools/postcss-color-function" "^4.0.6" - "@csstools/postcss-color-mix-function" "^3.0.6" - "@csstools/postcss-content-alt-text" "^2.0.4" - "@csstools/postcss-exponential-functions" "^2.0.5" +postcss-preset-env@^10.2.1: + version "10.5.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-10.5.0.tgz#fa9af5b635c053f6d68f91132eab3a0b5c4e53c8" + integrity sha512-xgxFQPAPxeWmsgy8cR7GM1PGAL/smA5E9qU7K//D4vucS01es3M0fDujhDJn3kY8Ip7/vVYcecbe1yY+vBo3qQ== + dependencies: + "@csstools/postcss-alpha-function" "^1.0.1" + "@csstools/postcss-cascade-layers" "^5.0.2" + "@csstools/postcss-color-function" "^4.0.12" + "@csstools/postcss-color-function-display-p3-linear" "^1.0.1" + "@csstools/postcss-color-mix-function" "^3.0.12" + "@csstools/postcss-color-mix-variadic-function-arguments" "^1.0.2" + "@csstools/postcss-content-alt-text" "^2.0.8" + "@csstools/postcss-contrast-color-function" "^2.0.12" + "@csstools/postcss-exponential-functions" "^2.0.9" "@csstools/postcss-font-format-keywords" "^4.0.0" - "@csstools/postcss-gamut-mapping" "^2.0.6" - "@csstools/postcss-gradients-interpolation-method" "^5.0.6" - "@csstools/postcss-hwb-function" "^4.0.6" - "@csstools/postcss-ic-unit" "^4.0.0" - "@csstools/postcss-initial" "^2.0.0" - "@csstools/postcss-is-pseudo-class" "^5.0.1" - "@csstools/postcss-light-dark-function" "^2.0.7" + "@csstools/postcss-gamut-mapping" "^2.0.11" + "@csstools/postcss-gradients-interpolation-method" "^5.0.12" + "@csstools/postcss-hwb-function" "^4.0.12" + "@csstools/postcss-ic-unit" "^4.0.4" + "@csstools/postcss-initial" "^2.0.1" + "@csstools/postcss-is-pseudo-class" "^5.0.3" + "@csstools/postcss-light-dark-function" "^2.0.11" "@csstools/postcss-logical-float-and-clear" "^3.0.0" "@csstools/postcss-logical-overflow" "^2.0.0" "@csstools/postcss-logical-overscroll-behavior" "^2.0.0" "@csstools/postcss-logical-resize" "^3.0.0" - "@csstools/postcss-logical-viewport-units" "^3.0.3" - "@csstools/postcss-media-minmax" "^2.0.5" - "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.4" + "@csstools/postcss-logical-viewport-units" "^3.0.4" + "@csstools/postcss-media-minmax" "^2.0.9" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.5" "@csstools/postcss-nested-calc" "^4.0.0" "@csstools/postcss-normalize-display-values" "^4.0.0" - "@csstools/postcss-oklab-function" "^4.0.6" - "@csstools/postcss-progressive-custom-properties" "^4.0.0" - "@csstools/postcss-random-function" "^1.0.1" - "@csstools/postcss-relative-color-syntax" "^3.0.6" + "@csstools/postcss-oklab-function" "^4.0.12" + "@csstools/postcss-position-area-property" "^1.0.0" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/postcss-random-function" "^2.0.1" + "@csstools/postcss-relative-color-syntax" "^3.0.12" "@csstools/postcss-scope-pseudo-class" "^4.0.1" - "@csstools/postcss-sign-functions" "^1.1.0" - "@csstools/postcss-stepped-value-functions" "^4.0.5" - "@csstools/postcss-text-decoration-shorthand" "^4.0.1" - "@csstools/postcss-trigonometric-functions" "^4.0.5" + "@csstools/postcss-sign-functions" "^1.1.4" + "@csstools/postcss-stepped-value-functions" "^4.0.9" + "@csstools/postcss-system-ui-font-family" "^1.0.0" + "@csstools/postcss-text-decoration-shorthand" "^4.0.3" + "@csstools/postcss-trigonometric-functions" "^4.0.9" "@csstools/postcss-unset-value" "^4.0.0" - autoprefixer "^10.4.19" - browserslist "^4.23.1" + autoprefixer "^10.4.22" + browserslist "^4.28.0" css-blank-pseudo "^7.0.1" - css-has-pseudo "^7.0.1" + css-has-pseudo "^7.0.3" css-prefers-color-scheme "^10.0.0" - cssdb "^8.2.1" + cssdb "^8.5.2" postcss-attribute-case-insensitive "^7.0.1" postcss-clamp "^4.1.0" - postcss-color-functional-notation "^7.0.6" + postcss-color-functional-notation "^7.0.12" postcss-color-hex-alpha "^10.0.0" postcss-color-rebeccapurple "^10.0.0" - postcss-custom-media "^11.0.5" - postcss-custom-properties "^14.0.4" - postcss-custom-selectors "^8.0.4" + postcss-custom-media "^11.0.6" + postcss-custom-properties "^14.0.6" + postcss-custom-selectors "^8.0.5" postcss-dir-pseudo-class "^9.0.1" - postcss-double-position-gradients "^6.0.0" + postcss-double-position-gradients "^6.0.4" postcss-focus-visible "^10.0.1" postcss-focus-within "^9.0.1" postcss-font-variant "^5.0.0" postcss-gap-properties "^6.0.0" postcss-image-set-function "^7.0.0" - postcss-lab-function "^7.0.6" - postcss-logical "^8.0.0" - postcss-nesting "^13.0.1" + postcss-lab-function "^7.0.12" + postcss-logical "^8.1.0" + postcss-nesting "^13.0.2" postcss-opacity-percentage "^3.0.0" postcss-overflow-shorthand "^6.0.0" postcss-page-break "^3.0.4" @@ -12848,7 +12833,7 @@ postcss@8.4.49: picocolors "^1.1.1" source-map-js "^1.2.1" -postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.26, postcss@^8.4.33, postcss@^8.4.38: +postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33: version "8.4.38" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== @@ -12866,6 +12851,15 @@ postcss@^8.5.3: picocolors "^1.1.1" source-map-js "^1.2.1" +postcss@^8.5.4: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + posthog-docusaurus@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/posthog-docusaurus/-/posthog-docusaurus-2.0.0.tgz" @@ -13022,25 +13016,18 @@ pupa@^3.1.0: dependencies: escape-goat "^4.0.0" -qs@6.11.0: - version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== +qs@~6.14.0: + version "6.14.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" + integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== dependencies: - side-channel "^1.0.4" + side-channel "^1.1.0" queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -queue@6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" - quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" @@ -13063,15 +13050,15 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" rc@1.2.8: version "1.2.8" @@ -13083,36 +13070,6 @@ rc@1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-dev-utils@^12.0.1: - version "12.0.1" - resolved "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz" - integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== - dependencies: - "@babel/code-frame" "^7.16.0" - address "^1.1.2" - browserslist "^4.18.1" - chalk "^4.1.2" - cross-spawn "^7.0.3" - detect-port-alt "^1.1.6" - escape-string-regexp "^4.0.0" - filesize "^8.0.6" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.5.0" - global-modules "^2.0.0" - globby "^11.0.4" - gzip-size "^6.0.0" - immer "^9.0.7" - is-root "^2.1.0" - loader-utils "^3.2.0" - open "^8.4.0" - pkg-up "^3.1.0" - prompts "^2.4.2" - react-error-overlay "^6.0.11" - recursive-readdir "^2.2.2" - shell-quote "^1.7.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - react-dom@^18.2.0: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" @@ -13128,36 +13085,11 @@ react-error-boundary@^6.0.0: dependencies: "@babel/runtime" "^7.12.5" -react-error-overlay@^6.0.11: - version "6.0.11" - resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz" - integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== - -react-fast-compare@^3.2.0, react-fast-compare@^3.2.2: +react-fast-compare@^3.2.0: 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== -react-helmet-async@*: - version "2.0.4" - resolved "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz" - integrity sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ== - dependencies: - invariant "^2.2.4" - react-fast-compare "^3.2.2" - shallowequal "^1.1.0" - -react-helmet-async@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz" - integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== - dependencies: - "@babel/runtime" "^7.12.5" - invariant "^2.2.4" - prop-types "^15.7.2" - react-fast-compare "^3.2.0" - shallowequal "^1.1.0" - "react-helmet-async@npm:@slorber/react-helmet-async@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz#11fbc6094605cf60aa04a28c17e0aab894b4ecff" @@ -13179,10 +13111,10 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-json-view-lite@^1.2.0: - version "1.4.0" - resolved "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz" - integrity sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA== +react-json-view-lite@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz#c7ff011c7cc80e9900abc7aa4916c6a5c6d6c1c6" + integrity sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g== react-live@^4.1.6: version "4.1.6" @@ -13363,25 +13295,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reading-time@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz" - integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -recursive-readdir@^2.2.2: - version "2.2.3" - resolved "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz" - integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== - dependencies: - minimatch "^3.0.5" - refractor@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" @@ -13691,7 +13604,7 @@ resolve-pkg-maps@^1.0.0: resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== -resolve@^1.1.6, resolve@^1.14.2: +resolve@^1.14.2: version "1.22.8" resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -13724,13 +13637,6 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - robust-predicates@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" @@ -13774,11 +13680,6 @@ roughjs@^4.6.6: points-on-curve "^0.2.0" points-on-path "^0.2.1" -rtl-detect@^1.0.4: - version "1.1.2" - resolved "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz" - integrity sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ== - rtlcss@^4.1.0: version "4.1.1" resolved "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz" @@ -13789,6 +13690,11 @@ rtlcss@^4.1.0: postcss "^8.4.21" strip-json-comments "^3.1.1" +run-applescript@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.1.0.tgz#2e9e54c4664ec3106c5b5630e249d3d6595c4911" + integrity sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== + run-con@~1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.3.2.tgz#755860a10ce326a96b509485fcea50b4d03754e8" @@ -13865,14 +13771,10 @@ scheduler@^0.23.2: dependencies: loose-envify "^1.1.0" -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" +schema-dts@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.5.tgz#9237725d305bac3469f02b292a035107595dc324" + integrity sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg== schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" @@ -13893,6 +13795,16 @@ schema-utils@^4.0.0, schema-utils@^4.0.1: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" +schema-utils@^4.2.0: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + scrypt-js@3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz" @@ -13911,9 +13823,9 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.1.1: +selfsigned@^2.4.1: version "2.4.1" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== dependencies: "@types/node-forge" "^1.3.0" @@ -13936,24 +13848,24 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.4, semver@^7.6.0: resolved "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== -send@0.18.0: - version "0.18.0" - resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +send@~0.19.0, send@~0.19.1: + version "0.19.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" + integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" + fresh "~0.5.2" + http-errors "~2.0.1" mime "1.6.0" ms "2.1.3" - on-finished "2.4.1" + on-finished "~2.4.1" range-parser "~1.2.1" - statuses "2.0.1" + statuses "~2.0.2" serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: version "6.0.2" @@ -13988,15 +13900,15 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@~1.16.2: + version "1.16.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" + integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "~0.19.1" set-function-length@^1.2.1: version "1.2.2" @@ -14015,7 +13927,7 @@ setprototypeof@1.1.0: resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -14044,19 +13956,10 @@ shebang-regex@^3.0.0: resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.7.3, shell-quote@^1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== - -shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" +shell-quote@^1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== shiki@^0.14.7: version "0.14.7" @@ -14068,15 +13971,45 @@ shiki@^0.14.7: vscode-oniguruma "^1.7.0" vscode-textmate "^8.0.0" -side-channel@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: - call-bind "^1.0.7" es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" siginfo@^2.0.0: version "2.0.0" @@ -14242,16 +14175,16 @@ stackback@0.0.2: resolved "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz" integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - "statuses@>= 1.4.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +statuses@~2.0.1, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + std-env@^3.7.0: version "3.8.0" resolved "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz" @@ -14403,16 +14336,11 @@ stylis@4.3.2: resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz" integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== -stylis@^4.1.3: +stylis@^4.1.3, stylis@^4.3.6: version "4.3.6" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.6.tgz#7c7b97191cb4f195f03ecab7d52f7902ed378320" integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== -stylis@^4.3.1: - version "4.3.4" - resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz" - integrity sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now== - sucrase@^3.31.0: version "3.35.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz" @@ -14470,6 +14398,14 @@ svgo@^3.0.2, svgo@^3.2.0: csso "^5.0.5" picocolors "^1.0.0" +swr@^2.2.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/swr/-/swr-2.3.8.tgz#aa15596321a34e575226a60576bade0b57adf7bf" + integrity sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w== + dependencies: + dequal "^2.0.3" + use-sync-external-store "^1.6.0" + tabbable@^6.0.0: version "6.2.0" resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" @@ -14480,11 +14416,6 @@ tailwind-merge@2.6.0: resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.6.0.tgz#ac5fb7e227910c038d458f396b7400d93a3142d5" integrity sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA== -tapable@^1.0.0: - version "1.1.3" - resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" @@ -14511,11 +14442,6 @@ terser@^5.10.0, terser@^5.15.1, terser@^5.26.0: commander "^2.20.0" source-map-support "~0.5.20" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" @@ -14530,6 +14456,16 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +thingies@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/thingies/-/thingies-2.5.0.tgz#5f7b882c933b85989f8466b528a6247a6881e04f" + integrity sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw== + +throttleit@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-2.1.0.tgz#a7e4aa0bf4845a5bd10daa39ea0c783f631a07b4" + integrity sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw== + thunky@^1.0.2: version "1.1.0" resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" @@ -14550,16 +14486,16 @@ tinybench@^2.9.0: resolved "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz" integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== -tinyexec@^0.3.0: - version "0.3.1" - resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz" - integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== - tinyexec@^0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz" integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== +tinyexec@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.2.tgz#bdd2737fe2ba40bd6f918ae26642f264b99ca251" + integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== + tinypool@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz" @@ -14594,9 +14530,9 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: +toidentifier@~1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== totalist@^3.0.0: @@ -14609,6 +14545,11 @@ tr46@~0.0.3: resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +tree-dump@^1.0.3, tree-dump@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.1.0.tgz#ab29129169dc46004414f5a9d4a3c6e89f13e8a4" + integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA== + trim-lines@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" @@ -14721,10 +14662,10 @@ uc.micro@^2.0.0, uc.micro@^2.1.0: resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee" integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A== -ufo@^1.5.4: - version "1.5.4" - resolved "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz" - integrity sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ== +ufo@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" + integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== undici-types@~5.26.4: version "5.26.5" @@ -14869,7 +14810,7 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -14890,6 +14831,14 @@ update-browserslist-db@^1.1.1: escalade "^3.2.0" picocolors "^1.1.0" +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + update-notifier@^6.0.2: version "6.0.2" resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz" @@ -14968,6 +14917,11 @@ use-sync-external-store@^1.4.0: resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz#55122e2a3edd2a6c106174c27485e0fd59bcfca0" integrity sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A== +use-sync-external-store@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" + integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -14995,12 +14949,17 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" + integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^9.0.0, uuid@^9.0.1: +uuid@^9.0.0: version "9.0.1" resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== @@ -15201,52 +15160,51 @@ webpack-bundle-analyzer@^4.10.2: sirv "^2.0.3" ws "^7.3.1" -webpack-dev-middleware@^5.3.4: - version "5.3.4" - resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== +webpack-dev-middleware@^7.4.2: + version "7.4.5" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz#d4e8720aa29cb03bc158084a94edb4594e3b7ac0" + integrity sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA== dependencies: colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" + memfs "^4.43.1" + mime-types "^3.0.1" + on-finished "^2.4.1" range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.15.2: - version "4.15.2" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz" - integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" +webpack-dev-server@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz#96a143d50c58fef0c79107e61df911728d7ceb39" + integrity sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg== + dependencies: + "@types/bonjour" "^3.5.13" + "@types/connect-history-api-fallback" "^1.5.4" + "@types/express" "^4.17.21" + "@types/express-serve-static-core" "^4.17.21" + "@types/serve-index" "^1.9.4" + "@types/serve-static" "^1.15.5" + "@types/sockjs" "^0.3.36" + "@types/ws" "^8.5.10" ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" + bonjour-service "^1.2.1" + chokidar "^3.6.0" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" + express "^4.21.2" graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" + http-proxy-middleware "^2.0.9" + ipaddr.js "^2.1.0" + launch-editor "^2.6.1" + open "^10.0.3" + p-retry "^6.2.0" + schema-utils "^4.2.0" + selfsigned "^2.4.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" - webpack-dev-middleware "^5.3.4" - ws "^8.13.0" + webpack-dev-middleware "^7.4.2" + ws "^8.18.0" webpack-merge@^5.9.0: version "5.10.0" @@ -15366,13 +15324,6 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -which@^1.3.1: - version "1.3.1" - resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -15452,10 +15403,17 @@ ws@^7.3.1: resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.13.0: - version "8.17.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz" - integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== +ws@^8.18.0: + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== + +wsl-utils@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/wsl-utils/-/wsl-utils-0.1.0.tgz#8783d4df671d4d50365be2ee4c71917a0557baab" + integrity sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw== + dependencies: + is-wsl "^3.1.0" xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: version "5.1.0" @@ -15479,26 +15437,21 @@ yallist@^3.0.2: resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yaml@^2.3.4: version "2.4.2" resolved "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz" integrity sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA== -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - yocto-queue@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== +zod@^4.1.8: + version "4.2.1" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.2.1.tgz#07f0388c7edbfd5f5a2466181cb4adf5b5dbd57b" + integrity sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw== + zwitch@^2.0.0: version "2.0.4" resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" From 093b6a57c7f468b339e18527b8d780317bef1f08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:48:25 -0800 Subject: [PATCH 156/162] remove SBE sync script --- scripts/sync-stylus-content.js | 671 --------------------------------- 1 file changed, 671 deletions(-) delete mode 100644 scripts/sync-stylus-content.js diff --git a/scripts/sync-stylus-content.js b/scripts/sync-stylus-content.js deleted file mode 100644 index 504cfd29a6..0000000000 --- a/scripts/sync-stylus-content.js +++ /dev/null @@ -1,671 +0,0 @@ -#!/usr/bin/env node - -/** - * @fileoverview Sync content from stylus-by-example submodule to docs directory - * @description Replaces the complex 897-line stylusByExampleDocsHandler.ts with a maintainable solution - * @author sync-stylus-content.js - * @version 2.0.0 (refactored for maintainability) - */ - -const fs = require('fs-extra'); -const path = require('path'); -const glob = require('glob'); - -// ============================================================================ -// CONFIGURATION - All constants and settings in one place -// ============================================================================ - -/** - * @typedef {Object} SyncConfig - * @property {Object} paths - File and directory paths - * @property {Object} content - Content processing settings - * @property {Object} allowLists - File filtering configurations - * @property {Object} output - Output generation settings - */ - -/** @type {SyncConfig} */ -const CONFIG = { - paths: { - sourceDir: path.join(__dirname, '../submodules/stylus-by-example/src/app'), - targetDir: path.join(__dirname, '../docs/stylus-by-example'), - dontEditMarker: 'DONT-EDIT-THIS-FOLDER', - sourcePattern: '**/page.mdx', - sidebarFileName: 'sidebar.js', - }, - - content: { - fileExtensions: { - source: '.mdx', - target: '.mdx', - sidebar: '.js', - }, - markers: { - contentBegin: '{/* Begin Content */}', - frontmatterDelimiter: '---', - }, - patterns: { - metadata: /export\s+const\s+metadata\s*=\s*({[\s\S]*?});/, - relativeLink: /\[([^\]]+)\]\(\.\/([\w_]+)\)/g, - }, - }, - - allowLists: { - basicExamples: [ - 'hello_world', - 'primitive_data_types', - 'variables', - 'constants', - 'function', - 'errors', - 'events', - 'inheritance', - 'vm_affordances', - 'sending_ether', - 'function_selector', - 'abi_encode', - 'abi_decode', - 'hashing', - 'bytes_in_bytes_out', - ], - applications: ['erc20', 'erc721', 'vending_machine', 'multi_call'], - }, - - output: { - sections: ['basic_examples', 'applications'], - indexFileName: 'index.mdx', - sidebarTemplate: { - fileHeader: '// @ts-check', - docString: 'Autogenerated sidebar configuration for Stylus by Example', - typeAnnotation: "/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */", - }, - }, -}; - -// ============================================================================ -// UTILITY FUNCTIONS - Reusable helper functions -// ============================================================================ - -/** - * Creates a standardized error with context information - * @param {string} message - Error message - * @param {string} context - Additional context (file path, operation, etc.) - * @param {Error} [originalError] - Original error object if available - * @returns {Error} Enhanced error object - */ -function createError(message, context, originalError = null) { - const errorMessage = `${message} (Context: ${context})`; - const error = new Error(errorMessage); - error.context = context; - error.originalError = originalError; - return error; -} - -/** - * Logs messages with consistent formatting and timestamps - * @param {string} level - Log level (info, warn, error, success) - * @param {string} message - Message to log - * @param {Object} [details] - Additional details to log - */ -function log(level, message, details = null) { - const timestamp = new Date().toISOString(); - const emoji = - { - info: '๐Ÿ”„', - warn: 'โš ๏ธ', - error: 'โŒ', - success: 'โœ…', - clean: '๐Ÿงน', - file: '๐Ÿ“', - write: '๐Ÿ“', - }[level] || 'โ„น๏ธ'; - - console.log(`${emoji} ${message}`); - - if (details) { - console.log(` Details: ${JSON.stringify(details, null, 2)}`); - } -} - -/** - * Converts snake_case string to Title Case - * @param {string} snakeCaseStr - String in snake_case format - * @returns {string} String in Title Case format - */ -function snakeCaseToTitleCase(snakeCaseStr) { - return snakeCaseStr - .split('_') - .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) - .join(' '); -} - -/** - * Safely evaluates a JavaScript object literal string - * @param {string} objectStr - String representation of JavaScript object - * @returns {Object} Parsed object - * @throws {Error} If evaluation fails - */ -function safeEvalObjectLiteral(objectStr) { - try { - // Use Function constructor to safely evaluate the object literal - return new Function(`return ${objectStr}`)(); - } catch (error) { - throw createError('Failed to evaluate object literal', objectStr, error); - } -} - -/** - * Escapes single quotes in strings for YAML frontmatter - * @param {string} str - String to escape - * @returns {string} Escaped string - */ -function escapeYamlString(str) { - return str.replace(/'/g, "''"); -} - -/** - * Generates a timestamp string for file headers - * @returns {string} ISO timestamp string - */ -function generateTimestamp() { - return new Date().toISOString(); -} - -// ============================================================================ -// PATH AND FILE UTILITIES - File system operations and path manipulation -// ============================================================================ - -/** - * Extracts section name from a file path relative to source directory - * @param {string} filePath - Full file path - * @returns {string|null} Section name ('basic_examples' or 'applications') or null - */ -function extractSectionFromPath(filePath) { - const relativePath = path.relative(CONFIG.paths.sourceDir, filePath); - const segments = relativePath.split(path.sep); - - return segments.length >= 2 ? segments[0] : null; -} - -/** - * Extracts the item name (directory name) from a file path - * @param {string} filePath - Full file path to page.mdx - * @returns {string} Directory name containing the file - */ -function extractItemNameFromPath(filePath) { - return path.basename(path.dirname(filePath)); -} - -/** - * Gets the appropriate allowlist for a section - * @param {string} sectionName - Section name ('basic_examples' or 'applications') - * @returns {string[]} Array of allowed file names - */ -function getAllowListForSection(sectionName) { - const allowListMap = { - basic_examples: CONFIG.allowLists.basicExamples, - applications: CONFIG.allowLists.applications, - }; - - return allowListMap[sectionName] || []; -} - -/** - * Determines if a file should be processed based on allowlists - * @param {string} filePath - Full path to the file - * @returns {boolean} True if file should be processed - */ -function isFileAllowed(filePath) { - const sectionName = extractSectionFromPath(filePath); - if (!sectionName) return false; - - const itemName = extractItemNameFromPath(filePath); - const allowList = getAllowListForSection(sectionName); - - return allowList.includes(itemName); -} - -/** - * Generates target file path from source file path - * @param {string} sourceFile - Source file path - * @returns {Object} Object with targetPath and metadata - */ -function generateTargetPath(sourceFile) { - const relativePath = path.relative(CONFIG.paths.sourceDir, sourceFile); - const targetDir = path.dirname(relativePath); - - let targetFileName; - let finalTargetDir; - - if (targetDir === '.') { - // Root level file - targetFileName = CONFIG.output.indexFileName; - finalTargetDir = CONFIG.paths.targetDir; - } else { - // Section subdirectory file - const pathParts = targetDir.split(path.sep); - const sectionName = pathParts[0]; - const itemName = pathParts[1]; - - targetFileName = `${itemName}${CONFIG.content.fileExtensions.target}`; - finalTargetDir = path.join(CONFIG.paths.targetDir, sectionName); - } - - return { - targetPath: path.join(finalTargetDir, targetFileName), - targetDir: finalTargetDir, - fileName: targetFileName, - }; -} - -// ============================================================================ -// CONTENT TRANSFORMATION - Text processing and content manipulation -// ============================================================================ - -/** - * Converts a metadata object to YAML frontmatter format - * @param {Object} metadata - Metadata object to convert - * @returns {string} YAML frontmatter string - */ -function convertMetadataToYaml(metadata) { - const yamlLines = Object.entries(metadata).map(([key, value]) => { - if (typeof value === 'string') { - return `${key}: '${escapeYamlString(value)}'`; - } - return `${key}: ${value}`; - }); - - return yamlLines.join('\n'); -} - -/** - * Transforms Next.js metadata export to Docusaurus frontmatter - * @param {string} content - File content with metadata export - * @returns {string} Content with frontmatter instead of metadata export - */ -function convertMetadataToFrontmatter(content) { - const match = content.match(CONFIG.content.patterns.metadata); - if (!match) return content; - - try { - const metadataStr = match[1]; - const metadata = safeEvalObjectLiteral(metadataStr); - const frontmatter = convertMetadataToYaml(metadata); - - const delimiter = CONFIG.content.markers.frontmatterDelimiter; - const replacement = `${delimiter}\n${frontmatter}\n${delimiter}`; - - return content.replace(CONFIG.content.patterns.metadata, replacement); - } catch (error) { - log('warn', `Could not convert metadata: ${error.message}`); - return content; - } -} - -/** - * Fixes relative links to work with Docusaurus URL structure - * @param {string} content - Content with relative links - * @returns {string} Content with fixed absolute links - */ -function fixRelativeLinks(content) { - return content.replace(CONFIG.content.patterns.relativeLink, (match, linkText, dirName) => { - // Convert to absolute Docusaurus path - return `[${linkText}](/stylus-by-example/basic_examples/${dirName})`; - }); -} - -/** - * Adds content begin marker if not already present - * @param {string} content - File content - * @returns {string} Content with begin marker - */ -function addContentBeginMarker(content) { - const marker = CONFIG.content.markers.contentBegin; - if (content.includes(marker)) return content; - - const delimiter = CONFIG.content.markers.frontmatterDelimiter; - const frontmatterEnd = content.indexOf(delimiter, 3); - - if (frontmatterEnd === -1) return content; - - const insertPos = content.indexOf('\n', frontmatterEnd + 3) + 1; - return content.slice(0, insertPos) + `\n${marker}\n` + content.slice(insertPos); -} - -/** - * Adds "not for production" banner import and component two lines before first rust code block - * @param {string} content - File content - * @returns {string} Content with banner added - */ -function addNotForProductionBanner(content) { - const firstCodeBlock = '```rust'; - const bannerCode = ` -import NotForProductionBannerPartial from '../../partials/_not-for-production-banner-partial.mdx'; - - -`; - - // Find the first occurrence of ```rust code block - const index = content.indexOf(firstCodeBlock); - if (index === -1) { - // No rust code block found, return content unchanged - return content; - } - - // Find the position two lines before the first code block - const lines = content.substring(0, index).split('\n'); - const insertLineIndex = lines.length - 2; - - // Insert the banner at the calculated position - lines.splice(insertLineIndex, 0, bannerCode); - - // Reconstruct the content with the banner inserted - const newContent = lines.join('\n') + content.substring(index); - return newContent; -} - -/** - * Applies all content transformations to a file - * @param {string} content - Original file content - * @returns {string} Transformed content - */ -function transformContent(content) { - let transformedContent = content; - - // Apply transformations in sequence - transformedContent = convertMetadataToFrontmatter(transformedContent); - transformedContent = fixRelativeLinks(transformedContent); - transformedContent = addContentBeginMarker(transformedContent); - transformedContent = addNotForProductionBanner(transformedContent); - - return transformedContent; -} - -// ============================================================================ -// SIDEBAR GENERATION - Sidebar configuration file generation -// ============================================================================ - -/** - * Creates a sidebar item object for a file - * @param {string} sectionName - Section name (basic_examples, applications) - * @param {string} fileName - File name without extension - * @returns {Object} Sidebar item configuration - */ -function createSidebarItem(sectionName, fileName) { - return { - type: 'doc', - id: `stylus-by-example/${sectionName}/${fileName}`, - label: snakeCaseToTitleCase(fileName), - }; -} - -/** - * Generates the complete sidebar JavaScript file content - * @param {string} sectionName - Section name for the sidebar - * @param {Object[]} sidebarItems - Array of sidebar item objects - * @returns {string} Complete sidebar file content - */ -function generateSidebarFileContent(sectionName, sidebarItems) { - const template = CONFIG.output.sidebarTemplate; - const timestamp = generateTimestamp(); - - return `${template.fileHeader} -/** - * @fileoverview ${template.docString} ${sectionName} - * @description This file is automatically generated by sync-stylus-content.js - * @generated ${timestamp} - * @see https://docusaurus.io/docs/sidebar - * @see https://docusaurus.io/docs/sidebar/items - */ - -${template.typeAnnotation} -const sidebar = ${JSON.stringify({ items: sidebarItems }, null, 2)}; - -module.exports = sidebar.items; -`; -} - -/** - * Generates sidebar configuration for a section directory - * @param {string} sectionName - Section name (basic_examples, applications) - * @param {string[]} files - Array of file paths - * @returns {string} Complete sidebar JavaScript file content - */ -function generateSidebar(sectionName, files) { - const allowList = getAllowListForSection(sectionName); - const itemsByFileName = {}; - - // Collect all items by filename, skipping index files - files.forEach((file) => { - const fileName = path.basename(file, CONFIG.content.fileExtensions.source); - - // Skip index files (filename matches section name) - if (fileName === sectionName) return; - - const item = createSidebarItem(sectionName, fileName); - itemsByFileName[fileName] = item; - }); - - // Order items according to allowlist - const orderedItems = allowList - .map((allowedFileName) => itemsByFileName[allowedFileName]) - .filter(Boolean); // Remove undefined items - - return generateSidebarFileContent(sectionName, orderedItems); -} - -// ============================================================================ -// FILE OPERATIONS - High-level file processing functions -// ============================================================================ - -/** - * Processes and copies a single MDX file with transformations - * @param {string} sourcePath - Source file path - * @param {string} targetPath - Target file path - * @returns {Promise} True if processing succeeded - */ -async function processFile(sourcePath, targetPath) { - try { - // Read and transform content - const content = await fs.readFile(sourcePath, 'utf8'); - const transformedContent = transformContent(content); - - // Ensure target directory exists and write file - await fs.ensureDir(path.dirname(targetPath)); - await fs.writeFile(targetPath, transformedContent); - - return true; - } catch (error) { - log('error', `Failed to process file: ${sourcePath}`, { - error: error.message, - targetPath, - }); - return false; - } -} - -/** - * Creates the "don't edit" marker file in target directory - * @param {string} targetDir - Target directory path - * @param {boolean} isSubmoduleAvailable - Whether submodule is available - * @returns {Promise} - */ -async function createDontEditMarker(targetDir, isSubmoduleAvailable = true) { - const timestamp = generateTimestamp(); - const markerPath = path.join(targetDir, CONFIG.paths.dontEditMarker); - - const content = isSubmoduleAvailable - ? `This folder is auto-generated from submodules/stylus-by-example -Do not edit files directly here. Edit them in the submodule instead. -Generated: ${timestamp} -` - : `This folder would contain auto-generated content from submodules/stylus-by-example -The submodule was not available during build. -Generated: ${timestamp} -`; - - await fs.writeFile(markerPath, content); -} - -/** - * Creates empty sidebar files for sections when submodule is unavailable - * @param {string} targetDir - Target directory path - * @returns {Promise} - */ -async function createEmptySidebars(targetDir) { - const timestamp = generateTimestamp(); - const template = CONFIG.output.sidebarTemplate; - - const emptySidebarContent = `${template.fileHeader} -/** - * @fileoverview Empty sidebar configuration (submodule not available) - * @generated ${timestamp} - */ - -${template.typeAnnotation} -const sidebar = { - items: [] -}; - -module.exports = sidebar.items; -`; - - for (const sectionName of CONFIG.output.sections) { - const sectionDir = path.join(targetDir, sectionName); - await fs.ensureDir(sectionDir); - - const sidebarPath = path.join(sectionDir, CONFIG.paths.sidebarFileName); - await fs.writeFile(sidebarPath, emptySidebarContent); - } -} - -/** - * Generates sidebar files for all processed sections - * @param {string} targetDir - Target directory path - * @returns {Promise} - */ -async function generateAllSidebars(targetDir) { - for (const sectionName of CONFIG.output.sections) { - const sectionDir = path.join(targetDir, sectionName); - - if (await fs.pathExists(sectionDir)) { - const pattern = path.join(sectionDir, `**/*${CONFIG.content.fileExtensions.source}`); - const sectionFiles = glob.sync(pattern); - - const sidebarContent = generateSidebar(sectionName, sectionFiles); - const sidebarPath = path.join(sectionDir, CONFIG.paths.sidebarFileName); - - await fs.writeFile(sidebarPath, sidebarContent); - log('write', `Generated sidebar for ${sectionName}`, { - itemCount: sectionFiles.length, - }); - } - } -} - -// ============================================================================ -// MAIN SYNC LOGIC - Core synchronization workflow -// ============================================================================ - -/** - * Handles the case when the source submodule is not available - * @returns {Promise} - */ -async function handleMissingSubmodule() { - log('warn', `Source directory not found: ${CONFIG.paths.sourceDir}`); - log('info', 'Skipping Stylus by Example content sync.'); - log('info', 'To include this content, initialize the submodule:'); - log('info', ' git submodule update --init --recursive'); - - // Create empty structure - await fs.ensureDir(CONFIG.paths.targetDir); - await createDontEditMarker(CONFIG.paths.targetDir, false); - await createEmptySidebars(CONFIG.paths.targetDir); - - log('success', 'Created empty Stylus by Example structure'); -} - -/** - * Processes all allowed files from source to target directory - * @param {string[]} allowedFiles - Array of file paths to process - * @returns {Promise} Number of successfully processed files - */ -async function processAllFiles(allowedFiles) { - let successCount = 0; - - for (const sourceFile of allowedFiles) { - const { targetPath } = generateTargetPath(sourceFile); - - if (await processFile(sourceFile, targetPath)) { - successCount++; - } - } - - return successCount; -} - -/** - * Main synchronization function - * @returns {Promise} - */ -async function syncContent() { - log('info', 'Syncing Stylus by Example content...'); - - try { - // Check if source exists - if (!(await fs.pathExists(CONFIG.paths.sourceDir))) { - await handleMissingSubmodule(); - return; - } - - // Clean and recreate target directory - if (await fs.pathExists(CONFIG.paths.targetDir)) { - log('clean', 'Cleaning target directory...'); - await fs.remove(CONFIG.paths.targetDir); - } - - await fs.ensureDir(CONFIG.paths.targetDir); - await createDontEditMarker(CONFIG.paths.targetDir, true); - - // Find and filter files - const sourcePattern = path.join(CONFIG.paths.sourceDir, CONFIG.paths.sourcePattern); - const allFiles = glob.sync(sourcePattern); - const allowedFiles = allFiles.filter(isFileAllowed); - - log( - 'file', - `Found ${allFiles.length} total files, ${allowedFiles.length} allowed files to process`, - ); - - // Process all files - const successCount = await processAllFiles(allowedFiles); - - // Generate sidebars - await generateAllSidebars(CONFIG.paths.targetDir); - - log('success', `Successfully synced ${successCount}/${allowedFiles.length} files`); - } catch (error) { - log('error', `Sync failed: ${error.message}`, { - stack: error.stack, - context: error.context || 'Unknown', - }); - process.exit(1); - } -} - -// ============================================================================ -// MODULE EXPORTS AND EXECUTION -// ============================================================================ - -// Run if called directly -if (require.main === module) { - syncContent(); -} - -module.exports = { - syncContent, - // Export utilities for testing - CONFIG, - isFileAllowed, - transformContent, - generateSidebar, -}; From 7aa4f656bb34277780169ce61cf4484ba5b909b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 18:55:18 -0800 Subject: [PATCH 157/162] remove unneeded diagram --- docs/stylus/fundamentals/contracts.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/stylus/fundamentals/contracts.mdx b/docs/stylus/fundamentals/contracts.mdx index d0ea140433..b5ba85e034 100644 --- a/docs/stylus/fundamentals/contracts.mdx +++ b/docs/stylus/fundamentals/contracts.mdx @@ -18,10 +18,6 @@ A Stylus contract consists of three main components: 2. **Entrypoint**: Marks the main contract struct that handles incoming calls 3. **Public Methods**: Functions exposed to external callers via the `#[public]` macro -![Contract Lifecycle](/img/stylus-contract-lifecycle.png) - -_Figure: Contract lifecycle from development through execution, showing how calls are routed and processed._ - ### Minimal Contract Here's the simplest possible Stylus contract: From c02ad008b147f8f7676652f2fe00aed04b083653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 19:26:06 -0800 Subject: [PATCH 158/162] remove unnecessary title attribute --- docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx b/docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx index a3e111bbba..fc3e5a7db4 100644 --- a/docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx +++ b/docs/stylus/guides/deploying-non-rust-wasm-contracts.mdx @@ -10,8 +10,6 @@ sidebar_position: 3 displayed_sidebar: buildStylusSidebar --- -# Deploying Non-Rust WASM Contracts - While Rust provides the best developer experience for Stylus, any language that compiles to WebAssembly can be deployed. This guide explains how to deploy WASM contracts written in C, C++, or even pure WebAssembly Text (WAT). ## Overview From 84742cb4d82827ed9c2fd911f9dcab341e7ef0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 19:27:18 -0800 Subject: [PATCH 159/162] remove unnecessary title attribute --- docs/stylus/troubleshooting/common-issues.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/stylus/troubleshooting/common-issues.mdx b/docs/stylus/troubleshooting/common-issues.mdx index 77dbe35048..443870b9c8 100644 --- a/docs/stylus/troubleshooting/common-issues.mdx +++ b/docs/stylus/troubleshooting/common-issues.mdx @@ -9,8 +9,6 @@ sme: offchainlabs sidebar_position: 1 --- -# Common issues and solutions - This guide covers frequently encountered issues in Stylus development with step-by-step solutions. ## Installation and setup From f14f9a03eab026cf5f410c6e38815ef5c6f3cdd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 17 Dec 2025 19:28:34 -0800 Subject: [PATCH 160/162] remove unnecessary title attribute --- docs/stylus/best-practices/gas-optimization.mdx | 2 -- docs/stylus/best-practices/security.mdx | 2 -- docs/stylus/cli-tools/commands-reference.mdx | 2 -- 3 files changed, 6 deletions(-) diff --git a/docs/stylus/best-practices/gas-optimization.mdx b/docs/stylus/best-practices/gas-optimization.mdx index 4be460315f..e8c35dd56b 100644 --- a/docs/stylus/best-practices/gas-optimization.mdx +++ b/docs/stylus/best-practices/gas-optimization.mdx @@ -9,8 +9,6 @@ sme: offchainlabs sidebar_position: 2 --- -# Gas optimization best practices - Stylus contracts offer significant gas savings compared to Solidity (10-100x for compute-heavy operations), but following optimization best practices can reduce costs even further. ## Why Stylus is cheaper diff --git a/docs/stylus/best-practices/security.mdx b/docs/stylus/best-practices/security.mdx index 6750cbfbb6..a3e320835a 100644 --- a/docs/stylus/best-practices/security.mdx +++ b/docs/stylus/best-practices/security.mdx @@ -9,8 +9,6 @@ sme: offchainlabs sidebar_position: 1 --- -# Security best practices - Writing secure smart contracts is critical - vulnerabilities can lead to loss of funds and user trust. This guide covers essential security patterns for Stylus development. ## Core security principles diff --git a/docs/stylus/cli-tools/commands-reference.mdx b/docs/stylus/cli-tools/commands-reference.mdx index 6393cd52fd..7f4539c50c 100644 --- a/docs/stylus/cli-tools/commands-reference.mdx +++ b/docs/stylus/cli-tools/commands-reference.mdx @@ -9,8 +9,6 @@ sme: offchainlabs sidebar_position: 5 --- -# cargo-stylus command reference - Complete reference for all `cargo-stylus` commands. ## new From cc8124df1d046508f6d0f1d49fe0f0ae847d8985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 2 Jan 2026 12:46:53 -0800 Subject: [PATCH 161/162] docs: add Stylus logo inline at beginning of quickstart article --- docs/stylus/quickstart.mdx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 510bbb498a..2b826e513e 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -13,9 +13,13 @@ displayed_sidebar: buildStylusSidebar import ImageZoom from '@site/src/components/ImageZoom'; - - -This guide will get you started with Stylus' basics. We'll cover the following steps: +Stylus This guide will get you started with Stylus' basics. We'll +cover the following steps: 1. [Setting up your development environment](./quickstart#setting-up-your-development-environment) 2. [Creating a Stylus project with cargo stylus](./quickstart#creating-a-stylus-project-with-cargo-stylus) From 2ec6df7bb8886cb5bcec38704d9bb387cfb714af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 2 Jan 2026 12:48:44 -0800 Subject: [PATCH 162/162] docs: move Stylus logo to be inline with article title --- docs/stylus/quickstart.mdx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/stylus/quickstart.mdx b/docs/stylus/quickstart.mdx index 2b826e513e..85b287caeb 100644 --- a/docs/stylus/quickstart.mdx +++ b/docs/stylus/quickstart.mdx @@ -13,12 +13,9 @@ displayed_sidebar: buildStylusSidebar import ImageZoom from '@site/src/components/ImageZoom'; -Stylus This guide will get you started with Stylus' basics. We'll +# Stylus Quickstart: write a smart contract in Rust using Stylus + +This guide will get you started with Stylus' basics. We'll cover the following steps: 1. [Setting up your development environment](./quickstart#setting-up-your-development-environment)

    MOpxsHvpXxQv~qh0hpxClNkGA5nNYZC=@D!$ARczr@Pil9||Q=*jgW< z;eA5G^jwFY>2GFDz@-#2nq8rBr+%MSyYxyT=sZ1SOh*Yp+Fpj%#vCo>Va%_5nuo={I5Q7l_o4M;ovcbA*g#L zJIH!EoKpjo<-Paq0}3g|KhSU6O`1^A>xy5ycx58nurLX2ouCF zR$%jn->zTyZatz@QXnhR9wg1x{wO8M%Sl_AO6b19HTS_So{HJU&P-X;v8+6I1P6oY z73W9f7gnLSu2FZhhWwr=K16+OKlMz{QnW3X630m17l4A7P5F)IJ>9lxygmI6i+_9p zgWk;=(W^TnP2se7{9p8YonTw`TuC59!%?fmBZc*ZHHA2pltc8-;;L05mm&G+r{1Tq z`HNk4JU%o_sb<7DXbMunjJG}qN73|k^hAQ_7lL{vWM|7nDua8^wZ;n4TQOE;;!g`p zZNsE^pQ71+N#|qH*qZlv(Vcy@tj*J6a2lF1(d$IhZmB14n0#uma7ZfjOe9|!5;`&C z$VxWM+19rlzCM23 zz;uPF);Rq`3a2EmQ%L#6A0dTYbEuE?ycdh)t}4R4+X2!T0#67`a`SxC_HOdRpe~wg zx1rS@y=sr<+~ZvP7er`yJIJ7}27_QR%Vm4G1yILjiC|z!To(Mm#_(T3Hn@RY{*E_O zGe^87um-H}iEK1T8*QZlJ=9I#X$C*xdkd^esm;{3rz^JmG23T+{yrUFB!^O)V7m0Kx`fvZk zeY+l8h4KfKDk$;2LB#}W8)*UGE(cNbZ3@R0$AtHzVy;2;=($mFBZZ<&yX0WQO($b^bTQ9AIU5Cy!#80^(U3L$#ImV<4lVh z3Z_09^Ee}{k$l56t~!&OJo_U`ZwXK_&A;l_eI3W$ALZDPYL#GNDMblN;p*xCe1vYW z`H~x5o!kJxuLS-!HkR%CT=BV4P~vWn&4ZqVz9uG-2)@9ti+QoHd`bEPSN25d1J01e z78r=EVRB3HRZa<4PC45FxUYf!tcm$sV&NaiLgL4__|IEDFx2lvZUi-aKhMiHl1u(-rFY=C0wA0ldlU~( zMFM%Dydv?IT@Pcgz_!O<7oQ}oUk+WT^IG(T4v}$(iTaC~b@hjWaVU5#;Ojjx(>eOX z)0cmK^@L*I-EzyBOyvIkbgzHOmT!vp-VcL6C&4&)5QRIWU`M$d)`EyM)5yOvUMZpqV!;4D* zI2`!R855>y*XU<5JTKFcILSBhrkk*!`cv{R7(IPeglpHsJ zaJ{u0yrMu1hyaknE%k_Hs7NH`A^F-~j}wGHOX2Q;JXLo&b7RlYZ-#-p?97=eMY=2G zcpG@k7w`WzRlSUV%~&u0Uz?tYPk);+oLHcVb~D3HBEj11N4*VLYNyACNqB&Ol)4p_ zpL8-!eQg>pKqqRyL9VO62GQ5c#Xj*E>nEbweo5)+GSIK9F#Fv3&L1n~GnU+}qS{Dc zP{7trVwMx<{@nSs9hdQesCV%l%Wj;yfe3U2ItzxvVjuvn>nwE~BY=u2JoPGSgLUVS z6VY|;Z0vR&p!4C;=)42L$lF@3HmCK~4wFDFoCPs-0V9XZ;n!O?;itW2#o{f-P=Hq| zuN{#4?}diaMa4qyI(%rpQOeY$c(P~2`KMc*zisFFNYMtV(y44pjfM>`Zp;iP@Bcz^ z^<%U@My6WR_(?uG_CHoH!5?^NZif2MH$`V}Hr5~-=054li?BJ!}Bhy8#_2Z%>-A9{4( zSaK7&)6b5HN{18GRdf@Te)Yb~dH@oQ2iJ>)%sO6Lp9tvnh%qTX*>CAQtqHEgYAr7u zu_$=a)+uDDxOk!jAWHpMYh5w)x8D{#m;Kp=&Ct4ppOhiMXUZi`1@EPrw)>HLZJabC z9*3Ka-LoKK7+MX3Z1!BF_4T&^SPOa89+&JzUvS*ddIGPVfH6--eUH81%pi_Q5*@P5 zN#8lb^N`{8CZuwE7Ic-pEzZgCK{XQl@HdEEFGqO9O&SNV&kEo4_pjZ+5iL(~TN^Gm zc1rkt_elSmfjdNsG6Q=s5qNFxhIH}#C$AyPGrl}PomOvw$*`{=(giufHonG{ar z{8<}2wIb>4^YNzAFF5^@WzJ9X(myHCmZuCUcDTQ%Cr&e-x*9Mxw1^F6Z&Caib-&Ig zHT)9HV1lAGK`nB49jvrcV^72!sgfC@&}djB86ER2g@?Xv+HXW4be`e<%Z4b8^r`zh z9-T6>;05Ob4^kG5MAXgz{ksC+VNr__y5Z(Kg!jY7(R~~qAePe{)nIp?^{oCv90dkZ zlUpAQiaKWOoHBcga4XD>4VV4o$1$)_I6t;pNbEF!dT9r0X6f;-_}I<2jn{O5nVITU zC9-8k269%=$Y8YXEvRS`eus7O%sVUV!`a%=(!5^u`Y*Y2)f`mJjk;SF?jp^rs_fjP zG$igK2zQ+a@VMzB^`m6aOaRbBY%muGHX-IJnGI&C>-r6PW=pY%F$e6BB2jw|bYok` zyC)xO&S+$SKpMDUrGVrb=O0Gc_51}xf_jw%I_(L+&`vKi%-*i3A7}SgpGnU>4&gB; z?XxVtTVxNRXqbQV)2oG9dWIf%HEG-4oN zHWBWBO(rhN!crvA8yN(vdB}cwweV!kM7Zl38o!?H)ag^eltA{LbcpafC)05_Xo*Ji zyG5FG@R(-hLAKFdT`=+3!TU7fWVMD!XWvYtSwr(<@At^#x%TR!`nBaX(}aY@ufmf> zuW?X)kV&IgsGgu#hN0~nQ`0N15UlXb`j~VX;6$u2@43_w=BE)gHAF2wvl@!~piOSh z64hg;4=+SQlD4Fp=0AdaU%Ytai)kwWcF~RyU`5p|k5+AUJ9hm(N!3FD3b#v>z21A_ z=Q_@8wvNS+H;Mb&yuq=?J2j9+tEh2OCA-4R!@El$VDjALh!S2@FHPP;6v``+k27f>nyuDeWcKEy^ov~ zq@1z6>;m=nqN?%dt(q_c46Xg@>{+dVL#b~d115G<=Hf`9@mw}HfhpH(3H<| zHhveJmt|(u%xUtJGb5TCdONSa5QKW7jPv1S=1qyR7Dp_lopBDKvW>j^sAj{j!i9~2 zhqMc4VOsto@SR}w@@FF6JX8K?2#v4i5Kd2a_$wB0stmCJm*^D!r^W3ou#1CA^R`m>daJFk30jotG%$LxZ~O3Cd)@*JYV zhh87#9^o$^h6D1)yz&)ym`X?}B9k+neC|KuZ|5_|9I=cTsXy--$we!2Q zS}N)W!Hbs;BeIW`su@4T<=e5^jhk$zr1)LRfS##4&6nD$vW@9}A11NV4NWaC=Nwkz z&vgA@1}V83WVd=&}IjhbE38cDr7W_h8X2Iiw5Mj5H`~@eZhX;fq74H&a?4| zORGz7t+sLG3AkG;KJOewIgsR3=7Hlb?%lqB@2iHohsFz_T+1O(4L2T;4mb~Zg<&v= zd9r(4J-}+v4ff#6_5+qc?N{^Hr3@y*tA>4z8>Eanmi2juDek2D+)kb{%bvCjRvrDC zX+XWvy#qu1Z6NXHqvDfK0#?{+Mi0Ys0X+x1GYS{%nQIEd`&|HUJW!cW0rA4eh zdp54}jc|d09>WTCY=nLLYhq!Fac8Fk`J0G|r(zgWF-Z2P)k$1!zWjZvfzRYuA4#Qo ze2%Cij7)I`jk~eCF$*gtI?o$U8eyJ&Mtb>CU%1(_tY6Dy#z;E*vjU?;nU;gTo|P3C z1z?jNgr7n=w|kqfu!hw>M4W-WXtreuwO12M7AnQVV%5;m(|?hoac`IJ(+Tb3pwehR z#hFUuK+bW(TN~_;cUHhfkD@5Mjp-H<5qTAOZP0)1kdsy$mTCK|WVXG$4Ev))hOWH2 zgO+N%(kZFtvcwacfF1E&QrJ{D%_M#hfjeo=Z2wHcV~Ch2>ZD2{GsS5Qy5IZi z69o}#JfC~imXt_|Hyn%epaF_oW?Uo$=!xB8@EB$tk&A zwe8d=SK*YSKMm_xlXGcfKDdA6k}h3hrrcFZqlYWoGZ*}wG|A`*HCnreKewUl@w#8W znMShjD3%S1#49o1^61s}cD;sP&PNhe>WNs4tVqR59MnHF4wLv5YA>fg>9q#ANtAZe z^r$=Y?J+6$$o9iZs79tgMx z*^TfU+73({p%G3}3S!!CxHW5M*4ecqkqWc$cyujhiakclls!BgOunnuHYduG6D`kv zob;o-rcY_ANjGF6(4aX#GQPMw)kbhA;p3^JIP7}z5!czASMq^MFu^bx5|f^0`Zk`~ ze3ON&XeUhAb8mlaIr;HtM=mzQAb%&$+)GfgNfM){f*^lsf?u8n^@wN|W93rmuTO@~ zNXz?#>dq&Lpb%XFmpR%2#W-*i@>g6x1GmOCx#;kvhUxyFG~6;&bDv(YEJ(46Fb93E zsAzfI(8F|uo{0T%IkhB+-47QKrqobH0~tdhfb4;X9ZFVbfVdO!w?0^3^DF7KqZaIn zlO8q9oO2?3l(ANJD$YqD#LDhIf0`2<9Y&T@!%sVoq8B}OGC0fomCq!{ji$I5W3yko zw4B~KunAA;e2$ZaGuR{2A?|^;*{gGeZk-Z;gxWp*H2ZQytW3pB&>EEeao};{N{Iy$ z*)-WT77D51f=fu@Oz(W)Vj`TNDlz?Wz6BZ*WMylpeFTIf#qBVUhm~ky@#Jz-`n=^^ zQ4xGbMU#;#bYqlG2h;$Gg8^Y2eB zJreF>;-nb0kiOr2EmBw%8?p3QMOR%?(QEkO@V$7q;?1&QeghHx)DSwoj+vaqqh}?Q zhPkVBLmqkQQALRk{(@=NEjkt3n=eu%0ZHoV_qw}tzwGQhFX!P{5fO9bV_0ZhhkE^n zCxDHHIQZ-g&|7EvtB5bQ_1$l|W5*RnBjR9qdd26wCHGrMI=c2F9e$%Frpow|Ko~_C zrviL3^^>97(TRc;6;frec=f2shwS5NzXX&<-@<#dU-~+B%;}0ZfWY_(4-fBd5G=t9 z3%$Q~0L*8Rf%_R^r{BuOOvG*$O!K2+h=#T~G%tx|d7FL^kuaMy?vzY9q7c^dCprew zt@XCagy`-(YV)a@{c_XD12%V(ai`DwVgI}^S4jx_#m(-;?rnv-s`zz%JYgJpAHbqd z(vKF=4R2h8-udfZZBnJW8uN6|hDzp{VFx`X;uj3us>c|YnUZKXQF1EW{}h?~G(USfa$&G&?IXd$J^j_&yQG!~n|5@TSk2;( za^j4{Vz{j+s@-2NlF=u=*JMZ9c4jS7VHU4y^z`&R0HLCB+ON_9eed=A*+0rk7tK|r zCYOubC6V}iYPfgg1!aI{mtTKLa0OCP8;6U=v<6rto__4Hov|Wq;I`f&|V0QreiX5G~2M%-% z7U!;CE5&O(y~HgVeY<4o&y+1R3M~SP)&{Zg@dXsy8#b5wJk>TcNztzImbw9lNio!F zevf=3|Gjei*Fw~%_Z4`NvKyR3XdqHCkWpvhx$ac`&@FA-NwV2ElA}BOxb6SL+gry) z^?m)~G)N;#NlMoYDcuOtB_%^im$Y;aAt4O|NH>UdOE(OiB1#V-A~1A%51;SzJoowj ze)spg_pkeU9X)f7&YXSrUVE*z*M6_}Vr^E;om~0k=But$6hU~qwy`mU9Z>5UNG0^o ztStS>5i6~bIm55Zyk$>9lK(oCQ(2xiY8Mr0Mo%b>az#h9hwanbGoDFQUD9R;F*B-W ztiE~-{|pc}3O_yR%i1o9FCClxQ+Y)XVvgJ?^gY#ZSGzHv##s-rpax^(4fJ#m2@k2N zy107AO95o3z@@$n+(De<`e?C86#7WCA^wEZFd40! ztcw$&KP*CTfVlN6`Kuu=2(9Z*B%*tH1SqX+veqefczWr0fPuF)SuIL~IMRRWPX0% z(3VR(`Fhu2+ZRKFQxsb_kZB*ZFGkO-w5YCth&nE(wS#uF;ET#Qom7ixU2t8Sx76#_ zmY~{Sk-@j)(*CXf#V(vXA+u;0cp0Iq^?O&l$U+=3g|jZ#+L2Cg58or+8B++21(^1d zx91Ls0=ya`e;}m3ZF%M+&iKu=WtHmEcs#ZaTldZr$@d+%YlmQHD`{FbKe_FmJLu>bnf z`3IN1gycz3*7UxV(T!Q_ps4wE%aA(u1$7~{IM7L17QKhtLqzb9=47lE=Wm98ta6E0 zO9z9B^ZcYrq=K>pHZAXc?%HJcrZm(&c26#BZtG=&@ALo-OSFye;u`qPD>s(nRxn`v z(EpyMGiRa7{Vz(b#LM$DQ=A8(d)O{+A?DAzukQPPQ(%eKe}3jko9j~;;F57$<4sLX zokg*>vFV@X*)oKkTLrpz^g?=n1lSu%y8O7){9k~bT)E#!I+QNNm@yXTjiY8}Q%^=d zR$@x}w_{jwUUO$m0%Sdf;wwy>9T+&7W|sXIMe8@r!|gc#w70~{i7t2SI-oI9JDWs` z8h8uqMW!h^a_obLDF#ZH@)sRi&o?eBrV6at^5UC7YXn*S=`HO`W>L-HvmE)~o%qKJ zv)(LV3J9E3{HTAuoAoJybq@Z0ev%fEs}*3Ah;k6_e+U(exNh;5zoLCo zkA59ugZZv%N5)UiZQu5FeA=!2i=ttXnALqe9^zJPJ|i!c&&>a9JQ^{xh0y7f4w}=5q=ooKXZW7b)jDI5(VB}V5F!x=0ns1`5Yk>D zOdJ)vs_mJLYH;}AaL=Pb*^==^psiVkMBCF^S~$W2{?|1_d@ z00E`zB<$qbkEwKl&;&kPwAx>*O2OTKWKCJ$*+FT;!Jm4vi#JaRCmw$4f7(XqsmO4g z{<>=t<*alcKAjfv0D*u2e;CkFvOVvh?ZhfH5`}@LOw0QMvZ8PI!`JpHYG?6!7Rk63 z4K^$Qq<@i%OTcH_#Wp}TjoPg~@?9_M%@s_gG2vjK5L2O8a!||9?UZBKCsa%j>}|NF zC6e$df}<1HJgFGZVNnT5(_0Z5in&>NFVLGrgIXV7jxR4T_;e20r*a0L-iK1<|#djv@N=Wh!=D zN%GxTAE@NgP~F8L<06{TZtP}+))tenQq$Pp(m->%)_GVV_rK;My|gSADjJ4wy-DfT zAqqCnjZk~1Qr9ABMC@VrkSef=X91(rY=iLrOP^{Axy$A+{%VTkU0a^U2%cGj-oOtu3$m&)#GeyAc zaK?rvFw`RV;obf3Tkm$fPNN&asewn#%4;~}Xc(er@GWTR_ov5Fc^BmG)R0;2*f~V6 z_MoLzVBv|DE^l`Wx~@JMAfS~y;$*E$J(@M;X0;S`g`#UTlm7|npp&0wtT4cx_Iq>M zklP{F-PB85l)FL$l|QAu;fKm;bs~A>z3I9TVRG&@{H?oeNR8%8289l?Ea}!pL6Jfg zpxDabJ(ijqx+Pu1B#KvZse9pMeVX9I;6IGbxW=wL=! zO#ay4k2JVH+8RJabS5Hp){B8a^!pH-tN52OTTPgm)^7{Yl@YeMRQB|E@PU(1ZE|x5 zlj`(c9UVG$?NnM$Gq=xR+#k$LW7nb64wAK$aTdhY(RbnNZubPZFwy2+VgH=C=oX*_ z50XJlA5;^<_1;rT(rm@1)(^h*>CQUcrE83un#RR5{*bhU5R?eyPOQ#itI}Mrot(wD z9B`eVuhnl9ZQ7{_lk(6gg=poB*vZhNPQH1E2L}s#E%$lf)=fq`%KSsa@ z5!c^@MsN=rJgmmT3Kk~vDP%T`-7hx2ReTj7Aj4%m^HN%TX5a^cJVt)vQ!39`aCyYy zI)}?-OhsJ`KL9~m&Xbb$E*Qx;#;5=E4?*=vZdCivqC~vf#BW5*A*c^xfrf=glktl{ z{^{nnZXpm-2dWKion|t?ABvel5GQ@rRp3Lsfj)(M8hxw%!SC@MvE_0cJg;N|H)Y0f z3o7Z~sBWKMjmwg$D<`PDZl;%k*j3n%$GzT<>C3{Dc|HNtfH1j{B^UDQy!kckzMttq zpU-9`t*g9KaX!QKed&3NiuGJH_x87_Iw}<>cJ;oIw3yxnn0RC?%2&3Nguf{D0||WF zT%U`q&8P|qc{DKy_!3^&WKv+Y#zyJHRy?A#(2RY|R5h40<-yl^8$9ltVB`4C9!IoZ zN@n|o>t7VH5S-j|OrxXs?8MzRJ=HIJ)Y8sPp%-j8EAy)PMbbNO#7+(hT(}1_&%X#I zHD$8d>ID3h=^d;LsF65T) zog{j5OqACATO$ItQmuw!K^A@IP8D4Na)-PHl}8~7PeYJ(!(Xn(Q$k#zYCt9B-r|*f z(yxDBXi5i%;iF;DOaDbNN5d$)i>cmuc4wVMYfyi2)pHl<0@#)Xsdl;_9z6pyqHp(r zN&?{hV+ugM2fHQNZPtjE?17}NHO#M; z4l)d=K($svGc%nOq+ghL?|}N75NuDOs&I>X#aoY!IZ;)^XqNBvHtMG%J<09^S6ofS zg52)G@R3^UGQJ+uGCckH4_U#Vi}-&uHB^0es;Jkwjwy8W(KVl0(4OHLLu(uREN=u& z8p$nsWnIA$owUr49Trf%Wp6O+6nFwMzuwo_{Rcaennv3nBX9ftSdDN& z>yxh!yfarHURdr&DP$r>JP}y)~kCa}(XgKDKw?sCx zwaRC&|M>d*K=pRJ4_=+Ups28K2Gw2YM()AV&kcv8CX;D zeruvcMs>oa(BE-eUbQ?{Hwp$%^sWZf>ruSWuZT`EYSkml*vL|z zhdl=mvT&txu`*b;+-;)hGGB!-QP(b}mS~Zi+L7-i(+54f_V5 zg2f>|rwn=y*c0!d5pSvL3F?~v6ymoi`<)Oy*uzR8daU@8%! z#QEb#mZ|*xQIh19n#^aJC!3-X8FD!p@3^8X!h#)IGfq+l6OeQ1gm^vd`i z)(Iq{(p;PBC-iqz<*(-6JQwEbm?N0p%L#qj z>20!?v9nBR(9AE3Uy6UkP2Wn?Kq5})IQ#0YIkBCfD|;_GR_{^+O5U8HY`en->k_%L z^(!g2?ZtlTMr*fZPrPJ^dQuUibX)xWiQXF-{4%HUe2OQ3q#NnL>|Eql7dd3|!jNtS zo2$DscHx{{Wcx3BMjdX?Sde zhcqI7F8N-1t(5VWex?%1BU^Z*M#ch7;P`!Z_e12z>)#mF<)?AVTGLAKk?CoH32l@F z%kdl^8{L7~mwg>G+|}CV8C)8_=J2|52|f9KS2WjS8&@OVJ6X*l5L) z@yco@CePoGs%H9W&qA>+QRR+H#F7vRM`cLB)0krvRe1~h(u2%+%mG^1$o6_C%vH-C= zz;R40k!EZPZeQIOIBMyto}g)8+o#o9L@#oWOMgF9oeo5mX35VkFtFdd+Py%{dPF-<yejsnh>SnpN=7++o7g|SZ=MBvAdF*0~SiP2-Q|1v4h`~ z3r`=wD*q6+_tpX+0KX+%MGp+?z~y;;KqXx(QvmKqNU#+SF$1ckJs~jKZwW1aUpOtP zDO~Zx{6|LCB7Xt=del3{NMO(0y{bj@sLgC>z484&K`whN7^G(VX=^`7_ZlEU^4v^|t7%V*HTwT}UUtm3bQT9K(BFFgN z{W#OxbOJ1;j%|VpI60!53%qfJi9NH}51o)MdDFDyJUCX!4^~w{(bLK)wr?2y6+DQF z3RW(j<5%>Vl`qs6iv&$;?}n#f$$eFgvJ$nYA>a#ATO2e@So6hCvboDfRKp4<_x`1U zL(qtc>E*qUo??A3{M-Dv>#f}lcP?IBYs^sJFR?|RHB9A&T)cjKWZgPPpm3#b};C?5W^Jvuc0n6 zzW4Unw6uu1h)ZufB1{)`Il0KKm4z_3>Ss#AYlV%b7lkH#-?@JC2$;p8Oc!Lt1G zUUFAxf=hQH*M2P5lT3G#TXzhTgzYxi*vY5yv)I@Mw*r6Qi+!DEvP~~NLNbZ;4FyLx zwa05q*)c(f={l5W?{^T(`yhGi&frTafxKtC@ES1ugUb}E#=;o4oQN9aTlqSq&CEdW7 zZQ{lvGN?BlSARR)qg+t67yS7>@S9x-|{sZuS_s-%> zYPS{1flWEd<4ap$6&9(TAyzS5Us_(6J>GcvN#$4ww&7IWziJw#*7=eq?W^bF=Fzxq zTejFGK+zp?P{Z~8pDa*Tfv&N_?hBVxkop1Tm6UN~M%h`>m z4iiCqbYqbx47bBUeAHonlnN0A1dF*J7qKj#7N~A;^1C-1c>HHS14~(k->PnhDRaJR zbX-1WcSpVx$qj+uM2A!}6 z-Gt~5F9PVlcrI${Ldv;=%UDlDF=j=1^+Kl#6R`zydOQ= z3z2!Uzzholv4hPeC$e-K({aQ}*FRC^bxPawFMFNh&FWx`=z7k?Q47U$`Lk#}zG3T6uI1%vAhtFc?;JNm! zd-NSdo81cispjw%Lq(zsrSJzCC*o%K`ilT?!GFMi|C0rQN@75ATi13eE@foR2Ky838p~{6;+Hn HenUv0iyD&$8Sl@%tN=`Qq3A&TOYM^1B#h9LlvZj2N~ z{YA`-=n$c)B>6>56?lVRC(r^4?MkM&#d8uTg9p;9^EN#lXTauLNQ*0Y6Z`^=D!^yh zRM-3rD^82%`TCiB*QJg=RY#t5m$Oc?e<{;6q3bMm6(NWSn6uS*N8i7KO@#R1*|DQg z`MhoG9hw3gwD2eRLoCr;B~&#=75G#dS8mW84XKQ4HOU&F>U(zWUla(n)C$lVXpxVC zUB_u0VLE?h5aRqMwvid8+&WJ`j%B2B%zcLz_zQnr)8lo63l7L}lwWhY*YuXX+9j$i z^HJVu1c(R^3SCSiB>Z}#xL*6P`Xc*-cq*0#=MmD;&LvgUj7(LOJwgkBjFWhPb8t|~<<?w5wcM`NOs0yMI(9-kdUAW#)8^hROKR+5=#3M_NbL|bUw5y_e&71>8k9A17# z)F%NGY4vCgFPJeic&A88msSVj@yi8(vbQ3WB4)^*o`Jpt=qxst6v4p*m@>k)tgMj! z@$MtHPtAK2ZCNil_>F`y$INI{sANVOuT*xTabD^>i5r@}`U#0_hQU~JZ0L&wUN6;Y z{&^hg9Xp-L|mI6QZB9PsdFP4NbQ1`uRtBWh*!g z8qearfD??tDc?pnq=GjaXUBJ0$@lAwb^r97KZme(#%<^>uC`}j7I0&zeF4O&(sisw zY0E2k>4K@nJw=20lbxgAJ+@Q}tbZmHsbZ*;QygA#K2Nphi+)n!Kx{BM5hi+&in~;T zsp&of+WkB>Ia}P_z|DpB6F==SBmZK#O{3`1l0X~VM4EOysZY80H_oS#{S9St1@CWN z8aTCf3qBpzb;%nds1HjRA1v%v zYgpO55R5alNY;cE#KgqP8TC_-jaj;^T7~O}01+ulW!QMMz$=6cT$Wgp>mA@|O_|Y^ zts#5*4xv?`bP1nZB{=|Q0psaZFo+V9nb#RD_mi)Q7S8iu>j6e=W~%oQa!V^vy!r5Q;=U7 zYNtGw)m2b~Uc55#x+o+W`%RfH8BBFj}UQ<%;bT$QJ+?>|$@ zInx$qjS969rs++@;&&+?Fz6aCsTeHltSW0{+2A-3eq&L6{9(B_=h-Znz|s@rqoBL~ zv!mDVG*z3}9vSTm68hs>EASWhyS?vzYAI+h1BhmGaCF;pVq;u7TDQVXm%hkh$aeHaw=M|*iL34SN2$YuG9S#Ka2 z_CkEhe>LSSdAQ1FkTZ7ADx%!Cf7lY#AAXeJYHex%qX@CT9dCu&SO+ia&Ai4-6sRiY zHJ^6R+VqHd_N8snu*3nosE$&{;l0dw-JU$Yo%z8dU}~>v*KZCloZ?wE zyx&nL;eXR!dQ7Emdbf{=$TMG~@6nD4 zO%@sT7?dvWs{}VPWQ=_-sPk?jCyvg|(*-r`PNZLnVqp)LLQhvMm zh~C(<^6C@QfE4>vqXxL`P%`H@5fvfaLSn;5?}i(e}mHnb)~|9d>R** zKz|V77>%o2&!wI5KhU?xHVA(^@)9)tMX<<#`wbVYYknX_Hr8LF;aZMPJSmu48QxCG z@Dd%;Pd#AcaqLm_2%9iYhJR)&Dnk5o$V!oexK~`dE`kif@!%BH`w#;CoMb;;xBAcMxMe<>(-kQJZUtMWB=T%>d$;-4IC%l zezqv|!zhZ~W8A@;Ct{Xk)1U9z@x^nJk&-7G=un&?Le~jlw^c{L_(5+5;#%%EMS;SG zG>kyL=kp)d7R(ASUNWjqB=S}Z{+Kjzow!==L8eG=BP&0#!IAuv?bG8|g>2(ixzEHt zy|C(G3Ta~*gX*H8YG>q_3H9X%qKfWVIj>p3zO<;mGq%a|zdUXaX zh1xMsb1(noAer~~l%Q?aBy|8kK_BzTBExrO={Rv+QTtG=#bwQ{cs1Exw_)s8@5>I? z_q`l`$j(nWJ? zM3te`8?E(c7)F-bGFR3~eJQC^D8o>0ODa`aV3o3ZbUJr&CLY6c0{mb%%$HkoGfbIUsTs!x+CT#Cc+fHIo6Wa%sa4jAo(D^={CNl}v z(aI(@$o0U~9oEQ31@@_PcEFuM$N&H`wHF&Cj1N@bJo0pLL39s=%!pcyUIRi->$eBY z$i#R20zYk&J(c5R3KuIaK(z=9orKuB&fWjOoT0`!Q^SO&uHdy4HM=E&K2o{J*pWD3 ztC==o{UD+?j?NzdWzfO;lz(^liygk!Zfg>hnA@#-W4UWJNvH9KScSugMOSrK57V;;X|5|G6T84nhggu=IB3Wy{1L z{bEE3H6k$ISp9pc?6wCHs{B7Fun4r5+eYap`?h7zD3hREF|%@rzbI^D>2tt7zYL-G zib2384NxxG#e(7?4d-7$zkpGlO4<+8r8>+n3=_vBwf+O}MfTwo<%$U<4>j+Jf7jM` zxwz^y0v<2q5ClT2wPq1h#Tqh;CBZnkNGNY{VR3ysq$?#T<2$Y9+ykNSaWtXtB_9C zn5u%vb!=(#*qbe|u9dU%C{*|^2B^CcxrKV_b)%l^Auh6`S?s7dd>0^j28ja%Snjo+ zFIn;XXWSz78N2GMLm{j?;tS+nLVXQx6Q;rdXvcgx{t!$Az#0v_fG2?{EBA&~iKN|j zGlB@|GUe)V4>XIV$r=2w>i3TpzWQ&(5uvS+&)9{oZ*vb+0t|t?13*8 zubTS5kbG9j)@VR$OiIk!<=Zb@|35k}tuB?9g1maV`^Vd|}z4d_bE zrf5nQNI-_3_e==$A#Q7K%u8r|c`xl&a+~^ASv?Fh62};lKF=~ECrpDP{SG^C{(q0_ zJn@iWyKDR>!NF{lC{$1A2;MfVij3@qA);3Z-3Q4dIto_Nsr4X0VIc{NB9AyA_qZqs z!DLi@HP%9Ws{;der~$lg_$kb_XR!)=|5RUtId|YO#lU0k+oG&9fpMNY1z~X_M{2q%I)89VJ8jpc_OVnP0pICLJp{4t{caP67rKfL zjcDPGwV1{7JdU9WBw_UbnR`zvqy=CD>;~G&u^}~nia=GkzC95CR@YHIsa;q*n7|?p z&)|#M4K}taKnW-U)Q{Nw=c`&?4qlLq>`vuX*1ss&dDO(%*~opaA+f9?MDNR ztl@zkz{zOgDvm9Kq^NtA8I1i!>E-&8vnBlpk(oKLcY;rLbgjrm)Dic#P}ZbU7?3(LyVnd}PC?a|e%|Sz8D-<1KLVGf;WY5b zG)KmRTEOJCjZi2I9h!O-r^g)sc(Pj>^G~eEbk~tX2y%#~S4LMILP)g1y?z@1c$Kt! zV^Ek9z93>YbOEjOyp)e19JdFRCzIK?KKqN(<5^R;SlKM|N_{tW(_jpWeSwX|yC1sN z^8R}8{hBA7FtF}07N3MGn6b(;@Gr`d(cpU$F0OA|WiZ&Gw%>svw9GvmKI3*IctFeC z^%lry^^EgTECT!o;7O_xO`921x#;hNUNKRwz7^xg4?7+m|l}VM*>_QRmF#*g2PRgcJMf$872C;br zu{j2X4AwK5FjDyjo{9>)mQ7g8MP{z}C#Np|MqOz#17ew~6Y-PkpX%w&e&iyyCM_ch z<>AVLV%%45HcvqA9eb!L@3>IGQdBrQFL7T~(PmW?`-7_pf%2Hk&`If~n3KqPC*f{1eu9Qr<@&YMYpfof4;uprc`kZ-SH*$_4&2aj8qeKqGUX0QcqA%~{<6gfd#+S3cNReux zX#9A@z1AFk+Oz3RF^=zde(4_~biX}`6myKj+$r#7{a+kLUff^Pe)edH?0oDrc=1!M zS*Pz%Tykoey>nP*`814JVYywtWPj(wdtPq*lCaN|v!m~K>m;!cxCT9=9@{nqAsPtbTOTVJJzrz?VCrNU0Fxh zYR_)R=TuH(mSFd+5%;bEj{=i^GPeZ?=J4GS!EV6w+%v#0iZtXr2JUKLBgBbP8vHDF zqxVkJ_PSF1m^TNFiu?j~dcl@mO190fs*;X=$ItGGk*aXfDGVem2hE-*^w4=0aA%=icy1it_;G;%l|TE85YRL+}jH*A8hLqxG%K7l8_-jkF~znrqV)NT>iY8URk-T}N9qoxhVs}tUbJK|m^Ibv7v3mDMT z$$fj!2_ws6*a7&vbIP%#PIvFBXQY40_2i>Xp`VkK8yaM$MXO5dA@Sq{rD3av%iJ@* z+e>Q5zRtRPtG0lhxO*M{!et>F;M;AVtnfjH3lxKw7-;vA2!aB@r}Z;2 zS^bV1TlSQoWAD`QFS$}fenJS1I;X7uKQ29meyUw)emwiM|Ih)O4^1TvV7XRT&5zs^ zH{T)r_P(#qdhd}Kj~HovZD%@H=?Z@(rfW$V;BkklF4BcHk=9YXJQ4jSH>F-;T?tRM7l z-V>KxE#DO9JJO&7WH1?cJ)Cn5ic^fE94sPq1fQFvcD7{hmLF^UjCTNQn2QkLO7G^7 zw#S``(_Cv%ZiE?&=i3BAo)jhM$?oLu?;pruKo_EL?{;;dmu zDJcUbtUw>?IO74EMX8~uYbNR3F9#f+w(9|&zx$d+;y+Pqx}jVA;5Af(h;$Ag=baDy zsZp8_+b@_h`1$A1Ce|>m#0^pJv@{pKvp&L_Qa3hM5w(Q!6m(1GXY@23tVM9ks*&Uw zeLJHd=4Z?_%*@K70nG2Om6?@4xMwIc%fC>5PV(%2G*(+HG)fC6>Q%3hTa;RC0b|gT z+6u0y6#K6fj}NOzUgKtDO1#aC=GNrv<7+cJ_+H4e>eCG^F*hK3ebN(WP}$ODP-{WP zW$0=T0j4Y&Z+wPvl>C={&dE`rPETj@>;c~rP(S$nwfv-#ae+;d`tp^s$BlBUu}1SR zedh*s&(4{zijJF4IrNaJ6y=#(k6*t^=d3JCDweD(mXDWLeWXQrG9TIu`=!Nqcp7h6 z`NYHGDQVGXgwZjFww``&Wx?wL9S64E+od#uj8UF~*M*p3x7*+E5u(b!ulTutR4reP ziUzoND>FZi+C7}b1y1rs>S3~49ISTo1zPMJ&W2i#0Pcw1DDC#q_9x0wY^fYq%2ftm zUOr5>P{64->KSmr+!OK^rrd{iuiZ=X7{0!LFt2nS_2u14OZ#gia{-PN5;Z{KTjTh)&qF|LF@p16~NeM z==v5OLtbR!`u3#9hTXf$4ve=F)G`nQf)oP(>Dv%q@Aj2StQA0!xk z+PTk|PMDCX9D=x229K4zdk?aras7XIX+b4CO9+-n`YZw8#7^*E4|cCYP2X(R?;Dqp&m)=@>G61Y%Bu%KsA zWALE&6J8wMBzK6_cZtn*iA}Y^eU2D^hG7AYHOtlb>Dniop7t8!i}=szjL4&q zmJXhdzbIBiZ0#2py*DZY-Yewb_I3~i0x}J1B7?iOldpgsox2u+d^^LOU#3B&b*wCrGuQE`DN=0BFtH$*ybbhHel(> z!*52e)R&S;%g{L#e5+v5{SDG_QIc;G@`kH&l}yQYqDmx=7_bP;9I%MJR`97YafFqB z-g=h$>P&d;_<9|kUuFN0K3o8LJ0a9-@q*wi>}q{gWG4m@db9Qi2J(%vY^Q96rwzR| zt!#CN?}NBZ>MrrfgKI6gVdTM$F42Ol@+yPaA zKwJiO8w0Q`gE}No3vJ!iYLd$c2Hb1`x3|;+b!2>8-+WevH6^{+F5Zc(5J$=gz^Jk!^D zt(8B@j2?%+ev`E?Sv*ZyM(e}~K6k5!xuv?AWZ`*()iK-2tR_S3Nt~kw7Nl|=82zqq z^PM;h+}|s_drjGZ&-Ow{X?|EQ|ID7>ryZG)%F*c_p2qz`?q#Mi7QOVFcxKc-44KFM zW=m4dzW4)At=WfFaSe`eRmOFfw&41U<%=H4O%Ae5`u!mWD=Zko3iuRxJ%3TmdZO9# zo562C2drd|(cT`a-~N%c@%6HKPx51d=H4ca)Qb>+zTc=J2YDA)1MBNCJDKN@Fz%F- zP{dgF#u`A>*cyOH+89{lGTa9S3J85O-jn zWR02#f$=gfGcEjuqEFYYz4ogNB=d)}eRzNUHb4ZnDdTbyRjdvZpopSuQCc6HqNh1g zIk&jwrFxiE)tE{=8D8*2)qW;GU~1yFy($=t7;fN7IQzOZP7>#R{gUXnFZoz;Cti;| z_eLYxQD?IHag4z}Eh)4cd2(P$B2%$ANB6ugohwkYKdg>;EXk2M)0d=Pz=n4qB=wEx zOOMA*I}*BwLOLQJ`*Ii5V#wO-D%WqJ8m-i*&8f-_wmc|$N{YH+!+mvGWZP}qqe*Wq zaV~y3d%pgZo;Lm%iw0-+nSvxC`R|XsEdcXvI1*|=h)bAYj*g=l62Z%~mQkC%x0-#h zBldMiEV=dJIOz(eF<<^peHr`UK?8PF(F?jbC^RO*j{w+$gKn_aH)#OrF8O1XqBT zS~el^d0WT*GL00D9y~gPUMGxi*?rB!(+lqb)IA(RYXGRFD!jup7zpfLYc)s)!h^k- zyaTR${8lRsY60y>2I;&6)j&E{Z~plNI)|reJp2P}1uWur1E1jPK-|Fgk-f;?du?Pd z;&i~DwV~qx2F8Ph55VFpJ9chh?LcY*V$*N(4D83EeF6Jpg1lRIY%=;M#~IDUK18363h6U`LMZl8DnCSS5)u5tQx21ri zdd&70DrNw1dE}7eVjd`F5aZp0<`%bs&os`R??TG2<+l(C$$*Z852cqgbji zi>fnD-NMSmSoKjvyBG|Q+U!5hR4h3s$ueY;O)Z~eQFYVgeO02H_KO0TS+-h0txl{2jD=6u>Xs4~;^YtL=5b*Bg%i!W+sJBaw3s}z^m znb|P)G1FXc;hf34Mx6zf-6p!v7(N-MRx_cmUw#l5w44FGZvDI(Was5F8NzLVw{(;< zjAA4$q=#qO5NWXBo=K0|ZOT3HW@*og50Zzwx23KA6|I3AAG7J(Y#zF`+mU^*X}&E` zQuHj9nxZQZ0ki*7&l__auIL@!^q9WR^Uc2ZDAl8vQCum`B1DuNTLNJ$F2PI=V?8`p z)GkZopE2_@XSmFDglq}(^rF!w6!3A5+t~9YT3j+L{4pqa79MbIy;y{Q@TJORx_(h( zKBDjM_<3I%2-qaArU}48odO4_Ml|^=Dh_>;swr$0v()MK$S0u2xvi&jAL?6jHOUol zHQwyr*t_l%P`h%q@6shH1|$+OPVPe;kNj^=qRutgcg}JQVtMNBEbw`T(y)n#QjjUY zFAc;2&gUxNd_1^wG31yRF=U1zF^3_5VIl(&0djqDJrKk7pq5;%F46|lJa6EDJGk!6 ztpcNT+sA`RSZx^fBH%Cyz=XlT&mOcRq&46^-Q*+z4I!D@ROieq5(bF^@6H9^F|VZ z5tKd|b)K^xeJRUp2uWG)d`h!I(J?&vP&Nd~a*~cYfZX8cXicxPu`)_>6_Go+chJSfXljVid zccWn1qKK+jYSAyn_;VfdXVQOrUNOMOnWy|=!YMn}4NX~dEYv;i_5)gniZ3_c$LQzG z-!h`+5ce+q7^+z;wq|X#%!}=Es&A1O`t%s2#w{Nc_7Sytsn*klp92w(kNE6Dy6>6; zOen|a`<}di=WHC)8o&J)Z8KQ#ljn#MJG{F<#eI zead$tES5SbDDqRJ<|~m4ZhcH_e7zvehXDEs6ck#-d*i+?mp0#{Ko?=G+BT@$8bAnX z#uL)b6Z#4ue)Z0tat z?N5I$!5+(8+y1LIGhRuRI6fRdtZ`Z=Y6j0<<4x`?qRXk-=&mZSAL?N4X zs7)D;0rmP`4!=p>>UJN0?O_|Lnv_vu$ez|PlPq9uXHJcH+T<=}6GN6XNl}ZgI%h4N z_ULPoDrW4bbq;TpZ^K}p$1huPxwJ(UjJ0S)!5Lb~*=^eON!n>s3lNVgMX@3wQ5TLGb?SR6QbF;0R0(fu*laeStAql7iQ; z**~GAztA-u_7)_X(8(74m75jT@2k_0fJ?I`ff??M$H5sqYuKCP&yHJC#txS<0^w z^oSlHJ~#|}7R101mgJ@WTWrHKd*qDO?ZFDzxCb1mUwX;4(X1Lg{5|!j+Ywkei%x`5IBy~oC7}blPu4@+?PG56e`-M$9iFU#dQ+(E3_QD68CZw2L@r9-I zQOqM~V>Q_N>cs&T`PF@DJQ(1zXy{=AD-ttg%s$9RCDzBxhsTJb6#*E8IJ6C}R=_v_ z0?*t6=yt2Mj%n^30~5SMa?4Q@PGCCvs2raTt}Fwp-xP1uN39-cTGEJRC#qv}+!4g2 z1spNr*vJ9{e{l9EfKYw^ z|2Tf`ojYTO!C10aLqnr%NlK}%tw>6=P+l2DQAAp`UPGdFETK)4ByF#k@RBwS)hkk# zcC=7Qd$Oec^*eVkoBp5o>-#_Hp6Bv7=bn4c^E}UXXU1;fiaE2E>^fYnh7E9j5<2&0 z+ehoFAES~-HWG*)CqH7{(M6$5$BMBxSuE!rr#ub}G(&%mN;@Vv7rZXO?G?}pSQm4u z>!|7r#1JIjrsOT8r0Ccezp3%nJX_;6WHRoX(u&0d>P#PW2sDy z&1)93c5wnyb6s<)Ck_Z&iW)CJjd&hadK=934jkgL&+pn{T{Lj-xs2|U$*m^k7OJOt z3$D6qe_ELseq{HxM+@Su4lhoM&EGf2^Q&X<%I`<(4X&qCcC9zqWj?vs$D|`VF{fa6)UD{!5w+x)6)Jg6-g#VxjOZdhw_ z$cd|55W9X-?d|ri_?ZvNob3J02L`<;R$jQ-|3PHf4Z9^HXE~;?iE?Al3te5gm}gNm z^GsJ<+yPZ;M@K}NWu2x!vJF`oB%FETV!Q32Ym;e6jFch{>MS`}{7XO|uyj-NOhu|RbGS#9V(osMlbe!2m3RkfU-ET5#} zef!>O*8E?)z6{%c@59Zskg2YwFEctEOXt)CY41`Qe$uD4Bs?_NMDwnj%6R8JC;ntz z3jAxK%Sn%i^yI|J4`&)|o|jm1e!*zlf5Oc*2A3@e>fDc*ygc@TcB6jA%hZrO<)q!K z?`rE6@BPxT)XQ;uxy$q=vxltR*~GJ%I-9o6DT8*jiYIK+vxz&;;t4#SGR8GytTp8x zoDW-9j?4F$u*v%m*kj0L66~evD&+4rIq6c<$w5AuJ*dsvGu_C%?>Yq)VFk9 zflOLa*Mg51;2_fF`24Yb%hru|JO43KpLl9<#NG90JIY!dbH6q>`nQgs7}I(=tz$p@ z4$eV8CT#X=TVGtV;a5q3OL>h2bKIl$vKGT-M~`-kuDi8ayM8FIiVf@HHBJE6sumKL zS|@*`=)zrs7G26de=CauxNfwvqGsr#RT*2FO55vC&AnPYfAq!6Ycu$jizax7bT=3H zTLpsRd5%X@$Q9sc&-AK)Zt9TZ#~nC~l;6}XOMbaZXKusnQ?h5G62WXA}RI_+Y{5^&%!w%8V-aJ@%zUr`&?TOBK6y=U$#n|IFM%<}#D zmG?qNhHPh@dOy@Piffz__~=C8oalM2gLW-g>a+C0f$Z%4%Psr{47*Zmwt%&8kgZ)9*B*XGUC%L=L$Z?&FQ;-PIdK3&C7ic#}P^+=Klw0paLnUu-5P z3PV?pJFK*UvvKk2fo(OXI3M8zqWNi8!p6l1+P8W-euycbYHi*cSM}EM*rEF|Rb3O- z&arAUms}?k!TMK{9pf$}OPKF(iKI+VXo3822n>H2JIUc3 zqEnnV+=;0xTdDP^c1KM)uJZNN_z9a1=Wbhc&Y9o^zQ!$Q=H&~yzR_V{tqcW_=j0u2)Uz16<_f=NpDURW7z2G%hHoqJF%NY)H&ePt1 zbN0$y<2=FZYl8ZrXPQv*4!Ke~@Lv$R=1OVcDaR^B<$*+%tt@wwLiTPS)-oT z82oNg{f(~gx4Ji&x5gftJtVQw{rSl)hs+yyeK?c#*>O|-t(u1cozpFJYRs2!-x09j z;kBkt-nosfX>fBo;G(YO_N0w11>c{+rY)G?@e}UY&fA?G>0G2{OLvAv25j7bf`C#`)wH^?Yt8Ca1MxTLa2EDwt64QQe5;Gg zCBrGKKQcaO@{Cl@Y<`)YHu80P=!@K?W^+5L3OCwzO~>nQ=}$f933ue5{*_qudfVN3 z&813Py6v{77ZrV7WKuCBs+duil4Rpbxu$Vv?8AeVJ6_|Lbc@EhUao_05vHeUu)TFH z;TQBa+AiEZG|c?jzEA`0)!F<0vB~pksQPkf+OMn2OGfX!d69=#9gqJ0ETH{r+tVBH zQ@1Z%bRvI>JSLp0_pL%=m*sy*co1L4j>C43S>x<6t~ISAYemib?`6|2m#pD+Y~9fD z?aKL>p1&JGPp3{;aU&vY{Ly0vI?~=m-k!6$vbf+NY=9f9%8FN1y}2Gy2-QP_+pn&B z{Nq@d4xlbZ5)c?^{NEJXjd< zK)3sLOi+7P^cTl7=8h#w8CW}9-d25t+cWd2Sw3y>VB&j~sNg#(0rT6x-zv&@0vEAc z3hTyew!rhmo#YpZT=X1Q^|AAxN7gkp{OZQ8E9Su$buXoSf)n>@ea{Sj{l=E64$DvP z;MomrqS4${r>E^*ao)Ey)7J2#$omN~dc&jkH^Hk;+#YcEbckj_LqPjs+etB<5bu%`+BGlDO=V*j-!D(+?TW881(X+cMFIDcfep+_0BsM@P z-$Nwdw>4=xKC$m)DMBtL1z%h zV_913MU&IDN__?nj+s_i9n%yueOT6t8}t5x&TevAM|yfz;O4s>-~I)u)iJk!B=Z~ZM_fpl_yGF-Q#Kc& zIV~%3%>UYS+21c>?KJp%$sMELj@PP=`Pe!R*5R#={fiw-AyMPd+Vw9Odg#HAtmxG0 zn4kZG6*V8Brb=~P4SZvy(Q#0q|C_8+gZx(4P}lq@YlS~k{}pYZZADR?P{BIc~jxWF`Fkih)R9o3rlcJN;ieyl;C$a%je;@{B^Bqovzbo zHjcRjUqKoY`zFih`?H8s^U~j6X|eLRRw7?Em=Awx0Ip_L7N>PVpu?MV&#dFH0G_Zb zMNIUqbIh&x?AY?r`iV-$`Ta{_?kX^kpCO;4F1^bts9b+;eN~rr%&(U2@|F*m>%%W( z>`bZLpnEO)TU%gEqnhh*`J@YZ9S#MS&d>%cg&%B$YmH#(M<*x!gqd+HCDHC~<2 z8GO6d?Yq$?2JYfNSy8howMO&trjF`}Q;lo*nF9;2Hu@JAR$OVloTd8rA#2?=kK4Y6 zkKW&Eex-5o)xTzTe5)~k1!sEoHQeU=^KxLNb@4io~9|E ztO7bcn{>(A8T<37>BotW8YgyBKTdoy$T$4xmv3GLFa;lu%2nl+!Iy2je`bu=y5VoF zS-s34VzusE&ak%5JhtV|?;c9N}ni}1RsF;r}qR|f+6QT=iHaoysYSzH+6*seXSay*$ z0IL&j=S?faK~p`QH-+qLc3ow#-T zKeT<@lp67X(w?>1zjUqV=E54)mtSuc?%5Bk>}Y9;PZGW}Ko?Be7G32Bn#u1LBkoDdyATMl-=wblx6&5l{PE`Oe7 zb3s61>CdQubK#8>KL_s4x#(H`Gj@XxZ{BBnx6limUUf`o{}dz7Y@T5%30WkvVYv z&<)Gdc&>$XAZd+j9NWJBJazz1G#{w0%k0ibyHfgO@Kc9?3BFb8X%{axt{LxJBktib z&_v0uT^!w-KG^lC!z;Ms)RmFtdk?M*;7npg_{*=qW$|BF4 zTWkF**CorR8-5>XS#&piC1JXG_(idY@!O~s-nOn}{AhUp`dfw9J~eeW{;HWY^km%E z8i&&8pHl<%!@^p-vo^<+W`19G^!qLNX58opabHv6(>1Pg?1l~>&cI6xF6Gw$3reh? z#B5wt4|g)2`a>I?xZ*+QPv|v|et-UTqgnmt!m8JBHV*mj6|nNjY7ZFqdi0&a8y`U% zk34nOzxYk$fu|1h3pYM`y2iemJoGts=t<1am*3C9_RXn*uAzNGcxO<@_vzNfsvS*( zE)K{F4D41N(D%NEZ0^7gXwh)J{Gs*a+pRYuFTi_>TYB2%>FvHJFME`3 zenF<4XfN(t>FN`UI==JZ`CIW@TD@1n{t(BPjc|-w4@ZstA6iV;Pw6rpo4J8}gy}Uu zv({SQ%etKNDeKUwPZ`(YJhFPu$>I0*yt&a86?lAW-FPkdC$_k<;`1`I$W!H@PuPo!NYkE-hWH)`o8Jt zrA<$dM+TmKGjHUZ=0kHH&YwR&kl%6cb4Er+x?HFV>M0YvE>rRB3#9vsZXq+aygv^b z^s<8bwT<_o6D*!*30D)O|Agg*rqx5VKV4VU6V9HSJD*J23{#UQF!22$NI__%$f0fX zzYTy%K>!LU005RKesXU4(`UCW26#L1({4_>G3llz!lqAM6zfNfbzfx2NYhuzGvwOw znQVcF@sq8yQmwK^zSR1-w1Q5b)@YfIxXxzK*+37>1|o!T0%#~3xFamYL5;zQKOxL< z;&G-N9`TN0OA8hb1TS)Npg$a_2Z@SZ?VjnE?0fv~-KIQub`#rk_7*)eO^cQJmQS!M z+ODe5(+tdNz&O+!p-_V0!AO+%bWn?FJJ)H7a!e9k4-;I@9>+_b5BKa$4{X;G4er{T z$it) z)ao(muFi*pF;x}=*9V7F${DZN)5@ZPg)AjlTqX^%RA1P6gtC#(HeED7sTqxDCmszD zxjGwo*z0=~8~$yV6kf<|VJUO56xU*GJ3WQV=Lb;rxPyp|g!^)BLnrUpaMn$Wm2W-O zyzN(%**nl!U3NRufJh0xG}FLvs!@+&MV8*1|+RnWGgf z9J)VX8;@8_h-S<*@xp;xJlervi4YUR#m7MNcJ?7b(4=BPS~lVmZWB6)#YNe6I1dHp ztXS#-E&w8s$HD-6FKdi(Jk?wy4!6Nw2`Y<&tBtmEuDHYAZFn_lACdo+yMwPf0rQXE zb(aoo^fi$T?^L#BC>Ub1Jmo-S2+m{OuO~b>e}wp4P2tTDu0#11fB@6pAeKpC03bli zIOSL9(3h{TrbVvK0_o205TnpdnrwuPIpKU3z>wVXXRdq@hu?@rah5R`q=A4;z^sf# z3?9M`!*a^jqnbOInBW#(xt$Kzn4oqDHwSCVb4BVxu?K#r;pQ?OfO`6K~wo$7%D;Ep9%2;zctW=(rXZ_U~Bj+WTvJ|c7(0GdKJ zilyOZER?P7%t2jI%sU0(EcntQ;!V4$JV4|@6;1~63C{jtFLL~pEk{U=$2nI`M(i8d zP1Ku3DeqE?tu)(LA-s~^mSR4MV>xuTAQzqQJ_dl4;ck4qV6q8q8!tN37!ZvdREq|` z$(C@+VMejbg9Y1KSKrmsD;qPM{+Z#+T?c?RAw**Zv4E|iZEzLS%fn2FC|ILIa3nU( zneIN!1>nYImMokL;*;r!Im^7#n6ls6VDqt0UIXlJZr5~Wuk-`M?9J2GCa0ymxqD}_ z&8X0vE2%htO8g-E5wUI#Emj)kb*^Ck0hE*S zN-vr{muwzDquL;>0_{JX-Hk^fCcuR*z$c-&kvYb7b^(4YAeshPJ}{32j)q9J7EY9eto>_krY?-m)jl*(^lbOZUptmmX7HK&qC$?6w1c_5Q z3&EyJt_>Sc(1=LTFii&(tlk(MF-m>gYoD6qY~O|kTkdKW0l)YUU_Q<{B7D^}8`ax0 zR@0qU0tavXHOMB7AZ~ysYWA0inqfQ_*k-B5rt5FIIQ#|UD(8+mr$ki#w{_wqhMw(> zNg7dJyX!HHg=Oh#JLgsL2C8k?Ih#?Jq&v}C-_m2Zw&9_@GlItrYB0Oa8D!wU-8Rk4 zY3Z5li0q-JL0&_@_>L-a?ub0YwbR_XqWHo@K?5bAqUD8fW&q=5LwR9Wrw_3-EH&~y8mir@P_wcz#~2b9KgyUNuV_NZ*>&xfuS8fQ8u z>?QyW`YvdubQrO4HoU^Xg8!ix=^t2yw~rTf-X7`8wb8sK>aUlVK(_Au-lEL|8uT!ldAxl_g0_KHXQN7FlLGvIv)WUa<#yAxz1@}C{x?_w zVT8Efx%Tto@I^U?b7SfB!~lAFvZ?T|4O;|z{AwqZE1>@ayXVDpT9h|2L!?Xm2edpy zdFIpU7D$c0JuSMJzJRWD-OZs1Y$;&>_4IiO-BKhE{x6(W#0r*P5`Tt>_%CRAjC#|a z8_$LN5*L+tnw!M19g|I|tdP@%K^F}3k7du2$Nm=%t#O%yy*aGu9r<6-@)+81i}P62 zs}@xim(vlbrg3g6mse&I?yP#XWYl=OM0qgD@ytX`U<^R1>`zYpwE!3dR5qh8Zrs*l z_tzR>A|xMBR76U|Qp?YvA3|&F^4I4#jK7}8ja4P$9q8-a=koo5>o%~mVOs2j{`paL z*C_!+1e6D1%LevW1H{B92G?3PjyI&AazcHRJJ12NS`3UBd-Pz&2t@?q_l9^~!ky&1 zZRq8Ys96=aI9^6*X5^^ynH7n)bV3mhN1Mu|%g=U?G0AP8RTk zCHmzoHKye3OTDYHQGpZ3V!ODC2)g<3E64%H#?md?+h^0%CWY7;bL~5>Vnwl7gZ&0? zMK}Ojs=gKZGcyOM4fi_VUkiY3!XVE@s%d3r{R)GC#9{7b7o%RC^0$5R-D>DkTrvFy zeH0lCIwQ7>+3syv5^cV+sKpdpfep!-njbaecOEt~jK^d9hMuzW9>iA6jO3YfS>-Le z-}18wMJ=5=nb~d_qx2>yH)BlM42LC(0Hk}8UC@TSQJNhqcb&KumpmnCEx~v{*CI9} zG0wZtP7w|O?aBjhbsZ++5?L;=>8}PF??dkzCXF~Wljx_^UXbeC^g5Gz_cb@7b~f;b^W6CI%{#pP| z4SBk9dy~Z}Q?{ZO{)Dt86o)p zzPTb|@XnFvXsqeT|pHGG>Y!TsS0=sin2=OmNwTsz7vcDypr006e& zf94?vP&JIa7QRC-b8m^9_&+i984H|;IIEOT3xZ#tWm9xKM4N6--{&DVU6MExt?N!REn}@US&DUU_Ud%2!k60=@eMx2OJ~7TG z*m?+GJ}>w&>&D){wqA`_93jC_()J%z^D5t!6etnFC6y$w075{9j*(ZMBfP+2MH1HK zn`Ck(PGhcaadxXPtxEE`2UN5*@YS!lv!{5GNCeLPWdpabD8&zjVmX4S&Zcfb`(92JlYs=3UQ8Z-_Fd|UvHbtvC~*$Hc~tV2fg>~OCgP!Vv@oJ zKo#$kB2@E1TKtP+%eDF>a&vYe+^&HElNleSK3r+PH*oq>`^bw)R+EBvXJkCQaZTIj zF#DhJm|&7)Zzc2_3u&VI(QjauJThNE7RjC~l0ZhC zN$LP=y%#?`-yu;tC#|vAea2_U27xCP?DQr(7Agd^y3jvKq)gBs!C6NdwMZ-@tGk>< zh-uhfQ-hy#55(J9MD+?_#0J2qMuk%i8w)my%Clj>nE<4vAO(kPdaIX2dt2%hRqUOT z-adHCDDZB^EF`%q)V$u3CW7CVwV=oUA4As6m|HVXWJ9qmidPB z;1^`phPi6c?Eq~8u9K)N^N`{PB2&V&JaL4)0$45Ioe(oXC$%VHeiGvYRmL|-I}S>K zHWJ5ef)`{9Nh*uTt2pQv+yI6?u5|kZ^F_Dq?F6WW4rNG=mNr(02ie1!49auMMw4Y~ z2D$t%==moh7WZTYeF=}9=}Po)*S~s2-Sza@FEar_UXsqzlJwpppmZU8e&b^7Lip!K zmP2EBapQuXbmVn$#npoF>=ml{DLLqjviL;rQRyy^b2Nhpfw{JgDQuCtP$GxvBTb-8 zW*kXo+#u?eo^qy}v0Qr?6phmv!0jXw-%68EKa*(jI08q5#%1=6(I#Xr$?5R=5SIWc zM;GAsVP&W)`a?bN0&}XSH=C9coUa$MfL}%@`FItAVMtA;l19Jzwo&J8j(cbL+~U#o1{qFRtU%!k+ZTF z!_LE!)07xWc^t&v8De{$L9=nNnXCL_8$_cE1S4Os2$fGaHcyV%%fxMK;>9Ah602tH z!*`d&d^v=~O+sl;G34u33}%L4iSbd+DU_y_$!=RsBH3rQ2i??g*T_V`BQ}qK7%GSP zEucmrsf9SPEOLYrZ4V)BwVqnWNiilOuYF;}dZP>Ytg@V) zH}a==b4SKp%btgG^dj>8DIDO+AyL%l6Ea4Ma{3a8W0_7#^2jNQ#kZD61SBarnakj> zD#vCHAvu{qb?sx2Fw*!Rk>-5%Zl6#bcm8GeXiz+x&LzccoH?HJQ@m z-EByS(qBh!wgLG{N9FPWz^`h;xs6Gr&~Wu=t3&3?{mR4-A_H5?>tiUwJ_`PhtAvCE z!)n%H7AOo=>2!Sozn~h z7fJ7V@aBBtS`Y3m1q3Rom|g{;0D!D&`rm85A|mqvX8`5%2D3KYj)xnwwGexRrkc~^ zwJ48jfHJQyDFugAj|EC(0C9Pn@wko(H5B_#LnnD=Cjc3b2gNW6A&w*$B?%=VC}$e< zKCFnE5~ck;iv4NC=#>2woo()B_!Se}`MQ;;2RBlLW=c{FA?J|W$eE;>P$ERWwREp^ zB3b*k_czab2JcSsmMD7&sgn`&6zL>L3S3-0UDyhK&FE5#OQ12%3!I&??-p#vM!|s@ zF{QW|M~ecvk_0m2EID@f2E<|GV-_xEl*$I*)r%-wO!TVyB3>WS6C*--9&(6ox#f~P zX7Z~O`}N-8c3wNsBYSBDNkq=DNyw<N^$CnPDQ{S$d85dv^%jVp^}DN`)I7jd7d z(@msG-S@ED6p_w9oB*`dBq8%B#ZlMWX_xtq-cVb)ak~jPUm2W0B&9om6jutCoE%!) z1H_~TLr!DVt-P!T1t$1rdQ-+e&S$$>yW@Tp1-^b8}0_KLY(qa)RF@zmm9EtEX5rX(r#c8?Z(k<{tK32OLp5{>(%s z@3#Gkemt`norflvOO+_{e$IN=vX|unY$50| zEbN3%>%ks`jRc6a_*R5%W$3vutiBF0IHma_bqr>}i)W~Wx43Urld%*@iYN(16G=!Z zLD_wNr`j<8Akzw|j5TmuA(3EVt+QcE-wcMKS7Nq9jOeRT$PDP%Z z27yr_>5lHX<@grXTGf2HR5DDD>B$HrB>F>?Y@A&ls=Wtj3nr6GBHq!6?n4rA^) za6BVNt0Zz@OYtB-P)7dYd6Ep!;!b{2RC0Ms<0sV@?NkpiHQP7baJDJuuNj9`%w?Uu zBne6M^awdoFQe=cB4q8z20JpPT4RzFTLxV7z`iXGHodW0Zw#YBc@_zDK2c$HqDuB zfkw~vZQGve%vNzy@XU)emEA9;-81_!)H}zB|XChnkPX!zN|GcF^zl{0>CMAANC+HywWqpFa zIEdFriDN`rB*&AC)#e=osPmh-D%1%^KE)3i=QR%!<+O^s^bt`^+x`9EeFD6X=oh=Q zQ(Q}f+|uCAom^0ya3VrEHOU~4XOE$ODZ4fH^(Up{Mq~Jq@pH8W{Mn$EZhrj;7$n8R z9w`&#XN!o8M!7Cv?IK1sCtuORWkDpKE|aL2RDD+9T(;GFnYYrW*vCpX$RF6nm+0+Z zK7<#2G1Z1GO`zY?9eb|@J)N@mYKBX3E3@!q>M>qWwv0v4Hur24eC*pX_pFUbGo|^V59w>^ z7%SdPQz`@VAxt5O#Q98-;*g!EgmsLZTXj!tCQJ!ZR2WwTFvm(WlD zgNVnwo-AbV*Dq6+R6=EXa+H*FG%cheSqdZPw5SmwE0fac+{fu#o}p?h&+T1D15)v7czE{OYwA`JMm+~s2D}|d-ZZbcSsrurY z0EEZMcwg!L5X9;@f29`FT9OH1OG$>$KKfL^;A#He;1`-uD%^eBUbab7NGa-x{f!%E zBJWG8URdBe1*uFsV#p#E*cu(1Q;Wy(q(HWWjQZu*=`|p^M%r+)UT*G9_%d8=VwvvHkFWe$9`SPGTiZ&dFHB|YW=GFeVA7KFxo;PFY& zwaJ8lUK)ubWTXnD$rfL){W(?d3QOX?Ge*;9jXpQBy1Q6|2_S_p}?(LmoD8;(er0>HX+n(1-S*?S!=5WSxxCsPc6TYfT0sqlUR) zz&tWK<{`N=tn}B%+XV~n7uBEs8by)b08+@1kuSYCz8u^9%q8=b69;&mxEZ>jT$ff z$GG=6tq-{t6=<^!5s6+D)d@ zQ*PNLc<5=|p6Mw`Koansd8U2yQ5^0(AtsdNYcwn>L9>oK5RuBhfL>|-IFDa?anP%r4^u9D6PkUq4<Zf3Jmxc=&-It*em09QX!=1 zV9cN14wuLiG}=N#=SRnnfNA;uJlT;CZukbHU%*IyDJLBTA@&}_G9L%~uD_C`kYbM1-bp9rC>mY_I_#_X#_tny#&Z z-I20(08v}GY(YbWU?6UysY@@fd{H_8RhrWL3=tr>Az(=Jlim*l%qN346tkrbCu2Q8 z$-XlO&5OirWwvWzF3fp7j%68srO(5Vu4XeKy#uV6U0)ORZ43qA#odH+)6&&7>H7q; zk5}HobWVb8Sf0CdMwy8`U25Mz+Urure$}%kxud$sSHvhdlS{Fe3tk-NW7B+ zA$7MuzovB;Q>#=nnx3O;b1{rRPSbX~Yx)^PbEOQFkkCdw-aJ(zkhLC!{l;)6GRoW35tQAI0t?pwl;J zd0T>kv(?{7W&f38bXOEJbv&s$nF4^$)jojC7jm{Nxzmn-;#l4gsfU#@*8W*5%ZRv* zHpc<%hez9_!vFI@a4Bw9!Aq;`4V7HfkHJ=^7B6(Oc)^Q{YDhyEgb!1hkN|1-Wm{T- zmZ?BAM0=zGo4+k6Q<@fh?itF+4I5^P2bSVt3>(_EM=0|k2;-WW)78hv{npN9WNU?w z1W{3x@Ue4d`v`E3C?ri%7QpGXzqb*^_2Rz<%i_k69^v0Iu6B^;%L0qw6m-!mXd&~jXy-q~SVY96R(lwkXQReu2 zSWE**dpT35esF($k3`1nC_t#$-zRPhJ0+YabL8CzK?s>~<~O!Qtw^13g5aooLckpQ zUF8`zs{Z^bPPHlEK5k)B3!h&hC|Ls~EdsoY0%zNS(KH1uWG%L*y5%-iYHh3Nr&CHJ z!0K9{`vlP90n&)~12E?EC(kwUDXvtt+5NV*BFR-3&Gz(Ml58Gd;iL_Se)zF>!8ig? zLICvy0Y3Co1Ehm#FiE!zQHt%KmZ1lf;Hxm9Y|zjK2F~xF*lssU*ND5wtzaGh<0F_^ zW46m@wG%TQIH{B&LYYNWU&=awd=&xX9dM!olv?|wGI6)a4^weMiciSMddZRSMHU{Q zl>h(-k20bk0P}D@teP`v&b3#}kw(YO%rL!~&Y;5GgAy{VA(SQThli5@a`xL>H!l5dq&L>#tXSpZ5H)4SzcN*)4rFlKjkk0529LRQIG9 zoA`%w`r~^gFtgtW6eOi!mcWQ4979gk9*5Iu+aVY)3&f87Ds z1r@mjxMTnbUWB6r*F#VYBmQZODD6D}j41vd(WZcak8Upf8f&%|%~906A-9SwG(9*z z;=|Z{kKwoiM1Mb32o@h1NB0hkRVs=I7kF?}RRwfl^2I|#i>ZiS)EI8x7?CUfgGDOd z9}fM7e9$6{-5A(v_-jc*c?D1oPGN9TG&m`q;vFq_*A&HP1@jNx@=J-LCv!E7>9)(3 zTembQ3)ggf#kww3Sp_n#gIG+wdvw80=Rwuphz zJ^_<{i8;mnD@zWfl5=Oo*rIs@9A!3{djPyy_lgNQEM#!_(GIe)#DTuHWZ`xtOY=b= zUtCRP7O8~B?^EZ^bvN1O1d>yy7dwGVYTa@;Y zRKsBtzTL-$7cw9XrvdiKX$YbPj^1RQL^P?uSp>GxF^UI^zkn^q$X@;h+u8uKq4nyS zAEsN6jgeLL(yGswrp@%#PP@faREj9W*Rg@Aziq@L+v7LK;iO&++S^w(RLYec!88z- zad=X*-#&M`z}O_ggFORhE2{$5Z$5D_+ZdkI3{QRc`b6z9KOUK%LWrAHsg7;WapnpY z6f~eb=L}FARCnoWw(jm1p<*@ZI#7yDFI3ZRG)7-{;?H}r#ZJMRxHCd$r^AvU7{SX? zo}-W-Ot`4u14GQ57ZM;E*I+;3A;uHfOGLed4e&kOZ%%5F-AE=lw;eKF%^iocVleotYT zpLX1t?znx8kcA(Z(Q*?60cQ{Jj|iX$s);MSnkIh97GQn(h+{o?g%Z@PPrBiyW#-GW zyi-w8eUjc7BNPPiw*;WS!?V3z<7ePvo$o~pzCLCsRC>ewWKf19bQBotpzav_>Huf) z6i7A)q*j(AX^emy9yoLm7N94fftFaR4Q&M13Tos6S#0@`4_P{rreVzTV38VhQV@uB zE*-I9)J)gJrdNQ@)zK-w<7uP_5E*wc1vzUXug7wcs% zp)$0Xq?1>JqnNuZ>z7DO-=vM$t13`+=cMrBbEm+0q&A9k_dY#=X=!?{eKB_O)CJBQxni|-IO*l!D{bWn*NWnTFpCWCtM*hlRl(LK_q4wuB@;7r-iU# z4d1^Y7^X)=Eq=zm?>{sS76!miF3>Sego-(_3;HFtqfYH71L#8^FYvHub)}jz$)LFg z82$;HPCoF4?_4D>>ER5q35)I=Jc7ej`*K)M;dRXeYU#5pR^>szOh*h^2q4@!wg@6r zOpFBYwEz?z{Ky0jq(Sv=DsHcAA{I~w?bCJ~JA~ujB-M*43M#n!70`+R;3a}unJJsH z`re|}P;VS6-c!a5&rO*@dpk{MFC04HC(VHdv>5_nv)s)T@`G%)5f7L%8=7XYlQy1* z>BRwK)~fOob4VJ!;qbEHG_W`Bd3UTwFTUzgI~TIRueumi}Gio08bp8C{Zx_sId}hcp}v1YuRjb z$;sdKERjb7;HU330mec&D9$E%xiFUtSu+g0OT6gI6!odpSP!|o{nAJ_QqSemF-dNy%W#gc_dnZ2$;}afeq7I=x{s_#Tq3e7T>D6i}`G&N}T(1yrn@*qJdE}blqJPcg0 zz@u+u?vwPy$~u;{Y4wnH2uai0k)06M$?H)_u2k4XQ9{B(f~?2hKpG5uqVxGEV%NCH zCU$uIv++f+LP#ltjpFbMDf#eR_AG*=FA%)|s>@1KdmKJV#_0s-Fx1c@y-(8%03#IB zo|P#KX)v%~*k!<}O&Lbp%eIYuL6(mo#TWrENC3RZ22^2Fx-sIEME#TDMOG`rYVp=~ zXS)Y=`4UYJfw(9ZrU;ip#H2x92#)#bL|L*+yjf42*b+4#myl9ItzTiJw=DM!CV@9^ zJ96rP?OiKrsve3CH^=4w`WdA9dL=eHWciF&$M&5{h#COXVbBAU!Ko*byY}vuON+Fb z=+iUeNrQp!*539S5C)NykZg*kNB0J<3_rSE}ftdLL0nOd(_#l0+BIiWrcmgz?$--i{Yz zd$dmMp12 zr3yMn01#Zt_fnkh{xUfbZpM!L#V+46I!aCq57^PGmwz)QlSQ%o*6R%+k}X|pD~0|6 z{NQK-4Fe#>mgZbPZ!}^lFM!)H z_3>W{TnB$VZlzdO2ts4;O^-uuo^5+U39?h!QP7i)fu)244fb#Lt>3O!h0T{VK`{S( z=SOG7`$3)(jwGaoG&DOJDJn%AOSB33<6p3KRHDtLoLrG20L~Le9;dsHuo*P;gpQypg`oTncd9U+q^6LV}hQX60YPFgEsm4{{Iy=I}O1b`N|e6 zMG7bi`2k!)K`77q3@l10G0_fQ8y~iS8-$7EwS+ti65+&1C?``yAPc=!{4&m-c(z?p zV4UXM z0b+Qk#mtw9CgJ?h#M_!j+T_)2d6qo7mJj`nYH9KNb^BDZd|&b8k^hB5b}s;TzR)c# z%tkLRcb-MarRncwf{S881{~JzuEv3>6HF@nkpH^Z%1WCTJfsFRB|jbKcNH{}ZeT=)TDc`kN1z{Rz7o z{FQx833dfTD<3v;MNCjeL$FSa9nE|ZKmsH z|4*6}zrvlvybFhI_dZ{0#i0%6KQP;8?3R4+y-Kl4x_G0&gqZv0>?b-26_~!o2Qtx)b zr4j2@w{11ox>8zkc_p%71^y^lr$X0}YVt2Ih_d!vX_v&xp3C>JNzmJ%u45gh^^b3M zpt^^~!s-Po^K7@SSQ6PexP8`+cY{(*KdgD1xX*O2->Fgd9Q}tL<^W&9CoDdBV z&0ros;oAl91C;2yS3jl;uevxK+&N_2IGzLW=O?&MvSIrC&4|uB|1BiQOl#w)NeRZ` z%R>uTVb)`pZd&>AAamTjBh+`DXwB}tFQ`4CEeN8P7jvNk^^NY}moxxwHg(`yBVKi-FyXDfHqmYs`queUL+(vB{^ z{dZ`Be~88kAOGDKH|}{;E%-R5@x<)iHs?0y9ZWP^2fq>b>p1rQNzLu_2*co;TPxUn zQ>yn&+p78HG1p2=ycU8bGrW12=De+?Rdyo9!u0Y~{_!m03^#ma?G{!+K!eg>mPt&S zzUz2{MFr)nLNyM*J>qQB{3wMzk+pzph+aCx@$p%bG&sPG>0fo2e@+0Hww_M$Ds;`U z&$Ull?yY)_4DklXUE^I$H7joY`4%3-GjeJs%?von2DMXeyPBvGe)uvI@x7T%{ffjy zja_pP-dbvAaLeOW4-NFY+%Zk3h)0!f7WI-C~5<* z>`q?nGj=fx9iK~Ip*eiS^qp?LUel-iQEW&9dO^=sA`<4Y(>;SV5sheyIhN*RzsDnu zt)o<|CeWKc*&~8QmO_thqfi()!_raHU{7x_`cu!O`qq8p1>e_KH}My;7dZ=UhBedv z1r}q*+YVCF7*_VKZak41ucEc()$v$q-3ZeYR&kNX}wS@qmhZ(e>OVzZ4&iHbGjGhDY| zDEcovT_R_h=t_0MUa>SRkU2mVahf}d@L1k(rLxrH$sE%=^-dhV8z(c{?X^>oW9;K% z6=Zdy@mVY0g8N(Ucx0yh5wefI(zyQSG}hMzbLz&wWn|x8FGz612JtZGsqwd!vH{L? z^+>2x&GqF@q%$;~hPXUc%@~e`%y4ku}I{QmWDD7$dC3Sp;hf2j~g9*_?{Xk+m!hulDWbPG6eb z7rGn<#vDzSaf%BTPl+%iEc4fg>6Tle`Nntyt1wu-AX!tmkYD9%+cMve4inO2zp%*~}=^bg(dzB7~^bneW zRF!H8APNZh4&L(Jcdh%b_012$B$JtwWS@QZv!Cb8*_-;sOrr)o3EWLgm6$}09+N>0 z_5^vFytJFYVc2hfAXsP_C^+Oqg%*e*AxfoleMNPL{^b|ES9<&U@)0xYAkZ@YgQ%+w zGtekmscbg~9kM>1GD?~-g!?A~|5 z6#c+;*#xo{KE2-%OaN9SyfLc&Mw0@FlcGQ*c=z$fsNZXq6B5-eHaMI*9>yIEP^*6* zy3!-7$VL)4eIj>zz42s!%r{5sq zXprD5pxpKPX}n#PaBUdG(HuM4s1@ckDpULGVW@|Ie6#F?Uhn$t^6MNj(T$>42+nA2 zY!iDlPw_z6His}0ahY*M zAsF&w28?15L@<@M&xh=FSprQMBC%1e&{qRd^je@u(sL4g36M4#xVnG!BwXdcTk)U& z;G;o&eA?{VD5KkkmTVl6_b@oU(#`}u+M|Wd&0$OY;IYST32zCk$tbJ^*ksMplF7P1 zARu5@2{AUXJRvlmqMVRq_dKL~Nhi$2v|;BvEdv~#tJ-9&9+Sm}zbjOln-tN{<4L`T zPT|6TNmrgq^a4$KeQ7zJ@&4<_|8E1ne|$F3V+kS%GSxyQRm~{^i(tH=nR*(96#$Fs z5^(q}FE2JqDO(AlvGM2xNIWL>&h64cubX2|U@E7~!MpYhcU4vJeA`I3CGV+F14(eg}145L->UJIJVt3X89(1?CC>%zfEvIb(K z1`|r8{6_;+{_l4D+apASLC+QA*_#LOCA9Ch5VO&3ar?)3iSd4%m9=szM`rbY2j#<; zYsWXnH}GGv8G{HTc)6NB&_o&WM7$7OP$7Wg6XA1w#=onDr%EXno62FyTcpP6nZ+)* ztB-L4!=kkU!MAUZxs<0Yao^C1>ok*jli5+iZ9;T`hahO7*He6p=v32h|)xCdBindPb zc8NNRqb7oa)V0v6go?Vmr37viO*bIm+q5r)5+Fou&Dx*{$J;9Zb>;u%5$I<1EK3@nctL1m0A zXkw)KsUt{*CqL9kY+Nw?^HOOFl+$|wpYxU)P&oh47p>zQZ9`=F!V(RAkPei`fd3a) z{(m%z0uLWNYI|1_C|w!7{js07bd-l9YiuC@^(0TkY0ZQ8NVLr>cNnK+*s2mH@8+EDR=W8v%u#l8Q8$a8GFwRc6Sxy>J47 z1Ou0;cD31<+%VUcFoPB;FauZ%Se?TYNQ1QC?zIsT#iVc*QK_?$JbLvk1p?77Ww_l2 z$oyQdh#c=Gmzlwrw_n8Hh9&Ua1bd>x+1XNopXpl3{QuY>0PU-QZ!ZayvJpk4x=77@ zYrtyV3cH@%(YAgmwXounY6uV$=r;FogbGCac82!to9e(cFgD;hd_n;U5`hTq+bdqc zE({R*%U3YW-5Ka1nyk2B~u8}p=wnV65f9{P?>ZCsx<34b}*DhU2OxhQPvL*j0+i#SU&Mt1n z^O>$#%b(~C_oD5UjQc9+pfuM7s|>QG`&bxShrFq#YrJWXyjG<}7A^lyY->xg{64*k zc^saai(3%_-_djkTx&caM}em$ZL4BVp6&th$hxBjYB!4v7=|LyLBPq0FyReqnNJ3! zc5g;p}*-e9-xQn42OcD$3@>*>fqS8QiselZ3I=RVQT7kTEc%&7UO0K3|{Cw}-lZQn{pmrah*i&n;vMQ?ibW^QWY0sqr2 z$v2yYJS?Qt<*ggddVfKrr1L20#<1ZHRJ@Mw6^ln$qVZpl5R9)cb-DXANTVKlYrw4i zjPC$;5EpCAyBj7zYBx2#v7)0C7%taKPyZ&NtM9G4fELDzCg6(Qk}IZGf7D0#RN!+y za!KLpsDJ^Re$FlPG_3OZEr)}Pz(=Tn3YP<2S>@>NUKXT1gSUO`amldxw|lO372*1| zs6-#wyAL%i3KahJC~D{`3e?h~qF0^sLgINVj5_0#+T9jXe`7P{Ss(EZD;cAnAIWOp z#@9M-o`5Snt;5aN3@Hiqx57@;cVkJ2U1M0Rx=f+AnB1a18JY+fTBVyJp|w=PL1ZQb zz+v52YH$`0p12P7s9yU%mgKQ6vmS#NJDt3mP+*24*OET~8%n>H#yx>WHKPm`>kN;U z#$6rvOZNFKt2*pN7rd(|H(p@8v{_Eib@$2OC;Voi7dH8Xj9{s0OWIfwqkPMN;JEEZ z9`b@q$9CYZd=W{!Kxd+p2hbm0M41%e)b@+5)eervLLJdTalhix6PGwV{M8TuyvfK? zL<0dz+7^YsD54*QSIx7CQoP^^&St2Jb>}|7b9x`FvyPy$J;h%Xi&QJhtu3P`ab%c} zwS_N0X-eNuniBK(7wa|35rQMY!R}CG1sd+hBf&?6Nrr8}{qQ2l7OA=jJX8b2S3AfC zj?%j5Ao~Pq6$Yr*uCoKmUWJm@LZ230_jv5yx65}cAtwpnD)Ri_gdE)bcy~?mtVfeW zB|pWmdXhdVGq~7TBq=(iuj6d-DTlnx9?36?kCz>BbPhQR4Q9bVFn>vOuy+xh? zAtS3d&s&~NBEh@E8rk7Fud|D)R~(4vS%WCPZ4O@1GgMu<7(A5Yo zZoZ&7=L&wHV_{Hppx@G-d1^Jfxg>wb7(tFq8|?=Xcg zp~;)J>jfsvN_}&E1eLTWOOs8?W;Bf#|0+o1SqKNeT^nYIxULjx+bK3!L`!WKi3f2_<#itz!{nH zgpjO>L;3cZg_HZvi^oQya(?DmVRJshXUm|$>OP17RIE9YLhv;JIsktG*M#i;Xw%V} zxgRJEcn05sG|-@HTHZmdB54F3tGah(IQHv5im=PnO0bG+fV8uhIZ2gr&jE~F9I#CJ zMyM=V+l>?-IG)6>7*B<*M6Ov4*ObU$rO^fOIPI~-*8yk`8<=OjhIY@T83utg@Q`y^ z1%%r=15~`C=m>ksDg9^!kSI-!7Qnr@#l+3Pmf%+LGUz}8?jPsksgW&G=)dF))(D93 z!myFfi`bME5SSM&Oyr`V97P9lM)#ReK9mCm28GL=ngiIKvn{ohfg=I$(fAkzD}_I-YN*8Lq-g6|9AAd(%m=4Tfdsu_gKTU zm`!#>x1NY^9zI)oPWEYxzxA=QWwFz7w=Ve{*2aZu(00{B#N20kg1W8lWi7V__G)v- zB5l=P_SenhSZ!qBdD+1^m-_>Xh2-gB;~z`Z0+Fk?#t}tiK?2Jn68lg})$Nrio3NmtZ^cV!A< zAA7V{`G2A;cK?E)J&HFzE#xCZiI(KBQwB`IA;Q1(Tk2=T2M#V(?R0QfMt&y!yd?m^ zk_z9&=k>z9&gh4Gkw|)jv0!2wrzh!DuhGA8@85nT9@wJ&K|`|I!CMg{o>fT;^>lyL zV{_ksp`mBx@R9k^V8<14Y)ocfd`~y)vA;!fb}R`wUKR=QFm?;6Vrfo@_yJ{@&oOcL ziFvloD4gB?cmP44!R8qK*a-kxiJhh4)X}6gn$D&l0=k*VVEL1Yk`+5aPvizE_OKqW z)q=0RSP45TIEIJD2eyX=E-POKNz7x}mP*t`^?SDK5=&D(1kY4@5pf z_CN@=a~WJeZwBWwFrZYxWPuYwTClK_IB=;{f~9($Q(3vAPyx)>ycdN1oZ(Ttk&h3; zR7d!;v3wDV?$6n_iUf;#x&!!)p_OVl$g)0@3b#gr{ln+_yYca=iQX&|EdZPibP-ro z8K&coT9AHP8Kx7PzlPCB(I}(fT60~_WQo#P8^xUtw@f^2-=nDQ`Bcw3PrYj~b;#?K zTwwIJSzw0_zt%yKUAFp(y8pbeh7hI;y;tsf!)N*<_kn}Kj|KZj{;{tzpE#^puey_A z+=?Hc9Up)LEX%x4m>7iww^Kruo<5*F-l?faoW1%E_ScYVZXsP*zAM%EEO{7DvSK>Q zYwQ6pkB;5AJ-zcw@x*eQnOsS2@hRi1xKmiW`esUQM|xw);6#kG`7M^&Ge@`T3mJf` zt$KVf$fT!n{cqP#q4l4?eIsih2L8uY1Wv7wwTW(qKkM5n&bW;bz(Fx_Ie$Uq@2gg> zNU!AvjoN_`QdQ4v@q+e|4sJX+ECZz&_L^z$3&bN^6aQ=e%UXE_-|;$D9p~ZaKB~4=O)7X_LwBlh=VsL(C7D`rNtO$Vo{LcV zv{gbjni{1_uk4%+1it__x5&oOnhD@!#1Dx$fRDF-0h)JAaz4$Y`@DqUI%8gwm%1O&Vm zL|QxnXqS}`y~H`#-I4EBbx~xXG{>>&bvzZ|DwE$n2x3Q(i8m+c*}%jMYb5?nw~dND zLG1IdlMx`Dx>YCL&FFfUWdMIrnApT(qtJK-x*NI2V$p*l0EI$~7l)_u9mkIkomwNpsC?kAWdq}{jRGCOc-NMw z&P`#P2~Eaf<4i5$jQ6AfIKo2~E$wAmVsb50teFS8w!js$fAV?E#>0lnfZwh-a)7}2 zi|mu(HAeKV)lCnr{6^LtgrM^)sp+Z1@;5&-yng3GFOCzd2RY6{us#Si6~z}!-pk^F z=OL#W64vLcvpzgN!iaaY^?AczhB*cd9{lDto59))Jom6NWiOVfDc!pq`9#s!o~HIg z5=$QC?(1bWo`#uCPl6V_N1-#<8 zWHfum_TFah?5!a@Nr%n;$@O!FPpmZQEr+^Pg`b&YLPW&PE~0s_xQgBP@fS)fVk|Pa zW)cpq$7$23|AL~qv#$VwoZ)l7g{h7k=KU9x0TbE=l=W~=LVoI+18!+_Gpy-BT`LuBRaeIbCL?D3Mm#6n*7tfRY+x==c_Uhb%aQC(@?lOoR z!cKkwO1OiwWD`)m1jN4hAg^Y@YW0G;J$@UNyI15n+g$MzOaz52 znqgp_H-~x(!nH%u*_@>^%##nTR`YqgyhHY+;TU__n6+8|bsp9Cst6HlQrcfJ&v7$r zu!yE{zA-|+GTL-JZ3@`h_QZ6f(qhr9-W=l)PiDG4402pyE} zy1*!$WjJ*#`BlZ7#BA>JXoLcg3Ivt`#`xmha;<=LhPq~n{1;xKla>IUmUaN0%3gOg z(Z$$LN+lM6wnGf`RTwOrlv72W>XVixBQO3 z{g>hIrr&=(x3HjG=~oc=flG#RG?uQ?9Z#|Bg&LY~(ryaxKV*oTMWh^Pp-%I0Hrg zeI2>P1^0KzOx|}TJT;3@#KcsG!pIzA~W3QF3nt4>M z$Bv|6jgCn&rTd$|pqrTPdvHPMD`w~c4>I-?(8{Og^E+>Mbx^Kn|DgF&(_tgB=KbV) z#H#4UiH-0|MZNv8{1QnBKsUhO0Zk2Ve^zg*H4s z>)kbqfj0=^QS8tY%8U(FPe`rb{MrR4QT5JH!4QJr%?mKJss)42zkv{d0TOP_pcf2?mPoY^XAC=#*lfg3wwHL+Ntt74x^bHS3EU~RF<_!`-v4d#3$ zvE0&oUvBOtV)NE0z>m4N@MA@cvAYFMb!ekS_|^!X zq`l($5D=Cv9)Gj3;N|l}sD3K}pBD~1Rx!+al$p=w zWbKzlXuPs9H;xqT425E9oo50pSK*~*M2|>$EJ4g_WZ`X@$v=0F30eophKCa22=fKN69IA?+Q{~|Ly{GtP@5CISuLqM!W97(a0 zbbeXR?zN3Z&#mEY_`sY3)-(jLcqfi&@1ap@mf%!uw8wS01&tz$Gi<*WB-8;Jf||yU$sNsa5F6b?QH$1#@Q}F!GUGL6YZL9h1=>orz)5Y@0hY)R94+)4 zS5usm&M-K+Cd=?9`nyF8Q!Xt~O=<#1*8S2&NYqXb~%W+TcGMP>N zKvZ~CuF`bg+>7hBl7IEJJot0d;qi{u_~G#h8J4y`-18Cod*EHWt&4NL*d>Wc@w@l@ z3!{`f-$>J+hE&=;FDyj7T`GmOCD-Z~6e>L}-l0D`&dM78%yYI!y-d_ra9nl?@6%9f zEv#uT5nLH#52&XyQ{;k+^Lr|EQv@XF@n@dnbjuYew6!bkc>=EhQ-V_RF9>3s7Z%-^ zAADt?heFsGP#WC*j(dwN+~P&?2#*j4hdG38MY^pCEq^*qFq_-cxx6{{)*>mURtNP! zN5Z3!t~|t8(qhx#MiMhC@qGJ{ckKcHIFzxz#>kWBidv|S$4JA!Lgz+c-$+>VNG;%3 z9RC?ZxhjYiFs#ZM7ZjB4>HqjFnHo@ra{U={oV{^!)fZDr7HJmB_=3;c1eUT;Vw`UP zhO>Q8ICXLUPWCxYs#7ELLAYxt{#G7^YD*KT=Pwjr!0WWu#lcovUkLh5Wx}iol9iLM zZfn81r`s$cnP%khJ)l-g5>Xcqs7RiuN9U}~>L7ig>En_Ov^4Rx!>fRi%-z{#82KV+ zb3Ri6xHCSwp@vF_#S-xYg5IKS83*tI!0bO5dHeL*g!U^I@Fk8#dG&JT>;h(4EdQ`v zD-bDIBnJnU;REl-FR}X)kLtX(p0@!J47~Lx6F`*2;M_)`inx2DPS8#a0K+2s0QU~y zd`v!Z#4|j8V&aC@Bs_~Oj<6`k1p+`Yuvh^$2k`*7*5jLi@20t(>vJ~1GO3lwjdyBS z0%hHhP05LlmgIs(t1UKpfg}L$trvpM;s)f06~B1|J2?3!4Adb{S!yx z{vQ&9Qq$7xbB9f(J!DmYtwhIxgy-$;)ezC*%))&aw+$NiNFSDKSmUZ6!WUrSp~jhN z8^$BcU~|drmB9jff1{(!qJ$N&kRMW-olHVXsqY3&9`ngY^QPIO z&yJTpwuW}5Cr%5MOxr8cs(sq`nJTdCmC^@PI?o~#hIfYO=weJa-()<{x}o8|z^VX^ zFYDhmmD_CcE})jn6cG<4lyPS1OCayt0QB!6hsQ;9dccNiv*v(+eu#V-$(yS?^TZ{V z8~}eGpa3F20z3=~p{U}yKH8}QK^tpSq-m!ne*FyXd{rMabJ^J)|00Z87}I6yH(tP# z%U>Ux(u%3nIh&3XiamWiTdO2l$T-z)Yr3uw;Sz?!%^pJ`ru zD^2|7RLkARp@O3LUDa1QAENpx2_y+jKThji21 z^$IRnDzMJiFu|%WRC&aSMz<<|Nc^}WHZ(Ie3{M@Opf`u2buaDt;{<0?R|QQX5*QMaoYti=`?ZwQD41F6%qn_BWe;kauJj z>0~&Hs1k4uGz90^>X~Ope>bImU@jOFjH3~%B15U$$QBv|&mE53 zs6UazfQ0q~ialz}uHKiFDbPMkkc>lOUKiKc+#tCD`87e5sK$tt3qBwC_K@~7f43PIFE{xUE!Br8jJ>>AtAN+%jm6R=&v%ftW_DSaLGjC<2XU_UuJpRxKHWZIhT^Gwvk7rYB9=L}kBkkI_5Nt| zNBiS+sj}khBgpAveLjWf)Z^Um0I3FtL)8U9SD;geZoSLc$up`10zry)RpW*YORbPs>IzVpI9zdJRl%%OejJ7rge0lY`6vR%v8x9JY zalpW3)U38u!Hdo3ndLiCzBN!c_#Gf|lcB8yv&D#FB(J~FwOEPEDWHC+Bcou3xLpzR zAL`}Qzf3`St6pGFe{cKe)t95EcXDU{q^;97_1&E&s6W{>Al*~_5g%$mEW?$=`{fgm zaM>qI>ZM$ES>^Vfu3qX+jYY^(TQxI|kL)kVy?frptq!eDw6zEz_` zni_`vZQTMYl3}df(J{KXMwI$yH?%4YSiDT0$zfQ_P3RVlkfodkQRQS*OKzCrpI@Gn zx!~&4;n7M=SnOm@Yfj75%<1hhk1fyjjD=t_R#$&nnx&MG6i$f7d8PR4AxKL(K~_h2 zy5XBoMs~&*p~_U*#!FT)3tx_?oC43DPuoo_ocCokY)`&7Qy%;C?x(96OaFacB?kSw zclRY3aUQeYj|!ep!t2K#rXTP8zU3!YgI` z!)fp?TuT5h#4*ovcZ!+P3s5-$aXF`Kn?T0!6Uv^=lDLImIK}hkd+*Ckg5Bm5?eo&h zCx^=S3SW&NF8T%&c*cX@C?JaM2u78)3QKhZd~TmT0Gw8=LB`XHai!Uxqvx4hp=GCq zm7#YI#7}&NFKrH$buSF&`>22&2lbadHoZVOUiuv>TPM#HYYfVB{`@g~DSs%Va_Xf7{#6M2bC0-U zbNEvDU&|JOmH{sVpV1_F?$e2kQG@>bvx?==q|?HZ&^wb#v)hHpV}q6*hfJ!^>&PRY zmNV()klb%d@Lz@8e+*tetr+c{{qGk-t2b276GNY!7QOP!=1N#p+UUO|9pG} zqv!?OQwIsV0b^_y5a9@FgzyZNHqLaI?P$4|+=q&3n2U^gPU18A^b3+yN3%G2m+5^& zLJ}5=pQLZ_mJY_OUCBM4V6^j~Nv0fl_jK^-Ur^YFaQz7%@>8B(;kP>o~6 z$6Z}!RRn$B@_zTGp5S-CLK z3u`tIZvQm!!(QU(PpI;2T`OS09d|ecM1O8$jY}yuj%kOr|Ac=xHO^~QG`&-{QyD5`mU)7mu==Krw zS$_t(v-!JZd=@vD_r=ZOZ7$wn3&VzUKLN6?ak_|crq5)whcKv}pVEDnME}2_4R)KQ zW4rAdap4!726)_~pf|5|)n8ZUk31p*?ncHT)yP7n@w=Bx0Yxj}LDqpH#PYLilnoY{ z7m$DzzQCeUMzQ_xJ}uKaP5OwL$6R{{HY4Z-?Yy0LjZg3YROi;gEw-MWB+me9bVSqV zV`13(so8t4Z>N!W)L7&i>=vwQhf7|?V{=UWvAN}0yx*kZyy%~=A9fFEqV(7`8or=% z%YZMqhrR6-$W{oAm;RG5Zoj@Z{y0R_bCEli$Te0S2!M;O9kk+!_mg8Hu5Nj7wZWu^ zW;0-7uGejRUo1k_e3UOJ-u&JF-*6Pz;m`=YcS5410pG=4;}F}kKLri z>&4j)BB8Jr8m}rs=EgOY@Ex#4!Ip)u{ zra6l{Gh7xTdyVkfu(^YVn0WJnkPw{i4!vV%Qj7^iLH8RfHyIv1HZevK3Wn!W` z!yn5=m+QFkr{l$xY>+e#k<3gx>>Fp6zMo>lD(G0l$hQ3o$#{^=s6JEMoORsH%5UyB zfTW1FjqLg+(O_arfyoQ=W0RPmo%G$RHXzYKs#gPw;*JjU=Qlaq|E08%y}$Y3PWyC=|77a;1f?~T|Gyx<8Jsj_yXp>&2r%t`7bH{+K4Wu zW_XLNpydAgErxqr^*hsZn(07Q!m94uD4;&*<<4}@h`AnFXqoiA#2MKfhT(elFR+~4 z(4!G?GewRYTK@&mp-`|}<_%-`N8+EZ$l1T3$hd5|Z|w^`&h)P}vNX!zSq#xkMP%-3 zzrE>NbnP)E#v4-g#6&s2FLX|D4Q1^E+nqSC`OU-PjkcMfNXK~xG*;oBk-5W$e;68* zSLpi(1t_uP_xrgDn}b8?32(Q{Gag@ZHy)6iBdwVQfb75eV_~3YuioG?y$(hk>v^tw zbZ{yBSdR?qihll4Z?O?5TmjRCKffXCafQbanO*6|m#N$En% z(5CpMk2heUzEC!+n&FaXW6k)@JJ!@5-s7D~!EVzXF0zflI41v`I5(dpx2#^@)|$x& zZpdv8i3w>!MK-edCyxhoJPeJEEZW15liUA-2&E*GTYp=WZoi%4ezBW-mpN;Tizy>V z5~zIu_>0zkJrXb-K(slB@^^_sK}01aJSQmk=J6p;N#kRCVQ)5eU7r|!y-5WV*uYM| zAi1+~X26DX2dgq?mApqzj{V^mwpYX+5sIQf9*MUM8eTSu**eR*p_Aj>+6CkrfZhi< z!HmS?*IKl_MZ!T`3oslgY$W0s!GPglSE&l<&xolayeytQ#{rIYE$^1Zo(!R@}utn6g3D7Rcic|WjFcKng@G7+l?gzZ0oUA z6aO3t<7RD75lcC7#Wg6hOfy)@7Doc+ii%-^(bD)d+NxxWHdb60h#Ql^r6`x`9%v`T? zIe-QyHJe)p0MI7`4(KkPD4uYv{QwXVV2`(uY77hmPN5}WS!d3ST=I0=IpDhOZ^a^m z0@|PZC5iWaI(tCB*n94Eer0jIbMV$g?JBhFPsrI`J^E**^UP`8cJCTpIA-0rr}x3& zD!;NYvb-y7p=G`$@bZv&t9l#rvHzhwU{c0#zR_mxr8q6Ov8>p!n(aC}{*$+@6mmJ9 zL>qE;Ecwl4;|%N0Pmb|`Y>cq zaG^J3GsLs2dwkuyW364`OXpi|>~X6mq(kY+YWi$VZ>G>k5QeM(9mvqC4bzM z=<&|bRUmu>d*Lej5NgEhfyl{wM;@@#|K?qzpq?L8SI3RClYLPP-4uxv zSAH_gcVtVM3RTsyvMe#%Iy9?z-qR~*IJ0sJ*j(7Ws|Rn-Y>P_w4EN@v+8n2 z_DXIn_HJo%4eKrollQHg{jm|rKn5A;)=u-o5<%BPOPUmWNjH{FZ~+_H{?4r@4zL^A zPXE&ncAAeWsgVfEu~o5St4;)FV@ECcy!eh64kHsd;7Z2PpgZiQvr!*t5D#LVc4 z(XZ_Ic@6%8?1+=z-~75(*G<|U42QS4$d`L>xJU2f3lIi7$>X!AICvPY&gQ?m@#d~J zJE*wKLO}I6r`<3yysK)0zKDHoQJmlGxp@1fmuQ$*S%yhr?p^L5JZ7;ij5IgkLZ(@6 zzAtxb^qdQ3OLUKSPI#8DLQV%}X5yM0vt|Db&5ZId$0F`~}G?#v#3|5A*q_OErz_3Wqg4jy~lXBt0!!2JuPTNpv%LvDCIgTKyN*hdG^~ zt#moH4hWXCy0Ik#<>|wU6L-rhx|isaW&ZYbHAEy!(!ue?tzt{921Ca0rpIIwT`Mtp zLXX|Jw$dbQ2^eTZ^C`)jADb+uYNqHA;PJXmiBph{u=34gT zHa5@jbUb$*{pU`fv_M1%b3{5pCy%Tr=wv&9Qtl2EHJKCXFdK@){pEGjprJ?Gc-ecP4<+k8Mu@U(L8# z3ywD{jwmXY-o0o4*f3?OZpYf&S$4&*lCOP&F26{3*Sk0GRqAO`19 z&_(w11O6=3(5;({)D%i>Hg0427gXl)>T}q`qK-iSTPU)3LNkfczw;dR3+P7!*2+~U zezJOf6&J4itzHXx-iZcNP|3xKBt6q2Rt>c`j$T(-2TugQ_D)(Quh;+S>t1~%mQAuw z_MH$tBRuW^k*clYxp#IpL{{Zc*zw2GyX+5H>zAkO_sU<#_JT`Vf2JFADEzbEE zKsE*{?#ym!My-Sy+=%+bdlAS6dxr3~CZ*4*?(7kL?%7T))&A&%HQ%vc`qHtCZV`)d z;zL_A!JJ;Xcc+@%nF6o+4Ff9G=6-@qt$C2Tl4%qT9Yqq+dCq0t=}!^`bXQ37P{Lem zf=?_qU$(jOX3_BP>eP8_NTQwWd(~bN9z~LKC493m_s(Ima+(rKl*qAJ+Rv*<&oHx; z)NI^gL%Bu61w2-{&M`#K>r99aG4B;5;RP9|QpJA^!D=9@9x+QJvbNvdAC?ZraCVk5 z!-rK=-Tb7;MMuZR&eyJ!50@)A3{rQl{NNKA{Pf%voj;SbyUXhuH`Pud$jOVHw?)m< z14Q}`#EiBm#bps5lCD_k$7%;$Vh!yt5j9=)1nsQ6X2n0_QyA-6q;2|(WDWs^tiU2a zP50$dqnIxL$uk0p4nB+0k5?19S&| zk%P5aSJ6qlfiD%c{Nw6(?v2?;3KcViedHdYR6A2Pecm2onq!Tgc4i%7YtFyQCYcoL ze;kO3Q5lun%ZQr}RYdHr74YLNV1u3)EI z=AKdjL=a7DA^oJ!hrEz1b(?2TVb^cH^pVH=SsnSzoOKm#FKQE)&sEg-J)H3$b=UE< z^mp!U;_{rAf~HJkewy#=QRZ|(EUKT7mcV@!<8qu%m_-z&-|cuY@`|T(caqK@E(n@k z965~dz?xQZLHz218*IGw7-YGRA}AVIc1i|Suk%iUF7_T?y=1q?pE!zK8b!w#8bQ|) zruS#>KQpe3?!}vX*xB{e<^2$2BYrmX$2q^Pw$4rKJo$Ta%BW@ih$Ecr==&MF^;t`; zfMnB2*9s$L)Aw<+;B1wJ+Bi8Lcq_kb*FkYXcFVF&siMi!9+lT~(vk!a5IEM;&#>u^c^wv-8??Qvq`y=KxAq8hSq4hOSrt6jX z6KmOdICf5Nt`bVhpdg2dADZw zu_w_6Q`eeWYIlgIv#)W_wftLa|K4i!^uaHu&FY~;)>;~7aqAKMJa<2JVaYJBgJ2&~ zKKWN|4m^*@|AJ2XTc3F?b+cS-%f0Cc2=gfvy6JTMgG{7cY(C4YT3NZnmdc3qr4)NLtMTwpqTXlJ-??NxqJ8u%f|8j%?lC@w zezo;Drw+1KnU&F9+is40)xltYI`3>!g;;Utv0kY4Ss&Vz8Azl=>6yItiPJBWrXK68 z%6TB=GR)u^PND`5=UtGRxD70MOi#R(2zOv{Tr1+N(>mhvaAB^B+v@4n5Q$s6n}N}? zae2%*mDY|7_>>)bFH?wQ_UPsUo|YA|hKvV+!A43<37@=NE%jZOiT8PEwjeed@#y^z z)pfaXu?YBGCTStPq+FIkv?CtKUqa4k%*6TkpW(0NEfhie~Cts6%Pm~us}iRg`NB~)A3dDpCK>5OSk~E&8}aLO(yD{ zRG$nR1*z>SI1f%#2Y~joOfs*Dj)z-znPkJJTN;gOPAvOyux|@B3@F)@5H(8lgWyn5 zN8pTjDib6FkOoy15&p7ouu$c_{MkF??=Pz)J_zu zpRZ0z5N0J~_xEAfIxovWK4288mocsnP1$}^t9FR?e|C4QQtjj&iElx62SXdttc=`O zrsL`Gs(w{s9XENEZ;d=nW+Q&RS9B=`$1l*aZnBLYBBhl4ug()##KdV9J;vU$yp;NO zPX)g?xU%g-A8c^Qarm<}Nl`;>6+MkAm0F4k_hJ2@QqT`51y62iCZFJZKw;kVkaVl6 zuYW-`jg!)Lo1($pLq&5rM#a^Y=^mt0pR95}ZR47U`0c(Mu1E`+u2)Pot(N_|m?=QgGpe0V5MDXC8Nsz8i?j6$}~cPVqhvSWkpWDuI||= z(X6huBUR|p>_Ang+1j%SBg=(ToAT3`YUA4Qb!+uUpM0xoXk}LI4cQkOH0%SO927Lt zyw9|ut>~&d{WMT*+!}LtRq+*4hWy!+crexLpX;V|`FxUW)kH#Dn7ke3k59KuNoVQ2 z4{VT&{Xe5;_%czS=!9Hi+TG!r!N>uOF)ZKgap&NDOq05M0x;_*O}jMywupx?QSey{ z0Xf~PV^R@jdapTdi5DWbg^Sc*?#oRqS+4Sk6+E(H)0CxYpnY|s+Cy?D_@h+7g5UxK z!cVTBzA+*dNFd?Q5H{* zR;sJrk$7-|<>k||=$Je=zSlC1bD^ZIR*R$$KV_xS)Cw?*!Xzpki}<+vE3_KkHCYQ7 z;-$!jx9$t~Hw?8*!6f7@ZMdXJ7nP5bE)rFyUdZ7Ku1(yt9KRX;>SB*X1W0>s5YXun z^L?iY7NSAT4kpI1RU-9(DNwC+H9Y>!SQqN+T56Y3d$8kv@F|IXceju9g1Px(|3RFi ze^|1A4J+^A8H;xH^r1x0#;${ zMPz^M4@_K$cp)y?ky|{=G=LCSBT>CBQfXLOMyLtt5(c=nQ>j6^>{J@vzgYF{z0CW; z^DXz&p8XYd(B$z+AJTeO*I~T|bYQ!4K>7fc8LPP?p0#bxKgtoyd?jP3M$5Pxp+BP<$xx92`bca_b z=bDyK8$J#A9WV^STx}!BbH`@73syT=1}(@eX6u!(%}-9v`3oH!g4ekfyZJ4_6`9(a z9-p>lWzrW5`MplkAMZ&2QY5|mHQ4|3FKFuQN|`XtZo_+H#u`O0_K{=&pHi0)zomJz zS~rc6W@AoYL2UkE&sf$JTM?~$yPDg_{x{q7CdGZ>8LV72bwp2OE!bt7rb-JwaVZ^+))ctX#lGNB~D$8 z@{>IN?|`Cd=>ZiVz!}#>1vn0%I(T4=z;sw3^CbhAiW*vPd{st!JfCAjXD4f)X zc~w8x>mFcYLMqXIgUW`y6Wv;aW7Ld)(Y+oyhH}h=#E*PBO^Td8{1dvS%vmWJe8tw( z>HIci0r=oKA@N@z-(-R73GW0!Q2ZM>+B@D2lI*_?MR4r(@cc>1~0< zN$&N$p-g4TH1lJlPsgV@oOG9y+a7aY@8(FIZ9^jDtDY!(~lF)cP{B3q$zLURwgMiVf zU^U4e1gGwl3`GXvFu)MFQT$6mSpQ|p1uy{w$eo=&WV4jLE_VodUOK;X8gtN%2@Gx6 zI;SwqGhLNdPmk2>+XC`w|A(}<0E@bNw}yvS8l)Q(q(d5!kQAhI=#Z8M2|-XA1Rj(e zK)SoTOX)7@hLHy8@!LGlIp_VK^PcZL*Y~~Gr4G(-n1TJ<`@Yv+_qx|!;nD>}yZ;td z$fMWeuvs#y8zrZ`A(s4};aHGpF=%Oi3T8jSwSCBIvy zfUYc(1<&VlX?vo9lfOR%>iCNJrn59JubJ6tEQ?Q4ohLbm6-6>7RdLO)ZmJ|AHf?=; z<}I&IFE}SWadX?C-%?_}ZTxJpNSge}V-7}Bj4Orxs6J}}f$FiB%KAC0^>ZZ* zN4%IxSThiL*i3JM0Qf0zEu(X2bk%a#B^(4pK?-~TFgOM71$_Ep@xlcq_Z?gy5aO2M zubNJj%~Sq@%{r9>(gr2eSHo?QuVrh;mj;6k`7nb?nO$+^lGKgbZt1j3T2toxhsk70=yR{)^ozYNRU6A7O8Q4AEze+iVoPXmI<+?P zfgI1|2!{Pm!myG5qoN}^X3Y_|h$pr43Oj585bTts9=zV>muLY4u9EZC&prQ{0BP?J z(Ydw&7kd$+ljulQ>_WP%DdJ|-B9HXv zsfx!hj>i*cdg#unCTH&N7=o_W>ONh04?+_0#q#-^IKJY^^_lq=upcD~-Lsbb5(=H78;yEeX4ov1&WO>P#7@xN#nMbFw z+DEWC?q4P1Sn}Q4Q?TjM^%y1W&fZ9dmzsVb{7%dt=IpfM8Js`<2eK$d zjM;IP98~1_R!grlKuNARZ0q5*4<`4TQ9clSurt@)5Eu&ceXbU zXzE=giCSg-H73nEtNOte&;8MV`Nn^HD}AXNe_E#bv#`~5j?~Bc)~rc|4_6F!yV>J= zzhbLTXa<`*4HuZlXT!z+n-Bl{JtUglL-oFKL*qUb;u8{uCWm?Y^#6f4&AOhwSt^WY z@xwdhp780eEKOI_@oOK5Pan1)Cwl9&kLAwRUjCS{yRjYwYK|R%n2z|2#c&g!z3*s^ z#)qdNg+O%`r*CE0k^{`UXgjNR`gX$m!VVBsj>9GsIUOdhs*4^VJ&CwmMyGV;X;YRS zty*R^o!yIFN+0Hgpd`AKuegHxs@;3Jog*Qtj+f4=tCk7P1MAkl0H2t`;43ad$71>6 z6n*}xRDNXhgMT1lnA7P?DwiEpuD=lIZ40lo+c2i7g8AFVf7ki7hp0c;_ye&wb-Ugq zC0i0HJzouZQokB#=yoHQ?0uK6EwF41>nljV%j|--rFjNlI?hH1_o_9o^T2z3a|il* zu};K!iI;VsUHLL59tym~*Hid`WTR^_(uLR??X776PGM4Ya zh+5g@(w=qOo8N26=PGX4(fC{2h7D21#wQ&$xh&O42?!g+RI~!IJ$(Fv8BKrORyJqx z68UkQH13DDed3-u2Dlq8hK~J$RYoLI`7a~%o&);~4jfJ!uOnoxCm;_{BU@d2f|@3o zTSCqoAK9SJ_8iCi7OwE&f*hdjU+=!~gMw8fId|Rhai5=hIUC?e5jXl`J1yMQ2Yjc= z?-6u83-=%ay35xU)4fPTYy-5?RK;TXmW^G+<3Qwa0dhm?1DEn^`tNJj?!cL5bh{l$ zY1+51di4hoPa0*v(4m$8fkd9Bv~5pR)+O8uJR3t*d?vmx!f8RT)i$rzQnX9)`P?mP z9q7FFk%z@Tm}QA5T&uVqaz&@~)bTnFoBd2O#H|yEnfe`dIPCCKzJ$iXOamvu`?bDv zSmit6KM;>?PjFgk_r(_AE9F*ILP1HNHT4_XjnH2tXlEe?FD;hn_6$JV2AHNRXq)+v zJl==jFLB=Z8*0&jUB{7_RJUGf##alS5pm4iq{iz((vWlH;pjepJ*xhhnQH`+#46}e zuzBB6BXs;?dD{MJkU#2y=zM^Rc=tWrcv$iYwvtHv;}i}`Y8A%(pm84g{8Ol}ngD;I zQ`JjaY4Sx}4DKE`kk0v9R?or8`P3ZhRK96?ro`-SdUlUIDH{EZP;8yPM-viqFkPo5F(2pz--l7s9M}@b;IG_DDq*!+;lz0hEPJ zO|8RKj%jw`kPHd`7X79^{09o@^xkt>Z|L%gCm-a-`4|}-b77JR=C)V~mHjT5`%rca zXmTlx8!f|!Z!RpiHf5%LwjAm2ZqHM2zM5|jJ+>2WOS5Tc?xW6JU*%7X7|7Ol2BpN~ zLeZYX7ZDe2-9Jy0D(RiG60KzthAawlb;|q>ZVzc!A6hm2b?!$gn1!`R91ua&2FnZm zMUfEy*|Pb{A5t@JoY6|fpXbkDsD9#XIZA0_8ye6n7&;M&b-8_#E7v9}*}blxxtTbJ zYIfK#za=(wPux61Yzg~{w?P(zCU+%^q~}qfj-XPBo2y~1Tg5Ju5e?y7q-gj4hGYgy zmMDj>O^V1^*qf+QdE)WjAm}gd*87#XJc-K0?(=M$a0nYZ#-rT^u+19piVGnfJ&Hs} z*zr~ED{*<{@ZV!7Ty2nfsqTAIx^_Ord4T&3VpeC@9srp1{X-LqOLp%ifkI?174ryF zC*c>Z<2pHuviN{(16`ELrJwM?tw27iHKnW~5qFs?e#0xm4u&%Vo9QzvEX<(FUpUTO zf3bErlIy;~ zZ`kK;&jZ(?xVpXR3EJLX;_x2yDSZojyZs0{FN%8c2lDsCFh|iE-8U+RF3fMF+lLph zL4~mSOuk#N3b>$7=U3NunT`^*@sC;0$in$GxM#1f;c!YHEVlk;P&nFOd_XI55lvVbE^>DYusfhKcMmHaYU zuitq0`2@ZQ-@DS2%W71{h;&8L1g0G^Dg8PuIf+C&RU-~-8=Qxuj_B2BPa*pl4%`-y znhe|;y_X6KO*L;8`MouiT%&1W+gG=$#MX~*(A+eH)LgVIH5+-q6e25MvA-~Q!|5oNqAhK+%ggtae8`)7p)7{rnn!NXRkr@y2bN2PyXO4D7laOQc!6&L?@{c z^HDh90PIn_nkR7O9syja2d1P60EbTHyHl_-&3Rhs4`tY_zd=Fe@!4zmI?pCkb+o#; zj{mIa5FQr8PruLRS%^2!{kpD(jaU0LW@j@S9=|M~b4urln4BuheuktN5{_9+Ky3e} z4rTfUkNaBz*;uWzr}3&wumtPeUMY#rZj8|hwHa(Js$mc|#&@65cty~fX_68Jl-jDcw) zv9Ro=m3w&9wSnw=U&|ly-hDgCbfr~@!{K8D;lrPqd&0z8a+1YwLS%n@A$R+p6H5|U z+TVhC$idn7dVaB+^9u`>LBbc@3=h3rMrd})^$k`R#xBXC=3?tq&*-xX{(6*WwiR)Y z0&97dMFvS)5Rs3_CQ2(a8IvzQ?WLyJ=^gX^_TXVNFovaC^qRK$M4WNzJG&#|pXRQ` zX=C!sU!Ucl&1h4^$#aepo7CGk4-6WpA~`N)r#~Gr z8m2Yos##DryJ%o$ls~@9_I<1zS!>OZToAEzJ`a8g;2}-=bFwlANu8aM{!SqI!x+QZU&w zV`%1{`@DE;pNg;B6XkWhPI}>KYm8Jzxh2yX29^Od?PCuh+MNta=Yqlq_)j3#~L}P_+9txW7!)K`^Lv)ESXh8E7 z*Hf+oGDCUrAO3(LZgnAX{NHV~?f;+@x2|Etd&zHMjkbl;S{dAuwyqjLh`Pv)0t-R% z?%D~N!ppRKFO~Q5esh1nHOc}OV*w_o#GiolC7OkXP&E5PekIfKb^5rdr?|9dDIk*i zcA`fR*a^W5;#*2efT6md-2>yzvZbXdOetsMVTPQ!B`nPxd1S>%)n26%YJIqoTYn&~ zVWDW0rdnMO0&)Yn@U(++OH-@o^W-SRWRA!6zK+i(PpuZs?{Y7o5|#ump&*wW{7h1H z&Ci7yy^B*EKugq~E9}|r%$c}@+Ee|+BIi;V1+J)W%rB7J=JVdn{k$z{1}p z1Y9IwxfAWJz)}eJ-f?QQT1+oK%Nb@IvGE^@Wu%JwpfaTbu1<)@zk zmMdT7US&t?ExrA=eYc#te#?YTPVkGxNNt3YSvo<@C-h>5Q{RSD#Gi~^gpX)0W0c{2 zFg~U=ryWX7i7m$qIhxp#*JmzG8{|d(C9_SAhSvKW;*uigO>Hpm^xy}@F*PNXH6=t_ zkJYTSs)!xpO14AWC4OpIu-R(YKa70sNC>l0lx*b?RhVtJnIJx$xMNqb3xy`QO%e!ci+zf6a1t6LQE7g9J`y=ifJ4yfkpVIR10q_>TCF2Z}((9 zQFC}He3z{h=Eem&725OO=sBM~eS>LpDfM+wP1Z_*gw0D1wNEzB4Xr$%Sau1+VDL&B zJE%iOiOe*;FKP$OT1JWl{dxO+8ghteC?C8lFI3WJ--exk#~cLOU!d| z1>uOz=gjZ^K%P;{3x2)RGLS|ekH@v$L}|9=TGDOk9v>Nr6Qoism~ALHHMF?UP1<6# zxlH7GpJt}!#~0Nc8l(fR>kP`lD3|PH^h6X?Iiz7Ca=vo+bL)-{nMff|!JX!0QcVvT zt__!|Hoo@!Hm11)pJoaR+`Hq{z8MzyrIWDzE#`#};s;MR&&)rFu1!Te|4a47%>3DD z+Y!-alwa5TTZEaOs9#T>)t1l~&GFnPh2)l0PgM0+=4!Hc6+C@VH|UzDzCP<+k=FjM z=Ap`*_w)$=r+G6l!#FwsOz|4AgKh~GXskRgHinLDFC@=M$+&Pw;FK6;Es9W+~d%JW4N%+Boof&7(YC>_KP0uAEX1*@8}4Fk2x zB`*9&QH}ly6YqOaS#V{ojHebaSx0?2h)}tELd8RXu>Uo4`n~55r0D2rM}X(sD_3gv zG3~D!3A?;^c^b50$9Erm8Rx5cX&tIGwyMa(w3B_;tKG`T-`4fPfu8#m4e?TT8{j4?{NSOwqX zOM&L!&^QR#Dy)7_qf8p+Ly&f&$Up~CS*tIOi?5#*+6hivwyypAXtOET5PR`35A$Ek zrEOOECxYv-{De(cuOBqTF6Izg}Mfw$7{H88A2q%}>TJV(qi3ZT+To2HZDue&&QuqAm492&s;{U@-{^xl#* zF8#&v{Z)VeRoia*SLxlsim|qnjL85m@rle|B(J%EQ%9?1X4msbAG|oBWYcxOwECKF zhPSuv!%l;Xx>%)*wMm0|17D6_KL673S|&lrOs`f{hex;3K+jT?EwN~ThhsmJ_F$=L z#X9|LmIJF3<-w|)hJiSq_({R??HrnT=hU~{T2ulmtSj>HM=jUCzwbQTfy%LbZ&bJ7 za1-x6x4GNi<Yi~B6|f3yrsA;7eg2JTQQL=&-*rIL6ZleiD9ara8tnQ#Lh&|fT&kQJxT1BY1n5-> z!wOECtl>7~J;thDZ@F_6v&ob;6qYMm3Wy<31Gzo0M8WoY`Zrj5*gEn@^`HSGt6wfK z1ZzzIk6ZVJ+MZls_~;&Rt64Qv#yjT5XqE!`oUmDzE?6`F@~ltSA*GhSk;^swn)X~m<5}w; z$W|6bM|0XPH*s{?<+ea`H?||+;isBdE5+3JA+>hf!(+mOn{ir}4y`d7C5lBh1uolR z+Ve8ujD4Ok{XsoTHsbK8u~maUU%w0a6?O%guBE}pW~PLU)cs<|7-I)LX(QV+Iw~Fpz7GRMK>$Z% zbUk#Us53*ggyRGubN`m5_V`x8Ln0_-j)E}Pv~R7gB(fCR!(Ec2j9aCNTQyUh>pFGE z;FDh)At^rLob?cox&Il87^_LCOH^zMUtx8$=P#t|r@F2LUSMiwNqbSHD9ljcr&zcC zHgq_>4F?~QC)iB~Y2LL|*|`4&AYy?Z=VY_gG~LQBJavp^I-82Q=S*#=U8YTNPof^m zq3%jh1G|8%PxM%S&8yE?*~sjar81Jbr(yOOoQ#OCpy$QX~uUyuZ^~t$A=Rjsd95Ezge@+eJ!x(mIcjd(y{0J}x6E)Z zgg>F=(myI=2hPTfRD`$R0!y?{%`D&|>NQ$X9&shE6cHY3rsi*RpDV}iD#sqAPUMKt zcB6?f+QIJ>hT1EQ07UQu=vpR&*eB=j9U;KDLJ{*0K+~!;!G0D^JQ}T>4N9mLVAH20 zCOyGd03e1muOT#thEQC399;ZR01~4*&NYFmaQ(^Gza#g({nH)6(aiQdC?@ENcQbqs zow&tXD3Ep3xYV{DR8^*IuN$LOqG-p$A?(lw<0N@V!2JjEnG3aeEFm$s=f!5Q79s*w zq}QT^=IFwiPpYii;umj;bHml(STkYwl7K+Uuf6RvB5Wz_UGzx8ENTwT({>@f~ir2Manzd&|Wp=aTJG&sgV^r~kSGorH%pY#F#Dps-?-bBL`Y3&Ih2jy97+!~j(6 zOZNF&azE~#CC&6&)>VHf$QTD$f!ELkY@@k6cT3IBWVZc2e>^0Fy*uJ^$suo1S%qft zND4V3FH76=*sv)mZLyJm!?Vuc9uEo- zqRH1t#82zmMPK?~geg7u3;cU{lialeW0B_@;s*7}asEI?vsPCwB5b#^Y#X){tF)iX ze)+uX8qGVQP-9~e*1Tpla7bNJiaTUxsPhTeQJjZFaUS2|N3}P;94z`J{we!Z9gS3I z)N8-hzqqfAjJGe1jL+`SG$gO(r`*2~4k`>ueRaki<4jB)opD~76t3abUg)=l({|SA zpFYoX+f_~ovYY7UY;5c1!1W8&ZKid)X|M1UTfK-&llA=ru{nG2&sZOde%&>j$Qc^b z_xb9kz5L{UK3+5YPR>ne{`vFxej}oqYQ_UZYvTW?n6M5vH3!G8? z)+0vgKU?a(Ci{{@)@$oOi;Mi``Xxj@W{7<{Kawz7TQ^7-bF8p!ZOF#rIauafq@T2{ z2L>ApI~9=Z4YbT0aOx0k_4(+WOa)_QS3AtnrVZkn?i7>k#9yqat>UPg<_R{L*{3xU zyn?p(X?-Tqa~k*APExL}vb7U%4?i$fC8BuuIYQg?QvymK&!I} z7W$zPw5PXRT&D{x;RUX8`Mgy~TnKV}uWNZXTc{N=WNcck<9W^%os#P#PwRvh=SO_R zD`B2LRwi((BG+8R#a-Sg z{omCYOQ0c0Q@p4Cb++W(=h;YMVAUG|%96|Ty`zqKuO6`V>&qBh>?)nx@ve2(@>Ej`C8}Ryq zW^p~+D|*O`R^zM{Rxhx8jaW-3tA93Bj5))G@IWs35FxJlLRyPa>pa%T#r^6Crr%#} z+i-I%QnSszgz(K}6->JN=)K^ZXtH||ZzwJdtG?ZGt~=F@Oi?h{jJDRU3+;PHJhkF4 zV9BbagV1K71H2NxC;v+KZ1AIF0fFf=Am>H5@Guph5u>Sj*zc2XnD&u>M!d9Oc z+cc@YD0U-xjIrS&oK>`U8Z9w3$ z&=!)Fe#1=A;>$WyVxR6RWq7v5)|1zOuxHQn4DJ8-bokgNOV>oojEk3NFAjjAQ>47I z(YEJ)KS-qIy8ksS)faXzP&(fEIjdqDkXugsnq_afXoUI99AREKT#TZq6S;pWit zVE=i~aE-x~_mPhgBiT9bQziaeIUVdp2HK*{y;t1>E2zgSs$@#+K=t#y`s ziVnrJF4930=(s^DJ%q|KXMY@fMy9n&&v@1hFpVXcSX9 zGa|q9xY@R65M)HIDvggGtZi}8=khT~QD-|t05sEP ziWu%Wz@A5g{L=_(k*`YjK?RSN^1cuOcC;X5?u9(=TRj54kT||uA%NoT3yjtXJ&KuF zqDTlWre5O^j-4L4`hglcUb}?W8ai)1O@==kF*xX*SVKpY1mRxY{Wl( zR^`hGpXjUsPVp;tdjB${JT}v7#WRl_{krws8|vEDIDi;GDd$j7E;c+MM~V3)Mq~RN zERa>EcmcWCzgYrcp}`mZ$aol_Ez4NSAAEFHh+EjLY^i2U2dcC zj=Yd%H8*_)X;R|3!m{5bmfq^m{dxV*78BxPjtK1{-LbEt)O_cEApD8j0~5yZvYY%T z3PpX;f3o_2vwZ#@=us0Rv25)wPxHZ9io@u^^ffOH;{R2%jc*bK*NoVB@|#kmI<@3!4)rmQ+}v+b=^ zP%ASHc?e_IyK=ywuW43kTz-yK(^(m9fR?T6ogXO_6FnCd13H##)PJg}H_Kjm-@}^| zt9PB%e0Zik%{!%(>_E;0e} z2-S`xg_K1mX`=Xfxt7{DJcVfVEwvmUcOJYYvZE)#M5o|{bNxhwRj(fH%k9jfkem&%o4*`6(!y0=Z1SwnXa^ zyG0b3s5odcYU95hLx_-Zc>V{3gBD&L1G=5~nrR0v`Zuq(NWJ~#O|<+j4PLjGLEm2V zLyjh1eHwL;S&piis$uwGodgKdq*?}!hR2v?8%P$%=(2l%HKGVm8h|Q+LTPx11&Tuq zv$*&G;)@a4I=$m9TdXPCiG>PdfbI{!11MU!7oEy;Uz7A6f)3Yx#3iH4|3U@VJyK}x zQXHTORl@y)Z$@weI&3BzNrYGXB9N@p^s|V@^F+`DpfA>ln4pFF)EVT@qm#!Wiq?A^CE(%!A6i zwq44_f#1;4kgpCN7ugTExkb*W*XGjL8kIS7TtA?@_QEJ2)C9%E5v zz^$-M0-j7fy=KS*FV-atb@de*EzEA!ySH$IF3}?T!gW)I@Eq~l_QgJOk?Ks_p5Cgo zT%_Sa8?gu)MV~D4QKuDqyFV^mIzFVq2t8>?wLap{zF#P>*^4*sMZ=AbAebK;c;ak? zcbHdIzk8Rw6-bKv858*+ea?Aq{)Gy8Z-W$_Oti$;GvADSctTycFyQ{FBq>_(=CEUNi44P)jLezb-GB&fMnw2a~~UjEk(# zSF9~dIdR+bzn)cdn|TwmxvN{bYY_xm#vOu6A{`^E9w0fX9h|UbApRyn{*4Ry`+>(3 zjh&#-WbqF~_kX*FNz6BnRKrAS*8N@OLLsE+_nqu~jMm7jfOwsF_6c4S>HRPn%LCxu zXc^3iHFyyA26 z;MsU;K#eZB8&&=h1Nv^c zOSGj;3|((I@|LD)V+FI?a7y7OB7=SFFO^r`abN9ked~buvMc+6McX<4N(!$*|JivG z#ge7N6ery1$g8ax*YR+k#L=^PW?m=3tLwCQ*JsN(qLX+jQ#=_B%i#roAp9aZspYI?%nZbI1TA=hEvQ&aBKcLHU8=U+vc)YL25Yc*PC z8S*UhI7%!_OG`>PX6`z3Np!{h2`3bKTloUeUAIp6*|2!OPja9@Sx4d$sM^c&&VNg%;q$A=_=;ZCa|I+%s zLg)PJ;&GC|e{{(JQj@R&U9x~NKMkSzbRj6q+iW5-GcSP`R8Rw85HP~b`gj$SawxEe zCfqz<<=m1CPH(Zw1b8u+p$|E{cvUjU&#T%IzcMRgFdB-+rn~4jRrYanJtbTfH?u@{ z$O;Y4QK)$3X7AIF{ZL}~?Xl*{q!gLfR0`2H^Y1$AHD(gHMaot(xy5B>9hXB)v}4qkr#5}sdp&TUvmx*8b>{3Ou793<<1bhM#a@#*;o6pGj@?Xnb; zKQyPnjNi|#4_6lms^toXslB7UJ}VTDKJWfz zpgfm!Ug?-LIkDu<|NFD4?Ix*l!Kbqz%U`Er$0dF9)MrTtHL$r;e;Zh|p>NCMrP`sl zSDo((=bK+jfa9;^{LrI8byVbzuqEw+hq}daJ0+KG-fs>Z?VECy=@NbO<*i`;1e<|u z88O8P!?8T9Bk5yueTX_c9Dh${i7yuH#D;hYW6kI%KaTzr+S`W~GA8TONj>AA@@kz) z=Lki{xY4PdcI%gh1Z_3S5SRF<7p&sPW$Xo_C9}3? zthjN4a_{Yk>wb{R1GE#fJOAQUBXU@BLkY~FOJ=E+KZ8ai@z*|eT=%ad}~ z42HbHc|!z3ZYFajy-s_wi>`uJ9cG}oWQ;P<#~X{5DBCS3dibR}b_&g>QLxnHd9sSL zH{L7Tj`%ZcYH7z1g1yF&nwoa+zWNSQy=HLi-HtBIo#eQ_W-_~b(dMkFaXhnfOqfkk zHK-?^d0)qiy5C#D)?djV$&R6AYO!5SoqejZqXlP#)w()Z08(08Q{;B)^z}WJ#BTlF2sYG2 zaww%LMqWdXHCQx66X7;0!4^2X3Difw%EnNXdBBpafF4f5!IQrgSS*UVTc-Qsrkiyl$yyIwcAZw=p@jaf0Sy17{li9nK#TuOhC1VsT6VTmI$)$ zey7@{m5NUbCgXh%4>BV!A&<;0^0Jah{QSPhe#lz8H0C{?)qR=s4@A3%H8n<|F;V9U>w(50B*Z}Ec3v-|CW z^fVfg{r&a>z~Y|DniF71x7~i78@1fDuB-p5L`+WIJTbrZZ+>xUIV|scG|N9(o@uwy z;Zu7JacQYTqE&cQQ*Nzjw$g)z`$P}^!WQ~sVGCVx^~EHPAYDuj$;c-K2W_dY@hYw5 z@$fzG$+Tn$cgU>UMikuQagi>EmjpPu8eCdJNJ6Ote#O5C({BXUtAn{H895v8Cge-k ztACZaPbgCjX7)!I)VRBeh9&E`l(FFaf%$tP6(zbjngW3Fd65d*#AOR;I8&gd4&wfFglY)CJ(oowwGDYT>pX(prYd z6QzLyf3Yeik5DZ$3_*>-o8jDV$HHZG)(qO_S5-!7!iDure;^rT9IlvOXk%!q1TRA! zo$XbN{9`TGdyW%s+Mf4?&KC4elSU0}qPDYt=8~~PmHKj|Kt-vO@-#(4o4qdl%4NoW zMt!R3o8FpXGJPdOX!6sshA{QUf%tGiNBe>hs9rpql2_;+)tG&d7U^dU=Y;lY-*oNq zH#AG0p3*-%Pql{5N?gwXBQ>1BySQHgwR{ zs@bB|xhqx=qT575h304BddsZAT0R<^#;QL=pH3Lq9DJGRApGnnIh%YEzXF!R6pGG> z>AQGrq*|(9$54KCCUcyd&)g@~&C`FeP|Pw`6X|(X`OnJgJ<(Ax8{}78XpHE@{ZaLf z$%agQ(;rKVs3+w;9O)^iuG8nF67j8xO3;o}W^7&cx?5o(qS*!cGUX`IdkG$OImPA?Jk%rj8~3JjmiaGmFnRU`r}D?v5QD|g zu5S_Z78kGa?hhpRJ{EohT%*whXzbJ3iJrO#P@33_q$+4}5puz?)9tE8!hf%UC-2?` zSPVTNGkD*(2SOlem4*+6Tr`?V#U21tb=;FfQc{8}nu2P321Mh}*Dh(&&OcxzTp8Z+ z9{I!gldspRuXYi}_SfR)yXN{&2dZjy8}4~_c6J`(_sY^hnj^9Y**!~(O}@0*cn$&I_BF9qo5->_ zozG>K8mjjh70n%UgEtaek9&$2o9MfG2d|`8A|an}XF+I54pLJQmNKEP*cXpTrl%}n-$&uunbRmv5YBzA2>Z>| zy=K)c1E`&mnprgmj*FUU(38e?2Yz={#cV}_ERDPyp&Yf>SUy{3H31=(MeYQ->zf)B zv3+##p~zOBmD#V~+#FxeX|?J4mlU`|^s7jsR3oLlCOnK9t%HVhV_NJS!t11LdsuO{ z$^YUAMP;Y6vLxvveYh#0!1mIjIDhfRk>Z2*Y5iHv3kzyhPTQxdYSW1Y+2a$Xd}&wJ zzZTv_DmJKK+b^nl7I(i3=VvhFS($4(N^go4Ng%S79clnUS?Pe`ZGr}hAUFqzfWq9) zliuN>ox(>aC<#1+B&euh6p^V-mJrPNtz7-6R5dn_woC6H6bCr(_dqYgt}|p-zI)G* zf5)xZWGWr0)^2Pl2~W@hQU(S0+`vi8=BI(lxmUS>d*$PG8Xf8$T>{Q=bMv4sXhXx0 z9oCg~kLl!-S&G6tcvg=7K&D6?Z0@2}@@}HX?$&9H^Z!8L#S5peCR>jU7RUG-EaD<8 zqPYd_9>H$jg;h`GiFWon^G%+7CTR$Hbx5jYIP+?bxP_6jr^YLS zW6s!b?q18dMhAUL)abTz7WRN$i0E}#ebiNK$D8qar1771SOkJi)*FvY)YEr;&EC%K ztzUoSQL@u2;W~X|Q}6Qgc{%Y?w9{bEZ}0bTG9z;I8`{@53bi7seC}MvZBRvgDG!$p zcQm!1f#)N-Evw2NxhWmkNNyBtJ65)(6|wVc!xfY)vbA){#M2v}VfF^$O+5y{{D#8- zr@!2tn62xh!agzTFGF|#XE~W?d)n(J6NzZA3Jz@h^96C}9l9z;<5CRk`f^T~!@20y ztJ!S1D9SsFdA?a|Ir*9|y(L;grz+R7Dn^N8jVr`0_51^|A}WrWeJAbfVA;$&nc~em zgdd-k!k1SrRz#9hyf8inge#=V=EuJXlbKFss(04tIo^Ik{wZr++hiz9q2SUPGwCjk7x&L%p`YhyT45TY_g;c+nd`aKE&dwrlO&p)_(x^#2TO`;65njwjRYaz44=MFOr{gh)BkpzRGr-2Wmzadhl32g&v_lliCOl54!f+Kka`p z`m%>^Bj>xJkV{NT|NBDFwqBHRAk!7PVEwY0-z87H;9a@!)oDL{P+79{yq(52O?>sd zxrf}TNrrvb2}q^Y-f)V60g{tWYg%;X7;7VjROqLY51{=6v}hb-K**VUO4KP5lveC- zMu%;>5>L&TYsU;1Ijm=UEvU@8ER_crzu{b-NghZcp5VkaoohEZsP(=j**s|PY=1ar zu_~Z3Y!}jUCoA%W68ZSkcz(&}hun8^W)MY5$nG%uQD)_v^@Y`tI(=4K^`}HRHp%m- zUxVRVBa)G<6>2${97?ZEd(6KF{go527x$|)kZeFcv7{mg7HNt)3gd6WQ0hi^F~|Lj zZ4b%3FRA2op6a2VLP~I8C3@Ir8-j12;$oR;+y?UWgUA(`L*7V+2vcoo1n+Y#Zvlmu z9Z|`%)nv5y7C2d-M3@sRf1hrtCqnGgAw4FN&n0IeY!b|8-OO((zW1uU|1I#N#tChd zjYGD=!#$!veXz2S%~q3!jcIrSdr!TQ`>EcR2t#SmHs2K){F{j;WVgJlHfl8P5z;9j z9ftC(j3s>i+E9ymh$R!V)Xfb0sTEVlaI>W+^TRvRFnNnBYr#&I`0bMFdPl+MRw5nU zp!)O%a4IXNgJ+t~Cz7@K8lBbeab+qPEW2k3$?$ug_CLbisoLT-;F=u6HR_~6c~ zOm)?I?)3%kYOBsPg!dC~&1C8yX<~}>cyo{ZK5jiw1MoM%7KR)w1L>Q(&@1nSip1S+ z7m*TOBiWh}I9P*YB{2dTI)v(Q-aPb>JHuJJmmlSWBjZJq1(S4sLOl7{=Z5s%|3Fyo zr6vC`J2)8f!O3<=6aT^%v1n^=Nc+lFyHy<1InpCfXh-sxBU)Z<-6*DU|LVo9;@>-Z zYp`%mD`t;m0B;$vJq7_YdaEn@A|a{$wI!2ZwV!}f?J0A|%0pQPmZ@=Yeqp>#hRE1l zeVNzO^}l7ZCHp^>nilPTCuPrFosOj49o6-hB!cs z$V#1V|7{lT5nmoVZtx4<2delKkqk^^Nh+@_+(Kd96~chvgLr&YJ+flT3rC**QsHYh zTH}tU?~SjjH@3BP_#Dq?e+}(iI;=|1|kSzUazD;^)^_10qYV z>Mf?`La8yN3G9Z%!O$N_%tMziu#P-QjjjC_E0Nnx^Z-S} zm(7JV`LkT$_d8CKMN-f@+Ao16cS3N2yu2GV`+YR(kN{MJ%y$1+(geCuj9Q2}FNICtbDYsXy8tdE5Mb+Fhq632~^b5_?)6lFt zX@{CEQnB|{r1Lg&r{mBPl6NxAE47t|Kck zaly+Bexaydq3#FV1fnrdqSBKrjrYP@E!_?CDhQV+hgBkQbiF%kjq!JM5-4Hm^g(>8}`z_G;&^JPe~W^fWj$Q zhe%2ZMi0$g`D56XO)yy*b=0-lvWtz4F$*Ryj;7Nd7YN?2IlyYxz~s4i&scJV|Gw*s zjm84?(Cge<`mXR`yJDSJ5wL}h%GHeI057IMR+;;)TZ0YnFJ#w0sBw2Avi?x@~=HT5Tz#-QTxW{E)7*%!p4Z z*6Q>gM(p#oe%YtGV}uD#gD^#8MB?5|jJt#xw8SzMF+j2#TE4U#G9ZY5PMzQlLVB8*+b!g#vf^$OtV)r-4k!TlR06>!+f ziO63YkKHc4J1kuKU_gVJd<{xPK-4ZSy+~m08J^M?yCsT8u;Lk7(ah`P9kZu&3{90U zCSgO18XoU|&F%Q)dynSwU>1|?i(~Z=!eS9g+3x~)&jv+$-z+_-QVX!yXLoNqdKD08 zp!ZAqC%9BsnY>AUSo{t%)SVIQ#|!B`a*!Sj9%-;)+1ztMyNTR}TcD=DT({5v;+8+> zdZg&`BH{)1q8Lqu&R71cuWnw-W+Ye94{`YFL`Fx4Mt=ERz@RyU69nefni0edJ@OSh zTQB5+uq?0ndrv=4vF2HDY(upAYH1DYh#2NzZ9o550F3L12E7sZ zx{^9-6-fAb@`bNqWZdC=kS>ZHyBI|Y)}o&ZSbYQHmm(}~RRP=3ba3{n4Q)#09mS1O zn+5x-og^6#kw;meT4HG zi?X}OMS5zZ%@{@L6vy{y(&IzSCPNp+?ak2GL2{Pfkf6pqkddO4C`~9PO@}XSxLp9! zt$_Gbk4c3t`^nPf&X>+WRB{?h*j1u5o%{>dwViS+?31Z$)&M~!Zm z#beD*YzW$n1WH!4E_-?nbA3H)9iRN@R)$%}B^mg9+WcRtA_^7N-zk`D`hHlevFytJ zF#X-*Q^PXNK`r?)Jr=r8An@g@(*Hx=TgOG&f9;|mf=Y>W3nEB|Fd!gEgM@T9Qp3=l zQc8zN4vb(&{S~>T&{~?CiyJm&RLx=2gxRPg2VcRZCTB!v%8rV#@96 zH;B^ZvrUSY&qQ^@Yk78lb{pzPN_RJy>FxZ~&wY}v6D-5ZG8wBVJ+k+FxA@y|FiLd# zMs=Ep@Z*{=R|pm*7n3En&5tow9LvhT(ALyWwXIJ&-%$r>=(XjANnr>T=<59hXU>0= z-%zwJI|!%;w!0BqFj7qE#_NO{n%O+f#y<+p;V2!~qz4PCsAY2*$(?zb@GMW)_)U<3 z)*Gx_Ja^e=RaUT7dYak>+bxrq-IdHhKlpXYvd&wHCVbg;me22e@h&pUS|~x<2*%y? z_-TpiV1=oOG=~=%Kft;RCFT-0M`&HafV(!40_YWxsCT!Ik_&tSWZlM>;y+CmfUm`y zb3eQf9Zjsg)#S9xcOY4C4lV zT+kQ<7YmH}$tV zVoB?^t{z`l9yPo?xVQu@y<39w`WWM<_)f$l0I8<}9k}Bp^C{ix=L5oG<`WSRRujt& zMan@LDz0$JFcyg?&%suAUL!s$9Uh>0cdba=S!T(n`(&AXYQc!-3U3f=y zmht|2bNQ9mx$^&qH)t-HPvlj5Bz|#ZeK%}b+~+0}BUd%;%b8RX^)t~=XA*7R6b|#q zcs=+fZciW;Et!O@X;)gPq9|y+sbVBp0VFt0713H_(Q3QjowSEvxOv@o>k0CT@Y3^d zwp1d@$SBzeM`#g!`jGCr`=62*3XO2YcuTl|z3{)PJ@lV?xBryRQG46e{WU|N$DPjp zpL+a%M>45Pp{lwCb>B%Ge6> zB}*&V-&j_EMcmIeq$hrFSp*G)2grJlF)qI+j8dGg;-*vUnt0t?$BbuWhF`&j%XbF1 zsW?8+*DBnIZ=3OzLVCXI10o-wW7R(LlKcE~=Hx7>RyFXTwCS%A10y|#&4HMeYYiQyu|IlAGHNy7-LKtwgy?HE#00>RW?26Q9&Gi z=Wje16;a=%#eX$ld@e1-RrNFYJ%xR5cA~CNGS}(im10AUI}nefz|XWW8*99uy@11y zwlXM8?qzp#lzpzwBiMhGSA^Oo5}a~tTKA;fB{FY_-=JQ>ZkJOh9FZjc?iAvC3Sj*D$5%>a{YSs zTsk{-!YH^H&Ikxtpbn5MZ~{B#*rcY=KmqWJb5+%ThhERn4lJMxpmt#PmdsY6J!F4l z#t4_7;xlQ|{_N`Hs8_mjXL3TJ^R`|vqU=R-5ms;WrLTK~MO3S!v#eOi*asvSdP=tE z-h(V916t95rka`quq8ajiD{bj?1@-4k=OE>4KYKbJF*3!^X;9Cm3H9Dr_buV9P=fr zr9R~Jb{;dcOEZ^TTap&dqJT8%op$X_UPkJ&$nchb^Mdnk(>7Q3>+eH&j2kr-C~456 z-DCqkCkN4GgD?a)S!=plK-5oiR{S-6R8{)g>g~h4KOGpG``KQo($E`jO>Y6W!PB|x zRnM}=>H&ijc+v9TQo=MA^fn)$?-Mw-t&Jv__T7hBVjGx-G7Lk775Rn95HK0gIiSdA3u~<}D`JcqMfY`smr;Simld z$2>ChPa}YG-`PK7>l*i7{Tv%)1~BjxNI&04v@cLn)CosvoiV-Fh{URt;P7~oCj{aa z-B#3C4rL#+6A@x}Z%J#`j(dEUaNcGg>qug{o!teG#RYrIj3gv-7H=)`asQvzlb2V+ z4}SYgUhj#h=~R|d6VNehetnK4>R!kuUGwEY`b#asr<~zY(2#3V6X5ThL_w$YEtuDn{eQT z96bCHr5OV^uVZjD17CbE7O zw2_L#Q!N}|J^YP4I_!Wep(X@NIT4KbywzE15mFz-K4F?$6YLGeHrj3K z`TQ&4bKLUWCP-3tye_^F{k#eNGeOKweO;YOy^UHhaS8UbN~Q|ebSV*Lgj-9-soJMR zlvE{h3?EjGOb#H858LY>EB9aTC#~PCA0X#4IDCt`VcW}ok7cif47WBfTX7n)_WNI2 zd3l=-5ANQ!JlAhd;>&(1ejO^D{GB!IaTF~toME^cPxXMzxV9!ek$kD}`Be{RYo!}>K6Lar+*LEJp;75hS4@{yrZ z#;Jdjdb~^pd#6Pi1%@v=dR&Rnb#2Sb(o0KW;%^!%NX12SshZ-8LGg`^yW}I3&(~!j z1CCpP;s|4{3Y+}KR)?X=Va2K#s?)0;+tice7+%eVsKX=|?1FB}j=>Cf+rW%X+6pChh9co~_>{yMtLehhA*m(4~izYD!T;`Y|34w5rs*-}ev@ zrHSkYa(<|n&+4xqo+X;+tz9ZbcBv0(n1T$1|YGZ?W6Bt@Gxr-x!3?*A%2pWBEM$JcJOYSqpBF2%P1+touLf2s9jc+d zwk;M8kC(FUEPRudwDZ~|RaxLuEVP^l9D|mHa`Sq2vtrob5%GL~ul9b7h??Oq>KLKR zH@W`QX+HhaQGedXI33sfUi-}tD{QlOUumvQkG!?={fSpD>CCL2#EXz7BHvW~=^fOl z8&N?_hIL{uv8p008K7Au#|Lw5GTa^_I1|xTP=Zds*!mBjhfA%}_juRnJatu=s?}!K z!Qu3VD*4Z>&G3A@G>Vlg`(xcMz=ct5IT{S2Q<_M z6$5muGBo7#`cqWGVm|$>ks$N#Lc9Rz8rCmdA<=snv3OS2ezZ6?D8BTK_@*Y!tUs~^ z1M`5#M7f>>kTp=#kqU%2u-?;cuuog9LQ?hJ*3eZnQ{}LyV4ZRCP>zLzbup>1uxx=N zOv&uw8^-nG_m)cQF`!(L#=qyuJabo0@0?y7Pq&U07@a3Tyloe+gV(LKl|wwaw1=?p z`9q0!a7o4{g8Zb`rrlQUcWma?f;Di7>c<<2HU*(TGxxO)UDD@ zo2$u;pG3=>%IE)7Q6!CuYu0UZ+lJU3i5Fr$__;kF_~ov|l;DhAk)oxR^GL9^b|v(! zWHBWMgApj}tN&%S8EmhrxEJF1>bBolq&hxgN{yI&rsuBU@QH3R!p-*`gzNNHD^+u? z{)@<8Xl3Y?gI8FbBH7oQw`Ob0q4>ofb6PZ^A|czJutm(+#dI!g?iUq~R)=8HJ04T@ z`1Y@QA!mViVrV+zpfGqviQSz&&csaStoN(7CChU0Q#E>%At!zo^^X}1p9O5|1$zck zoLt_;36b~|+~mjT!(Bb5rBLGF*`_ZpCB>car}MGbjC;ehU1M@W6(?58odhzscq#*{ z{YNpxj5f|YGz>U_ej3S}+G92pl-}#U@areWS=uHOW#~#=X0sMrQdd9gqP6c5t}l30 z-6PUJt#^r&U&Rm@;$^=w>&SZ+ELM%Tj~z0FKt!yKN;_zqEkgqEIdn%8w`*K(7CXT& z>@)1w$KZjVr;OEK!^x{jQOJa4L%-EUNC(Qtw-un|<_;;s^f z)5eL<<9u22Z6u(fK$t`=Ukex!`-&+E5^Wc#GA^tB2?8^QAADZ|-Q% zl9A4-yMi%A(sWL!)v2h@5E3l#Owfn{WL|HOd_|y}cCPk4esN+KFR)chqdz0`I;mRgXp9kH63=oKF#w5V0k%z%{Cm zoXmKHZeoSR)t(K_>;1SobVj8Y&Tb6yORV2!t58OtCOX<`-z3&?xIJkg;7}V?6(e5e z*rMy*nfPr8j~ILurBAj0#+y5o;r@?}M$0tz23VGIp`y5-O@+@INH+DsoFf zj;Fm8w1W0pqHRTZx%G?T){Vy0Fq+jh4?iVd8nfZPSxSA)pOD`E* zG2Xl3ccA)<#3&Y$kr)KCeIw@34^Kh6E&gVwDGI(16Re-+NlN8Jbh2e#GTj%d3h*TD zLJhWAC6&a`w9~4^la1nus{)`<3Fnxn0hpy$n1=%RiOzGAKE}w`?7Bg&l&N2Fams69 zF>U=!v{Vyly1jy5qx-Kaq{lj{l$C_Ka7QJoMnzpC7rKr3vug!{{Yr7Oz7iYR2ew%J zfa7=D+!@ihfD^Yiy)Re!nyFQ{NbzdUSAgrRz421ZI8l73iuaZm6v1Dg2qRT*;31O5iJ=BCu#`e>aIZED==^VA@(E7(IT&xRQi zV$UCfy3GzC@ofNV1I64Cz)cbjQ-Gsp3k&+eZ&U#qX_ad2xl4;`xGWq8QtM&v!IsqA z)dvzmloibETE;{-J>S`9HG+P#%+XzVGEuoRGp{PXy?haVCrxEquf=A?M6*CaVR=t- zK)TEvb7P#NJ4J{UIXxMC&hucH#vFgd2O=W?9r?`Ecpx9tG$0^ z$h(OU3Zs~taUXXZpyjsprf-ILryox*$$I6!je#Hm>w{RT+yQCJqU|d*U6;EGFR`1T z_mYe~{w#9zUpGvLuI?`D{;}Kk-u`mUR#MydNWbZ{=V7TwOJ!uW(eZWRI*p&lW`>_- z@*DSY+QfHbWxjqFtFu<{#9Un0i);DGQMYl?Y_J&)s=syIGnO}Xa?xzI?oc%SNo!1(l%&zKn{;zuJa!7SQ6iG zVuK7bn>Zm6lXFBTm=GTF<$&A<1xX1CnB1U_!sItpdIq@9JOFDTcD%Vc(0n2K>pxi6 zf)`L27`@EykeYgDX%AXIvIVqk;fR4nn)J-fH25uBN}CAG$(=A_LVbXr1hfKzakXM0 z${228JEeM8=lH8myh?En)8GTnk&de)+t=x zVI$xG)MY(6q|KnMQs^$JLN$?Em$tS&(+&`xn`^UuS9X@c(GOsSgP*MnjoBww@?!(g z!>cz5RM@60Fz!T{_yhSppeF`m0|TShYoJ8r{#3q`u)GTa$R5)dW;7)e}|4{K~2_Z_r?-iC|K-W@Pl{VhiMH`HfvbRD$v z*}wS99mOk_^QM*zfWE?`y@A`x<&CS!xYI^`M4ZW1lok$!{w%oE&=!OEnnjkT;2ksM z4?WYRsQUQ*j4+RR3HGoCUYNp`KKHj?E4%zFQ%HZzn?6yu8)DWxjzLDc9S$pUDdDXR zH|S;!+5NV7$Nms=%*qodX9&drQJEg9{wK5j_P4+BNX>L9+Pm)f;MSV6CWRmZ{j3gQ z?wElm`R_Fewos6V+(|DxvsEb_LGczaryHnZ)78Yog$vG%4I>0IObicGc?)y^W<2`{ zzk`P2t4u(Sf+;C#Ou573%>~K*h+Z%F#uS{j9R38rDwy%R6>&)sbj`m8qJ!2B+^}ac z??EL`*@uVw)7?G1C;`kb-F8yIv9GoWR1n`D8ch7)UK8<{J^n|bCvF4|PiIa%$wmew zkyPBvkwmB~@=xO$XqrK5p-2>|)sZ?7E@xrscr+vJ%>WCe6a)&;@k zbE{|~ERoz#dK2S&<8_YdtU+uWa25nt>dtx8$Lx|95_Wlx31tp@$57o^_UCcGn1HMy zv+GTwi>VF|Yd7>e_b!qS{=BpJUp#PtEP|}sUuysH=k4&x7y*_BicN$w$JxY*>0BS7I2`EG9~%jYHo5wFZe1RZo~&l?_Q+1h#Fo+g4-X#*C&~BA z3n;5|zI1LgvT5&gw9|c2nThc=HWlV|_kZ@){^#BsJbH;~67`KdI^=UQzgo{{4#-st zsLd8)cl+!lbH>ptoOGfW^XaVTL!oaLReHcW3m0vYg}d?s+9^+ZOuD^UzVifqj_uN~7VU zhB2<&7xJUHgc`VR?#pPH&?u=un2lxjcNfrTI|Hoh=id%`lsyYb!5HDdjugq~7(h!# z0*qiZ1@%Fif8=KAL(wl!bTw>#F@Ech))m79l4E$u&v`tSiu*ILr&43_b`P&wf4M;K zj5^;b5mJl3h=?>&-&ViYCuP^EFzb%|_aF8-1>>vIWPDrIWErP7|H=ikiq3CFBHgcL zNXFFK>;R0#;BL<0gUMx?k=+yw`up>HOXT)_aqtMeNs-nCU>_Uk z$dV)0x;C$kgU35x*(`V?XMWo*RIu6Hn`p)0O&68$HlCb&e5ld=NMkbT(RSHvm4E+o zy?;|an{Muxy$)R^%O~V+b%3|dlFtIJ+@J)|UqrUs)xjDle}5n;=B}v@o7XQ2)H2Jw zjTCMvjxQzSHcTvk!-9S}IjTpK!y0f10*UJ=f;j$$0v+-t%JYcI^0!ytCt8m?iPrC%MhY{EBQ43+(wfTGsC;^t3Z<;!zf zzPW@YXcBP{cwKqQ7axN-CPa4YtJYrm^N7*OgS%bM9uWwuw9DOeC zz1^2>l3@(hsUsC6@FM$c7A8WP(j2+a+T-zeZMu39pSYqcu7dZyTY(T6FbiWJS2MB9 z#j-K6MBqQ60jmo+>2_qzKpagB5uSRY2A_~u*9&G&WQGpdHkqe06MxGQ9(*cD9y|tn zCa<^0x`A}@GgIL#9a(e1zeg+d=FoSznXh@ZLv|C2hj16td(^!M~$$sVw7>{@vGJyqd5iA{)f!foZqh6OCUi);<&L1R9rfk zxTcEt*McF#A9fYHgJb`ceebIa98H6Hl~tEM+m0PjwRRs>8Xf#%{_XJYbIOf*-0day zr`34VSdC-5HJ^3a`Ay1ccx}EIW#qo%=D>13vVlz;yw%)d6EA8xBMMfePou0tETq4R z?FOq>{>>EWg!>^2aw6H^cU5gg`92(bQaOY@D0+wGUT586YFW}oTAJ$-?AAq;>4<+Q za3ZERLWc(lT+n-qP8cvK@tN;0G%tWl_a-alb$Z!Z!Yf+FPakgFrC`xG=_g3)-+eB+ zO0g$)N-b&znYxpWM*CYkGd4jpI9~I|%LBH^Z9GE2`8O^j_(DqZCdH_}rRDB4-P=OZ zAVv{fZ~dO5^Pz|9e0gXEpX+IZhF|wiEzCUjH~Q%8{McF>k`_iwhTi(?%ff>lQijg`l+6vzScgNf(6U#yDh=PL<(0rQkCxdIVju|`I6J|bqc1t`VJc^vO)=_bn^Q$4y9)v5XXq0iMH|K`6fcd0IhyZYOC;kCgv&&B&? z@d>-wV)LI9Ld2I3UwIH>Qjo8T)e+V=loX2 z>bqMkt^H7DXSXIs#N=a{*w5o8$0_d|S>wp8rwq2E zpEX?`sMdS>KCItCe$QFW_uby1Zx=s{gyYm31`lI}W-0JAiE5q+? zkxG$om61$cX;o~YkL2Wp5s!&OK}@9IQn)d!)^8@ zC&P)7DCNe+5)haM9Xh1L&}}&XJ8jyLg>UF=w$B*Ib8oYEmW9Z$BKD9}>Us;RmXWO| z?ChOf3LOJchHd=T@eE||9!y9Hixc5>?J#N7JU)|6Y;N7X^Qqe0=D6Tbg36OEfkmCV zdDRvUx3v?RJSm#S53#WQoes4~+7dn2CLyB}!r57}`R|t-&C7S!vS*$!G5!wzjYDn` zcA59X>o`VGt2yM$Fg(3AzLlisy7iwfY18vQ&j-ngl1V84&aC$FE-Xi%pNNrq@k~|B zT^9xjx_8&TB&M5uIM#iBv3<;MB1~;ij)tybIL6=YE~!?`F8xRjq0lj3qC?U*lKCSg zTejlWVy)@gby7T*Uc5URY&LJc4OcGOS8XrlS5L*4E!FPW^Eb{M51xei1euRZ4m@mc z?M3|^>T|>csZj585{DTU9wLXRtS^-7Tbno{$DKVIXi?~^ygSFwni@7Zhh*>7eaAU< zE!wf&iaTp=%y*IA|9ZNM##~2lIQfH#tKQ6B zOpRW(YP;Nrb?zU6&0Y~o99}zaV^{TGP`e!yXgfceV}+ZO=_*TyH)3Bg2O)o+^89Q{ z{hgt4wqF*=;&!hZU0;j0UsS7SZ`kux&tblt?W<_BRr9+qci1oRt}4FR4rhEe`+=cQ zQa=C2s_7jszNrC|y5cywS z0BHHRWLbq2;?o@&GnH=prF3d@DCGAyo((qCQ}PfR}dI z7`@yp*>s9k8sL4p@eeSaMU61af`|zwBL?lU`OO%Wlyz{V3xf^Gu?7jv&3>a-Nu`oE z2GM@34t^=?Rb;h1TzkEsbqaR1<_i5h-(I#7f+h>0dKT2FF&49YL==%Ymo_c=4kbPL zgs4nqVf@r7pRiNqEY?j!m-4)y-ffOqd0+ejQKcI$rl|bjky)4htMv2If5+X{LtbZ^ zLdRgj{^;7-!)=I#L)sA`%?_1)_Wm3_47m{8Z_iT$VPm=@bU!G+Ki@g$RJ)W~WiM%X zwQyl?yr!Ve^h^!A>fXqKdtxAj((ZXJ?jL!y9HK1qW0$)-==E-1-lB(r2-cm%%4VG& zQ8H8yTfLI%p3u(&`#EHrD&;~^N@a2s*3p~Tmjjjl%n>aMzLNEW+U&j&SF+^v`!JQ=dzxlv zb%mA3uJvcW%V?UV9sj7Kg~+lX!;kF8vH)GWVq*xKmKRF#l=!P`>G9X zH{Q}z`uztP^|H^Y9*nzF^E_759p!!3#g1NlMJ=9ke_y`k8hrsSW7JfBSrbH7;)Sogm37utW3tk#bRCeoPpp8r0O6cQJLVu&$f zxtZZi=?0S!<`0T}uua!ca6?y9 zhi{v!u=GZAZti^gA=?<@82MQK;M7P?vigGk*1ZToUERt*dRS72oH)Qag^d zeKx!847tclgh-_RY@W1_bIYfA)m+Pm7dS6Y);qwa%lvo3XL9%Ra$5Zye1B3Fvhg3T z*>Tx58w+@Swo~8S>^L-Jn>OB!#o>{*F#Oa~pZu95ZI>*Xv7Z0z1m#y3>E6)t<)ck) zR@FYo{0(jVlxms3ee3XTkD&%`5tL(SvN79PN*C;rE-{2lbxxt8bAEp`JnPJ_^_Lf0 zt@2Q70qRwB)3oi|a0g`x{qd31Z^mU)SET#s>wM#7jaIqw6kWTmFIHTQzyPy(u5R*c`w3YHyIHPpJij85q#?`B>-dB*T8rn9rN||FeBXpJP((IG}qxXk@Ulg~+q8p6DE)8?WB&E50x|PoDKv z*b`+u%^>`v9PXFb)iS0&O*dZ+ zY`ZXUbj34O2!H6Ee2E?CEKCb46G#^cc} zUr-=!&M}k0ys2=@SGaM@bv-%Rz0Bj0q%AbcziyrUFVMnU>@X%+N_`}Ill-tOZQ4Jv zS}+A|KER{95QI88n-hjF6!z8jY zWM-Fl+(v!O7nJV^2yeGwUu9h^z*8m8=UZB+*o9VfLv>|n=-n#d>;~XVzDK!&AsbY( z!-m;Eg_Azy3b-N3@g(}t^F6|yxzg$Lm$4^Um6DC?hyUl-;%nT)>kmCRj%m=i%Ms@0 z_1+$(y2Z~(j$@(&bxicB9B7bob6w!)F~w`>a^B@N=C;jhXm?LYK2|7-_mX|>K6{}t zaV0^pd7I+{0q@(=-?~K`eX8;24Cks)~F)O7Ipb_ zyR9_8h5VrIz{_B8bjO8{ZtSI!El>#rG$2wYlfMUTPHvB}N~%M^O6cW~YFc8`F&Y-%PIK*F+iwM4#97^997qz1t-js67qi()VswmIai z#C)v|wszf4SL1|dVpRflzv%9Ub2iLaHD0CF+3LUL;;8PWYSECN8sjB*n!=i>xOC$p z>lm`{LZ7eVVvtA)t=u0?f+4A4;g+Q)C%O00x)s9K{ZCkS`%wj$uEw{08ByeHZNr~- zB^ryX5xkI(bqvL_LXT*0#hVE5ixKMqR$98Ftt@6X^vkQBrakW&>tpgsgp4Q9ve5-t z@on?BgAlm>O@6P+68%>RzN{~l8Sh`OI=08>WLG>ad{RmXif0VZg79y0!_FY6yIRgv z!gz4pYpOK(j!oIM=-IXCphVo4Onv!Y@UetdYH&JCPe4NrEK2+|_q;Q^OL(FDGP7+E z5Y51K$5AwJF$C163Bb6<7T6WS(CviPe>6VUI)*p;MHom(<7xPhFru0scvL|N)uhk^+?p;@3%YJD;9*(fQ{74Oq{)_!#VX!dpl!JFtb(=#}l@MUy7(+z0|) z@jQQltGdb}0SuT9{J5Y5a%*&WHcBw1 z#<9PnJlwLc5=IAQD>|9QPY9W~8LVX{E|kYLG_OOadEfP2mKSTYX&H#P(= zP0u0}P^AY#v;bt!Bl4Zv0NV7^z!giNZrSS_X2S^pY449!@09X0qmg6Cc9e;_?O{8g zvrOIJYNvd@5H(7D5+vk_H$J}vC(9eZ0t<_oqqCeM_Ikb-7$};kE8KPXsLf(E{BC@+ z6^dF!UhL2Mp6!YHoMwppQT}qB_dmV^!`#bG3Zied``>&L`$I%UzU@dcpWuJ}eIz4u z@$&}lFv9yEV>##BS$AQtY$7qH{^D3V&TJ40x& z*VoMX@r3$giZTVWjDqO-^@lE8!*WfqG5TcoCOrIC3&RD0Uym5IA7`oK30fs!x}vSL zPCStcCwwXw_wPR=q-#H?ETyRxy!ZUfmDecTa{BZHRmsjMrl+@>%Z<%3MVaz z$4_(vX8z!x7m3Z|ZV%`bn@e}Px%2m{Mk2!G8EwQ3)1s`GJ>GK6a;4kdr2ZFg7*5Fd z+X+iZdzYn}pv^D}t=+qXbgAsj&%dRQvN9|clFfG(sU4a1TZdLIi7A=jbs+rjcuXBN z14)5r=3c-@O4tZWiwI_XK7w$wbMgVPixUN7y!Y z{5$;1FX67^SD>cuR1&^LY-WDbAGqc~thZT%X&!VXY1V%jnURo~CUnANIwL~as@lv}7cF8t5hjQg@-u!&b z)_I*vTYuE_Y8y!O&e0FiH+qR_BIeX*Lp`bVx&)nyCt^o2nZ+oJp71F#rZ~oZDtgNQ z7FuZw?}atMtG~pHLq!rgaJ^WX>+_vQlv}Qz@+f9vnS)%w_yyQu%YbR zsu<~K2k1jLcfjeo!GH`Dxr{6I;?jBH|`PdkVJEQKz>G)+_f&3lp`MgFe z$g$1=m7@0Ecc4WD4K4L8dw6M!Z!fZ;lvmzboYg5nP|HniXh+yJw(@|RSG6MQ~%5@@lE)Xz``2ooYto`$02RVLqHyuk}J{=3f%PxZsf)Fagp_L5&6tB5Ic5Pdp+w3ic-^srI?(1-tXLFZb-N;S<`%X zdj@)RP>2r!F#@8#Cy^Qm{6D^z4toBi-&(xP<_}BAmIDjLhJVysy2O?B81m*Vv_=GQ zvMhnWOPbX zd=!3HtqTcVoy*%-tn(ZtPVS<{)Jy_b7GHXkpQo*BL2<;r`rNXx6+bJWT@JpxPiD|*ymlvhOgR;RSV zNYOIta0>6&)#;5k9OoMT%e2|l_1#HsbA7}-<_F)+y(!BymdCl*Es!hiyw=S{`^x^3 zoBG@qLrcVkdM_?+)vhQObG~MpnqopL07n+HPyIndow(-;f zniH!evP66Iv*G8Ptb3C9$Nk*9`1K!Ld9bbfdGZ1VUH&nZP8Ei1FujX$uSkcpfrqg1 z>hZBI#qgba!WA)`ms5&R#!s6X-w*z@b&>>Nt_PA3*pXu6f6_pUz7sOcwd7L~$0?of zk|JRhHaXBye`VS>s>^^6lrc&88+yFZ42V~7{8`(m?`Uq4*nd&443cC|e#*&Zm*h;Y zBPEe}=AQN>r{ZaMXZdU|`diD~)+@~#PRW#AOe*SiCs?&gV0YshtRa<`?XZ!<# zu(Mz)wF~)zUfje0Gk~0?{f&S4?{8A|q?tpe556#H^I~rvhGIyYM+r?%j%dv8(yXC7 zs)qrkbNO-%Unk5JhYDUzrHJ}4zVH&oqT(`$HkX-NUEO)tut#`itaWPTCi)&~il}x$ zS7&;&!<8`&HfAwKI+e7?a#!?I9v%^xv6ObwZi(d8+AZxD2B$$ z8PE^Us_eSRab``?+;E?4UFW6{)C$^6|DFH-@NT0F0lfqg5tVkZ^mXaSuBo~zry8Q+ z-oqceAPFQ}&%`Dtp%iM@QFYWfX#DP6#1muoz2mhUF@*ryvzTlCRhRax!aEsVZ3!h# z@=s-oF+XCYOx&#>kc2$tIQqj15mWi_Rq(5xbn&vDi)D67MlU(;=OS^Jp)(B$&mhC> z`vjSKYTuO39aS7{-O3B{lUdZ}F+zU)P6*SmnT3)avkQS+czzrgu6QTtrdZ~O z%7(dm!3UI7z#KrPETDFd^Goi)N0yxUC9?;nLWV{XeFmN41n7JFiN`j29Yajp4zV6} zVRMjkl)nCyPM68lckmPJbGm-C&XoQZRP7Idr)QP!0&NEOM82(as2UC6S5VrMs*HTN zi(Rkpm1@Vc3Fh>6-{RK?j4ng7)uo)K?(c{R!GLMn%z`XXiK55>Q>Z6$+2N8N^F4_h z6~QBH*9aZoM%5>gxtP2I?MnKT(&DyL#zzQ&rsRFpE@xno+sDXxB!eO{|Im@L2BC(g zoK%T!$7YkJ>19`IykdeCr1RO_O_VH!{>Kavg7qYD=t)amVtPQE{7gPW;`UXz`y+N| zLcKhDm5NC{GG%^kWc@_VJ+09QGTCu*Jni$`vrpGIeikDT`^rZ?HSeKGiL{&;S`&q0 z500k9I1qN~Hf0<&;0u=Nz5pX8qlCGooL|YXJOk?ONxHKzTjF4h9fKz651HZQ`BY@6 z1)a4lSH6q&7Y`l2R7p}^p%QKM`FQe%S?p$*XHCak{c>CQQg&KeQ;_5}^N(XMbrT8( z$IQiF+vPl{_si7c+Zf;;J-C;pEh8FNOc=mQX z!i6>-P4m?%#RI!LDYUR3su~3ny=)jH*ll;+wH+>*`cnl%t!ZL8N9Ja+=2(|U3*e_F zc9o@oa#w=MEP*TlrDW@S zu7RNU@S%}$-{I=hv}c{STpYP;b=P^muVWB5nslJgzdR=7lD&+e1=EV0b-}uH3vel@ zo6mq(XPhIfgfP(1$nl{k<63>1xT6O-OSame!8x{dTf+)&;{ZlBCZCC+6L5Q=OQ&0u zG7YcTVKf_wFw=(Q=1( zJ$?qQ$G>1>4)o?*zPnflmQUt~zQp@1yv3g0ES9D8665U>vn@qoB@K|XZ6YTmXI=fi zI+YCz`i^!LIb`rhd;4A>TcIAxEWJMOMEw|6DSeNUBZ`|tr*Bd#o90iwVjT3hV-Fsi zuXPk`qw+gzAC44$%s8U-L!WEUw@GDoJhBDw|;dxJZ-LJUfyj>6t_E)V7 z!f#Q9_nxm?xSdDN@sjzP*!$iG+r_*9bECeb)rnZ`g{^nV?AY0mRee~n6d` z(I7#(+$gfVfM{|qIS~}vR{NWemi0kGJd`g*Gp^{j?|um&-r(T3P8f1aMNa4Bo!ko_ z&*Df)p5j4GaZ!q`%$xmE;G^^My>LOC!TrNW{`A+BX&EE8FRv~qww2^XTG_X+Tl~zX zzAV1tC09LtxcDEF+8ypOXRkjU-R7`aYXv=o0l(3jFks+7a*^^jFg;RaA72VwQ8F7n zO34h|5K0zOza&^W2YB6Y0L8fYwu?o=OztmL zVUiB{66FV+g&K63m9_1rFcjQ%4PJbHXlargrF{UzXgDkkS5bM7$YTo9okN6oubM7U zoBep0XeER{6W#)CxrZ5|zTnXJ0tq_Se%65mfmiLD!?(xSuAIL*!;-Opm;cveh6fP- z5k2fiu?OG@w~r}Icygz>vbayul0OGG6APD?22TmPhTy>VC^o&$NPmQ!JruAEZ2npO3kM z1-yHHylMTW2jKv%=ORr7CM*wf(a{%yIgWby(5cD1jT|e;$ZyVe%{! z>!>qw^}qGZ2=MyWo>E>qnv$$^lakzA#<8o*85gl!UFA!MVEZ-NNI|jYbOK-y2Ikxf z@Bkh#PDuIR7Y*TY=WU6F&#~fq+qf0Rt4{vLt>mINa!Ef5A14~4*{I+btBtVV=ylub zj0?r+TAV}CN&r{)@a-HZ6}C%#@4DJ&SJox+E%|~&palA$ zVI8Zs8+$j;HNlg_>FeM*=0ssYHO1^hPliwAiW4x8+7Fcb&nND$0eX7k6!2&wWel?O+!2y(aEvaf7ypY zSvV-TL;toF)F#PW02Te;9vTabB;|$KcR~6**V26VW2bH*_LVl9qQB7iCrc-e=gGQi zv6`9a2BwCQILX#B#DaT5z?(&!f#LX4krtmp?>-@aQ3r_A9_K`*>y7V%>FVZCRmufw zNVRNCw|2M(IsL6w;Ik}p+xKFVhW<>r0;Fl<55|2PotkM;0OE? z(rG|A^&^t}aXA>zv$}K)Ul@VXz9h+<a44% z?}8%*NNrsYQR_odtquZgJs*0X8D!GakchCiM1oIE-g~a0>1wo zmNSFtfh$Pv$gT2GmoM$vHy22AlW`%`g@kiI=;fCi><+ejo<*7ugL6njffl7nuADtZ z{om)!Rh0aZNsJuJC(LOAy`h&FS(@V9^&*^T#QDcJOKLwQOMxdP%VDd(1N|K|B_C?g z9gYHmX|Kj393JMCP0wCE-!h&a*J&cXx>$UC;V`|-cMc=qjrDrh;Bt>FE$ks|A(sMbkT0?dpkbzdVJ_VO>P5!~Wc?>;FOCTSrCRzVD(mN-0XWAc!>5 z1CkQb-QB~`B_Q3>N)I623?SWzlynRssB|NObiez-_q+E#XYF&&Z~wX1I?E+9#1cPG z+<9Hs-Qjzj#o4ws8Y5z{IVMyb4@{#>rR}Po3t}vL_SToQN~O}JSVi7cx8;e)qRPGn z>|hQmCRKmBUzq+6O6h0FCz=Sb&G3eQP+Y?)Yl0rI5gQHUzz%|Ab!LFXQ>iVW;WjA{ zM?RMb4)wf4jesx8WOS7pYZUUuFm8wAJ%=Yvq`3;g$4wne14~TJTwF@9Mz@F%lZB>+>QEGpFEc_pCYf;l>EFh?s2p#H$1o~443 zQw^n|n*+m3nH8m+0ku@BlAbz;SE`aO^}`aEPkn@;1c@CN9@IY|lHW)TizsDi@}PP* z%}T;z3B+FIw!==(KtD`uJch;`9V=H>8_r>-kN$N7NFJ7&`3MY)ZjU+8?J-+T1VXbF)rImi70nPXpOgXe}7BFzd0zH_Cbmf%s zi}5W>&M<;TH?cnB2YV=eDn9~;(-1cj-)gd_H&)dOuTLHzX0}=$^BONumCDT9Y>ozO zxkTfMElHJPxCYd55GH!miNM7~-Gfl7FaW*31jRjfZKfom@sK)>^3DZDNM^*-30Ba~1&P^~* z@Lsu=L!~&3%sm*wwHsNii${Ynn|?ORE8>%6b}jKiJpVsrVp z!*>Cj^xpif?=ZM9@>-=36K^Z?4&Ske$y7TP;Xy{rtLsu@c!SvH0q)43qy4mgP7Q;d zm-}a=6-SR0ym_SgwOV^nu^A{`{M?Xl;~)D*v`e%?%4Rqf)9Iq`FTlUlhvG;ASRg0u zQL|L`pC|M8QlPg39jP-x{;Jwkz~UL`&#} z0u*X5s9MgS{<$f**>X=+Q&fP&FBIyz6 z1np!VJ0LFT^*(q9pGU>#4|&1hzHaN)X0NWB3<9~AKSZX_lG3SsuN8fTCDAMLVcBBY za$bFjau>)G-cH(=j1(7xF*_L~;k6R@z;D@|ySUf@By-F&pW=|>0q2jPB_xlK+i{7v_fbKKB{G;% ztk<>yZGZ5A(o}-}Z<6hZg0@iAQjQwvR#8!*!g1Dmo5iM_XNiG>nrP&g_S3+6yiZbk@lbLG3-Om+YME@H|Yxx1mzM_1qP6 zew|ZkYbiJmr&;!OpGju783jA0LUsFG1WvQc}a*#*CsaS5k zR~VWrp-F_?`Ah|`Ac5*U3Z8y=kFM9=GYW&sDWjc)jJsGo$5i!03GJU3J90wLl?)x& zJi_sV+&T#7-)qlF5EiLdxU|N6BahO1o>qWDtna9RGw~gB2G^i!55+w0Ydf@VHl>|D zke#e_eD?i1I(OG-h&whD+(umsXBVpt)qC)#F%z%!TMX*sEur$}Pv>w$$X3xQanQ`M zNL<4tuiZg@^{0WWJ|_K{XPT2INUvg6r=XD**c&2d2iy;zUMt|QtV^MVAj(E2cO#!v z;=8Fjlt0iVxA?9ugTwBm@h(d*TuXr(OCJU+U(0`irO{#@i5it#L~7mic6eN&lda+{ zwsC97Flu6WnVq8GXieA`ynZkpTB0p`_qyuAf~F8RcH7TKAMF6r5OfG5 zWYfs;@F?E7O!NY2slRMSir-1)3MH;0UFL#tq$Nqg94I8r5w(x6nN@B%^I&@PKtLw& zdcm)%PP7zAe^%@Pn9q-ViFxQ-ARGloqdZrzO>NaWQo(s=KN*25g-6r?|5C-S6jt;H zyEp_Zixx;LWhKbUb~BJV%gTP1c6>b@M*{@uw!b%MEdyisAxwDqK?nZK-?ea}!}G)3V<{RZ8B z1d~`vMQ~W2-2+1fYITo=pZk?9n->;A-af1@xY!-gSx-?z48f^UV@e@>mxpTD+`Y{L zi0Lq`2Xg(`e2a9?@(~G?>=kbg$6z}++=U-v+JX`_vJ54YUtt|d$QNn-tf2oqaZLGU zOT4>o)0m^mp|eDXR%C@#rQu5p%~{Hv7LF0l_?xrUg%{B%5S)Cn3M8M;5T=H@Ps7Z~ zRo8bHZ?RE)9#lyL<5Im&z;ErECo)&6Jz(1A^!g?~2X1of@v7rbR&0`fA0kYgH_&<# zmblP+>}b}P)wbWvTec?0a78bg__~{=f};^sW}e%z+I1ZDm9*chZj4LhN83Y=AX@Ab zF1%Ho9}favBeR4+^cbtqaB&9ST^#B4pJ!2m>vnRn$NQ;bdo)vIiftcP_{++Uv1NS{ zQ~wQZ;GVDFvlR+y+^#K5OslX`xg}MjEJ$w>MNy!6#n*OL*+?>2g3^q35KK$ls6}z- z@{OYPu7Fp0^U;rhM}9>7oX><7*uJAaMpxrE;lh(Gb6K|j2C>&{sFd7tP9l%wt!mjn z4Po3!H9~LLuOpqTd&)bVak%)RyljGHmA(?@dZ@uE5lG*}>tcArXjQ^8ljkkcGHw2l zS+WOYm1@k4N7}3$+(mM7x?#!QXp6Qn4x?mTBhES<^pm)O)F@vnU2`ws_4I#~w2Y@| zWU)Ur4x~pSWp*iccIT<+aHS$l1pJVLPwA2QLepBs4UF4cX1|_uXYE%|Df*;D5pI?D zKdJLic(IW{IiT4>`gVx>nS(?HcZAd~<+$a&n3=)!&6@@KwO}E!nXy6)9OEtyyxpsi zOgshc6PA}ej|SmppGTewcF+}5@MuH@*2%+XLV%;IgK(qrfpA>+EP}L$?1Q2f=V^S%|T{5R$riv9%FN-p&Vc3f;s1UcU3 z#q_K!OMcU*)9W1uWWOqx%YLQJ2NjCcLZg$8dgr#voRmV|a=+K{WwF8i{QM#kueCg$ z_g0R)q@TtdH)Q7GP9|fYStk_7vqj0PK&BWANEbN%vU=n1c`698X;W}Lp-v3FhCgRb zZt)Xr>G8cuyMBeBI?S)EMqSE>+S=OWvY_M-&H2;^dB$@RH{yhQQp|Dqg9jj zy{Az{*zekXZxb>#nsA%CA36WHj1t4^rSLbDJoa?+Uod?wYNi5qE?zq=4!(>W;rcFj z(-nM_C^G^1MgM@EE6lBq$g2;ReTn%;8`<9e?~s`R@9ypf-0R{Tt|PRObuq%GGnQqe z49Yt*I)3gwZ2KsCM~|XM2oIsO!ml8BkDsrzwpCq_@M3%Vze!CF?1q<3vos@#+5=XZoEYtUlwzt@89czBuaY)PG z^`k-$qiKT@(mhO91eSigpQ+r#ihXUqJ;+`UtaavckwSbeFjt#c)|5G% z;4OtX3SKlMJ3c*}5=D?v!vlS`Q-g~?D`8-xd>;jc=$%da$p$u5cP6^o^8s-I#=R$; zLIV3~#}vy8?BSE;b}KnOD1p6%Y)kp_fhgaQlX+OlWt847M``MIx-7e!NmwWg$$noV zrh%??4i2jlZ**o8>)T#v_F3~9U7X5^O4f-Od7wz5N*|KTjS3bOujqv?_@(;$&x_z> z4?aeMCljePgJvfZc3ewd@Cl;&IHn)s`r2f7ZYFqYlA8SH-XE=s83|cy9IWa!P+5uP ziZG7(TX3o{c7zFoROE~ked<8->>$?-50-74nd;F7Sz)ioUz&tWxlfMw`mvhe3Xc$u z0bJjcw?R}N$pJkHB1&@jxn;FSCgxWPL;wqA0|)M~P0*AA=fl`lVP?q3{58}IYRCCI zUA&S(tP7gDsnS(usiSIerRbJb$qTPxg?ig~^M3VX;_gWb(|j1y;OJS_)MqJ|hE*vI zTxsLZ6P7EW{^P13#CRuz*_?Om%(o5EkQr>UInG=|b_x~yyD1PKZR&w)NqYZ9rdOs{ zME*7|zm~YLZ_oP0l(bgykpB}V*FZVH z-4k<)SI=9Xk2Gszu~>&C3Blt5qYIT>2|d})cwsasD~mGwW&bq*W`Nm1`U^53M_dD? z>~C%-4Ac-qK3UpGD3w3GQOXXGC&1PE!8Kyoy-j5z$ELJgTQ?)M69_sZ z41i6sLWKue)p%V46KCcEng%ebd;+!MZYFDxyaUm+W>D_65B}=PV>$P7=rh8@pQy0T zYp2^!tchgKUlX#yz&O2+NojR?u3rK9=$iv(*YfeG4?}t&2?X)M9*-G_jRCU7x;dS! z><@qi;Z}mB8&aYO;TtB+C)(v%-1(zXp?wlCablWcPS!2;eu^?BCX&*e3Z2lkv6GGu zZWcJ8ADv_ye7Lx5B4~C0IU%eP=H_HXG5$#H;E{}$k-8K{C=5Lo3 z9S_zP__x_eAJK%`HuOf2vx&Mq?@Qfd27gJTuEc9$a82J0jk?G7ey01xoavJT11 zx?)>xwD?~%G%W*@wer0YoRHY)Z54b}JMG6$zgQ+mp-u5}Y+f}*@nWw3e65x<-%LOl z|8eyeBr%IyxH3KxRM|VGMd8d>^0fivZ`;2xYJ6DHQ{5WA&Q5dXF}a_64iE<`cvPRc;o6H=KlzR`lCMjCi%n6(4D2?r6~xZ=)Esw9BHN8Xt4j(X z7_fOddWe+C8F5>|Iz!uiXOZv5K`X|Jee;pEq!Uu#~;{ z^rRUvH!`h9^KVidUJYwu-;f68m37L;9=D7bEq`k+qke?{IjHrdSa;4nsGyfGr}dM$ zhGut`+YA?T7u#;(k(zX+RYS|s9(S#xpY2fN^=~E($PWiVSnle(4wn zzI=~BhV~VM^4g4N2FOk4_$7>iWUDQ(Oy{E}q@_y$oWlF6yV5TwLgtppaDTOAL~_L7 zpy3Laxus9hlA0w3~+@{zX@WzF{vh@15E z9($-&oS!ZDzTFpnd6rFcH5Tu;LGnovheJK5g{AKwlw;w%W-v)6A6@FUH;N5M*22e& zBFo?RC=<^&pj2tW+%wXhtW9SgGvhyNOj1hfZQU{iqb*gQyGYOXzNa(d#8&?0O2MxF zQiY3w`Wt&1UB`!iP=@c6`Kg;6Vz~_TF-_?+!>-BGQS2s7_XorE6}#O(C~EpGR9>Fqk|~S$ta|)l^n-{i_nVbsU55On;~w%# zQ<_`)I}-!!KZ{4OlWO}ayR^lv?v!#X0u_dP~ZH+Jby6tGP<`gI(vMP$e1Bdi;_bOB|A6&y z)L42}tq8Tb5r~Zbvbd4yDM!ThzHz(H$?j~`fAIn;2At2h8baD(16aYxeGdnc25D5? z#v6HRh2WGn7u5aR+9&0lGE1KQeHMJ#X(#V$X~i_MRVs|u;k)b={)K$;KOUR>n5b>5 zwZAFMFnK+c5aK%|a+_csthy>mudDx=HQv3)f{l|N?|B>XU59MTndsxMa^9qrR5=}Y zOLQMSNw5^zKI_3YGW-wK2(lQXnjj?PAKBbyE5NLHW>%+j;PkhoJcu-Q%sJ;!(MdN)a@Y_VK6!XV+aB7X?#iqKO(mE+xR*zt;n9%#x}F z3S!qBLp-S7S|g-Ep!lV5V3e9HQSIJ|f?#|IlVxuMa1eY3grYOJ-l{vblR1BZrG$V_ zOP6mcOY!-o2=JT$FXGY0Avhf{Z2Eb-|9W>qcWLYjEjED$6h>>3;|ppAAFJ%pa954B z`C2?(^Sww%9+u{N-_N)4wlXH2H_)n@RBI4Dc>7^YtYB%6`7ncmtyZyu&P~HYHNx9d zFhU#pFrhC2O!P`0(rUln_hT_yQ{6oK2Sqr)L+q`8z=*c=KPbO zm`KBzu(%D8vc7z))F~8L1Z3ovlEd{Z!l^t#PzhF&njBVF4v;ifRNe0ZpaWD9Q|Hp0 zQws#inC0Pj_TE(02*eSmcc=;vcx&i4I69jIp{MQ>eQu>kbJ0wb?9;)i+o(iCMpBhdntOQs*peCGN z0Uy_jv!jZ?<3@UUacm^E36W8}8lEM1bR5242apB?Si&7ge=AMnr=qps0szcT$O6ca z`&>tu`5%ble7qF`0l$!l>K=}B)Sk$I?f0;mrEd_EKpykYk<7XLfDoB3@S2jegdQzEisbfrb$;l=KmoyhrUv6yYGOPat)00IBwBGwY z`M+6^)N~K6&=7@5y^z=9w6Dsgy%i{?l$E3c4#gl$|Da?l?%RpIT$*5{aPDHs z&d6V>S9Dnl$7!}zxZc)+egUO3Y102$CnJ}KlZSp1cYXZez`$@RC8k#-P=6XWoO6z^ zM~}$VB6Zg!%^owdC#5{QF%Ai*15T6+So6!L`jy25D(T6BDL^zTb zFbN?EF>lP)$|6vQXGWO)9xE)c6y+8-lNj1v;Z3IH$M<;4@f+IwcxMmdyaOhQXuQ&L zXWU}RDZ2F*j03d2`j1jwt6Gr>k0l0-rpR9?Jc>OO_&f)|pD=h;e((P@+y76CPN_P+ z02Q~mZr5qMbegBaR@v_Y!{F63mE;im8$isYrwwRI;Kly@_^?%|#Fa;H-cAN6V!ENe zACbz~pnWAsCIBBO#fp@Wb8!Zd3;<4s=rpc?!m|))CnNX#z{39x#PtfVX&#@4&C>Qj z$f5bF4RwJ{Pg|_+s>>QOn6rd>WtR#!A4XNcV(WA0bsBZL-TQk|Eh1(wvut?`hlCg- zTRXw6-n{&Dh1Lw&m^s$LN`5Sox2B;HW;IV#%bkNl|C2gtqS1ays^SgWD8`gi*u%)5;3MYiy$I#xG4eMJ^k=2X8dIBi8#h zSghVe+9l>6O!&&wfHiMu$|2#`weQ9E+fD&rgMa<(|NDlS3vta}`0NOGz79K~{W!k* z=`(x*}=>Q|lE`X5xCi1HEha)2ZX$F?sECxt?FkMmRkU;oeDw@7SE z`ipNKC_cRZZhDOTKDSbp?y6MM(;QQS5sHoS#~irdFHSau4YgXYk5;HFe!!A-mG04@ zq2jgF5(qk@^Cu|N{kwT<0zXruc>p-5a5?NN=k-_5V8-mt3+lqcqm7yZ-o@e1#lyRd2G+wi=&W)Rpn`7R|!eXK}w_*Y+=>Ln0c!VHc zXM?FaNJ)7YqDHQDo2-j!O6=kL@F<{Tx%*ARl%NQ~Sv|!5S+)=0)RGhc)aNMDP!N!v z&?bgw?&$3Bfg;!w9^KN4Jpyb(XvWp8bz&RjgsxK)xMzO($!h=+m9CP{U;@aFY7Lb& zP=lsQ6sY_+vMfLUKE$TxfQeNvRcTd;=<-S4#bmby6en(3$>P4k+X1t3W0J!mBZJf{ zMnNAg<-*HX&xBfkh;3e)N6RbX6$y=%6Wcn#h)1ws1kcqe3YR zpwn!-0*Lk5Q2ZYT9#I_vkU}E6X7mQ{x1Lhw-!0Vm+l-6)uDt~JsXQ(^2cr#4XD1i4 z%s0qUpLgr=F9uXl_QlVesBos8UG+LCTpXndjPKgao6s(e^yyN@&I`@`Qn~1ho9i?O&9bqGAobbQKoW>hH^TB5oqT$P)ExTK6@yE!6wt= z{;K<}j51&30l`#eWn-Il84l8y@uRWUJr539$LJd=mOT_=1Z*#}YvQMLF1$s^M`34~ zsD7n#zo`0}kpYdQ;>ASDPW2z!eC^Pzlr49@1>&R?g6PTL+V)ef!kHcsD1L;WGDO@Z zjLwfL-G_bWET6n{uM+BG=PQAge0t#g!aL$Bb6GhE+S5|@MWS$2$cc}Z28#NkPO4q%BwO^alf{pSW&{pvs@?+dM!}1_4J;K&wd|URxxV#$lLKBris2GiJ_Lki-4-MV|4U#3}9M+_?WP?Jq-3&m$Q^t>4))+Pg67TJ$4x>Z#@Dn5Cnrrpn^ zKz&o)=GZ-r^5cbVqoqb}EcZht`VhyI7w-AdP4nz091HlO(c9c6uStUIM^bewQguip zsoqP%Dcs8+r6*?u3cpJoyIF8FO=RFxAEuB;xn$I59n_u4nGX*?l1C>T2=5%f=So;a zq5FG&d13=Nx!f31iVliVq`p0HZ+i2vy9yZr_Tzu`@(5%B&mSfXnoyR-ulMP4>Fz28 z0Fl(|Lz`aX`x4w=fml#{_qE}CXF>7j8nGVa(SO*O;;A6S;20Y~>1|_Kh1W8-c@>ti z!O8Y~y3~n_-z2uJT44YTqp{qTiF6ClxDA;xdhmXewADO;s1Kn-p0cKe+BxVsPus}g zU8dE(la@wA=}gSlrKJoJpE-6#K{YJ#fnM*FN@ZCDRp*s_R~&5qVVjBDaHi;9nv=o? zr;e%E^iCf@%lph;_R=b9xj}VQpGtykRRl@*+lIT?G8RWG$bhI4ig13K+k_odb~aDn zB@=^i!T#KSF$Am(mJ$7=IGN zDC&fsPlkID|qF zroKJZKlPpIap4Ooabx)$)tEYzcbJnGE$uo6k2jlc>E9`7g{K=E>AkOxr_`ySqc3_l zF{^0jR%sTc%e(N9J}O08h~?zu!nqRn_fCDGpF!Wa0@_dXFv_Fhs*GEduy(ioCvz}(k9TWBc(qne>AIFeTOJN#mUw(Ghd>~n9*HSOv zHi>mZlVJJMTgcMkjn4?yz_j8jQ;O}LdgoG+dkcixjfx10)BKCpM(_`gg-a8Z8EUO)vW4R5}!8KIt}WJ9t0o1%*ow9g)8lW;SC_gtpicJ4HO8_6x9Nl z&l&i5g?znWTJ`#`dQbU2Uy=MSW+|^P7*#Mwn&@Upy7TvH{f+6*WB+3DDDq+gXvQ|3 z*nTB1r?`5tka3e(83I{%k2_`eU_*nH;c`nTb7@{ zw~E-<>b#Sqqc*Ekw$QH7F6$`czE=O05jLJw>Gfb+oqXfHdVKBsjpE^WNf&J`+#$Ba zAfat;odrTd51iV(Xr6V?JT>UL0J)n|b6lObAsBJbroA?9K_rU@PU&QrMXi8r=!*3v zeSzX=v`m08cmT&^P_sR6uMN1`=lyQIv%k1okhKfb}`tiV}mm2H=A z-91vGC)QdvvI;PI_Nb{pOk@xV@$&4+3mO4cm!Q4{e7gT>C?}>|j^)^@GJ16pDs_|n z*3)3@36M82{s+a@ncHehb_+hfJMlk^X2qW9u@D(R<0~H+7$*L;nqYFpG$$2MXyZi)FG7}YQh}IDIleI-_^QC)N4$s3fou4^FyV$6NIk^g2r?5>T z3{zsAqK5p%5g>%6lRI_GXspj@5UL+uj`2N53QOL1!HBG@4(H!st?ZNGoBf-9fUhT9 z?AQH$14=7iBj4y7P5YDLW!7pE@g_6QQ_XnOQR?Jt^}*(eJbTEM4!GuOl`;8DG5}U8 zahI2_)K2|_GT|jk8A{v0C-I4D(($LX>cf=Cd*sL3TF4~;?0;`#K zR{iSv7w%gyb4GQXSYG@V``xUY|0qO>ArU{Iz>%|YlSg6vO2W!jew|``&R6j|Jw5|W z72Cz0eo%(14tVjN@Ru+wkp$$>J7VeL#%D&&Y$-TTw6Q9oTMLMKFI&x}Opx?@c zjcqd7x;|dL=)9W2nPYe=zhuz;Yp=3}V?(IXK67^gHDP&RZA`$iEm&ms6ueYCC0?u) z`(^XETIaz)iUs=Svb^86Hsl5w?m#L{phEs+d{qwlIq$k^CJwm?>_*!vl6J@N`w{2` z)GI#R<_ra-otX&g#X3Rqf_*Tr=Wdmhpn#^J1idq2#S38kl|G=dJ@fK=xMo@p9KDbn z=^#{dkdp~-ye4MJzb97sW*Z~A5U5uE?@1k4mGs+Wo|Ru9U0XhpGGXzJby2~ zUasb)9Aa|XD&L5gS3g|t9IZNSn&E!WbU-CzD4&c!NE7Ssykx5Tr!HmqyHTS6_L)cR zMI2IwMG1_?z2D==FO%PG6HrHIMAYM1dF0z8@Bym+MeaRzc82$`cR{j`TU7)$>YsJc!(I{51)h)V$BX&y*%f{bSk z)Kl-?DIcf;S}yp4-4THdkV)wPqiydxF!rD$L!l9J1deiX^D+E-?oVcC4_c6vd*ZLP}`z3TMLFv@byOwsa%JAmqrtTk<$kGPu>KzlL*pUS9wS&O*iZDyvf-Aj| zyD!ReFzqXa$JyxlcMH(gV*|U(5&`_??pz}91%_w9vE1`38bJJOM0vB8%l9#fyRq6? zsPI7RDq&vecKPdF`T5`Lo?zs1t42mfYN#M27Ob19L+K8?MuQ9<3<-(oygzwxVdnMm zh3Q-TLI7r9di{Y4bq8}-@n-jrn9sG!Lg(YNs-FKNKH>GQQSsw)MNoFX)lU6zy%5t^ zVMM#zsC^P5UC5s*!{vZhf+x#F0c0w4G*&NE1mm4D`d-=b>K?lhM_Jn%qzb&56wdn= zV%66QqY@BE#QRQeMJ;1#z7DZ8ComurW{sG?FY{rT=arvTF~?8S5jTq2XwZ|~Xhr6_ zB%o;PS4OftuxStT>)QSYMbPWdYJWV9$ba=Re}MXlV}#Q~NJ%jCbSg*9s>Fyj_10EN zj1mA11j9dXcJ&?~05LyLlXu6U79S^gdMkbc_)u~LYwcrjIg}4}ry|g~bP9l1 zBrHXp3=Z|-(i4gT@_w!;&sE}Xq|5J zY4*^q5p?6C<;z9iz0xjytS-4hZLWoeQ5!#hY+O|tfV73f1MwfD zzRjZi1R`^M-Iv>X{z}W(T+}<}>>0Th>Wj4$%P+DSZEj;LYKaUu%^eiO#fm__{^5>f zN8CZR{hdKCCrHHRh8cLy+jrDH!(i5aPYK8t>DyM&0BT2EIYFYA9R4R4+3o%|`zGmE zvm5_Md=fQhVD$YhtXFh znDpk?17OP-aIuIV*yt(rmleG$9WEwFkb2{Wsu!@~AJL6#J8h3YiJ7X#U}Z4R(GI#L zbmIR~*8htalqWM>RVe5PzIN-dQQnLGfc;xrSz8?%q|>N%F}IFxeQK9}fhGca4PqT( zX`uQ1u3~QqfDZjM?)t(&Ok)B+Xzb*##52FiSOW=RQh_ z;NSauQO>1bD8^`cIRM|453opa`E@*Yj2nBfC#$j-3AAU)vB* z$9T^p6rYhQ`K>%pwxS3vom<;oTu^}5Q>E73mW7Ni2U-r7L$2gqEi;s?$X{^d88ed2 z;5{GCJ8PDjh_p~wi!~i;`@toUWVb>WyrL>R$hD1G@}r(61auo@SbJB(u#^Ui>1H<0 zTK_>2`dB4ea;!A+Mk?)4P*F9_QAm7dN328Y*O5R;SFWHwt0PNIE?aXqm>7k1s9FR{Lb z@&k}X)WpW--Fb{#(0#Ja+RX-Fr1A@T|4G~wghU8bvi?CCS{S<4xi(q7jR+W9z39K5 zjt6YGO}YMO++2&9xQoolr+vcQTySoUEb!RsuJW93lPpKTGcxb+;G{P(DgJoOhS^vVd3TxY2GI(ljC<`vaJS!1AlkEdsIjpTPWbtGg^=HqQtPdx^{vt}$-GPvBpV zh2Yk;?+_H6f(*;K8kV!7$1|RH-RuWtFr|cR5-Q4R8jJ07kyt*|@Da($yHK?E( z_1?z`(Z5{m_@gB7#2%#xG0F3bb(Guabl z;+_$_9!w!IM_EaoR2|8S&j7#D+4o{SP2V8;(szHcOPnWLtbY^)-$O2%6XQ*Ag0UHx zFUjsUL` zC(bHTNt)x{)d4KIzeWdWb^v_D-#Y+WF`e7rhakurop8MYwl#46;c@JKk-eRRjNX4_t2Y@%+}C)kBmGzKQrOWC7#(JdybFOUu)e5>C6gEHv%bQj-M zr%spu;zlKLQ%HQ`R==Ah6+w#pa`C-!b3^RV*WX>SZ1sftLdmTb_UE;C!)~t=TW>4e z;h`J6=owmYN22lNmbd2Mt9`RU$^a?@ah&6=V3FvA} zG5GhC>4dY<3SS3oUbd>M!(z{8rQSfTam4GFxpkvt^rv*P%M8@Z3bdTqcO8$}(Oqmm z5&C{=EzvB+MiH<(s(1WlZR&$B-xyhNl+gOf2;CRHsY9AKnowW}iJK;(Ph_9NknO@%WPYoUaLml2=<6aou11XER{kH+lcK^Rj)p z-CrQdClw5s?-YAX)9a=eAdoz7X+=55?DML^e4W&w>xT_(!Mb>yKE#@U&HXTF@dcbj z+5AY=-U=Ze)Cuqr1dl3BB*FX!-@_ zqTk99nu;Y;~IU~YmY<~X+Ay{lY)Kr zRa%Htz2tYhcgLG)2~VjpQ0|TOkMzhKj({2G%1@u zftu~}v5FUk{uDe zM9#A-&X-qGz#Og3Y-e0P;obi67uGdLBc_sMjFWIcqMX9AMcdp)zwShIvamq#Nju|E z8~u>@VZ;1=JNN=|7A954{N|%2E9Jx?-oDr6hcq(_4r?)Kz+Mv^Gn4 zV}5%yo9u20$5B3=alQDH-UlWVN+EM#}M9db-h>_$fB88*<+>!Dd~I_qa_ z#Zx|O#Rq-g!Bek5tvdd&j7J%X!)_i}n6n^(Abva8ei@k;uu3;&Dh((pVdB1@y3+)BeVqA@>=SRRUO#^Rk@e(uQQxCvwSjjjd$b&MyO9jCj}kx7*^emjLQ|mORz@sn zC;d;S$U7QOLn;IVS7lslW8!=J-hbC2m7d5Et>Ybi$yuYwh-APXEXy-}K-s$?LqtjPh9vN7V z{(bwACk0DNP99dOxDea(h2iv8C!m&JWsPH2m|R>zhsj>!(O&NVLqb}Uu%5{5&MkPn6|M#++%38^Uw=hOmM$^bJtp=;`aWsd zCj_ft??PJMGNW7u7SBPz^wxs_#MAov8351h&}WbM(|0e~iZ8U+Z z+PeB76mdu$6D1~fw33{n`XR^qw;~GnKAX7Wlzr(=6mKrgGEv@+`DwjR{6_R`{EA9m zc<ZpSU#CU@q`oW%$hV zDL$#i>K;(_I`Yzg_s1Cp$jUxJOZe!-x(o0v2q-oF#g%`br1Fa7w$HRUi==pddb#d;!kG=P?k8LHcHA|`Daf}kJ z$muyj`>r8eedyve~U%i9B$^HUaw|vZk=dT(H&1K zg9Wc6B8y+@#WpO&u0?CAli~;i&BmMVGXCu#px#`j{NamEkU7KxzcH!QnbVY;&{Xct zyA+sLHm|CN&7eCX?&(g{&DfyB?^wNnd`YSzUnCbNf~%{++unTxjNZNBTpj@vMe>g$ zHXd-MYPD3NXjdJ03T?QVIxWOT_bUa++2IlAJ$|VTG_rB2j}6vHr6D>|cJ?{g-yPyT zz|`ASGm19<2ZVFUzHU-osQb|rr*_ZLCF?7LDld#b`L){lW4d+K4>8Dc559DlLE7Ve zplgO(Z)rc0vJI5~!Y1mUvUrPzo@AqWa>g@gii=h0oDaP`u*R8dq>@+&Tt~x5;y9Cn z^&PTP&-iflZ#D;qU@`78{W+rxGZG)JU)FXq(xMC|qAX<0A+=LOqoIasNzb;(x^PK( zJW^J~h6J1j_tDJOwX5CagGpHQ*LI~z9_iRFzBPc}r=g5QEX1o z@y%-wGRlS6%Enlu1}`1GO?I~e4mS>Qa8@mfV4k{sBOoygWlB38`8XZ!&_GAQyUyri zZWoitUG3?U_}C7fD4S^%am0RRjbd@|ujrk0ysvhHGyEUs$%sAZv%&a?XG}v{HQ+PC zsB^RrG|z*+EeklcZgz8vxzf36*~!@IRhD@8^@^o&G>YJqP{?;3zP}dhelhUP8X9Qj z$E!BFm6`tXFnoSGr%v=|M@ovdg@cZyIi$y$wu#V>xwpBgPzJvL;%kMf27f8LErDmb z)u;T)dPYaarHkQz(d5E5+7)6jWwCfd6!-)jzLh-UOJk=`W;ED{`zS&Q|%hqyeg+&ekiCp8qgZnS{cIwmZX ztie1VKbyaw$xuy};!g(!0E&eecX48T9dvZN6vMBWR{vqa@0PiR;i zMLT#a5VrI6*4%0%OE{s)`7%N7TmPcb?|$=mFs6r` zEX-UvhEhBw8`okb!-E-6M0Hk?Rlaett9cYoU+}gZa>wjq8*4ZOxBhx~2+~!C!j7y> zP8TeH51QP%yqSXU6!(x($%EN9n3`O$b3yz`8+YW^n=2T zG=lUH&}YbOr_rWaRTDfOC+mb$&JimVR_CJKpg%$TP9-{)*E9P&Q*ya#^&I*BnhQ;& z&i_O)PGI261%G=EIJ`yj-#$lBQI_*e>X}XDaEhjGz4CGraCvGa;;sNqHky`Yu=N07 z(YyJ%E~ARxoDSn~!^Ptp9;So&>vi6-*|<$LSw}2VHM4qLrKg9pb{Nqy_9>9>q5YKt zyGHPnF-vp{6;TIXb&gf1n>P`?@{s1*+xI_xtAvjtQ_^*ozj(PT`dQ)Xk=HV&wkY9i zbrijlBm}XcF_L%B?P<#plvp=KnR7d9PRV=m-u^f#=rA*DNEH37lf@d;YOR}Vc&5}IH%H+RgUYClg|LCc9Zs_f7kS)(S4Do= z%ZNpRNlL433F7ex+9A1FDmNiLv+)7=nXw04&{;cB^*ZOz`-JztueI2v<Vp;j^X^uGaP|^ZlEzYVYMzX@GiEul z^jBlTD7cvJinw%GtP-|k?smQ&*3y?X&u3YG4bkq`G;mBbPJWkB0kNnmY zzLS@;hBLsF>ib|5CuPwNgQ7+r0@~?>AHgsg`j0TaV3e8-T1o2g{^DQv4mJGBX|XP8 z${`vStwY%WVugRvGLSWlh5<=wAM1?xT1u@C=2s2VBpEXVQl45Dj(HApj0MLaJ|QO` zI%inv<}_hapna*vD)LprAa;f#w>3 z1o8p6lqBRr*4_6L2on@D0a!153jN{S~4A6i=En5-1#xzh?pCa2b3f---R8%~9LS!#;{0 zc^`0P|GLMp6#oCe!(J_561JhO9_KPB->ar+BeS<%{#ul7DigS6)Y}ML#!-k3CE#UO zxoM}F&WiEEFcw;}YxU)gsvGW^tqav3Alk7&mdr@*2Oh_q9T+Mq!S$D4TIiJMr$Lj$k&^tNqMk6nVEjd%)l1_wUCScSdxVK_2o~h0{^w_H3l> z?qII$Zu_bI`dHT>5!)Fa56Q#PC1Mt*==?dn4mM0(Bp14!&)n19Hb|m{R+6OVbs$>f|L?v9ZuysE+wVRhr-#S}n zI)kz!qY-s~E812W0;#48;0E>1!STU^l3-G>%;~VvZYP@4FWN3Ia`@I-3}nQ_*$=IE zs5?tBSxau>@<`HSa`-+#Ni=Z`2RWK=+WJ4!2WRB2hkeBBGfapljnXNz#~O#MGP)oF zGvFW2kMV28%J@8-2sZWUUXk|F0fG}ueK?(M)<^D_p4blWiUp#yZ-)83rKw-)FX6*=-g!ve^mQjC_4a7e16_6~EIbKCC0|)?6|CWtRg=K^H#K+&BE%zCC8a zjf6d;hFkBH_Kk~e_?!c5>1lV7qWt$$T4if7_P8%4u#tix@1a?QMG^I9--=(#mUhX4 zCi(@x0&VVV+oxAG)k}X~viLz@y}SyZRHd9=skKe1Jq=H3vX^xh@#C~8Z8%oDDm3N0 z&9Z%;VF{IfI9N8=9u%Q@Ahr*&f*ul5?$Fu66PA%-P2hKbRF6DtOv98Vrx3o3%ZFH{ z>t>vDJt&2k+SPy?SkP-zQmD5d%b71y-p19J&uSb-9?pt8M4fX<;$<8)rx~or;dMQI zy7|LHKWpZvP;?2b$x?S`BI$tg&=AOT4}VdlZ@ji{YS#6)=7eg2xc1kCl+}x(UFw(( z!8EY{XwH@?KKW}H{tj1_#V(p{hS!BM@kPdlQ?T$5*;JNh<}BBkB&QP zJUdplXW`40X&Z+G{EGf%U`l>w|Gj~JrQq@18|iFCXB5Adq=hyCuR5Hoa*XaHj#s*X z?HhUF7%Yf(q(c{Qy1_o+fQ-NMOS3EBfWFfHo@RcuRoIdJ+-y?t~~m1RPIwl1B~e zs?R!&I9aun-g6Nm-S~t~~^|n2u_Jk?1GB0?>7WR}Ga|y(C=qF7E;~8dl5_GXSXw zz^=cdxwn0E{sXXo(XM2PeNv2nt_b9CDnq|vdXr}xK7%+@2v#IVvB44M2cjWe)WS$1 zuDWF_yT2g6nADlHI;2pU79P?xO2+;vamX)0RQd|vs|pYe&SiF6-XDiLYh7~fmP+b6 z?vWLn{tSJT_PwJ*2F_xYX4jnWAV?+Js2-*-1O7AvyTnfIHTxXUH_k#?sUM?L$Kl0z zy2Sd5nJry(;Sohj*I`j56LL!4*fdwJ^?G+ zQ|+b0f6@A<8_{PXs)hswBtfBTxJV>VS1}B>Phr>)=4CB!Hly;N@#5ZvE6te^v z7juZcbkrTvz*~%EV8qGop{}_DKOhB+_jlWZwjBmy@gi&IlLXc+SkRf%dvaJ?@TTS` z;-SeSTz9xiZCK1M-Q}0}S6rX=Wgx4$>kv1=puK2WO&o)Fg;GsShE%VzUq3Qr=5i(= zvoEA>5#T(_Rm{q)7+utlJrsV!C&f-&dZ%D$7=Bp#fkz_B|I8MHon$(8v7< z=>hVEXEO|RWHWHO5L>d9#|s*A>wRgmgkJpT*uK6(Hk?-akv#0MzTz3MS{2?d&B|1x zU$A&4`TmMda_T{0CEU;}+D8#8`wgqjTcxCL=aYN$ry&;vd3Eb}$IxKTnCtJ9bKsvR z#@erywD>3E${3;xKC=*bnnk2@>U=$-^&Z(Vi|1^-h*B6$nr(hl=y0VW-sU7oNaEIL zSWo0(6abDX>icG(AJDMP$R`EPJAnIB+EL0T(bHt9W5NME%r#4le8R(}`Le(_^rES8S?mj#f%6v`Qc*t; zvp^VRT>Ula|9L~NZoq4L@%sBcemLj5m?^5(f;o5I?z^tqLj{WiUxu+)Cq1>+-uT2^ z6F|S$Jf`x@>k;+jyHYP|IH_Qbd_qem#>(?I2D&k*X2Fw|#VUjM@wJ`E+TOs+HQ7x* zpqaX%Bx8C-|FC53;ja4gB?;P~EV?YZ!l0tT!G)=5Wy_;9ha$t0f6*eY<)M04kFIE; zk2h{1L3xS-ZE>F_%Ld-f`SR7K3FYDHWf}IzNafKu^{}_SvSTkfzms@E6%^6a!ox7x z29I{t#!i!gcio9`pA-dPVRm;AuiIY=H75OAv640+8ek&( z>eUnu^(yC`+cV9#@g(5~Cnb?VX$gni8+XJ-SDP^`Bl^#mP5ODA<3B>4LrU&+1J6yq zRCXRDF8*bAYW)G;E}Gn$+;1q9DQs{JnGNqO=ahx-zxm(ShEpLYbn%W%TN~oFxCi65 zRo)Dry=tXI-kHa!*D$@|KHC_fZ5)%;`|~WZl=R~Glh_(QA9fGHh1*BCEBPISR+^)I z`Fx-{AQ5^!WjV`&g}&UBJJFeThPD6j2NsKE$?@x%)3l|UaeT-q-*(!1KMR5>)^XK+ zjJNnZZJ+qWYY-GEw9Ts=bU{T+ru<8_r!MayS^Irh0qyBD$%o*y zex1{9SZC7BE&6)D<~XPKRPB(H*Vik2w9{*Gk!UxHDFk($zW#rE<=Vk>?VO^69tJ(M zFpzKr`_Lyx>Ml8cM*raT1iQ?~Q7)*ntZxUTx#eMx9DFui;28PuCG|Ik9PDd=+)iY38e z*Djs&RzCagJbf2Q5|@HvKb981Rdk1r{#u;;$c3sdMWT3TdVbY$7uTK#l=)2QuUs9n z4(_J>1Ce}5^mHmu&5;+0VV9U&(7af;npQh=k-CQB;PgU?eWf`6yNzZt^%gSmmr~9(}@<54!`9QqLafS6xPI!q=NFUuHz~N*1n~^nRgk4meW8 zbiTX{6A%nmqW8K|uywyfV4O;Qj<(VG^YTeI81X|6>V%-~QZD=#)WRr1Cx_dbsn9U@gN*t6%Lfq;fdZBnndM`M)!%3^pu-1coQYvXG z;>W_N9~ba8b9^g{@Ns^OaZLfY@x|BIUAmQ4(h-g5G(v9~6H2j~KfDTYl5U*M`$eaV zybkuRV?M*oF)7=`9NYB|^?V^yh_R!@H!?I3w2>V+zzBLL)xye38^ur`) z)Yv8!L&#zKDolm0o?@JC|Zn^=kFBU&foLp1U?%td-mo` z47co3?7ixcp)>=8=9E7EC2y16ufG<7_J(!MZ63W?qq*~RdgR(LkQ`i}9vz=l!I^?e?u#D!g%>jL~ z6aV0xON>3!BAzjUG2uR#D|7C!k%AIMtab-j01e8bF9b^tMgSl93{>m4f!+){B7@)P z3UY7j{~zzn%3aG}xk-erDcdO4F$8mV?#Hp{pq{2i?>D$)w6v?zaDzM-lLOt~Aqt($ zmK5x6Ty5gWvD<`UgDAV=1HZ9e5_G561T`c$yu8PNu{_O}(cThgwBx`v_bjSrr+{+P z3Lf~ zZv*q|49+8Q5-wOh&w7U%7Eyc)=aF8}>mj^XTfNK9)#nkNGuSglJJW(SP+ zJ=q%`&sv!-8+8=&pALoE#xDWj=&9lt+9}a&< z=}6Li=8k&}v1tAo_`ahj(RR+Iy3AzUn0@N>NiXgu!y7vFUDaGu+Y-;~%V=u%(-4^V zXNf|tjEh8UUarDLjTZ%~dgp67@^GIkIq%|V*G~B^s2n$)x=7)l!V{?1a~g{bPaBS- z1YO-H`_aaFn6mx0ZFc^1Prj@u^4PH;+_z)AtZ~>%DB&(Wa=7^_w8RtyPvV8MQAs?! z+7J6S*|nN*KE+Xw3Ls3)k0kLDVs^yXGk*V1ib4r_3Sz~q2I-;{f!8`dNb)%8B>*uh`Mwp*Dy9^Ix{d+yyFnS9R<2cb|+{>ZIS zt0ffo)Z7V6?>^vSi5YP<6{8j0N;@p!iQTT0z5GC&WF>qlt+UDGafaZ`9I56TffLM^ ztB>A-mCyRU1-0p8_e)C0^FcNK{SM*i3{CvMd1)l@B&-Cg+=roU1z+=NF-#VYJPIuA>C3*KoouFnsZXKgXZ0rN8K4_vutUh$MA_gxQy`m z({-@NZvCNi0NXMd_T~XLdX4nxSB&j)TtB6R)z{Ivq1%#`Xuy&S-up*W^PO>CQW;C`Xtd`LrUPY$%K7imy+C?p zJ0xq9vHFqs-$Gr=7!*l2<8adUgT2R-)iU$#ZK2H2S3G7J6$rLQbNyKsK6BQV*J4Rx zt5}L`&o?q0Eu*}caJ-_tUOXD+j%4F(MTx2r7>%hs=#Bwl)mX2)gi`Qxtw)c#pwW|Y zY9)Ng7~j4ag+_lI;Dn@@!qrR9FeyARDcr-V)tGR&ByjnvsT-@Q8*nb%K*J5Rk?y-6 z-x}>-XJ1W>qz=vc{MTUgXP~&Zz!=U2-x|E3U*Xd=0n`-+DqlZT&J8kAj3}2=N0$zzyG4Om+4zsSH5U=nkjEm8dX-vJiDE2CY|oj!r&rX z_+vDA!gQVIxwn?m!#pLL_t@kBuQvr#cDGo#uqE(;(d%{ zTMMP#<`BC;)A;60Vbl0WXQ4A?HYn=!y!wvNsAyLMyFjaiHjp~X`ucw<4ijKAjBJ+p zh@d;mU928UmE5S9c@BA4;?$2Yh)5Y#0&BQA6U;snK{lCa&xl#Esy(}W=yx-Y|w zT6Qrm%(_;wOVe?&cd!v3b)lak;-Nt=(w`i~-zX5+ZRug@Y9b8OfU;#}ZI4%ksnt1X z%G2OxE}=Mdj%dDzE{xb>`k)=kwT6@g`}6qkc!S=;OUm$bt}SE@P!{!;ui+J!+_j`% zWsCVd3`fJovGczMi@P5L(JkKrMJ|MMXg-D@~tt z#puEn+%KaH9fyQdHuffOPXBIqK%W4zIQOyQ{Yl>ldaS{2^F5}ffmz?=bBA*~gHEza zQ+-UlJwprKgUw19Nvl;v&FfBcgM$^7;VT{L7EloC8(z^~XwR^f2RcKQG2sgnYO_B0 zZAQdSgJgJB0C~nztG>rd-~(52b5|Q$J+aGZQK`l2ed1CZ$sV{lat>$t!hY>nw#j9$0+#iW@RfyTZMAkhC5 ziM2obpH^(F(@6OE|JqbIn9~9Rfj|(5KzQodbCE~mxNpIOD}u3T@V6?A{Haq!-U)|_ zji-XeU&=pfs62 zCNXhH_N^AX-CF}Koiddq>&zHI32d6@WZ8s4MvazbUl986^r7orJo4#&W$GBOsI?!L zxIJdyF2f951CT5TYD{n*9J5aUu1|Q7Eu2+@t=RMZ-5GF{EoWwxt)V;?qQRiGKWlxT zyC3iGr!dZc)V^4U3(?56IfPDrR7vWze^ef@o@`>vK8a%mKhTZvmXo87h`k73F#yZP z&J>|QN42BKDPTuq7i$^`+a4Xy=toew5o9%m1dF(hb85#TIYiThJ;!sDgsVwZR-~yq z&H64g*SDfH{jcFxlP{V~M7q}L?OYufC#{_ET2B5mB>X)^Zof)9RvI@^6CI5cET7N@ zUr`$ySd;BIzOcCDwwV7QR%eLfgMZ2%!hSkbZwKmG^<6|+A2~=LuYR=t&^qBA-tISW zYg9kkxS*YI?DIiG%|R1autQW&aLm}%kLxSuTdHJvidmcvhe^DaCb(Ll*yq7nq?RT})vJI&Q$ z?sdGV^j*4HS*HGkD7F` zS!<+QBlOak(uvZGI3`|}I@oZjpz==c$S=9i zZHW2fgZ#d15wr7-8RUcydB+NjyC{j7jDWpNeH8CxY^x6OR@*uEQCObQy{j8lwyd83 zj$~m8XT9CDYtauYh60ebo96%McvueC>_JH zb;h`=2zsEaaL*RONO#Xp0j~J5!0DpHEMH zZIUch5fK@_gyR1?gD+UIgdV>A`#zT73-pS%cV0wHNNkt7PrUl0HmI2Ce%psoV01Bf z5f9N~3WpP3)QQ-zQxcy0M4ahi27sV9CQ8j1mUR}MU_JUrZR+HaIBXY~n}2wN=Vi#8 zb6idFh%bRB68{KwAGEM-5L{VAV}=nXUVYkoV=jIg#?xDeAO}Y;d!$ZPw}YuKtUFyGJPF#_??|*xF|hv=E+| zwjkq*gxsB`Bav+T@AXxT&$dnG+aB8)=YhOlWy%k6ca{s*3nBoG8PRQ;@Q3l{W-9f) zMo#zk&CTSuC6xG7p8JYq2`H_2{RaOBuopIWP?sRzj~50mcgjy8qr=*4U!-u8A`2Kpb6SVcj0KPB5#noi$a^@gv2~XW|+NP*XjkH`S);V{eNe;H{q@O^-b z$t^KNe45hBUMOa%F-y(vsLcCFcT$%JQpOl*qul2|C=OW%^jTSX$*ZhAHgZHyb4r?o zvOLp_pIg>Q1q>~WOyzE#++N>A5wdkE;|CVnRojg+TZ7GgN55m2+9j70`rnT*2&!SK zuCo@C@o51`h~R-wYxr@Hv8OaCE9K#nZ=MJP0PeRV&=B!%)K-3C=W@0@wU7|Am<;WrLMh5N@3ws%M=6msip zFOj&VAAVhaX8T*pNDdCDGu?DiKS5UaMtnxVj#*Wsfd{rBbH;ga<{~V=Tj~rQHkf-e zDD@((4VZDC3*J7OTk~pM#64R;G~Go12d8(X);AC18V~epk|NH+lUW+BU0qzBiHZJ_ zjeQ~KTcsKlju2H!hSPp@as+0qc>i{1iaBbM`Ydo=@J3M%@jUXWS=#>s+3`#%sGPXZ zd;T0X2jkP_wjdjsK;}7psTQzsawS?-C3GJgx_Wt zrnuz#nUnwM`9%bmZJIzaUcuSyW1&UZl@Z@;+296%%J-4VSMcZ9u}bga8TTSwGaYuV zdjY~30D%QX#_oRt%>uPPv*+3wQ!R-zUNM3?%C@NgRO*+T6%cs3{Y6Z?=Q5OMS=G*=rYd(*gfbC*_|seY ziW*WBL%Am#YESb;_E#z?{rKMi%XZQHc6B3mZ!(@Va~uXYCu4$J2kpSvlK62lBKzUP zsIX=Oi~F8NYC6`!WBnEWi{a`vfEncp%tJWFLQTyp8DfV#E&OEQU^=R%9?nKKZm65l zTE`0_AgBqZiFLG}wuc!FUc5<|0^6_tl-(0C;$;ZFJ9<@42kg5ScViwsSOvQkD>HuJ z3lUiKADG6NSZa2d9=c-0+v~i^W@l*sKJd+HDu26YBLKtjf|DI-rRu$&(^fbly(Nj^ z-2rvIJ3IXstvIYML7uIUu(!V&=OYSwMaD57W<*RZR~~Ox5iS^U>Hf=*4xXhzmn3G% zOIQ|yGeH>%Q!rfSnByg1%9N*#D=Qy9WP_BdNaS<5Z3BRJI?oYOH}RrvWU~IKO0{eX z-gpZPmvJX=P0H!n1I@FY8P&vbzugYjeOkW+^T8rpWO>Bm#_V6xfyv_4N?>&KW4TKUhfMd^9AMkAfNd*acj_pGHgEF+cme$pI%`L>SgWRx zcBTu$*bIZ%0Hf*22NXuKn7)Vb=O`|wniAVDrYFiDw(WMn?uvsl7?lrNXnP14Nli1| z!sU6|IRPpcUTmggkWxY`Mu+>cB=f`vG7~=5pYKSg z@t-iTL_R_V)%#cM@_6vM?Gg$0iky2OTm=!1Mr1DBBARLBq7h@DSw85Z^lGBr#<8uM zY*5vgXe`J*{@~$c@l&Ll{Is?;5%r(v@D3!4Z+j*rnHitM&Z7$X=%?hy0Ac5I&xH`S z><0whWz0bKpRoqv+N0CCLf{ZIU8QhOFuKoff3$W#kC&XLS&!Jv-R7#2+);TEh@3@V zo=kcZo4!;#ZSz(Lxitw8CY~pZ9dx+&QBuzy>b|<$$c)MTXdOBA?#CG%dpf+G*|OI} z|M*I#YyR4(jQc*)rf#I}BiZNR;My`(Kj)sg?(1FhjG>lM=4`80)|?8J2I0`nRUY|; z_jKwEaijPSq<0;ovEM63bCdiE1C#OarnZNdVg2}gBcHuH^yaOr6sz(qsbS!zrZI(q z;+zJfrK3;i(Cm8S!K~VOl!!Hs^PPw~aj9#+rECR}N@KDpLoF!ts+1%R5^apDoKCoU zhj*woD@b`|o@$=?dX@HyOLt2_2fKNH9A0OvlWIOK%97^Uk?4^qY6vX)2%7V`h#Bk5 zTy8v+3!m=ZUkGbbb}wcvvkj26zh74(#w!+uEC0wcq6;jZmOR5OIR5qD_GU0Q7PiKF zH29XnNaoD)u|U09&iG}abd5I8nOw5~7@LuRL!~=6HRnzJN+0{asF6+k_|>IU9gKuu3agen*6#?GdonDy|gLY5#BJA+zi9w%#l-2qnm z^NIe4Hq19lg9iG57Y8y?04u6YqIA=DeQCa|@Dm2rPo5)112?Jnkz9BPO`l@Smg|A@ z8PH#i6#80Vq5966L~`>nog-e$b>HEoY(n=grUroXgIeV4!7D@TV`ne|nx-ZMq_ zUM6EY-irgTrH}fxnE$}??ymmsan0beS4rz24(<-9Uzc(FnrOd(JTLu1wkEk@U55aX z_g5}zN>s)86vlsFVu$~iE{fgTD~T@`YxjQ^ifgBmcLKGSbCKC#fVJ=Pr;0PPF`Mt| zL~W0&cN;;uEa4#fqE`*e!%D>3s1G$JXe{T6IhXw>XY7)DsHu6 z_V-xfbkv|%z?A`x`)~kQ!_ybP?2~}k_J&g-gZ)}s5h8Og23acEww`|Wv zWBtrIy|d~71esy`HFw`O(+}jWJnsdCKr_soMHuAYGymT>qMA_@1%|A__3@G$G zr*=yAV@y)-r|lI_k7ke?LB=*JZC(2mB6FX`mT!T?c+RKEx8e)A{A+d1-E)M5mxpn; zilX$P^SJ^SwkeZ$I(bmtBJRYB?Ly?*u!D0p1a%=i4hyzAKeM(+((ZKIm#kvs=`E@n z2N3C8o{9U9{j6&XlKAs}DkQ6pSeYKJY=~&gjTI`#k{ISsA^t$nTz|;^cxj`sax-Ck zVm}JQJQ2x`Y z<(=w*m8|{I_`cs-?oX0wiKuFDtm~$-xXp_;#&6B$`b3M^; zSJtx6?-L0Xu&TqCmqkuhSxp<=i-kbueafnw_o;_p`>)O!4qf9+N~C? zjxf-|Z2roi{&5)xm)kFCVvzGcu$_dnAvdh(32=Lv4NS=XGJ|%W7-5g+@=kVWtmam_ z9APa>hS#~)OjDWXxsy_ zlX6pij}9V!m(r*cE1bPqzebW#us7#d$kMF0|75QvRPtZ6^2)L3CG!1H-3ZP(;-~Aj zo2>iyZUaDoPSap7E1DTnr20J+xGzpstD-;A`$+w|-$=iZM;*iYQ>`rC`SY$OgM9!>GX9cO!tYL&Diz^xwIZf0-PBcyJ z2Q%ia`Ht1~&p@6|)!K$qSlX64AwkDOFrH zLx$qjSHo>Q{L^30cJTK!0;V+4sc3(!(p-g^(N+6tocc9^9=%KKA%%8u7&KthpaG_K zNEdleW;m>U-q{)o@V+irbxX%oC_?WK7%BlA_v_aX2gmM`9Cg37U@TMJ9C!7)mu5_x z2S*1z&JIpuNXz)EIv+%ESr@Wr`}wNDH4to)D7*% z(N9ZlGAPt6u`lPTAROX!QLlMJQ2vkVKUdcNp<_xytqS~AuJt;Nzn^qhN@00d9Xsd* z@MD)Ks~fr49Y&inG<4g-;np=Vba5}DMmPnF)vj8)n zsZ+`AYaF^?jOYhc1S`Jk7+4&XsB$jDFge_H9l>;B;5uU@qd+FS|o*YOh05bETyu^S8$DyAsX_#!my zwG5~5$qDxk zrnWqd795#85zq1rzI*u&*%L4Xos-NrR-Kw+>3!A_sdR@TcRGVhev^-!((7uHXIw~# z;S@K?)9mDSoZNG_H~HiVL-(FK*;k5Ny#hQG>_s{%hdu@%6Lz1%IC!sx;YzVhIDtJe zC*HbG=Hv@}M4r?1iSfmWsgP^BN2_Eqc2i28;acxHGqzJHk1~-@bG3&Gn2HJXqcS9B zWvF?YWTGI>DlaG+u$+iFr<%VF5jQJ)QQFJr)sH2LCQV!qaxpebwFx<|V;p6^d3Cq* zM)>hR1hh@SV2Kg*h8ctDBwTHW_bK?4FNszFz(3((6r#UF+jadf!t2*F1=}%m{QJaT z-7XgYx(w4_gnb+0S8TU&rW(A8fUN=Wz(i=R^5PR@0I;+A%y)DeE^|M=vnCoj!Av_c zD=>C_=NnzJm~%u`df3BQ#>@XcGb}^mhw<^&Az^2)2z#7#)Gri4KT3dq8@CPq*!CcB zUHM2;yA=IpyG>f69!1?G<9&Z^wE`j2wN>&8{0!dFHBms!dAekCL~G<}b@>9K{yW?_ zVCUC@XSkrttghE(_=N^=Gr$>_07CQ~U$>+c6gv40T(fbU+bd}^xB=>V94?!5m$0pRVbjUdd0NN^Z;N_1n(9$092PR^u{i4;NT<};V$T+u;T%)XB;!BiwEw{VdbTpo zh<)Z!U=7Kqh3GA@9Ao)k!{b9@uhH{#(kt>;2aVbY*ZnC7Gd!&*CmUg-EP-Oj+>T!` z2vQ$W@FH>5b-WvBIf=gw_ZiL0b-{Cx3eeY=L~K8P2I4JHg9;94ww5!13&=NOsmSk+d$9ILvr=PL9*L`l2P(}mR&`Eu?R6mhMK0gv zrHBSR`cjKrHu(^zr+u=m=WGa{5F6_J^qo~+y0*cj$>Q9M5j_e zz=eG1kLWz6Jx{@L?KV)B#H>aZ$dTu52)rw)C+ZsK(Dd<87=*4GF%-Ff)pD%*F(~y+ zS8=hw(fC>fho&TYo)Lq*YRthk#Y0!w>!i*tHKOym!^cJOgbC*q$zTy#Ux&KC3G@zN zdm{;t^2<;NFBvazQKIgF^y~^z{p|e>DzGUIU$b_(#li6PbfwqSNrXR-qOwxS;b#=F zObL?2gP&PS7idLmKk7!fQ!F!`wf&=6U?Sc(ri*i`3p2j;OauGpV@;wGc!3IPo*KUP zyr%v2HVG*-fGI)BfB4z6%&!5zW2?d3*yCrjOaBS3pmPB%v>+m# z!}+K+!blN1sP85ILSZW9K-ZQd3={}W?W)lyCD(1Y!9UASI5C_EK=Og(j6Ab93is9jFaWTAAaOiHD|~P~Lnhh|+4#1WsaCh*rRuv< zCD*kbcDZ&@II%91grofk+NTm31oPOUW`QR&={fnWH)Ahd=eyF@0MW$~bs4@=0UqEV z#k-do4mDytOAnX3tuEVgIB{B0KTg;?Z^wLMTgrT3O+`T-T?hb^P(glU7Z>-fJ8)5N zbK7H+Bk=7n&}sl+3FKD@Al zYZ)gvRKGc5CS8OP;UK071Y^rwL=eI#+6sFH*!mE`kA&1kn77wOnpd;(dWS`g-;htN zaNRp)m))mXlG|M?EhXjKgG`Qw-}s!QCWWR$`n+=z<4V?h z_EztYc}&3@qAK?IM_*Y}`f2N5X0zcdvh}gQK40iEXKjUav2bG*HX=nB(6OtNt3#8GsUr%=)_})9IK?z8j zjxH2sT>GM5;jo{Nrb64=Zb;9ug-nlg3`ZPGf_~;nM=5&cudxuqN6uODt%`2-N}Z;c zxl4N#EI%NNcAD>HUYTl!9-q{DrY^-CClBn;_25pHn>%B@d zZHpBaBxXxJ*Xj0uQ*@U{w-r2S)P~Qj z*BTC!)@Gufa?VP2I^NAg_X_-8W!Hxt>Rn)UZ^^BCdTK}Kwn7%3X`{$a{7WSzQDgTm z;hM-R%KKQ4?MALdZ}sVSpu zt%aRjmN___q8vyXL^Mk%N{dytU;89}Vu!g>m#3}jtE&3u#{LfTV@Hr^V>dXAJ|;UW z)@az9e>D5oD_Wxlb)M2PGHKDvemw-0@>3GMI!jb-846#V0vX3lEn@EVVzW%ad-1XR zj@>?hVH$q|8Abg^v70kmH3BLh%n~i{dLHFYR|*%GO!wkixova}fn{<6Fozt=li9L_ zV6Y*&KiAAL4zKokJSEvTHF==Er$q%vp9vG|69fDN&>>p7kOrS>pFgGT&)Pws`35%p zNq!ak=E(kfJtrdtnek?msx2f8uj~1$)>(MvA2Vgcvv7RDS! zGB1Hb`@80aAw6*vQ8a~ zi{>&!A#k@((gN+vUp6s84WL&AO*c~1>F-9;e?mbrhLEhX_m;A^?1PYfIE2FI_d2@o z`}@6rkH_zipK~0}bzSG;oa;57ujgyL8wu0rkSfJKL27t$e@#@<5uh#Z_K80!ADsFL z21`YN2ZnOVtz)!-v)%?O7&G^H6=Ftp`k&7s--AY>hpTB|7yIGIW_nQm%JtF1kaQ|K z`-2Fj3z7oS@+kVB=rlD|y-cpj?w$-HP<&D4g<<@#*F?NBq9$G7(Mr@7Tl|!;3!F=4 z+pnv3%CN9#Lv~ZkJ@aB(7dMXqxujk^z75qYK}NM;gxuNvuhkT|KcC?QldE~-T&R^; z%DbZfplyWYY*0bz=-hkFn?n%=aGctnf^4?j+K^|V#p*3D7KjH^ywL%GkQC-Hl|)ivjB*3O4xCZ&$r>TZM|J+5bK|8}Em zNp?ZrF1D)SRT@ZHK+3`L=lbcwjWr#)`?5Hitb;IitMQYzc+-5Ownwz2kE>HJ*Qa8l z*#J!0jfqel3_%X9H6HdG(@#IykfbU6o>!>}?01GQVGUn&jE_zq{bGa!;Y)f!@ z@94qWEt|H3cd_y5jx6*J+KpTD4JK?gVKP6{9e*E{QW{CKxT{nL_`9#`^$}_+#Gsmk zkrc1rh<@PMe_zBvLGj(edEG+T{?!Av)C;OJ%6xb?L?`o{J~m?t3<>awtoeL|5vU*T z&3w-5m0(r0_*_!z0*?&aBMbU@mVM| zfsEa`xg*bkij*)xX2#36i?DNEL*n}y6_`b|fuyw(NVj3!6`}W4z-;DxI>eUb?lf!{ z{lLkJw68roH!b#Rr47%i`FnZ-ALjbDZZ1*jIOklm=X5>7^l33l{P(h76}(2sZ6jh) zj_nQDl@$2P#4+#assqfUjPI=#5?@-^_iIgILUMA?>lxCh`h>hysUff|Ko?q>=a@Ld zFbfCGM^X^D-=yI5YmunChnIRht}!)`Mp0-grYZ%VW-cZ#?&?ASN|(BX9W9}L>r{pfPQabAA?JLnkkG{D-Adtyp6zv0OLX8VHZSN-Of zfUL`x-4>9sy}*dgqRBPG@X|xbYNO-Ri_al3wvwK)+Z2H|dZomhnZ(K_OzNbEtK>$! zX?>5>Nk2{G9;C%|#qHo*?=T2Hp8(P=VtAd`>NMviIm686Va#EvUV1s(8W~hIrttgP z$!?FOEi9Lm*ku0-CtEakyqtD$d^uzZiz ze%GGVM5`t#{t*_fqnXu57IP?x)z9GA|szov(<$)@1Wn}Ji z!`y)g4quL7=;<86P)ZeK(@DJ(MQ0dRva(OjVqn_8RQdy-o9XOrwbO6M-s9Ww<(OD& zWG@mIyJNiGnuvJXzoScPtn@b}nA8>XX2`Xsl=4lOHdX zsb}{hO^WdLDyHQmd--My!_4~c7KbeopXLlTu>kAt<_}La@O>v5D!oDlYCnDw3$PLw zbZwL{d!y%MidH4*^ehO#p4p>WY#}rO^wR6F`8~zA$QR!gL=70mR=I3Z8+eZWPDO=s zOCJOBIT-kid+Mdt=-#uUYRvwu>&dcH#XKP2Y9=>;y-v^YDx9CNzX%~9>k0}}GUb`=YFP|%NMjdZz zh!gfb=>ZCHSN|hOTYi&vQ5o!!7l*;jY@hJ&Ftf;K1 z5__{4^HbZtwKnvTsk0EOuyfB9=jTa&i6^kU47G3?1yE835Z zKH7`-kei;5FSn2R6~N*o`YW=NW{W16{dk$nMmHXFqAzNiDRWeXcTUhrmCX%H=zG)% z{;Gap^%S&hov>sUsAQljj+X^T-E+Mq&W6(^R&7z;*QXit6--~FZ(fRf_hO1)VXI=+ zEn?UrZr*=vwT+9}6&&NRiXnik9BgL6xaRA5ax`T#O2y3%d8?EyT!CO;KFtUCIk@!K z3>zE3Z+kz^ZAV;_BUnQ~QFh`?usf_efn(EBw@5hzkqevuZ*=HVn^Kkjs__+j(O8AZ zWprKJ<}>%;Im=n@HJGb-VHm>^+*7dM{Xf6Eq4S;8eJ{j4@Ds^8<@X*ss#Vf1AL)); zinW1FpPJ4f%j^*V!G^aU51O^OH9ITq?AM3uUqUk1Y#U;BOc)@(rTl=Z6Zzch9a8g|fSCwsM!kE&iRD$JHF zOP5&o^@X}KbonN<=lm&wm;)VXp!pR5Nx5}@(7qSl1G~d_KZZWWE5N#K(cU0xT9vos z=&m|R$6k43r*fQQxfBA3?5;t^n}d;w*l(na2Rx;AP^N(B`t*-yJ=KHl8yDR57n$r)}Q!-e+=mzr)FSP5Ji)AMIWgs(7c0&~RD_ zR|GF(Km0D1YxY%Vz~Ivo!|5ZOi*-ailnA_z3x#GH$x6A#4tacuHEglLZ2QA?Hczhn zQuByNIU;C(eYJb!D5>6s^u0=-EUhXcr1G=*qbK>{UAa8A4>-d^B_tjctE4kGsjI}J zl4- zQu$XbwzgPqLPM)GYMdtvHGbom<^Hp?rn-TIe=vX+WcBq`?i%A8a+%M9MrKacB9*Z< z=vdZ3l%}tuA#!4_|CZRTB(IF&MhVs$KeYQi^0$iWymbCl(fL<;)_FUZ#PTtVG34a- zl71xp2o_)!zm;*B!l;FgOy&8S%1=(sQq^tK@HvtRGLq63*o4mZXc1bs)qYXMFcz0< zU2XRYEeR`O<#s%wi(mJ)`~VFwprQgZfTR1+HQ(1@&G2);-Hzu0s!BT!Pvu_ZEt9Fl z0Fz2IN&3}L$9x6$^yoVGL{KN;&Lm(wv19mZ*}>G;Kj34dpRt!ZrJv($q&deul8-LO zbXJ}=aVE+o`-z6U^gMIONq4X4`VGjo;8ePMAtB#_R|&1C7d;z6NBYJj{Zyg&`6LF~ zF$#7tJ-ndrdz^SSVR89m;T+8(3J%b-++i)(&#CV*odJTi2NG$%YGhG6|>3MRHaMUAe-S6cGEa!Qbj=+QUBrVB|&mS?n%&El)=3zVn*roB$t%gP{h1QR zCSBW0g@oNfuJ$s5W z2S!dsnn}%}v%KFxxYer`d5|~bP5OF7(Msb6@uKu|Yp;qPi|g*q`cO81jkm(rVT(R~ zOci#!*keiDrm6g`V%l4(`fzfK&y8JIe`yJtn9pBadAtmIW?K4w^H;*!niwEbg-yvl zm`qS$lJUAx;->p{!g9hgkaKVplr?a^htBImJ2;-b;K{MpcKS#i#$eJ9_@Q2rJ6Jo5 zARNM_(>Nk>|Mc`8kaaD#Osr2WB{6N>7S~Gr@gPHyvO=(Sj#{C7Q*05St49ZU&fg6i zSQ}v%Q=!33(1E)ayN?egMN)VF*FC=^j`dboz7+*r%HY{*;+oXLv0E<0uN*CVGOT-k zDfrd3e-v%{GzYEZAAPz-%{OpIY{Z&A(HXZ}WT9~)sU7Wd&NvCZ9r55HlFv=Eeh%h! z@b@^q&&m^D2)N{9u`+e==iGCN9t2yY1|W_P3(#?(>FDQNW+9CWBa+S&2JV)1f9}s9 z(&zTVVtjh&*w@4YeS1!B*Uu5p&!M$I!Top@oRo>?0umi4s)CkCy7##HW=1-yYVLw| z=^{e20Yd!E2K*f5yjF0n-|6d;cc2prH7Pbr}J;Y9`K~Z z9gO;Rq_f1(M|eRS#gVE|g+3gZSGoih+m*k&l$p~l>*p)%&5ZVLIHL|N{QSPWdP8>` z-iGmlsqmiN@1^eTSl1c*nqw28J6#7&R=u`fNilwV+mDJ|aX-FHfszfwez!|(*cR;_K0U>&NN?d zzFszM3(QGcz>#VxD{+wjF{pK30`{R(23Z1 z0aHoZ%k@aD4HMBSBzX?T&mLuT^8z+V{@Y3XFwg~_8nYPMQGk2?lkBxJ>smBI@Pn`L zgHJY%gES7^vjg)aG78bdr{imxypx1)dj(70jvb`Go<7Y|enC6CDsq=kENAr=pY-b& z^dGaG)bJeh+ZV95fXsl5R5tCn4~X6em)||Sf;$+`?9v}^AExXduVMZ4>(zcjUf=td z19>R-vwTyb&dPKlac-`>e(fl|6dI!?eOlAdE$)%?s9}%hhtRP0qO=uZSUMoGSMdG! z`5qNh-CfR}HPLUgJ7TBHJ^>JEA&=xz=bq@r8u54U1IwQZ9Z?5x+3|bNSylB>v;PmJf^S>6;#gm zvp3>+R)9?F+RPGYT6{e(L-Mom;PHgPgwt^1 zKrL(3M1M0DkLScAz2SWN@YP|!KD*U#ow#TUOqv8z5>9Lo&>6lK#39V;V|mOfezz_5 z!Y~-|(cbNZF;vfy>6^iH_TltF!8E9oDwyT|t>A6lov#2cKxHlPp~)5T{M3;@nH*?S z3!)6cg*>MsPy`4VDg#9ha7@!1Fw`{Vt__kt3j6!%`2*}G85y`We%@C&&p>wn3Ma@o zm}uY_0-Ii+gJrb+N4p1*V}*0^g(HA`Ncs`}S~t;u^>=#d09&Xn5M1uL$5-9Bfoyco zWw?|iM2GNhW!{~B;4BJJACT2AT?;ln>E!;$fA!aBDmwW_;U z$U`tD0lCmyh9;U|sakuRzi1DieZovU^9*mrth4Wbgt>Y%9%6){hk*ZQmKq9`&V&DZ z+w&E)S!}1hqm!#>G{TA&IRXM5@#R_x)ei0w?3d@m@&8#{p^O_`AnBU21TdqB7z zuVQTf?j8%Y4jOofw#@8}_v%JgeS*TM=QlvZLCA;EfaY}?6KYv=S@Y9D`n-g-`3CpI zYFcwUFS7q-Juk9n&sPC`q|-1#SyDA5K}01tw~seCkqRf5GV>SDK@q^DgTyh@{#`#B z%BfuRKc)XC&|-c{uvqd{Sq#7`p9e)Jdr=O7?T2e^8;SUWUi8$+;Ti z*GD8t@dYp0W>OJ%7#e#vCn#Z)173w%rL1yR5N#BuV5G?S5%{+3~uEh%g_?E2Dm(vBOR(C;B?#R z!zZs#UZW+sIQv*(Z~wet`4k55Wpcnlr338eW*uTn#s6iIn@t~1o$R6a!jHt$c`znE z=f|B#1-I4xbB}x#oP7cBlw^UFd(1s&IzGoGH=o?Elkd*`{U^}ceLLw#h~Pk4PDpzl z&IBJYZl`39HR-$yajCVck;lmVFfqUML7tRXJqqwdj5uG_ zTS#7YCM)+%A*$P7l1%=tYVS|~{g;cVK);>ki!E#pjqFw!u`CV=cG^=0Dni zKh8TaB^vG1Tm5&?2@9R|IQI%nq|!X3j}2HdQS}ZtEoyEj1E>?}?JFx7=qon_0mEy~ z6m%g7MDDd@NYvNE$V$nUYJnq9nk?sJ^cm<$xx_MNGQ$959bpyXi#?{ddzaX5CPrOfHz_1S5 z=(5j}4{wmlDy*FBCH%hWo*$;!eukD^u(Y!vpX>|q$bT>hg;^Oc{Yye2W^KN{rr>RH zBUj1wcaUpZ;|Uug-dW`@_*U2(NP`6u(Gq*|rVcI33Mfi+;fkZT zsXMpksLXZr7!oKXgvWn>>t<%5CwifAODPvZFC7xqye1S#>2cuCz4j9#))t1B^@{{A8UMkc z@Is>sdnY!0Y@m}oVPQi>5p)K~2vXjjsy9myBz5`6=S(9f#QEF2m4 zR8(4KvwaMd3glg&_6``G-A#xr)qd!64*;;;KL|bSEv1D%A#DHOXhsQbZ?E=UyuC~0 zwEv7xau_X0Xq$I#Xpu*X|1Dat(L!o8obecjV}UrKh3`Lz0VGZFq}EYYe-<@vx_}<7 zbLrnwc`o?>#tt{ZSOfO(I@wQ$Wo%f_jNn}P_zlfHNyn~e8E=Bc0ZmMUdP{kmSKReY zOdrA>twaAylF`!Lv%&a0_GLZw4qC(&|7FA-QV&jgt9{UaoLo$BhZ^;lQ9iMR5Iebk z4FU*|xMmK8yBV} zN6Og7VmxBMO;XNz+o^9!?ItL|3}3yxLD6$>l5^ zhlTE6rvd0(gv2{t_vt0H(B<-eLkn%UcTl@L&f2+H_OGEOt~~D{;Lvn-RpR{ccC@=% z)`Vk!!V#)B^A9CSHrjW+>rBrLCqY63bq*Kw`X$i|)Bc zl0H2yn`hPvqUw7Ef0Gqx3MFBMvsd%wBNThr=VO2}; zR#&h31e*GcLmFo@{Z;Y78pNjHG7=V0{m{_@RwQfV6iw|w{nudTl^4wyrO{2NV0(ZY z#7uRt6!q(W4Ge^)HJStgA|q6&SwB$q;V{~mGBwX^1NnbbekPLxoYlFQ%}4~*{@nq_ z^X{dY)4L#sn!BQsKaOc9;RrY`{bdn2bwCT}Ra~l~J|q7L=OpF)UmVl^m9rsh*>q~% zq~4D3 z2k4T;*-1xrc%6z#^9&jyqu*w^pfRf`*o7c{Tjy0YDG z2wcIs<^#C@+#cw%dJuCs05J^;z*MuTUVa169O*!??$wUNn3gwX9t}^R^#trFHye8* zI1GAdIEiDLgI2is z;&;EqHWi`m>w>DPhUUm<{QkjB1$Dp#@Na^R0b2>p`+Ef-vlQp}_&jmcstwNjH3hm~)QIqtM@Ip#s7FdqYvB?Ef~v?)i!*ddvG~ zDd{uEu5Pv3WQwakG218=w zzpcR?jTCM^+5l909u3`#F7oA6dw4Gu9HD)SFFVE$oxm6x# z+qZwU2p*D-&<&cAQPxj z=w(SPN}4g6EM0ye@O5DR3&+M{-`Yz834=XkXjTJho~J+I850$q;j*aOjoS1KE?3TW z({=>f-aD@;Z1=A@oSnH=XPjw3yLx|D=DMzxM{a5cRI;EgfBXtHX)k#WcW)Jx?+Jdx z+K4Q)oy7RrN(bZ!On7Lqs(mIZn?1*#L$#Ctv_w`)`7({n3eB#}xGmppFXSH<(#w&h z5xBWIE%A9XM3*NVZ=}vWwkQn#E~wisR3griq|HfW%gbTgV#`$WylGIuDdi?Fcadc7HGX|Q8W@GT~+7{z!y z-F{lZ`h^TAf`B}U;Ro`oU1yff)F6BdOjA?KM&tTm*B`teZ z2IARWuCXTeB9{Y1R+09^!W-%d4AFA*Y&t5_3w5ndRC0xDFwH}K$nb>jjES^@NZOmi zsJ}Ww>RS*+F{N;IPdGsHq>y6K;Xf3`yr032n5xE?yXqnnPHuRL!y;T_OhF}gU{C-s zW#__hUgabSRq9e`!3ZfAbb!suEJS@wL6LD$B`gLup2-x7Z;AI7Cs=ap%ZoXW{E6Lo zTjQc@pQhHR7X%TNF>jCy9&y_3pd|reRfwRpGsQ1xE30b4S9bamUlmK0P!ZKXqkYqQ z7b{`*5B_vCN@d_e_F<%jQ>$7{RS8lJ$uKu$5Nkv-!ayk6^VFKGLI@ef8J+lvvlOe8 zwOu^Cfy|yao+o-DIK=ibVfFRV;CDP55z2-k9{NmJ?oqX`XUd!lC-^w=$!PJeIrQws zPp%xv?57XMM9OtV&`5`)U0u_Ul1!0+0TwUuWiQL1i;P~@?)ld3rfrg&y~MK}Ki<@_ z*vT+jaO@vMq;xYXLcJ~yqgCM#7?|`S;dw9NRnUkQJ#~+60pTYRqTR(FtBedr)Re}q z2?I$aDjX8GIiB!~Iaj`sU^RE}c6C;y@UeeVilve23`>EJG-VLSPzg3D-rr(KNdD2T zK5gjF^nf~SS6VN4aI&TFTj2H2LN6|lMb))b2t|;PWN`c85VpPt>rq&Q={nJdp3^o? zgLkm-4VhX*-L}EqKt)%YPZm=gr=DHsPyWfSv^{EqkBubX`Z-aqDSND}x1j(JO>ZfU zHAbu<5^eFCKn5&KEj(4KpUb^CrhKH{HjRrx>CuMUk3_6`jvLY8lLf88?{XLO>z z;}1TNEMKRAW?~t=^tg3QUd-RxMY$JOgbn2k-#+1ZkG1hq51n3RfY~5$nQ!_@4n6^@MsSw6I$RSseJ68>L%8Z zFsVkmTC!~O9(3U1W<^ctwroUf)Y&`p(ST`#B|)V=xi{S;!fTz6T&1}RBM!`yxD~2i zw7k0mmK=$VBf1&^LUZe>nYug=rZ;O*HbRYV;!=o;9wlDoZC?vq%nFM4B3uNTLQZ5l z5!i(tg}e_8zGIjnXcFG7O1w`x6;5|!pG>wZ*s3usP{-G7xpHj|HGj7NurvLon3q&y z;-VV$W%XsL;*+rHP+Wq2IH4R~FuQkpq_Gz9IftKA<4JbRgOCD2O$pW;xiZBu`GQD!T@URCFTu~uK=gUG`3;cW(cPJD6Ssc4^%`YY5F>gO5&9q(hCu|6+ z_c>8u>ArUAVt#UO#^W?<>rcZZH1x-Quyq?}`1YeN+Fl)d+uLbK_3G4aH|Y}ZWo2KL zfSSe!yW06Q1;ma64Az%AXLqTu$u(TP=g?teuR|!%12Tj*_Hfc?6N7}@>5}$7!3X&5!%UjDnxtOFR!%Ko}cZpTU*I==4#|?WB zF>gGm^m5m*zUS#m|(DLK!= zKI@tg+3g^m`L&5cd^<@VQO8_-4w&ExU19Y7EjXc}ZXgwr3(S_4t@MHw*mqhzd$9c* z#F%-W6LNTZYZ*}?8!O2egs=wZ{2aA6G9=QJYVFi)*d_6Ukkj=oPQymSuK^-r4<)aj zmqTI8v%%G$;u~@8_ri{{HLv*~26a(rP{{dEhJ2(o$yM;xu%cXA>d~knp|Gcmv3ZpS z3eJx()b$QtXp(pX#oy$4{hCxI{-Qc%u83K~iHPrFUwSH2r9OEryv$_!dhJacWeV%E zk`X-*jXrz0Q9DED8c`Ijh_@h)9Z3j`L-T|YqapA{CfsM7E4iyk9w()4z*T=~joI+Z zmN9#({)FZR-OFzs3ub^PhZn~X*$l>3thz}IFUDNR9Jro!uQXg+8MXb|#9T*~qp^I) zr<@t(<1D&@i%5BewP4z&i#$4qfw^MY3?-W7{PoL!5`Se7-nm)vCbwfFmdKFLZ;f4$ zlw*9f0R%BW_%f*tb)HT4}NP1X~capny=UBTr`9dl+@J7Lcn=PuLMFBm-%C&epR zZKcrL?`59MX-}VH0l}vfCP}Jhw00Do5zMRTnKwUL`X(Z-5;aFC)+OtNJQsil{`J_Y zX#_|>+>Os*1eg`00WB?iBcjwsDD;-l(i}zCX>3N6*hEoP_0)*lrrPv^jd9+6I;6V} z3Y*G^NL1;b0K5i?tEgZGQNuJB$sTeu;#V*oMR|)y$NdlLyI3NQ{?SNJZ$jtA<4zC~ z#xt6#wA-Ioe;-NM>8LIB^YtBGs24-&(3m&Zp!F>0`TcTAQaj;8iEFBQvzWAQ>d zbSW;n<__tJ3N^LeJjMMT@^8JE^G|hOFV6C}SOq8Mq&`(CmMV&4_$iOAbVBE84Y`)H zOsx9P{!zzqavGZDE!;V2p#8}B+LyjBu!VVJNOJ-HAr-p4Tw40(G5ux7iG#h58m#mHRL{JD%LbOuS+@L5znKk!Mk5?_KT^S=<>#)z+zE(^y{gJ@ z7axMH;s(9TAD`ZHV63ceao0f_lw`lNe{855#DvGQgy&&ZDGV`?y0dOLwxAj(UK*80 zFpohL58)9JXnJLZYikjXD_YB?)a(hZw$SQdS&g9+p$_9g3lX3?WN0T~C`yKnvx&s0 zwUglAC822m-|+6v(j)@YbrjBg#QWRZt#2c( zF#o9em-?Gx%6`g;h<*4pr9|X%efY{XeDM>?vV8=Nk%EtaCvvf}mre6Er>?XksS%Yx z@#AH@)?q}IK&e;j_XxOt#3DSL#zqhH#-z%QIB4jL1a{rW0WtXl7!=PZ!vkkmo;nfM z=H`NxxSp5POy8Z-$95-g;CtW+1knODzob`?a14E84Rc{F#3-D>Q<&+dWQ<2tKD@z1 ziMcTh3+^TjL@V=zp4JKw1`ap`-eT9)NK8y;+waJ?jv{^EC6~=m8Zsg-XnK>FcuYq5 zk$-gbk9ksCxXe%hugA?#cF1z$Gd?jPn0uI#DxEt2wCoqcw(*Ez?u6pQ!qbmO5F{o< z_adrFPA;Dj`cdshwZ&}LZ^tdVRWR;UuzF$E^mT@WJbc z+8Ae9B`d&OyX>)#@9_S$k-ss z-_P1I$GC}Ln{)qcDRG97kMsrQFpQ2vc=VD#4ZWvldE0lXWxtEazy(4c^bB*dJFcMR z5y}26q>2%w^h=X`x3!V4wr&l%VG9}=Csbe!i`oZ)*GFZbDxfC^VTOn>)Sj1UNtL}r)o2bv=${=dYt{g+s<9kzwp~@f- zV6ycoNpo*pURD;)`4Kx-|Esi`tWXd^i0y=ZKSqzu*?9q|$fm0{PK#0%G2=wu2|he* zH5{089LZe1yKJMi<4F_Cl0o{j64hUt!y`+Sk3Lp(lrHf8R&`L>A(eC8i~W*K6NVn= zhX^T>aijk+3aU?>SYvTbiCTLChtV7B(x)y`m7hsr5E51xld7Z5Jq(vtqzJs=Z2<<~ zhN!R=qfq)>RCdtN2lj|Un3opNkdrWm+>kD0q-rMY^Vk*T^wH0`y`lxGPp6mK7W)}M zJt!#na@u}jxZdjH5J6mUnfRhP{ftEKOTkkI;@08o+8cBNPNDP}%@GN`-umB|s2vrB zSW{ogx?-|_6JJh^%jZ9CtF6SaBybQNG^p}9Vw*WQago1{dWK=C(YHFz7OB)+uO@flgU8hQIL^)^r`+z0E^D$)_l3EZ^Kvw zz9_AO-;by;c&@BU5b}Bj&++INplc@PzJLL2q9(Uu{+<|3e!`+xKs-6#6HIH6i<^3E z0%U}`eY?_ztW|A9HVGH~w-(o;`g_8(R!HY0nFsIm$sOb!nV01BYjNDohQ$=}IwW0F zGyM70`^}@SQ;&c7-E&*{d3|y61{>$)4X&A3I*+H8lQ`=H7HTn4TzN|)w|}5co$06h zImmHeq_{B45mc;l%^<`o_=i(>8&m3@i9oL_QmPPwqTUy}#4xZfdpu5$U6-fZEIsZf zCv$-ZUctjjUf)Ntay;N(@b$T&RQ&lnT3tO>g;pGfq!wvIm5Qo=FoM_vE~ah!sC)|= zHr;>w9d)X->2p?NSiW|QxCn!h50d9MI1A@{Ub^)_+V$bgUiusQQ;TSGnE`gkf&3Ng zc=RdQQogX<`4T%rR^5uP7g>r$k|Iu$%q@%-QO8moH;>3tR^?7-YFk^_z26}!=FE)9 zLXZinVk{JvsIx0)mHh&2fE#;Fd1qlfBYl5qYZ-dvnnQ;STjhNEfoj-81^BB>O)->= z7-Rqd4Y8wRSi$3g=mUvS*|CuUj)#P%nK-Jjv2n#MP8Q?1=3trn^Y??Cb?2Nv1HES` z)ZK=YP6hwXvsDxx_Qh(EEz=C9Ah+YEtBt#378|Kd*0Gm^Z0Q5tPLT`VA!WugZ>RtEqLmC!r?TBW~p{D=A5cex6v!70bgZ_Q@IlZ~! z7qlAgA`O6~S@7vPl=vqNWu}RN)=&me<^?t!q3|8*N(@^E61M253Ty|3jAQNPdN?wS(@IVG z9^A=6omn5=eS12v0v9xM=KRU$)z!b7@Rs5I8mq;k-~B4;?uVy2`Cq1;c7phroCc0F z=iuPxx0#r5hW)$Aq!;fVXAYj3sc5dAv`p8dA2<%(7LtBtzCF!f!O$%@8Q2Ws6L9x! z=6AqfJ?V7kVb#X&J#N1JC$smL{9KUoapv@y87@;#(UwWS^Uc?Ol^KhF23!IVmN3Wt zcMVbM>=(s=3BA4W*@m-16rT>SmoN_AYVynVN57Nv)0nobo0?Gbran6Z4XwS0Zs9_c z9#603;QyL`yUp8>FZIhw#5*7j!F@!w&>oy&L|e+hH1nrdJG_pQ?M2nV=KNFHg9n%# z&MSAz;SA0AOzVGIJWM@NlUKZ{3)%!o8Z`WRb}+{RrUzV3kKQv7gl25J4tQ*Q$yN0~ zU2Txu4SKX8@$zuN`ZwEI^im`XUrpO`Pts*Rv(A@(r>j+GCyaipJ9iMxRVQs9e;Z2l z?USu%x#wg*ti5lO6tQuKQKX>JVaG^5&l>^FclKm3(sSWyY7-DpPYrU=gJnaCq$}>v z!*nMk<(l**Br>ZS_kP=V_QEE-)Hxy}TnPr{r0VC#Ii&%yB6J+UM1*6@%HN=ioth%K zR{i`5~igWM531ZB=U#FHUw4S)`UWx#x)!( zB)BmxTLL$p``}t#Gl|JCs1y9QO{=B7G@o>4mp-rBMduX&%jm%`E%{y}yX>?3C(i%= zMFDm(ar|q4$N%1X{(>lY)ql1+OC9dace5#fx~M2?G?qfn<@{r#@+)&}eCX>7hU?E* zuIbP4`-_d6i8V@3>GsN_rxpqFYMpY@{;QsBE9Qo3Sr@rce3S^OazE0w2) zf!NoI)qEltZ=?M+1U?FyHiYaa6=H3;|hdmeT?vgiU34XNu0d(vuJa9h8M=@z-BY*`Vy| z?<^EAjC*FxR$pZgr4JdeqB z9k3aUG{J^q|gH&ke zluc?G8A8P84QdXd0ieY;D|?0bjtTHTVb$UKQ+}Q^5b^u@9C>7+R8+~nqd5Rh0V@&C zcmRQzZ&;my%{S{Wf@BbGr3dxceA~}rNRP>8c}596J|-HaSPeR1iS}`F%YAvB+(*a+ z#a*=Oy;)pyd2I6ih>B4I7OCPQ3rb}T@UJj!JtF(Nde=1?Hw?z%GO9w~9r(zmiRnd# z7zN$6SKSIccIIu(RRYd#JS&XHE7CPhL$ex8qg!Mi5VXSNl9UdKe!9}v!hA*`xOP=x z{X?9@qGBCo*;AFexalg?l?pY9H&6!jyb#GCHA-q2E<(J!$gS&7D(B}pj55Aa(I^oV zNF(cn6+9(o??k3X58NlIpR%2|QL-Ie*ojYa#CAYMAQB5l!km;`;H|GL6hGKW2s*iH zQr~$cb0uYeV`tpxk#P{;6LeIMF($ye=52~$LQ2R(xDXZv)v`-q2MM`D8Pu>TnR1Ua zPp;}Hh|doAue4_d{)16IoKQj_+M#TjVke_)p_hu38ke|Dm}n=T2bsDWcQbWte)K!q z6%|u5`7s_LiX5*dyj(0CEe0tJNBnE;uiF9V5L{cjRwF)N9j}z zg|+3tykHnr!ewfy;2GkU3zxinxgKmNEYq7Sp z!@xio*Hx=W`%4Tfeea9eUFmATmd^Usfd%j~CT@h;to8A&E+ItQ>0 z5KQrWwSJm+7@XJhAt{W|#QA539jp2CJ2o8+{A-bZTpy-$)bz)IWdMN#xyMCBsN82&6y-~6(1^i<^bU(q}-;$HWasb^?1%+GuVK>+wfbvNY~#>bxto2 ze+~#*TdsDz6QeU%hElhy4%lDvom`|p%oEwFj;QAN_50Bk>DX|$`8pmEon}=@0#UE7 z#>I&p2KMxlCNEP*x{9vGW{KLdTAH;Tr{5Dw<5aqO7Q??gb&Yb$D?l5uFQhzm2|iNr zu!GPHK946F(+v${_wFao5eQo_)+lsL3IW7YPokcX}((NDccANJRAOPJ>Sf|>Tp*w<nCAiRfFcl3LUd9!?ZVHt~5wz>I@md%Eh29QIoH#>8tW420i@pU4eAd0D5W z@%Q4tfCTJ(8eNOx_!k90QGzyrD~R)aaCcYXKNzaq_HDVL#yBfYdg-5kX}@?clKxU` z!pQxR`Q^UXvHtt34YJp_%`Sb~&P#r1oLkPT8{xub!$PD`=D*WX(_;`t`Ps6WV|h_q z9FN#qs$c%jHQl#zCCOc)Lxw`1dMs%kY8zcnc=Gkl3llM6DS}Yh)^=_=Rr{z*TDNd< z8sfA&4MKTwNv_c??28^(d{SyaIG1npUe%gpWEPfckzonIVD+{njM{2VSR;I@z(^jn zVN@A&!D^Chz7b*WvO&0;(;A}klE&NUQ)R+K;QyR)bF;}@`aKmojsA1(uPJS&l)7eS z9#8B&lvd;@6Wzt@)^v`V8 zel_h!#{Jbdseon_KR8(DmXMa=eexGH3T8YHDP`waWHT{_G<6JRo|NH+gv9@M*h=Lx{*CQ9+XQ2Pu)bY|2*5bsT3y?22`X z^$NApjyP15(jH$IN?D~WY+W3T7f|wf=4HPY-tV+OoChOP9Lw;=5X{`*dY6O4()eF9 zxC`A!HM1KEu~GA2M8K3Ifwf?(o5y!>XhY^@?(ZclQ2*4-+vT!J`y;e+VU7~g+x+6%q_sNGX#*B@9lTf*0{b{rtg8{pqeAVde)|UXHalXoX1qq$Hg16hd z@%6ITHL9=-yOUqU2vAzw$-bp0SHZtv#!RVf`C#V7Q?nQE=5T4`1h9%*Fx+gS=r9L8 z-fC;zHv7SUsg{C}lI^maOxNoTJ_W4Lefr0*ytFR&T8r)(C%6{|Cd6 ze~vmyQsWD0(NNVRiVCxloK}uXrUpWrdM7Hu528!KA+MKo!@dG_VrI1sQ&4p{7M|Gb z;x{O?OUVEH2P4gxk|I-h22aIl<+^!p-z4F*>BCbzLGHw$;)cHdeKi-&zONV`1)m`d zat7z`aeL(3Mn2z+jTl$IZ_O>34w=<8zA4;Pd4i&(cFcm5b6^_6?&cT4@-P)@SFQ<5&bl0muVFX=I79gh*CCI8{VegCKd}9i^5v@fTv!O z%^+}5SSr%)sW*ZxMzZhPRW1jjla|pf9THux#Xo|3E$R_@>WYL&?fYdsiFtJl>$ZPr zg6*7nLhltTJY$O%9D0X^Uz2>J=WGUdc8HSa-o4j!P|K#|ccP@)5m0#BpaoZSnlN#e z-3Lod*Ho79(bKHhB!W+k?b#PfEke0Roo_4Mh$bL)wlI3<@ZoxwFDdT3gXeZ*F}8jZ zyswV3HKJNHlH-Z3<+9RmalO0XFhs)m;|?u8d&^+;nYU+rxu9lJ=Kmq>E5NGiwzUZf zLBOC}kWQ6O1p%eILqKxV-6<^~l5Vzz1Vp;Sf9~)5&N=tod+zb)Dk)Syp2s~cE z?eK0^^SNKBWT`|-WMJ0f0REy~2lZMvTfS50suNp8P)O%KV5pq;rOUFf~%Rz=%F-?ub69S+@ZiQNR1hzU<^+&M9o^I4GPv)xxRO-kh zSAN3h4hG4@Wwo^mZa1rxQ58k0*Yg6PACs=t(~=Xa>|5UqZ?8x34;eCLUdEU4W7`C6 z#En!=YKE$#^!zHtIg$LKJ0fAPyI91!sF!wX;z!}Z4BwJW)4h~B*HT2X-SRfDKT8coaUE*)F5iQI5|uG4?(5$3THc8x77gqgHM*27v82iuCF3-tYblX; z;;dzjNe49MMoUyo)w3v=&sMXaiOG1b$TsG(sk8P0+@`8u&}tOg7G4u}gs|0|=r5Wlsld@J;cxbG`9&p6G0 zRF<~UN6g6a*L|^3Pwa7!Mt=J;ckViEA2rO{1jqW#n&m5_v0jPo#Xx!3aUa?gHGx?F zq49c;cVdUr(-97@apO;R<0Gu>!_CeUo5gmFIW*gW=mnay7S(p<8phRLxsT(ZPoH+( zEAk_JBT>=y#cil9DffjESNV|goJB4fyB>~CryzXSiQcH|3${2))3dtOb9Q zqA94{xS~eyqgAbPX>OVu@SKx4JxVy7=hUaum!Y92=6*G9(oR8-Zix_A@<-VMN0I)6 z%HYnrR$`68HnJV>1@7CTfER{S+hC8w%nI9=dywUf4aUI;#EM|m&y;~cib z$64D`@%aRp9_OqHG>+s^&2ROb6;a@m)I)c}(|mVvK0mXj_jg&RzzF{kRr94bO+}&d zHJ!h10*SF6^FIG7%H~&@2j6(G3h|YQ=VoX&>J2lq@?gt$^_c^iCkmdupIO9>I;Dw_ za_363*^b=j%{10W9*t&}mPimXm!aI7$)Z&(C(yhbHvR16o@QNLBT9FbCVIbPut-Mu zw7RocX;Ep}J#SfQE+KslT-pA+#wzz?S2H42xj0mil@BNJncykM{3f5S ztDL=*)Yi>T=%N3@RsI|WF(7)l^YWVj(gz6YlPA2348whQeOZFhA~>e1<$3hOKRCBA zSuly)#+1zU>OjsHPypC~XF?(KI`fIx@>ECnM#p0_4XU$j{!Iano#`YQ3Q#WHDL7{WQXt1l2{mQhMA{6-q#G7Fu11?zM z+YE0xhQLV1HzWtl>rW%w9-#bk?kni^-om}lo_ps+%tYM+Cm_fy)XUGIK$+q$wKB}LJ8haVO=Q=8#bL(4C(ru^Ul1iS^5~Kh;iwa9>65Iu@|2tQ>dw>vq^fwZrBIQ=FdNkHTmFZRPR_E6U=AztDZ`ma-!G6uBAY)2w>yUh)!uIIJHZ^dqKlA zjp&J;Ok*Eu1G3b^2ut}F`8}CVgj*0_17~t(o9*r4#RjN3(`Y7xU;`?DO^F)#Rl#Eh ziaRks(7|muuj5t?Ru16QzH2!lf|Bg)ZvU)Y(_bKp2FfI(8qt%A_2RODE#)%aPq($F zD{9FD20B-5rB)}T4p)O*P8T;ek7u8s#UBp!ABUFKtztNjEK>YJ^J={Hy;IsCJqfC- zQj*WEHiys0i!;`U60xp5Zx$G>j!F#X&+Vi?XV@m3)moQUvZUV_ z8~!TWL%W^{x%NomVBuMO?& z!x6X+Nzqwae3W9g(RW{u{+$n=w@Tx#o|~KeY`p_Z^PXYTBhNnX{M?HAW~8MNZF@)f zEN<`g3|@3}7`OPVOcs87rCQ^dxL0PNFYz}1eKk))qtKl7#M$sVM6-2oTBJXJVqy_W z-nu!dp??;QTaBDz7BJU%fH11sSZb3VMwG7kXzoQJDI%{E=nq)sR+W>1coN!!r8bRY zZugW`ZX-v;{Ca_KC$sB~zPy|r^vzb4o3{f!iCqFT`W8CrWS9@6X$T;&iWzXLheya#9>Hg%w_RoD;Y zGY=$tlCqWyj+8$@Us6z)Q-ia7My9B)sl7rMTF%0!o4x6&1kbisq>04W+cqwQFqs*l z3;d5Os~kO_Zl$5bP3Q3FFDO7QfFCCIieZuiVBa1NbfNt8Aywn90LpaQuKD*LJTYvxU$QOxN%d;&s zOrsi3ovC(2T0QXfE<5}K`90i^Oe#`|p_!7gOc?&*xyd7*V}McAss3ePBK`7n4oH?jmyx>IA0?bG8TR;;)^En8eqf24aLg1=3i%Ll+w6O$4 z&uzd(AIU6Qy<-t^d>qlO!N+I^-$g02!Rza4ASfd@drmUA00cyU;`$iN@f!&figR1Y zCERkLEa2iN#N2^%&G7KmGfO+J#rG zSqyh-9b0h|e5DVZY#}&eI@?*a0)y>oXWysul&I$1MKY=$`8OB^73Pr1u{3ro!f5ySkc(n~*QLr@rF4`sBW zKDVp$(*}ki&!YxG7IUj+Fqt|sz90QYT0whLg`D4qE3vb;M^qw>;fv}O5klKG;R&vB zC1;sU!%++O10S(fGYAHI^JtWl<=^D&0b}TYB*)-GN;$gb2KZZW4`3MoxQA7d*KeJK zWW;vcJASy02*L#+Hbm(foiJRD;99)a-F=5e%iPh-qF(!J9TwP@|7MaRX4>F__|NDJ znH`PU*B_tS%<5hWNV2#Z&x=UCF5rS zg;o4GnOSGc0IOdhRD4|S?LhCU*;0PN7fO==hGGTuX+kV)(bSXHeY8@82M~_)3+n^k zisGfl-$-`Susr5DfzksjP^}TD6I_cLgGePEH9b-W9#N*V8}M?7#c5Fy@r@I0F22)oW$SY zTS+4-r9jn8SGJK-Ipa*+zjc6`l!qtqC6~g%CK3OT6Nh}$g)SzFBe(06Q0h~IH!kz( z-nq?mCLhFFYq}gyb#Fk!1y4%<(x_47Fl;g_M$#y$i0kvqiGs?^xwT56n?3;mCoCR zSw-#VcWB@{#_`YR53BXedaN3Ux5^XD4VNx)%!*cCCjQgU`I?}p-^TcPD* zlm{y&ew?2D=acjejUn|ddbStbzmbdzvT|H*x=0gugPhjRKmC!c`NIqYU97XCHV_9+ z71aTA4D1>r1vP|=&W4T1nnokHDTkRikk>iL;aTMDwU^cI3JL*2wliawpFVEw03yc( z>nQj368hNo!w!_svEgjgw)KBAsrreJC+MlZgi&!kEo;FzUT&^3BakY|WIF0D>XYVS zcFX;qQsD~cG_$ntmPPoJ2L)Z?&xh*3#M$`s!Og zVf`o(c6E}{a+c~2=aqvj%RJoPkYvut1?vYGNw=cTP5=~J!SMX)t-vva%LNc(t`XRp z5L&L(RbYtVDIm$7d1U|h1v1}p_(-P%AARBz)f3=*+05TM(br-Sl>={5q|TC$W6ml8 zY{u7x;Zr3puI7<~bK(l}_&DW$Q8gDdPT5!w& z8My{soX}|l30PoDu6%&wJcqcskb|cHc_}5;-v8NItVK)cmf*(;T)k<}t6eoC(=~0gYbn-LJWE=9q&k-H9ZcN zmN0%n?~2tb`YbcoRV~PIASbJIP`rRv#stQx?(Fk=u`6K1d`fHk`&0aE)p$dg?SKrN zPh6sJdi(&s?ks$H>4hhI!;s-E+Ud{w?nm9J^?nj|9>LdO$y^xnw(IeLl|@`w%>2Rm z$fdV3^H_lcQI7iKOwe8lXQMM}l|k$rSnTmV6u-tYq$~^Nqxmur?l%G5DL(p`mdy>- zY4hEErP92X%>kKpmzQ|tNu}0w)t8Og;gUPmA&((n+xkd|EqGhI50?w_S%0YvXRIq` zKCn4@llNE}TPECpxc_hpURa!;)yhlvKzf2tSz_Dq$hZf_#7#9? zb8F=ioHgwP2;}crtiXZeSa3=KAdZR)?gH)W!$k)-1Ei&-!xNvFmDniKE4;z#7y{S@ zftor}m&#gk7~C^=0q0hIcGHB48#AVJo?2ZcP^r^~kG{Z98#KBK#LNI11OVy+Yz9A} z%_7i(t5eH{-Qq%J@Sdr*cpxZ3YcIvhyCpW&$3vw&Et;+P0ewx(+SSCtZzQ}4QQH8_ zCv2LPZ06lWly6Mp9yrIcLH)yL(40O<3{1zcxWnfh!iTYp1I92UXtfij^mb%fM8d||Q*_)4h{Hg@$;9wa|l%gEmj}-;t5)Brg#!wkaQT(M9hhY{;`x4S81ST6P z@Az=H3b62zU8ij^{xW7x^RIeRci^H53!|o0P~6^7t*N$)tSM^*$kc%W@Dmfl>oE)< zbN3%{ia&rtT^D(^SRHdiHl*@LhzR8XvUlYs+>{S6kA>%uEg^b1bOD4WQGvC0%6S8E zn?Mx~2)yI+mQWdKDm(;4qLcTn{MG~f`JXU4=v386S6s}UHin0C>3p4a+$-z<8cFi{ z(09edYmP!08A94Oe*TCU>GCD=@)NI^_Z-(x>-P7uM| zuQNX2h)vZT=KZQNOx#8izSo#y=*Ol4)r2gurReF0L{Esm`9Y z5jzope{-Z<8CdSl%MZUy3r{xzAb4c=)>k!}OFd33Z+jV30+5{oM{|cQCW1dkU9;fZz?TMX70t}o(#%5=fF0&ya%r0T zz)hr*fvoyU#U`l^x0p@Q!K7%5$nq9!9F;{qSoDqT$SW@toh8FhR(rHam1)pN-f|5| zSI1DFKlZt=f`Zfb(-|V_u`x79a=xXMED|(6G*Ld(YO29EP!xir3PIuL-~V!RY1o{W zGU^hE9%{yV?o#t(Iwf|Tez<`Qx)w;yJ@zV_wc~<9{_-Zr{E$d{7V5EwnU0umXSs7r z#$uHH-*PkZV~tiTn9}vbwm1@ChCM>0o~<^NIhSslhc9>Jrbk}Cs-956rf^`VcwRu~ z5(Gj10P~j;l&kMHr~hatNR>_^{QPv^VN%+{DE{yzy=TCy?J68%voB=1$qoY^?=-n3 z_$Jq*J)bQ^GSUZ&-L*HFC~<9CXnz#^k?u~-UJmtZ)9_=+o-ez|=Szhbm%i0mZPu?Q z&#uG``?qy8ERVf#$deXbB&4L!AVmR_(io1v(gC@Fpt$5;+i`+$$zH^w4=)x}4afn{ z+le%L1!j2Xn?-X^5FWC5gMEk4OvWADs`C;NY%w8vF%)zS0BEQdkO|-aguy`k!`*_e zohKYUzdJ|P11BvuQ-~eunP!rntNbJuLf5EJhPLKJJ^3NRbRb=>@zrVruytUA91LKf z14Ba8WAWo9DfAR{yI_q4I!#D|lt(hubWsVWAMZ3BO+9|L_zsQiKJqITLjJ~(uYTcv zWy+<_8mFjk{3M|n%I&fVxD=9OgLn4Z{DW+i!z=u-60ukkU@+I9yfJ)!{bCLGvd>>h zRO`#PpS&+I7WnK!pf{!FW1Ih%8@qmNsKJqz7TB+z7;(5G z&bEZnCAe6HZqW^1T0Sj5V@@^=T{Mb^!PieejI@TMpQh@!lmjk3D6?rT@a>fD!*LB{ zn@@EDqF%RDyT=Ue7|W70(~69l{3M&q=m`W5lWB41?h#MwM@5=e7zI11xPPl^`L3N7 z2#td99?~Su4Z#A%$)~NkhRGRlznw5gbvLhSZPVha@!QH`Yj*jFyJj+p1tCl7zLejx zxu|r4c&PIxWJtJDhiT@rHWTGosbyjoDz|6Mf0%N%Jj^U@{@~5+I@0#HX^ujx;>VK6 zGfn5P6CNhaLn=$%>2>7HoIpdf?$^k#_0g6@HE~c=34?Jy5p?15QDYwK8y|8tRw&I1 zG7Qg4*r*panHM z(FVeo=Y0UN`t=9$aZJ|I#(0gbVNP?>?0lM^JgyKJO4i`1Y5qo(!m3o~gvIdK#Y3V& zh0b~)@AEDmE0@EdeZ3C%CVC^J29j(47v_LHhm?)8+1Hk+QZV!DmWleJXeRgPr2zE2 z3aC6Qoaly|jo4Pe;&CpU#)4D`bip|_vu(%*8(_}7$}05}JGjet1p5K#n(oAzyKXJ9 zz;qMjJ05^?D1`L}DE`1f&PHI7@-;x8{Cp5E@?7mbl^0egv+I>4jr%FnoNH-s;$~U2 z2PPu*KZh36n7MPan%iTMC+vze;d6(7vr*4y&UV}!HjoVU#yGluPZ2KVdrtZJ$~S7a znMk!W*DI|xaQV_~OBi+Qmei&P>^faJ{Ec+>GJYRf`(AHp)zM+-F<)*^X4^(?7uo<= zFj9#S{EdF8rNr-|>x5(-AUn4a!qTQ^tIw`Wz(UYwLD~?|-AnW(ST^44UcDs*bd3WH z!2X5k>4=zb7?KkEkW{=-F`V2&^{%)FSBq)o@Q*V8liQGp8D}AE^9KIi`6RE68&8ea z6bEHv8-3*y@<>R^k?V-gU9WFG8r#opocFj@c8+&<_bqBJtxHi}ScLx;z|)TD5yW{s1znq1lakz1>L2|PAMn%0Pl8yiQ>VkKIWG}c9@o}!zhZsH{wtZVoRrd!EVFWa7PD;u z`p;bkEZ41$Stov$A|FQyFzB@Y@x*L{wL@Y?CvwU%bAHgz7bko(6#s&NkiKV4Y6U>k z>FIYWv(A*gb<6r0NB;G;52d^#K}t1+dN0GaqZY@2$bI$Z7Q0>%-ZrJ>m*2wQVWULA zHC_|D*lblokAm`wl&%o|^HP}4+_iG`uL(3nzfY0f zx-Gzaqk8Jz$uBgfR;dr5VIDej6Y1pgdy+yZ;Cqd|_B|e~(SDWcuMSVt0CV3`!WM+| z&$3TR1Ep(MU>C)9V)lCs>H=!@7=DetNOSeUH3bCO=P9w|HzjRU>cJTcT)KuKj`YC zPhGw!OFZA(TPb^ z*ID=LQiM)9$j!Z7uT^=t42@Y@O#Y4ZK}SFHv7D70hE^_=xP^x&ETZUOBg_aYjtGxg zh`8uJsHd?-*&h2=Yxv#U)kT!IN%IQ(K8zeO=*o7SKKQ>MV6k!d_fP((pIgL=7_U9x z#Id{J#Jv7S2a52*Bsa@emFjoS<7_-`>FIfoZ~Fh$#oWi%7Fd0jl~7&150UOk)8yZM z+W)t2{rzV&81DVc8|dhSu(^BHE-T@1%TSOZ{?OmQ^0(ih);s=}$7wRj{YbBe72mP@ zuithipi^;7x|R7HP}T<;!kKMK`QoEdvzycl|6o*HmBVB-0I{emdDN+r96qha9ji4b zbVpm(5Re3DjK{RORyW0a;8fwK?H7+hO_|s(Rcu(>K0fWtsdTqfy6=3uyK_n!s4}B` z2yv^7$pGClpdo_>wl*)qk}_)1`dE=VzPqc4LGP zG%Ve#?)DEa$ShHs9C1T43|%+VTXIH0sm8eZ>MUY;{om7%$bR+MjycJJh*r` ztgaquc7Yb(h>|W3x)p^GHQj^F?XxnEp|nq4^bZ{`b4BXO3{75{CI$gP<%;ysZzQR! z7ql^{23%#kH`2FDlmEsGbwAl=xkGF13CoqQ^1t`OzNOIYdH}PIsG;+<-PSn0&HeKw zWAqNCeTmhy@cKU;M*OcO%J$MD#q$4hWn2+orrizZFXL}o3;*!~PJ4!m(X`jjfh#Gj z_@n>7+zC>F^|Zx5&j0J%(Tv&~>mVBf=|si4@K`XvIvdu*pWvdXqpo_|EzVkA2dV)k)czZRF1A+V!2NtA#nNR5bsc;Hn zJ_XMAJGj*|aKZniJu82lD|ap41L}R~gfu|H1U{Qo=wwaWR-$Ig21y&$JPJA+7B&pi zpoxYKY=1x()ZQbSDHsKpV@+_P+1WV@>@CuK+`#JrS%YRtrvGPW12tI4+ z=%Y-6GG&4$Y2m9qF211UB+^n6ir0*InA&7rC7jc)+v$flW@EQyfUC+9X{C~?yrvAi zC9V0UDrJqXP}MgqoD_j?l;sGrov-HRX@Z*`?6$YFFM1KV=u%LeJIKBMu~EmO3hKtA z#UN6=a0nPPWKdB|ZaYsdAxsXS)4f2~U!Ii1RA52wuJa4&#;iZiJ39d0d^{M`sqgp* z=|tT%vgOXo7F8h`|AcwT zls8SS&T0bPRJUb}yB=$Ows=rv9W^7*qfZvkf!Sil2R}>o$-G%S5v>FClwA~hzlNwE z5m>u?wTImmnn-S^^b?>EB4KC+Sj` zpSl)8^ZT1dqO)gj(cYS_U;IYuY9H8hbF?RIUgf(GdLR@Sz^}4SP-?|zQi_HHJY7fd z!Pt;QQ~A<6j|YDMZfWLZ+9OZ}LKrk3&}id514h$Oa%5@IP=0S3sPDCjEc)6{T7|Tm zGz^fx4%uQVlF1=P))==EjO-(1FL!!?wt;N|JKHGL)MHT3UU!5=K7!6(3CRA7QDv*Q zr%Vb}cdWuyQ@FN$?Sb+wmqUhW+wf6*fK#3c3MT3gQ%`Rt=MnL<}lng4tJ4Fd}qMz`LmF-+r*Nz zc0dwhRgK9HTEJ(uABm3N*X_%7_Scj@za07T=A)j zi}RP2l0n4t%ARq`&{R91FOmO!ZaWcL7U*8}9 z#30f8#&=@rDYi7&UFJGpVO_wNY2rdYz2E6pCI2v0H13}cJ`m&i@BZsQoWGBWlp%-( zjN{x*$a+-r{0Y{NO&rppp81yB@dLGGZABF@8FgU5OkqV@7#C}S$H7kn*TCjA#_1G zZr+=wluuhIb(JxXVIk zUzNT3q2*XgMEn`Zl}GOQgj|<;Y08V6?N)Kv?5Fga9cBMvYY^7$MR*xngApTyaMpO@ zVOEIH-7?X#Zmpusj^Q}asqZM0opQrmF@4=#bVJ;lIsCW3H=-Cs)*;M z=z7k5zHkg`F4RxIQjX)pTQ3BJ(~tMJuc+c$9hbHtXI1X#bmLD!&eQo*5{4V*8aepm zuqMzLr&~kw#~xutceQJ@ctAC%@JIq6pHs(1=)I2(Q4kmOH3&XGu}Q(N+bzv^ubQZI zju46F6(0RDkdg$+_8mL;!LnsNtXHQaf&Q?}V*w~N66p6QJVEQ0Q1#aCxDYP~`DTwU zn_iW4Cp9hn4UZpNaaRP=A zfgyIM z{kP%FrY#f{BAwX10`3$Hr$a;9bCX^2(j1WN2VBW280qU?AgKX!KzV>2VA=DEdCJWv zJ5B2a(~d_EegOYCpZH)abi8)CK+p2YR5p5Y$D+Y;wZtXmt)gycvyWNTh(+3jaGs~^ z>F3?&bAS8D=Eu`I`A<8?nKLXp>E@dZW_Tn`9_3N`ZF zxa=+Va<;_v_J9hF1MW?As4iB(8Ld#CJ)*Am9LJA`QY~vbnIt06NXYo>CcNHb5*e%2 z>l)}CuRDlyLUG$^ojG0y~tF0FVHgYR)0RiXnAS6)OjnU+THWwdr-p*dThE_hC zT{$9H2tgHCAZ(ktDq9o*Z3FwOmsz)0j_<;_Ty7TeU>D1ynJYf#@0|J6A!Yuoa_8Qy zwv<)R1U^o9?myQ_qf3|s6uPS}AY%w2VeUnMa>wCq0(K!D*C+k^0HiVH^9zT`x&L5^ zv*ffnEt=Q>Yp(IJw(N=`$jIEc5t{Jmlk;_l04e>5eySVT;7eSyW`Hs&9-n_X6Rxb| zjl0A+P2fx7g9!;`41hgVTzbdtqO$yKy#PsH@1i5o>lTTWbc>1Wp;rCjRaYse^rGj5 z{QRx1$4K_AI+j4j`oyaae$K;E#rwr)BO|wo^|qKwE#-A1P120+J>!vT@>Q?Ll4?tv zPz%G4L2F?7z<_M+@CKlTZP(DOGQdK&vva$fGpO3of^E4+L9vQp`4FpqCDX=x93n^2 z>KeG?V>IxKnh~c-K>i3sQdLb$23Vj}DNtUCNv`RQku7?x?WqHBVIX<7AYZo%gqUA< z{^Xki-^;Wfnz+Cz0oaw{MzsFlco{nsw|2YG%6TKU zRn7u-EolWiKK#GG*p0LI%H{rhSNd<<3~Qjc(&TR>%QC~H^|Pk>!u;)L5$nsKo*uYK z0*Czp#o{vTAyqXvBLrc+P_(&(1O|KkR`-EK?E4`C$pgoT#p82(q>Yu=`)$Qd<;~A| zA*nvDyegQ$xpQ`hoGm4Kaqz%=I1ug4yEyvR3coIz@rTzeChJVvLl)Gl>>u= zvN)>q8XM7w_Vn|+=p<;_Wl5&;JSFTw4tW7cYTOmqxy+VIZ!UM{*O`Odja}CqJ0Bbt7`kTz@vREINjbtw^HHelaQjI@4Gl9&?mZHnGTe3FhB#BxJ8n zQ_O(}TVYD#X;>5{bhV?qhmrOg2SWqS#N(u;UldDTDLh4J?qCxtxzC4{T(y?(^yIK% z$!NoNm0aCG#~o#8yj??|LO`Hc9gn##`BKXyP z<%o|mY?daA(t+!lr5P{38SWrgZhzEGK;p?}R<3*_A1o(>&xXHYbnqJG;trQ3bh~{> z(Z&g@K{DlIx7M0wg6ebGR$hn*Oj|!xdG&Hym2kQGjVAj*vH8YeZRy8q0mBvze3GpU zu7_*50@d1}bp?UqBxoG|O~3d(&7v+A+Y5V*jM^7E+}Pbo;^JnEn=~rM%HNg5>&6{7 zb_PfAB)BMAm$NEVXc7ZLwBA@B3wmYis{Kat+g$M0%3j<*3Szm>hOQf{FlFFNJWyyOB7O?w1&M!Uq6nOq7k*0fTkP#U zHR@VWT&c_Bf ze9=c5O;<_|6E{#2lEr(C7? zt_43H%`uX2E8d}nGTdCyw*xqG+PwepfZt!&ZB);_HRBH&XliGy7caDX{6?(<+R%IN z!dvmN0!KI_)oDnk=qyNAMo)=qT(|zIwVT=Ei5=N9M{_*8Oc@`rW$`egRm#`rYEI26 zBfPMm)l0AU4=+XVrrp`%frOE`nZqgCHsE)BX$OjX09D=?1BH;V1y2Ie+G-Vb;o4lY&tBc_~VAd zBcfUq0&x}jV%z?krz~$Ih?Ntj4!JFxHcaKTr^1rqT0??SlJOoX1N>cyr7skR%y%~0 z?<#lTJ8=>w_ZOeWAsg}G)>0|TTu-BQOlFO##@}-me;3g2j{9z*l4hcCJy}DEB2^(_ zY#!}}`LoOl{}lA+N%!Y6B&p3^O;36ndWxybR2}G}7CtB{y~HYN6ey0}%&X);9EV14|_D@=3P^^4Vz_oS?pZmEY&qJ+usIghUVBBAE6x= zaWQepEHb~>me@=3Fu&W!m`h!5xqW0krJ=ijtnzaHmN+lA@>*=|l(*$^MOA&Ka^d9G za&<(;`h5%Alsi+c{*g-@OSp;tHT*g^`I&r$gJ2UfxM!NZtO5$Hp}W3T;Ft=Fg%bnI z%flUXzXry={1Nd+el>L{dQ~-y9IC>kAC%Ys^1+5mYKe0q78(XRw$1=CuNqvK^JQkU zOt6?f^&Rfg{1o;(pYyAmnL_<9mz7-w-z~rnP<~Y!uvGN7>Qz={^KUx~{5%d#yPey= zm$t+t>6jxuO~vq22;G=lM-pvw4ib}S6m|$Ry{!JyD(i885JvQFrx#zNC3P_?eK4%q zp)hrvL@n|^iNvyGk7Ftr)7rzvto+HTBCv-QW*qB>quNl@=ntn*58bvNW1=*ADUxJV zX>?^R8e^5$D8 z47tidaa%?AJ^mB|bRW^TYDRfA-_lK4lYbY_Y!}xoWvfluu~&qn!L#AqZnlV8ny2QY z%cI#E0ZcVzK`U~`L)KKx(~*UFbr!tK1%gy*cw!(DbiNRYRax{FGk>eKcl^%j+LUA>QcfSI=W=FLcZ}&4HgB9Dxo0cRKk{}PymP?* zgTO~}FWDTTP3ofPgchgi(1d)GsJ{DdNBSa`$C!QU;e_P{X_D#tHjIPSeJE<3?zKa!1BN*i71Zvw%~>2eEegbk_Ms;%PMvC zQe;z^_ThK^nq)6{`N#&slm_G#bz~|YS4@HyzG9GZixtV0xaIp%qvxf}Jhe%ei@K_#q zk*x+r4*9`eG}6G;nt}-oyb0a0KkGS)qT)lR?O5@-{gox~Re3cxMrej6brc5P6eBla zwf9q2p?MI@SWDmr)6cfPv!xaL_RUHm7FoBo{V$cki0h(y+NBH!>D84?ew+@;;Esfz zo2KQY;#30cTUIHMtsr>E!2XVX#p&=`9b7^syOcT>JyigDhy#NwLG4th)_h=D-!Y)P zxbz1{dz(S7++ufqW&A89P1yW8R;TBWdZbR^1}!Ku|IGXpFV+HX**|0cwrJ~W=XM0) z<9F7K^%bY(sA)l}MTP4KY;=LCG7!lgG#J%~)l7|>7B-&1tuzO?_4SU(FoO<&b`e_$ z>G-y$fK-{*wt)&_GEqGFb(+Y}qTIBa`9gAzM_sb3RKH@Pa#lalqas=;DIh$!ry_~T zT-!Oym2k&IgTeQ8nIB7&--NzK{8L^cm}Lt*%AeabScbVMQK#2J-B?vkZ)L-L>{oU} z{2{wwy@HSv)Rc&m8QNpcU&NM!Qj-_P;H6c<&h*e_GXZq<6fw@0^y}i)6qefxVXP)( z2=>E;WNet5t8fxz3qG-6_fy{_E{dZgm>G3cz6jcQ^2xtN^(!8foBOqYoILUu$+$Kf zBy|;T^OMKJKlnSk1J(%8jF}BJ$4Fg98^?4zF2O#ftg2*7|f(&9xiiV*<8S*q}DOu$Pt26hV znkQqAJ02Qp_?Nne|5=ssqW(XsC;p45;a?w+AN(?lwZ3GIkG^yg^?Gh=sMG5NYDm!Z zKHuRQ9~w{Qp;^KDe(FIqa1GbJ)K6<-5(##XJKd>A1T5U zBQ(vq%#Fyg`q0C<#gl|GRnso0=<^!_WS|8&CKVWz4XCwIA{+M-+MbQ4mf1W^>+~u3SXi9sgN1jD%mo!}Ik2jJ`7kg5(O*IW*^P=*kmv0H zyA6ScYpIR^EUvuTBaDDs)?SL9IPvh4NamOSv&i9p`V`EDoV{B_FqMLsK0 z`i;FeV^62gNf1-vD~>z&CdeJ89CM%T_%ecyiMjiT-uvGVFGrLw(}66tdtGFexfi1xYIv1-={F$ny3)|-M#s7nh5qRCTBkO>bP}*(YLr- zM?K>g4u3Fy!Juh#DcJsL{6N*bG{qSdcC_9z1{tfmKkMJC_4GMx*>PJL#?6fvYp4~; z!06%DR`KXB0u~xL0f^VVdwRVrh1_*eTVM32X)IuGfv_rH4#1x;-`4){U4h~VEVM{* zVv%Q>;4B>?Me51Nb*g!hI~;5}4xHf}6J1GdAn)A{ia3t7)<(Xw(>bhYU0+QJ6lRFQ zI~CZoV<}bOo1eyO_0DQwF4ZTa-~M$YQv~y3#03(A<@Z_9HUi|6YSZ8*&S8v9z`H%9 zZCiE&J@VpkH@}IDDK97Lk<1RC+wcior@zUJ_Lx}#P7l zkO{cqMdxFryvA@o_GzK~e|+s9=lrK1Wi&x0ul?75>c4#F;YYR8rRSDi6E}HG3!+aM zSWbHjMnrusy3onoPICE)1Qt}eq4~*CcN#r+fp$b(pP94^J@_kV8xsfirz0NCY9I zBwS>^%hT{1ylW=yd-9bsolL2H{mpNc8_!wJ<>O8@wmof>$_12L-%<934}m?K1cpFd6RO4m z_DTd=lx_`uOm5o&A3!-0*NsN#%lgRUQKZ-6*kS`9gz#5Ul#BXQwqSYvMnanK?Cq}x zbmcOb_LaDmsN8_RuEU`PZ7~nP8`G0sKNZ{K)_pzO0w$c5^Gy}xx+jLE6Z2S9Z^1;tp~GeCzE-aP}t*y^*D(5DlmZN zZb#Yd#@jQ$K=R~ogxZRTbGJ>4TbB3no@=s4p1&lh-_)?~Umwp=yX}1&FmEBkwRhS_u`%NFnU*pt1pW-OcVQ(KgvZf#=T~7|0|&(MTxUx_+S2W7 zK`}6i3Q=UHzb~q%(PqpBK4czC!T7|aiIQdy9{RQjV^|3heg-d>iEs&n!bX-GIS54f z?mO9la&-Xc?);Ph{I&tea{#Um3ccZxmy8J*sKk-*mh42_ULbOtFVD6jVaztG$;cH+ zU!r*-9!$)OFMd16QyQsD_HNTECnv5ei?wXyDr#bX?ch$DWezfx59+Ga{qGH&Xn5<= zgz1!cWPVw1Y!!V#_Q{V?%iR!7?XV?FSBD^h`})LWEfP1{CyFv74i=@{v(AfS&|k(n z?Bh2TljNkzHykSXR2@2@(Zq5k@=9G)IQcXHOZ#~z)lQt=#JXKJyD&1i`x8lqY3W@? z=KJ@dbUTBh!b+BXCI zGA1v8v^S55Bk0}(9$b#mzB8{3J^|HK2P;PH!37FIbHM`-z|cBKEBZ0`cNw92Rnj=gWD5)qzQ@37K`JtPh{FJ^O)OVpX6MIAV|DE;nT>%6Y&-@XFU;7R-fXfg|X034q%fWgO~52xXw>N~yNgHP=X zhKAKap%Uh>okgG-jvsMyDt*?vx!!xYp!%aS=g88KOZY&2Uk;ihY z?Z5qkP{1V0GxyvNxK3Etl(0&UlN5}dvh~lv<_0%n_LuGhXxg7klSxB=I;h&_6azul zM-%+}JixnR>Po6<)b8$k@kx?L=FTmR=GNc$${G7zx*Pn%j{p3y|KYueB%cKCU4Z|0 zXZFwjWH>><$G+RX^;<)`5D(dcrnAp@ZLRauCI#-e$@ai-8L;FY8Koe-r+94Nr>0&} zMQmmU9^Z`0%H_XA88j?>z#|L5YEXT^?3Dzn8apdMu*8TWeQ z1g2HME47i-z2BqKt|t9bnBnbj$nqGDNa(DccV+SI&nK0e_OAnm_KmV8I+Nne77W_J z-Pm*ByHKv-8Jo3KRK9((2f<_z0d5oH{VlD>f z#w|(I?2&v_|;*jfPV0?72V zvqFara|QNC3~*zt+)Myt;UBU#fOAFNW0I42nJGn3;0VdyRD$^tKwbFcsx$ zfpc!d`B4%bz+2~X^i{uIN{4S;Fa10|94UDX;`~Kg4iC}m6u@H)<~F!($%wz*Y@#kL zvWq>2`>BSpP?Q($GUdnP(j>IFt9GQ%jSF?uV~Szuhc z8bw@i@+LwC@?vrp2;D$q#p1E8M#-PWjWG6l@NL1KFIFyZe~ti8rjUsS$51@x^^~$F zyH`_pucw|U@4(N=li~13O3Ycl%-@zAJg3n7{xbaq`7sD%#_z|KV%3@QfY{!_FDKXM zDaF%(#_f>dvBKsS{~J=HbFNnPJyQ{y*g3JFS5au;YFbclne}Uz1qS+gU`)mQH!u8D z^#Hv08`1oc=FZRV!HA^zWzr zD!>nIzqgfE|C|G&_s;1Nui=Bem7HH)*X|YIDxP*tI-lQ8+up(0To%ZSo1DJlK$rHM zEQ`WC=#qw5;H0L<2D*d5oyOC_^;vS!Xns)VAuDMW@sAqiT`K{P0XJ1 zR8JD!Zp}PP0enzVu_*?na=`|0Y3H0duXaZFv)tWYMA@tfGZ%26eM*vp_wMW<$mdYh zo^JFdI8xEj#Pnh-SA@xas&JxoE67f|(w8$&31gVh-SQHOR5l~RHjZ|{k6e!v(C8aW zdHs?pIpookIn?_)s;0xVx#O=cIuhB6~7N6 z(N&UMfcFisl7XZ(taTG-JF@?})%Cd|=*%PMGUQ>4}Kt8>8-_e?TZ^HCwFV zT2tk%9K3Xy<6JgX6qlTR?XYpz@I=39&sOzT?<|hFh($Gqf!Jd@!77X>n@rzCZ9o~M znVL1BzQV@Al;jK5G4Z+6g9(m==Gw6&bq6MLEr5Ul1FK0j7(1YHxlxtk%P6@r9uG&K zc9D*gF{J>t%)?2A1K=UuckxROUrt7)L%5$Ow#zKBK)T)zF>%u*z5gopI(La zTFJ?2n;KmfL}ki^RG=ik%7=`9phk(q5P-2qHhvuRcg#b6jAm5Fue%VSq!CDsj;=p! zoR!aRY+C@yWJ(k1u`aE zAv4u8Wl~7!KqCzvX&T6{jurmvSw<@$LKQ^bh<+DO6oZR|cwn0>aG51yN`VLc{=b2>G|OMGy{LHsaE%8Z*U`B?UdWD>a)9ie3W$13dk zb+91}gKd?>HqZJEDJzpf0lFYG`Y_495RxHgf|W09i%=Xjr8F|Zad$OyI8(cb@&hv= z)ddztIP%>;>E>>siR(Q{fHfA}P+RU0V7-MiNi`2hya zpQ}yK0Co(JD6;q}TX(N)3Ntk1_zf|?n!4I7B%DK|YI=TbhV5kh3>z_cl2~|nT+Y6n zR$YnEyB+)bJJTYDyXwwX$g^NnF`xJ?y=392*nNqrSOh&xZR}S>CR9RtN7!RhWp7Q# z%jHzFmc|!8wVTpWBpwZjhA}5jaqhn|wTDjB`z0V6xE_fDV|MP4(Ss zR9_8g{D#yGIFI1)2st)nCm+||mqzxM=6M^LK+IWPH2S(px*QBnxcl^l+Z6jRfyDWYGO0{u~A&ubIanfzKH$6kH{Up?2nZ}FzL?u zoE2bfh+=L6=k8I7GhA;Bo}-A84JSX-_)g(RK+I2CZe|(ntD5edy+gxO&!o-L(M~cK z*m}7W@|?-!A?w5|e-4?!FE-1tS&>+Rkr{kKSdDF@dh>)>_XxGba>YaXw&ro=Kn(WD zz*>`A6@dYd`EWbFSnVQX>-9rYc12gF`RKh1)?mxJ{O+M-&X~a!7=xXxuA&;6+JQU) z)8g=8-FpOE@^uEa!=IvNW{b88ci2W=L5-C2RTN!8NYH~n5JgPfOjL`Fl=IQH)`Gs`+BW*ARkP?ez4_ZDL9|&s zOXX?s`@jADtjE!>qaSLDr7Fqhml{TWJv zmaZBf&i#)nW8?zTf>Zai7I+=si>g}$5XAuwno*LkJI!?i*{!+QthBR2b&)F?&c2}g z-A%kU(AQiJ5pcL39+$L=3n}JIIOf}B^tRp%r zS?{+S`k49+C%AO`SfC7>@O6K-K_Ve?d#Q~Rbv#B2pBZ8PORLiSvZhCuQEf0l-_ofV zqWIE0VP&R%gVE&$MCN0)vgP)C_0Ey1XwP9s_lv<{JQ%cd=7{HJ zAG(-BBpH8*b%+@g?ep4zB2B}Wij8}&(HNhiY3VVv^%#oRn?eU*jKC=YT8mw5w_@kMZo-~r1Bxi_o-4PnBCd93hTohCN``N2LKh>@iZ zQEQndJ};$55e3~mk6f*TnCY?B8=~$Uv2_L%@7k!>-IX9y8s|%&)_vb+v&KRaw8rDxn!P2Z zC(cyEu?8-ANBk7uy|pb+9s@{W(&6HLd%*zczcnH|INPnhb`r(RSZ*mP0-~kfvLh>G zsQDKlkBiJ6iw9|R68zy!@mUwlqiA|#R*;qm=lI_9{XQqV2f1_|`p)kizGLT)Zu_0_)wwq)3=GpA#-2>##YRCl9tls(3l?vbXIt#@8AF!L19 zM_M;h?_@y3g{1CXc8oZgu|hhwj)=QzaQXO7#3MZA|6n5lg+X}|1BD0mb@J287;}hq zV&D+(4<>n6T@}}6p&I~7KNsvCI(q#-xW#2d_E_-f_n|OKT%;aw0V!?)f zBw*&4j7_P<6u1wLVi+D&OjN^UeU_+z8#h4|7-Vh0=^3!R4tAt1=wNNY-)?t}yS{Z*l$wA*L(#-WsZ-0@Ur*#tIlEDe46R_ms@~|y&ep2cxK4(LduooII4J|p5;nv3qXdU zjJv4r;#VMF-CSU24QdROE6uWnvtsZK9eKVHRu`4EzkY+AE=^sH{%%x078Zj>-@*M= zcHN^L@(xScwzQ}kbHLAn@XznQp>9#YXi~nmOMw~`sX~5HXlt%q^U%R}QcT+}BF+IC zz7#*jDxSfJXEDR}x@h!N?R+U{>Jji$MbE;1b*xTPv$briaHx0hUVyM)^P~yXD2y5a zgzX6G=T1@p#03d2sBRuA(Xp+}H;YP9z|m=VHFH4W&jRLANJK5Y1J9m5Sf~mUEMb~H zx#_ca6MR`Fl;V8Eub&g%$9b~k#uU9mdL<6_zdFunF+TL5Igpfo9&NF;M1g-|y7vjt z@Ba#w+bO>*Hspvw9l0LoCoN#uyJPe7^`z~hx`6Iwkb8wKa2^Z?qHCKwD?iFP3bW`2IjQuXnxJ;d=u$D9+4b`{;Wyy zh%xeNN+vOPzkIgwt)dsIZpJ(-taoI+< zi9VKn<9=3vS}{O=@%X)v_=K?>NpT$W$SMk3h?&+@@7j5A7X}^7#3IRpr^zy?$RNon zk(qZ;iwRpqMWu^rUCM;i(`rDE?~;#5*lXHROrCn#NnhjUwKYG!B(#KW(RO{N zkja&|{Lh6jzH2Q;Z1*~>DDGC0Sz8#3Gj4s(CZEW7ZoG2gW5U#UX4A*4_ z0v9nX?yneM;`K@LXVEyF;2`{N$u!<+^9rgSneu;^6EdqRPVBI3<(0qjhmA`LhEhUb zcE9DHz!eb9y%E@?%fuV=cWALCh2KX=Q=7@4L+$f&Q2l#H5!7ZvLc`LlsYE)RJele~ zegDB@Sw!-m8<7asn8V#lP@Ad8#YoZ2VmMIwL1*e5hNHL28JHYIrQ6RdtD4^m|FIqG z8g8~dq094NRmBF!S&;>|9LQ2?773J1HSGuZ58hr$0@+Eycksf3-Se}R`(hYQIWRnq z+>3_qZ?M$x$Ym{F-g4<044vX-TG@&O7^QCKIEI!2SuIbJr|D^7hUMw3%+;J4q=YvRZ8EZ; zUSt&Gl(wkmM}T=vAzM+CJB#W3QbFD30V{l3=gMbejFWIwUY+#E6S?GQHI9L$y`o;} zXnt+<&8dolE!4q3HADq@j7+?qi(a$Lsx^{M4{ZA{v?*J4^|MeG~V z^xTw}QARuBwv*hI2;+!ObGivC^_7R44Aa#dvVqw_in$w#A=Gu@C&OXPcUef4VwbhY zrJMV@_@DBPF zPh0c4|K$yqiG*S`^&WxC*E4tZELU#(dpwJgayH@EyvNPB;8AcKi8e*Gis3ljMDG3c z&Cj|tuoDW9Mv98^tc5QCy<#Dp>Tqlf@7?Yjus!5jO^g7V!Ag(oKqv;vZ6?BR!QABv z##;{M{za~v$*p_9lAFPH;P}h>&4!`!JLx^-85NXyop^Qbm6rxaOe3n7(OdldLT@ST za>UFPu>%K6zu{qYLbJOX%Sb{sdvr8e)$2q*X1iXTVsLnwDyUZNK%M0EPm;LtyODbP zt&^KtZ*x4ZZvP5UT!nJPeMT9#tP?rz9PddKk$YF}G-Ap%ZE(Rn%~pkDc(3M3@+?4? z{@9C|3z_J(7u*XIIlS(?ds4AatR)dI=MYLFlUd4)uMR5SM5?eL_^Q&-A44f0Qg}{s z<2~_VUj%GDjdNKF`9v{-gnS_h<`!8W zEd4z>toxWI3fIGEZx)Y5T{?Sgm^?pbmB!ZgOIBB2ltUAn{u&YNrCH+av914uu#$^( zn>JFL_Q{plUkYk=&X~UxdqzJEm{3H)S=buIo~*S^tzN{c-^X{osa~PgG58-S%_1n1QaGCB(6jbclgCmF_xbdT z4HwsTVPWX{4sMhyOzrfJc$fD#WNIg@@O1xr8B4Q4t7D<@ZdlbXUp6!aF(j0N`M#m- z0+hG_j5Np9kkwoI8&bM_m{!e2$Pk^yp*5%>0Vwn+Fm+2 z!d&$CvDM+Co^-KzJTGVlUu>IkRA}g2_8C9lNTf~{)?`W>Te>s3dS;>}YPV~~@@y|~ zG>~ULh0a9Y$?ulTweyo;B7)&sxHD^NjnX*b=ShzFh0lkE`#JHH>RCKqB!<`%1svLI z&Xvz?Rggp;%0)+iw!<)TFl97Foa|uU;hI(Q;-X>r;BJmxO#T4MF^_>c9Hvc(DPU6P z(6)Nn>DsdC{%!5+Nq|db7sirzq0KmdQk1_zZi!7FOGY`2G_)jIUEVfK;z1Y2oj<=5<-KBX|t za`j0$3Ni1x2hl+x^fjHKKS0W4!1Y|L$hzqZ<3u$EzW!Vmv8xsllmY_h1apnwqOfEBEMxOcEz(N8#e z<&kpz_bDqyB`P~VFSN0w&*b}gOt@Y7b4)E;M(4iO{a5o1Z$nPVjvjoIpd6(Xa+3ZO zrW8R5?aHrnAdV96>`{E%=y_>VPtw7`Q?{8zpHqC$WCZ_PNeHw34=Vq)?#W$(n|Nxj8Vn$_4&uL8vG&Ad5}R3oqQM=ULDpFD=B;{b`ScUE+K zg_rHiVK%6R{5VZqdjwD(%;Tk_C1;b7^VSB=sA`6SOM?#&hRE#4dg0vGkt^5~S0U$t z0mCd$J*0^%%?~E#PaMT{bbJk&O&)mAS}hZ4VKTDeCbrv0{(_ze(r<*A8`ORHH6;7` z8?)0FF}{><)`y<1r!`3>%Rke7V9x6g*ha{|Mjun56w+3H43)IYci2w~liv=%&(VJ8>=A%iozevRq zW3ZhXA$``^`|Rh+A6Hcf`ye+v@ttR_;aI4ntr(JKn^Req4G1z5mAQ5@msIe2vN1Y-HFBUTJc25ebTNv zfk>Hp;b3^p4sz7eeKu%~xmA{&qMF%!3{>f(Ly^wHmo{OEVD-+y@am|-$3^-g%oluq zKq$PgL(%u6TD^lW`;ud0#OcW`K%`J93=9G~%Smjb;&)mAL!XPZh~Zv6`96W}@&Y>~ zCrPz{sA^YM+jC+|+z-z)8&|ia_ULy^; zkzcVx67`HzQEFhM!Y*(}?%@x%N)-Y3Cx0Jt^Df4Q1NPoK3kPxLa-p?i_Cd~0PnL*s zD(+$Ldb`&~2ExXUpC;fT#91jr;#_h)g)ZucVM?-P4_a%EFYol&rZ{&_3N4YlHxvu3 zUe%A*>EGVEvQ3adby<3`8Z;Cg+SF|{Dx;Q!#t3ux;lg~W3d%Wk@RY=&hFX32Yv2Z; z$^5e?-D!(^9w`JzyExhLxNZpUq`XQ%vehtO^5COEqZE}!%(ec>JjbKLQ-LITtV3>!}s zuTDc1bj8=%N96`8rbrW9`h|9!7ZMER%{Fc`#z^gw=Zk(BD>T?`yA1h=R;4zfrASlW zM?cnglL~Lxb=9itt~zB$AC%D7-Ze6ek&D$Y9)$Qb`5k1JX~2O^b#czNmT~o(ok3M( zp{53RHvGdffK8U3`;LI*m3(2NRle+#PDXQ{e&+j0S;xAsIAnmVbjTyS_4PjX_Wcc! zqM>PQnmsK(-NgEN?pjZ4Hz`-Qb#Wh|P${Im+f`$b(r$Ej%`#C^cilr3*(XHITNiXh z(D$cbg^FpgP6ok>C2cYoI0yGP`g&!9752){58t&JL0 zOv3!xPS>{mmHV&cECA@7H0P3a&PM{!jSB$r_%i!~oI81<=5Al)a4IO~sp&$}&pJb9 z2oiN@qh@>@V8%%Na=Od@tMW_fk@sii7jV7q=^d|2Hm?2~N901xscPm>zGV@-TWcRq65QuCv9TDgTlF8DgiSHO?YN-?m-s4 zIzTnOaqji54vfm!C~>ytQP`5q`MxRE-B-Ks%I)5lRJZk)z2n{>p)d=oaafghbK7Wa zJcesJ?HAXdPc69Y?DL3qJ>h&A)=sz6( zuXqn4GVTLH)lV~3umb!2)5FdCncW7H^ybTY$WY^VF>DU&=zW46Wbznfx5g3bIL`_b zxKV!Zn;-dlR7z$exf7U-Kph0_9r|QYUoQbuA10=C@7<#^2Nrgq-6U&G*8Y=JDd|HY zsT`AG)u;T7PsdOme*R}Y(0c(+F-Fp(10znscZZ9sp^Be?X2iX^CP1!07tLRtq>H{L zOLF>#d`={F-aPO0x!=8+y{!Y~SL=eI-t*0~qADhMqqK+M5!F&`UHa|W->>v#*Qi(T zkU`?e{CU*=Y==k}*2HZUv8fdb*Y_=L@ZPC^-2my8;;#+-pNi}yrr z;Q-y9vv`L*@Jw+ms>i|!2Fea-Ic|L9;aX#nmbI*Ol34~Lhd`~%o&&U0rhiI!8(dSQ z2?(GBqlB;2NCbEP5w;euf?d!EHsmO0lBl~MB})oEc?iUwxYw)$^SiM2oZQzP_?j${ z)LPW_?#o|)LhbYWWW5+=2VqjdbPj}^3N6e=M_+kL=q$L(nc+(vJ6{1k=b59KY&uN- zs~A_Uw9lr$M_NtVM%r4;8M}x@XkvCB61;QTS`jC#rlUlfg_!3O2?ci)mEC0GYLYeje zmd-x+^QyYGLs3KERa1Bg7+aI+JM^D%N-)?o&&eC%^W0>uRU(adBU;%JKX(>Q!ZkRv z-BBaVUgeD3ElI3>oXV6*f4+K^bIBk9M4i+aBR`QfG|e?Soer_B`^m8{??@zqaUE$K zD)z_|b4P=)A&<`pl#GEzvoWt$`IA9^h zPl8zm!_F8e=G^cI+<4TE;#y5y4*Cxy;U@4r;jk4j-E^HEzAQ^SHh8!GU+sP&zc#S; zPkxK-O{wvJ`d-Y_qP^pP^6}w&#fr}Vtny8B#6p>4nb4wSdw~GK zu>X^vhh21i*5@f*|M>F-bGPTF1!02Yc4*}vf7;n<2F#BC@yPq_I8_Zb;}wu@d+RjiEAovO-D*S~XS7rUl6`M5VXQ3{Z#DS^tYp(`-^*Y@ z7++&5?0rh8>jYJ_MH#ZUbJZM639Mm(M1IG8&R&-Xi^kQ!wG{BIfgM-~;4;$l0mKK4 ze?%N{umS*HeI|VCH)Qk**ZZ{COAdRe_#y`8G4}ZERI8Wu6_T_^u3^JUmB1jOFj4>R z$yZDj$uAK2#G@GumtK3vv9bQc?KO=n@hK_m*%ps6euI$%e*DwqSYX*Abf7U?)qEm7 z>8uMrUtG21lw=c{SvQ!^lbzA(W6d;%AO7XT3Qb%6{M%H8h##CWk-|BgkBnk-CyTw+ zjvO(H#eiaorcdrZ|G5Qb1Q7NDOa(A$7*T+U%<<28V-S0F$tyl@zMWV)xSUB{Si5TM zHze!i3CfNp(oZ|V_6C!?_^zf5B()O|M<3;4LMcpgjzh@sK%e%e23ve z;=WsCXlo@yd*j^G(^#YDmIOa7*7!np#GY z$4Aw8{mY{XsAba@(X3N@)kvY7m{2^;=WMmJ0F#U7A9jI2&q#(Pgylm;{?(u%%o&ZA zjYpOds)z{?IAh*6_oI5Cw(BSQ3ET^23!4=H`))h(R!44+?_C7F-9^Q{rD)(x_KM!! zAH`l+(`_q?bGxgtS=xSdXcy+bx6?kIX1z!LecMu{&!?S1=~PfKz?u6L^tnWws-fO7 z+4k+9_NCy;!~_+(oI7Zq_%;qpDwyjAp8xVh+&K-cU}*m-gy`D%eO4*w?G5)We-78y<<=6CkD61Hc|AXFNt_1@;ZE?k(}Te=Wcf9Z6ARyL_Q=ph z&@r8DcQ9MWeA+LU=I)9tsc)B~!d|xqVz0%9*8+}lBz53l{FLF%m^NXI*o$?*v!htK zY}>rC1nsgsBh#uQIxD8X-$-eAC=m(w44C7v-;ST2|b=LBc83N?|Th-ZlQHz9?OH&32krc zw^!!ZRRY5OJEl7$Md39`(V$NXBJdwJfu<7rw; zq*R_Xu4sID5s*%udzRPD@ZFcO{#^Q3l}^D%uj&Ja7Yiz|p!#Z-_Thju748g)#2Vi4 z-oP%p-iU*E;LZB%GfVb^(r@)qvYT$ZQJ6hM??DkN$ zgdqdKp$0A?JcI%s(ioE(1nQGIsL?_B?TSu{BflZS$oW3#`&X9$r2T;~!(ODHV+_SK zs@s>WI}JUHd6x?%PkAoqj#q&M@f<@%%NHJQQ1e}Jl)2UnlLDdNLU)22#Se;v*1VRZWwO(v-m+GuwB^DDGB2aRhh z9}T&2@HSBD^-y>eh-zdSwHay)3k?R#CV;u~!(A%bZsV;!`ifW1?AHwf+6zE> zYWjl59&6T+uFiS{R?Is*)X{FcA!N`D6_AIDy*SD%q>9`|`1;UA&npCuhtESMgoujoe)pYe-A`_%=UqdG? zWsK6^2KP>X`t*85`T6#B@~PLoB~s@34a&w3_C6QBd0Pw@6eJ#GC8QYu(8bMSIzvn+-DWILy#oCmigrrb>N))1A9SUZDdlJgYmyThhsA*;?&ZUjcDcxClgoH>&96ydFOc>)c)cx&UuI zXT$#ZJec_>>tlw>=3p$oM}NaVi}zk7(ZR7~W2(^OZ)-VlmRr`S0G%*%NYO0jFOJ_^ zsk87a zq-(Eld==^(*X|NXk)56I)|Rh;=jws+{X^*(0!rl{K&KOTL%;Q69uQ6Si;)nD-{_cc z=j;7Ss@kHYs$}D`bEh{(WBU(cug@-q`M&=Lk=Tb%g<@VO{(I$E^4iYA)rH&ts2EFK zRN*^a|L+gKLPnR->)-gh`Ybk{%k$q5E?xMf&zK{##;41*OlSU$4jUB-(A`CWaiE=^ zbKjpzn7;Fxut>+xmKwWhTu|`%Awg>F{_uYgpsRk%E*IS)c9$|&ymj0AA70q7svro} zoe}>`fewK}INsuar%lIR*fZwz&m`~syrLH&oFt=)|3*oVE=%*Ro5wo*ao@J4VT(Cl z(#nw~I;s_;XM5Us6H477kS^Wsden_2j;#U;h2S1Kw(jPJy#sQXh=ufPpDoZ>u$OCl zJ8XS~euDSAWEY$r#yVh(>T}}wPF@Ms`c-@^^d^VA*&^nPp~;kydm+{gZGZ&5SLe|; z`hV6@8fHmIC1}m^y|Q~nb2Ot=-BFfj7@L- z_wVDW=%-{!M*2lM07?=GpV8!e`8G+}q`=zK0RK6m#vj-)`C66_<;)8LJk|gbq^?hDd^KgY#mdCoVXJ*5uN9O2ZQBKSs?5;ghw&^ z7?UHaDU(ZesHq*o8W2$fCmO)?w!so=Lt%FSR4a3w3VTvZLj(2nX_KTZKbUa(N~K>b z7s*Z?h!tbC=LAwt_^T}ZoloLet16tfcGzfDmVe!RqxW2myxzYXIeM^59gX0N22pR) zI!G0dnhr3-IBx><+=G`!%^lrskF=3PQV0>ufaKt^UkROwLkpvL!GS5w>=_sk2R{X% znV^IN7;{Y67mND)t$^X@8C0^5$qv{yO90-qz%T-utkS6mjA;$#b-t6+!v#l+oIcE* z>LzGX&hkw+rShkl7-LOM<0K8YfSEa&zRKdG@7re~A;$3xqyao5=07%oDrJY(<}P3y z(&|OF_4G1TwQP!P3^Zlj85CY|g-p`9-C7Y9CmHOXp3HY)7@wJpsckDI4c_|#R9W~q z<;oBn)}E1csZ!}Zzs1Ilz#y4w6cF8GI(lHit_6{^5zrHmke8zlnX0)C$7gTL+lRB9 zPBFvfpQ1oT^VoVfUFn%Ie0eGW(!n$jzBG6^3=&-5lgEIhpcxPLY@W3lOyl%Z91p=H zt_1?sC?r*CpQ<)(A6*$!iWNHxB_KYJ#OVrtAHWfvBN^@-Nf@5KOr--uxZ-~H?Uj{H zM^nR&gzjxX6Md$c0fD#BL!(6O_O)MZh7RJ{>Ia;+%({?i`sM zwETv=o^&HuVw25hOK(f9?4}}m{}k0!Iz{kH>rRUQrqr5!Hc6B@maRAp(eN>Tfh1F- z_ILU!1&z?(ki*+53omz>U-CmwIX7oP8C0^y$+2)UZ$s_+E}vdDt$&KfM$KWccmO)G>Nu!3az@aqDm&7-VZRF~ZQX#CaKlvIR8e zTLG?z=sCOm(q3T>Oe)M94v^ZdJJci$u*e|Wy7J?W69et`6rn}a0#?5o4kNWfhsG#O z<`pvZDCO!X7v>_+vCBpYlGP4^R6pAklZO{-KPWG49mM5Q@JagQEU&pMXtiw<8FPci_3Qla*@gnY?HfYE&5@I08R}h1vsi z9ND6-xhI#&Wt+%c%5p_9xpAP=7K@D+WVrVs1mW%^2AGS10dV1}iQ`kN4neA|p*A^+%fO;-esb%3u5VXd7D>Yzktu)y0H$NEk zd<-4NvDk6U|7q&(|2Z&#ATkt>ThZ@w(_(qG5VQqu7b==Vc!->3wPu)1?p<|3H_h^_ z4~4#pukn^EP!MiZOP^G}deStmYT=i+9;i1Q*D$q;`{#|wMMTL{culL~$wE(>#*{$% z@FkSH+m}MEdbqGN_>{9f9^3L~(bopw;$+gZT#Xn9wSLt!l~0@s=B0A>ag!7<-qA&7 z!x!0sd7Cz)mxK^Xt>J8+O?fyU3Z@<%g{U#?a3k1JIGu_NrrY$v-#&};;~TGJWB+!& zbp3tC7o$A-pq;?!Ec(%v8yAxa)9lOl6e?``LAET#X8QJt8!_e)=lNYPkcA~t^4^K# zMO-deMU9U{#1IbB8utlEBMafD>N&LVQ`^VHZ!m9{3VwK=feC3qN^nsq6vm7vr?JuW z+O2cNd<&)U7d5`VVNl;n*a;CVBScpXlF~I9GtCaaHs=X@&Et_a2`Iq^Ft(B& ztSKde___^u$cW`DPpp<)-B%%B=e4T56r)ppj0~{M){w0ofoce7)UHaLCCE=~sGXLLt;fT!)Se;;%*B#1eac_p3m3_1 zN=ixbnlu_4fmNf0iE`F+(RA5UpMw3U?D)wPFcom<(#OsJc$U_k*V~+ChS4vpoo^=8 z=rypKA!F`0(w2ctGtHybn;(6)t{_kWQ1V;$Wm?~BISgFUgN~* z%4CyuT~-{dNBX{Lio#hoY@w4Hl48G}rIGPCgsR{fsT`nBIvsDBrjPIC$V+lq&{(Tb zHlHGn#X5P=Nk*YW`qg%C83SB8Kbe+th}&2M*yoj-Q<{W#lqGR2qd5hdAJ|fj_Pyj( zJO4`^I^CZU=s=;R*^CRWQ!r~XcG8FSyH0Rpv1tVwff~FeYoJyt9-cM0&5d8$^KG4ebvFsQUyQl}Wg1D@>2q^UzE@#) zB8I2-YL0$&{O-d*bY-$}Tc!8Gzn(FX{`f3B&H8%R1V3rL51Re@OBnmGu_&L_y)m9szQ+h1bq}KmNFJp7dwWX(f zX7*>N=&xh$u-7z~U4sJE9GEo<jaZ(@{5Evso+Ns0*^@vB7cUOZpoa%1$qKlt}U> zzkZjvu;5f<6*rwBR;F79W>mu6GNP*i;;M~^*jb6dT0AVrO#uJ1NCdV|6VBH3Upb&h zfK=pVXA<7pIY2{Mh8-W+C8ltBvv(CDO5tTe3!!V!!cSvV&N>>>m7=ila1$lYV_VO3h@e%H(BX6@)p~-l#3nxkA<%~)y$SrIT304h(X9d*%G^H&wKbkwn99`G zFHZTvq-eTd*rBc%4RAV}%-nOn!IqkJKhio4&H0dJY@x}*TG;xDR)LP?s{xC*<_9=Cm_LzO)$F?u&y!vNu<(OjYeG5MI`H5oU9%XAaXCP0>L+rYb zFy?WUCy%GrdAZ%x9dfwE_-MisETqnw{b|4j_ILKhvh#sm-bUNh? zHEejcU1%;b1N_8dfuehBZdSGTabgII;8z`jN+jbB3$hM0_O1Oj{Fg?K=5DyY79y;f zlC(!KZ751&MGv$VTTVRvMYsj_A0}GHxr$8Xg$k|*iJ)1HX}K77dZ5Ry^j!xP%(`$k!c|>UKscOB-}GxOPqA+JYj!qIG}RmK&yps z^)1tWNRV5Sse_h)n@FoNIhZq%2_3WG9X}>qlDP&`I0>NvXL3Dt^e3U8LMpb-K>gQ9 zY(2wKf=)8I9^*wU$vWp3Q~XXH%Hj{Qs|ITM8y$l`(mg8kG*>5W{D$$$fQU3Dy6D@> z$IPzuNRpQ8f!gWO=0EdEnO|bpTXT4_{SZ?k7$u?qRk)A*K*^M`)M8r1?6m2@HV4+&@#DMb+lYcp@9!wim3Qcoy1U8ImS%)*~EeVlyz`f)t+@8a%YUk zhaR;l0Gzk~n4t~m;IL!q%a%0nB!i%5Nl%j&RLu(d)ZUL2tZ`?cvV$o55agR|ONd1i3`;Dp_;X{~OPkL4pKMY*A!lf+VCY)>z}Oj+b3$&8=7%Z_jJ zm`)!&JesUgWWqPdwHKHBE~HP!D)4!x531-Z;*Ol5SK^5qJD^U1k~Qd^T(e73%kicX z?@8a#%T_aA1O50A4Oys+IW3i$otaPZ(@Z7r)`;OqpJbkIA9Uml&3Boqq8UhX`|I9I z>Db^?N~JdIDIC>IdsdpC#)qIARhX#|X7kKScVnGGWZrsCVpKn4dFuNHSzJBFwx+)I zj~A&KKNv&@@#WJbzN(fCRu4yh@-)tf*ee^N$ba>TfX-iZ`+c66%H+Y9PBmkVM~Dej zty#!#=w}|yb%xjPfYH1T9BtgMy{4if8Y~|>WrT_Tyapdcc!-J<`_L-c~rR+o5m&SoC-GnYg5wPYY{Iwc5rLKl zlHBstOTy-%__05Z`)Qvcm|%<+mexKc3uIC#a4@lNu&W<<82zG9k<-)_*KD>ke!HvT z`Hl>7Nt;F!uI2#HlC@E>c#P3krV(aW(bH34xH}$JfBPHKx9MKJ9z8I?2#hF93aqA8 zf&NX*EgvnJN-lMXChg>Y3<3ou;;`7W3K8^Qu=EkMFG|grgb<9F8H$>y4>aSd>qY{)AcskOTXRZ6E)05!s50RMS zuh~|Q6Q^%(EL@YG9AW-)vl<|sV5c;3=OW3Em#OWMkYO5qQQX?Pn-?CKi;&ii`O$&z zoUNWmRvga(q=bP#j3m&}lz^KsuIeF+rsfp5IF7+_44wYGT<21Q6mu>wK<}<*tAney z8}6mk{nP(|Qzr~qy6U|6Ok}ksn=TTMO+{~cDsE;q4f=n-{{%6TFoJbAyH;ggg`x+` zx3)Yov~{>r&i`WWEugAu-+fV9r36VS6{Jg~q@+<79gA+IyQEt}kdl<{?(XhxL|`o% z0qI8IyYKS*_TB%p_desEd+$DXTqiIVi#4WmzVm(hd49hXnVNywv}!`SLA}`re#gQY zUkqs2jDMa{c`HjiIWrUb^!ft!;i2&QWFHX#4^suM*DL@i&j-dQUrN78A!Z{z3``jy_6y zp#Tn5V_hC=W&pQ56YTb^%x|`m53!CO+G`L6ueJ1h!~FCUF6)VcXL@H1Rbw|^yUl{x zjBm9?;*n}VK$y9U{_;oCgQ%ni<8|_T-l(~CEB-8pAY+Rxv2esNG3H}NnLg!qSQXpk z!@!E&3|Eh$tCIGsD#QtL{(L3=^X9V3*zOQ-%Y{jruu=bI(iu%FDlV z#OdKXecYAi=8s$pgG|!ud9)miZWLK1@waH0KAP1O-?@F38hAN%)Vb9g4_6C>jFw6& zHm#r3MhI{)#h#AJGZ zR#1?Zj^UGl8E;KAm&!fqZ4(OjJX!@5u32cED1NMU%L=nRR#zfoI41LaNfarhM{4gb zVORWg5tpe#UAx#VPQj!b$k=rcqdSQk=9!yNkmuSRoS}eIN5`m^)o87J6%?bebiv+1 z5T$|6qREvUZpzD|UpM;Cq;1-}pj3#w`Gp*C)#x4f4?jZg2%47X$wAVE-Sb{RunoKA zcIt8|9F@OjA^*nv z=%|{{>2r<~tNSzSl9bxjy)J)0++WZ+umdY>bX-`K+87EKIu^tYI{0<;UKJHXJ$7Eg zEdKFaItI4A?cIwmgl2xH?%a+!d2KbeIZVI#BfN1R%oe*2%<9p~3BK2Ud=^5!_r*f~ zb()z*i94cpzG197FCd{sRC!-1bHNK8@L@F*shS0MXan8%h9-JUech?weJq>q1j%+9 zdgR|AXMao#zwujU~`q@cT_MkBehR-c5~>rO^HzC4I=7 zQpwHMAofphEr*}Hu-`E~`TUC_3}b6?+6jJ3%$fK8j93}oEa`7P%XSZ4s)nU~$pP*+ zWf7JM5;>Z>0OIC`jL;lFnXMSJb*0`Av98;P#ubbOvA-lA7y}YJe4idixr7K14~)9- zZjepSTC{jj4~NUyM>;c>6G)u0e|&F0mG#it_4)!NbY9(K!0=N_8rHID&nSk@A?P!0 zu+S6b(&!!D$J56sIQ0YW%iQblBRUl?&@IT8>bi0mR71akp-TWYK6%8fqMxXX^pHC~ zX_u=RG%aG@j->l+KQS$M#j{dE>kPmS1T(w%GTWYv+q{Zl1bJP+3V&k$Li5 zzH`HPifu2J60|t6Ww%KaId1JqpxCE(!n7l!NeNQEB+e1P)TMhQ$Ld-P5$pb)Ii+@a z;+_<6t#Q9_RiR^a0h%L^OHUf0Cvor`jfiBE0sd)^W77kvl!wK_n~!t}q})yR|6A_h zKP(0>2X_dz_-oO3q{mp8ATFgm~c)!It=kF%~fI6xZ&b z;8v@>@t#K8HoK_nbCQBncI{;iO*$Jv&UdGS8Id1i9c#)*`3}S9*9V zQZ=uS6MhMt9mn_@!61kk4_!HJ^Ra%7*E=ThxYR>vswwEhuH5$DdUkt>v-Vl3AMl7L zJNA&SctLyFDSQP}NEgek+q~8Z9$jq^yv{|QCb5165b%_&c-2~R6Svs4G|2GXB&};H zh)D2rmK>HdNBP}v5P^)7+E=i>00rgX2_pYzKf`yZSrMRPnDH(WmZs=EVqLCxa}ax@ zkZm1p>AuY{h25$%CY}_)Eu6S_{(JS0s$|+lFh|z;|IMYSqV`t*{kxmqdq=*leY2yc zo$>x@*{&s9QSHF;$a211bQNnqaXef%EYwEF)npge*Ci%DN(s+5_+6K2!~Q5J+DNFX^On%uLhof zefK|n#c0lKINghM*go7A{4Vt3A;+of4b!8-bSFSdysuAIGS)CW=dybE^TT(~kvDqB z4eA1;-tM9^6{q3MWx%}&;nVuKoJ{umvlj4xv`9iT>sHI4LBJOZ?r_##o8r*t6I{Cr zLsU@Gr+3E_3goXQ@c+wy@s8_VG^s7Z!i0?E*$Y(HkdK-=r6=)fuS(21%H+LHdH^kI z8InMcDhvmc8$p&0NO^k)S@6h+hT+)~gs+)P`)0e=6W?C_(hH*DR_Jia2L&VSFFM2N z>K!S17%|N{b^uNTo$Z71zOF@hW2qMoSjWD---oAdesogXPrvi)bwO4N0=q^*!R35$ ze+5_`h_j3AsqjYF&{tL`uD_7dv^GgGLcN?14_Sj=N;s zT-J@{nU#9i?>`e%`}VR%H5cBCHe60`-3jRR_ciNm_#|dDjWO0V#Mf~3A-qEz!?4D( zJhbJ;R=cV^bS+{))k{J2xvP%o5gP@0ZcXSt`9_(>hdZtC6ZE#1X-sX`Xeg%8qkV1Lx=5{gjnO??Ux#!i^~-YWe9+7f5V0u;+HLj)wtE6Si)ksQjYKwKh!^e6P93K zbSvp!adW$2-Jxaa)weZ(_XSLj1Z}bRFu_kj zu>r)Zu&gGdZd(Ri>Z7e6XaNHFGY`$`7iCwe<~E3xQ+2KOF2e}Saoc+I~K;Q>}=RE%5VUwHzpcNc`Y4L!v)v-MI1TNhKo_*&h6U7T>;J{ z9+_T;-{G+q^Bi9e)8qTFekAJa@KIp~aIp9_xY{;{w1@Px9I4_kgS?F-u>)UE6pW|L zBkcrqD0Vkpt=exRL#okz2t8z&(re~a-#Jk{bQCyLgUCLx&oiu@tYkROR>U8O<}m=V zz+RKLPX&J`u}?PiC9;VAAp} zE6!$o^CZ}dz)2*sw&}1wxF>6~0;;=|G7zlJ0?GV38CiDp)oYjDp|-WpyI!>0+rL+~ zz44@TpVkZ_O~$b~_z_XP+Q39j$oelC0#FC1GY?3HmC{Ncq zOk)i08D8-}c`8BLwy17ms!#lXw$@K3>Yhl4$KwPfi;csevGd^Z#MCscs$foHKt|Y* zWt1_ZiVAX;IjitBoOEf{SBrO2VcJ6MtDlVomw_*T$$l--XlPIv!8gwjLx#3I%ldu} zt|tDcAeQyTN!(AsXQ8@-uQ~j*a2@J9p>;~z0Ff#@plXxD)OQKcO7C`&zXdwVsp~aj5EC%ErpC{gz_*`je)(^RG73h8=_x^`I(? zvZfALu+Ji}itXUI@Ui*VM~-}mGH|g#TPmZW4Wg1cbYT8R#e@rV-U_???mlPj&;0mF zW%5G|u|}0q^|VN$U(##&O*WC^kJpid$QJ0A*^{ADWgOG?%9g`5can*wRSwc3daYjM zc46t?xyuIj;9KnX^r&uMnUc-H)86uijLmJGEu;ko=#uogz1Nfb3kenR6p0|o!QU;D z_L48cNL-yW7<1vGjCfQtb2J&smMp|Z2`9_Xda~NKEmS7}@V)1e z@ti_Qywg4ZLfW`~h}04DESgt8-505yu_C=IM*{_A`fE!zQX;T&ly#ZR7`KwXU`D!ev+2gFv~M_6Vd{H8WR?y_ zY6_j-U>m?p>?pXY#opN+XVt+OtSM%4a!kJ1cJar@<9ZO9`Q=x0s{OSItVx1w4c=Dz z^{hAbc2%8Aoo}b6e|PX|FYed#(gfWXf}`3S6K3I_uiXrFMP}ezuf_(P{yInmSVm-kJdRqH}2@m8UtqPeOSf!jlo z7Rj4<(;xO0)C*tKeUzZ{NV0a2Y@*)z*%(F$i~Z^oS(O>5HQl7f|3&IFq8?@w9sRVI z|0iqsN5VDSHy+%}=;RN6v^Q7t$LAyt?&1eU_Cv{g)d#7SQADygYxPZ}&9B3kH z4to8G*RJUCDBTCT!i-i@rwkHJD<85#GV=Oee3#*$Meggxu;k+Rmnup*F_WRj_^N!B z?EzMw&^NG1wa^%c<${U3==|D^vNWqPELdzcdCb$|M>D^Az9MK~<@x{#f|_i2g)xr2 zlZj^Ri;J^OllqKi^O`4~|u_Wm+^bwG81O)pxfrq|q$l{NAE0+2HQS3*X7JcOee z8`VsaRTOfG+4NGSF<%;2IT4KKpw~Dj>OQUJP1MCT&94X9N)W|>CybS7(Vm~E*v^Wx z;>fIrUwa-g(lvQW311~2xO?8Sg1%m;Cx7KFy3FvNo4&~Q3)2{n77^yvVfuF@ObO(k zfB=b?vC`GGg@r}2O**dBzSF@>O;E{^(V@fxXRDQheK8DzEeoe1$Q9Ab^NV@p05;PW z6{QklGHTzfRKNMr0%hm>8JnDygqB3Z3=+cTXrf}egjKxaIl%;&!$Xnrd111kMzOyCdx=6?8@^pgj6yYdGZuBUINf-C0EaGE#Gcqjix)T}1Xhm*-I6aT9VH#;8B#Cq2`=Y8m0@T~U}gpoRAT0g6@0JH zxMC&pF&KB8UeDk?TA-}jd>^Q}tUz6aa7xg^(36Q{2>Wo!!$$jLXSY_LVI3uki?KpNq?>&Y;JOX3<-9I;*9!iRCyU)+5MnqFiTX46wq%;#z!Ye7?pSoJ_j{c8`d{Cx-Mf=HHm8kyC1*UQTSqZ( zvE7AAq)m9ga2Q*ss}zu|GptwGu$0f_$AxALqT8#eE~&Mj3Tr>%nhbA!%N4%pSif#q z6g(*)a*vNs0$|nh+#69SXpo9+`hmpK8x8r<12Kh21kb>2hBk!4VYI4>=xJPqx0AV_%{sSOm=eu0 z<4Or95|dw<>llqD=jt$*Kjg4_+%ep^hR3pAT~}=%Vr=H};)*Rbh!|-@6FH~vWk3-p z(ZDL9a+A_v5l(15l&c-n5T@w%+ZcO>J8QHm+|Chc%4vp`!?5+OW5NQ(lA zaQ$WWxBd*tDbHr)F!@XfPzllB@su5fzl-M@UfVs!j{GV&;T5`fRKXjSP zaGpOA-t`_vl#4-UB$Kp(R&OvAu8t%5+f`BPws!mA`B!>5dXnVirZ{D-IMUKTWIz?(}1gImvvsXm{iBi zz`S`zBcCCUh5<>>u1cOxrUPrk>SiO6%;#AKrosm*&{L$%-II-6lbc)|e)t%<^CZyX zTOsB;9n^1hFSKUXoL}=nyJ>G(`}tDa(CF1*mcj&#r{muusUYn)xzvgShA<6-B1Kjb z@fghY{LJMte^5o642iPCC@UZ1YI+{a4o#lNjip&)X77ue&D~gi7 zOIK@GGVvl?L+j0Y@IA!~`8tv}F`!aQQU+U84ftVU_uWpVuvv|gx%^ z+l4)w9vDkYE}H3!FU>A-P}}~YET?`NJF5!j3rdNkI1UDtqNQVVty|m&t(bM&{y6s> zpGzwzV5}rW8UXjqsoTwvmLiUIBaW=*(S#$PNGT+Q4f9erXg7>8Dx@Gzdq*%2Kl@|6 zRRc(X`wf(&k{DSnPXd^s<;nQO?LO&V(80);8~;%Hko0lWUr0jaPjI$_@7&$pK|&Dm zWc^;h-&=@>S7VFoKC$@S@sl_2$7*by4!`bEP7Z3_zB^^xuji|w1WHP_r2IHtc|wg{ z&ZxR+3<${&T z%Gj>d|Ll8>3HW@B0d*J11_aZ0Ix0jw;B>E&hOzoqTN2v z5SYdG9!7s|?>d2lQM7-W0W|oZdQ>0#OE|dh(~V2jxpg2@lGY~sq>2B9M1lzZWUHfO z8vmo6Q?ymrfi+kTG?FrfFXzx3S;{1dATj+TLMbrtDtjQ8n6w^1_3AZ zP}d?49l}-brgy`^mJoXb3cha(oa}HfZt72|@QNChC;9G#U-Y7HUxgeq51sHEZCu6u zy7tnyz~XD$qmzxH+iLE@{}7f`YFCuS@n7BkG5}=76tO)xR4d=qV4T{fRC75@rG>n% z+X}A)dw{IxY#9tAYK2EPd$Zm?K_r@1+{$6-4y_Md3~`&W(G8CO)N#EFS7cp#nk&0h zGd0EWGB|G#;rof$=xeueJzMfJeZHNjfL(<&Xzp_H~VfwdWcK!ghsN_Wjo*G4K zGI6WD<;k_20}PNb@|hHnb<(~pj#XcFgMS9P?uOp^hG0Er*Lx^Ubj7qNML1^rCQlyZ zb{MCwq&1-ci3{?TY4msJGqS)f+22wPyp*I{pnzHg0&F-UrGO71)Bk(-5kxQi-mEjW zzqpaJ7Qp47P@L#i=M{d9*;mx335H%!*Hf#`gg0Mrq(KgIW)r}KZ=fYNR#ZEm4N3zO zLp}4Fo2i*`d@~N8eq#7ZQqK}sy)NNY5HBb(=SqR3zg=U)=NyoSb!p?p8cZAkdv{f! zZP~(m7%xCtiyS_gUR$csz_J);EzL`t^mSywc)iO0zxRzOWL5HEs7jH;$W7a5K8AQ( zt1|U1-0SL1u3=z>8cKHCifSM z`|(3n%2&Ix)@0+qvFL9)?HljawMNfB>E6CIk>BO_)|k2;O`CPRtI9h|5ib7U{^s*% z?)c_fI(p|gtAyG_M>8LvvSOIIkIMA{MAGWbRgEGqBp;_kehaUMGDnLpT=k0TP0RX@ z9&ZNvq=RxUM-MJS71S!*uKccY&i}u--2c2TU2pZF_9epOOph8OO&twOt58WifIECB z$zbNI9gDapfhSd?{G~@Lfa%bd)Cs`(9A4Gmwz+DQHhVT-(tdWb)$|)JC7Z%u*ajW2 z_CZP;*1z!j z?LSYh{l9+aJ}t6M0SjpLd7DZ5z%h{{T`LZe=>^K|Z^2zXpF5#v_wKGy&!8DfIh=Gp zq=d7-M3LZTZv)EtuSNQ`;4_PFa-Gddu(sk8@@JfBFq`MySVo=bB4 z2a}{XXp>r1>o(~5S~;y%|Bq(S{_jq%p%kk2c+!aLX4PE>aE{`VK36^cmj{#_m14BqSX!(J0AHXuwWC^O2q}Tz@MYT$% zpfo&691s=9TEGt4UcYU7RRf|;-9uAHTH^!X+Vi6mMCZRMa~_e%Y(FBnq&Fe?v`QR! zu!767VIo{;Ojkg_Y2PEJ&x|=<-JQbz|vLx@3Og;tS3f3pXk@BHw?Mwu%Bj4 z1}01DLov2C&D{@2wu38oAC(^#FLg|Bt#UaR?Fer^d2#JMJ`-04dS*B$Z_P^fxH{^| zl}&yLdtrpado)VRC)_Vl#^I|D(l_@&{ciPUQBEx==f4(^-b6$Gv zYB}R@tPzLPliyyMd>{7Rk9X_th;Tjxx=sUM;*us2cjX1Mw@vZuxW9cD98;E^RmPuw z@%Z|SH^amWt1M(-5m(2L{NqtQ;hDk+1KxY>e&ewBEs<;vz#1TMntMY>W`v&;Xu^-Y z5yN9wp_@;%h~=_to~zETisU$Zbs%P#x#|J4qfh@%dpZvYK_Gs`-(4K*Pr&LOQ%*HH zdk26ybKUEQsO%>(BRGk*j0$>A5j9(Zd<#;C7o7%rF9t?myTtIbB8Tv?`%6-uk8Ihu z9f!&{_lTRcHE$eT22FOSI|EPSP=Uu=5R_anQRBU+Q-i_Hu(D$uDy;_8$6yr=8vbs} z|2vca)T1z>r=Rm>0iJlH51B~KAw`mE{^v-tnZV?xBU$TsmfaxRLdQW>R#qFa^&+9D z5=gagntV0b*Bs3!}6Rv#0K*%%Jy2lk8kh!=EO0bt;1ORgwA46V8`_mMGD!!s1CKs zd$LqXN%e^pRib@WSVyHjt{^zK54*EXkK4c1H8^jR?iNtV!LKA7PJYXQuDoEuh+-{N zYZ|)b%by1AgFSE@QwDNjMD2obVPu1$EA|K=;2Z8Nu0yty-D|VZiSMy*a@7w0`yL708ZKS!2P? zshFLOnktv(tq%~zWBL!jQoc65Y~uW9dHCU2VDADzFhGGVJS7unRmw|Mxm+^rCyRS z3dSH)xYl&!})vX2?;DeGT#&OzYOM^~yDt0CY` zz!!8T;wq@+o)2ysO4DFR$o=$kWV<|iGV9EQ{c-_mT`JA)8oKH@{N>y>?*zh_!0tJ=6sCWSgPgr@+9K_T<>GT3jRv zW^~fRZ#GGCTTLc1QRN`3N_`fQZw1vfH$E-aka_KERsQsQlb*KpNIZwqWFQVpO|Rk6 zvCcDnQeCU*&F*$;ar`)>qVeXg&U&kQNz?CaZ~J3|S?!RpbnI~!T=MW{`Y{cxXtN?X z3j^utU*x@@(Tk2WjF%wM2Egsz3%E}AlF-@I4OyMG0LB*dv2U=WH-Y>B7iBYTh2s%0 zFXl~avP)}b>P~(!5T*TkEMR{?%!1v`?dZRCYjYK$acVcA97Y|B8FP##VH1=j>Q?kT zvpSuZk6L*;CbC}LvOO9q1}TJ<)H%C0*KVm2?(iD~IO#{Jq4l^uJD@;TC>{(+TNbS; zm6M~A^`XLUBzMSWpqQbgu z85lz^&=9hjRi;K(a`UpwD_wVbC-_HWvTpU4Fg9n!{**YGAPzNp%b#?Hiro2Z{bWN! zbm${0IK~poDyR=>1-QHCOg|}z^~16j2vKMZkB|t9VPNVJfAh9r@;>G)da|zdHZz-F zHz@}c35F3k%Ey(kxYQCZC0HZ;C+m~Io`Y0@ON<>M2B;7ynMHsxOtP`Th;b>|jK}Ob zONOC>ICgU_Dzo0g-EMPbZ{f*NRV(c=?hUMFL`M>0YEHmCI&Ra&_-X zekR6c;Ta!dYN^{4qxr7xEcjCiH?Bu($0}OW+G8txMWa-?Zvh@f;`u&x+N!vph(9T6 z=WEHiJfz34dt@^_f>VOw$hSFBL9VK)*WCR`bW`jzFx_kV^r3fb>E6ewoaPQ#Iq%#PE)&GHzVL5EAr zbnJ(n&6~sc;IOZIVdJg^SInLp;c+!m`TcbLiCjx<1kt#ODaFdp z@mVm=>=x5?;@sfE5JB>(*`OC{NM_|HA4y-oAATK}NDtm=R@S1sC-RwaryjKc5(ZAy z=9EEFw8amMlvQJ+%F=cabX>^<*1Rm7Ei5sVo$)cTiz(?+u?Z6q8}XWke6Ct_gV=mj z^(q@`T2u{9t^kg}>0`}$R03<*XHayqQ&s9TD><=_ut}wP1d%9SCXbgY%SQR~ttT*V zqbM62Lplx9XG)tdGr=?`sg@})^b4vDMOZox%cD4Su0YHtW`PbARdOtrR43V)5AK}5 zBK2uwPI}GnK$!;EYIyzdljoBc{5Z? zjW9=P!qOP)x25eXllqE#=XprtYQCnH12`a6iVk%yixl-|<7+5=bVw^RF@Y9W^$7~7B>3wf|TcvD1+xK`oLsQ21 zMUFU`PahMe1EU}$p_aN9sydexQ_4M_wQe7~oK5sLkC$&&tutipL8wFC(@>_TFLGa7 zH?QQO*^~;GxFu=6Z8f@FFrR+N|`n=XhJ^36frvD&Q zFyZ!ocH>StmUU*<=o+JCK@rsC8#n3%H&rCvJA<-mZVP8@A{y3DQngLil~)p(ADDJZ z%f^z?xS*IJ5XO!at__8x0HVfMa)w=FFVch2i7nmeQxQ<~`?K@9ty)0OiyaSa0t?4j%DjHoq8LQD_jn12DiXB; z?w^A#_!FR=bg(_&i@1sTGaOVA73OY*&Zo@I=uxT}Q->}w?$tE*zV7aw+3K@)DAir$ z(pFybWGp~Wrlr^gG(f=}PQhzL@48P~0FU=7tN7^I>bm|w-m8f$JN+HN$b+b6fk%Q; zq%~%3FuI15qdZB%&{(hKGD&UleQ8(Ow@Lz7B=6m8UtmPv1nXfh1-vc~! zXe?*agF6B$=K#WCTu!1t`qA~!U<*B`-S5welaDENxs$f>3cGXIcKr~kSId?hB0$ef z>JgRk-h`~j5$H;ED)r`hFDAD()HQD$C>U-^1gL; zZ6>Egw4nqvHcM54)gK2VAL-IzDNlhSNaq3MvTH+1sjz3JHb6~u1Nd3#AYOu4gq^!$ zZ1wL{rFy!pc-VrkP}rZRiNJ9E!jAMan!tiDjng2;wc2&vmP+ z=9e(@+_m5uq2|i~c|rSD_lIMi)?Ds4z8b!-Aiy$sOkM* zNVL4;E;47n+5b9?0$$UAfs~s>Qp=LQU39z;YxRldm$OXEnl^Wk5hq0Y+fJYvWd;Fc z;#0mZZ$AHb4S<;N>ftEpO*c6Vpt^SC`Ol7K%;9RTU>MW8&lZ_s zjo7{TVoSPwj|(FrYry??gGbjSTaF{ z9o*Rtn=amV7+H_#B}49c0X6|}xS5py9lwfQS8n8`YWYf%KD-JXbJz_XY{6_NM zmys{yYa>PTeWjJ<`3w&bR5{o-tLdR0OOH6NlpumE_m6$xG7~wa9(R*ySE2a)Fx|TW z$r-T0ju?}?j1ybEaLe@684+(;wq$I%9Ra+lnceMnqn*EyR*+hU8`e4{CUsPez+46K zwgD2?(S4pc5uI1TJaKYAd-@m@>eM25eL$;H?fKdlW0dXgj1-OY+e-^~Sw=#hjC(}&D9 zlcg#ET&LiHM$R9>iywLN!n0+qR5kjk#r}#Ug=6DU5l zh&&3OR?a0?$totQHPBAo2t@#ZrsNSKwQ=IW+Hx?+-xUvEMH)(SMo%Bn0eKgYZGzgo zQ`gdcCSrw|<>rDO4B+Q1h$ipjSRk5YoiKPggv*2#WrF#U76R-l42<3RwYQ?`*u|K_a zQO#={4Z%Y28WQ594HvVP`P=oD*GA4eXCpUtGvMUa#c-{qVH%l_sXSEv3+WU2FHcJ{ zJTlB-QrU=ZA@;scqScis+vsFUM|f5&K5UvRBg>O@p)|Z6Kwy0{FV=E^Jqe8Y^M4*K zNV5L8lamMQm!Y2NMtog$#h&K=1`_aFzb%!f%>C4xLNX;i-SW=J@cO94Q&_=2>~R5N z102h!emkUc&VD+dg{ErYEIwQ{R0d8WJ&!zxb+pA*r9Gn+`O+#v^zhIAdzuB&r3SbS zK>H#)B8J@1k?X)vhb|tl7K9j+hq=wzs=eU7KgumU;RB1ScvAHkldlSL_NH;tJkRgH zkPZzL%JXq_mp;;Vh|IaWKhArFR^nON0Mmass_<>*{I>g#kQ{3KP;G6?2fC7(cM=i% zV!8tfaREc}VDo^f#8;&3S{OgohPk@Ro|)&r!ZPKK0%UQ^uxP2_oA7(Xu0@5W2c5v6 zG3vm}J?nwgi0J%t?NJQuYCdd{sPf1_KjX||d4MEsJNSRZ#^C|)$5$?H>wkajyK(EZ zIlwoyAe<;+%qS+G3`t2_0;T#x>1~WVk(>mkpS$W4qbs!sXKn5V_wmJ{mRKF+EVEDZ z+6XInlY*h-Q(*>HPs^>n4E+$64#2$wjR3Yf4(CQTRlfzNk?nrO@vaPvAou z;@YGB5fvZ<07$kAvM5_uhss?KJoo0m_0Nru``d_A?rbDRPUnQss4r^NDfd{oUaV@> zwE++Gl7wF8X(ns+qvQ*ncqwr))Uh|7&=IDTSsLfi#8(6N>jMfBF!M-)Lu9a*Zb11~ z)=X^w=0TW&{vW-O@q;unlbGg{GrClz)&(2=`=cahM^w7n26#)Sw$d)7acLBnl zC$f8yX$#bw{Soe{DCv_=x0+JXf?Wl}uZ&HEw-u@U(f2NPhjw4R8z1;zJ!U!($DdCh zesz55^aN`jj9$@<35D!F(OV8(f-4H$5lAMr)=A5H#V6>zy6pTpv83s2mzmQk?6w?ZOt)d+<<=$!(JG zEL-Tw6IphqDJKd$H2N~!rjjIZ9IgbCTE>#+9~!j&rZrD0Od6Bfy*Dis^+CIK9`Z3q z=e_eQR8a*a9Hg9kPjO>ItSmU?HU)`0-SM|m0a;=U+d;cF`5c(cw4MGIh(n{MZGmOR zUBX%W3Z1zbQsI-KDd%|g{-V^7a06xk(sDDzwfLY6>x$+%GXv9X^7~GM7QyEU?DBzN z@Qk*|FU5>r92{!h?`ZkwzI?@YUg->BC~bXR>($ETbVy;>8`+@Z`36f*v3E}Mu?uO7 zOv7$;XAhyGo6GnRN!}r^juRExfjhlq?_QnOq3VKF?Sj?Zn@+2Z=R4Gh9_GnY0txV7>kUccr<{6rk#SfyEhyIIlTIFbb?DVnV~(>8N=YF1rvs&Le1 zYO&P$`>;Vf$nnLn_7LLF(b2N5?l)2|%}!%r5AC-` zPD7dv_3Zzz4#zx*V~*$77Qu8@hQ4*BB z2MpH;KV;yg7rb9|-?|Wey1=Vd5hMTXrt{)lyXsctWT?8Vg87%cNv+!VZ)P@( zo)O-B)+#p{%~X29QzD+{Dc`IjXioUwRzJXkd3!lxo7;-$j>Ag;kt~icJ8`Yan z*ik%*KR0z(_2`Q(1cc~KvRibhbnl{bZ&*3xA|~V7d0T198GZ{1$;WXzrWWQP0a835Ce(Ep|@{++~hv=#PTI5Zz*%NyFXh z*1O`SffH}eCB-4LrEOx;;SBT98P=*v!yKAwhxSj~p2GM%%NNI?_Z{|Fp|S^Q!+V}L zIkg@U-9M?`tUgmM+7J+XI^Gr|W-=k5=gp{_+V*Wk)*~~#N_N5>^3jObZFKv+YOCUc zKn^*cRf{2xWdJ#bM}DeC{Gwm7-8N)@Fwta-d1~$ifAIFq=z{j#)A;60@5dH|#@+Sq z9pY^N`n`mQRp&jtA2)w;J7jrvw~Cpe$Af4T2yVQlcL$4}L;fhd)ly3Z-H9ITPG=)< z7~-&=#QYkKsU3Ug8KLoSCp&ia+Jdld=m{?(XrmA{uz`)=Y4q{?0J6JDAk`k6C95on zVRv)r*L4T~_|=_3^F!g`GI_mWUQR?sXfl3b`x5aTH^2Q_#m&$oRj)y+`$Al?Ay6hCOW{;X}{94hY*WIFUM6MxAAg^uwB9VU zqq`q4R;}L|u^-+J?wzHs2+avatp6G<2l#;mRqzqAftLen?$##78r6A$j-&ez)#@?t#VP1E|5$ND z-S*{Y)e?89#Ul9NbMdT=%TPWyaq_~mP@|$j#thxxgFGHB75b}p5+!Ea2fNH_Lt9tz z=lZfa)+L^s?wPBzKM(k*;0#}htH~rk*b~g}#gtYN(TZZQz;gH#Xu0fdu6@uP9F)uf z$hnK<9xnw|LTo^Fm`eWV;?eJ`yxJm-z<+9NeE|9jbNymYo?^viIlq^hz@#%*U+I{n zf}93KF*&la%$%mAew}fnPQko@xfily6;$o+0eNN4$XXSntc7@KCDC3Wa%TQsZ>JaT}@ z9=y|P)slJgNm*M!_%rx)&BbxJ=JY-w?${zCepHiE))qtZK*m&uqsmbtkoDrn$J9GT zdvkdw37E{7libhrsh7W_Jcd28CcIx2k0Z`FXnpprlgjarq&e=VOb|FCgeP?;gga#_ z=e0ch;x@$kEQN6#5XA%O(wUzGtv|oqa^2R!>C7bnxeg>=+CLKg z2DF(c3qyf1AT@Vol}JLo9g!?v!m-g)*5Z~+~7@l;Vk{Zot4=fuZmN(-Zx_LbprSKw6s zP8|Xn)lD&678|Jj^+Nf_zFP^e#~7fqcS?a_9=Q~x5s5?0J-cMSgOpl{%19;Cw0eA* ztqK)xdT%|(*>doNp6%a8;znv|-Txsp_d9mU{RHtKa}PAcAws!EJSQAh)0l~abpg{V%jPB7;+$?{Xcf7-%Tr`XZ1mqEGG-7u zV0YG&AKrcab#XvzykLH(H||40a>WjQ$EO*M2>=N4f8LEH=Ygq+t{f`fkb#5 zX`UXc^HRnZ)DIt z?_PF+u^W7kR^Tqnv7&q1wstISU(Z`r?IYq)nJ(j7Vr~L*hENbdEWhh1wR-1A%iL^S zUwavWZxhku+fjeO0c>eYkO4;T_mdb<#ZZWxksY7PI;?<@&2TM-dMgHLs%xY}p>cX3 z78t({kWJvK`pUH7Yia`$Dd9z1J;i#S1M!$ky*KOqV$-518n=;NQ~2o(f`^n zhWus4xnn%aCP~O2r?&703uq}lzGFZw9)%HXU9SX*dY;G59Be!)?{Fzgh8m{vWqEtt zy$axp+ryIlmZEmmp#xbqnq00-OGM3VJWMY|wF*;1;WawMMAeK?b|LY@S$DwJ92Sly zE65hy!sf;LiZhzw^P-u*T@Bqkadc_**(2;4~@&;(-DLw}W5pYX`*Z6IZWQ z+{&;#2;(GxcVt(Qi-GXaLug`K?H7L}0B6SbocTx~)d7&b(L-c_W0UnGmy#3am@8UB zQ?e|z>fjViB)izliK4T)VSQzVRP9EMs%D??K8L*CTsayKrNK@7TSV+gw`|EwH(6_1 z1EkGH9koc|QQ)0&WEtZU)3zyQHQQfEKLGOeaZ+%sgBl*+z&6?XqMX?6&6?^%jq+S$ zlyzUDbuTY8C3_cVD$L5`*w9w4OxDG8t%eXP2clAA3z^ZYIPwj~t`dm~-nhaE3c{O- zIYwp3%s)qu+asLmx-U2MDHEJ8C8zhuQG3f3_ z5$Wy@LApC61f&I2ItD}-5Gj%F2FZb;1Y{@ykq!w#&i8CQ=X>Al`oI4GdYsv_huM2Q z_qx};*0Yw_x^CS+XrXNC!+-#Sic{;(P^8IVtVNf13j?bNd)o0KQ$_hffzCsWktB=Z zIz*_LOYW6toj+)0NG01rSlI23p1)jR8nh0&j4E)Q$z1Dpz>d|*t0BRRad7Nc+L#Lv z%|N8Ja-H>2h%2`QWw4-^+(@@FkWH_!K!LT&PlZQ%G@#`om8l8?9aIFf6*~=c*eTo6aIpd7F&~QLZS^Ep;#`OM&XSn_#zB+@W*Jfw+;}vv0cec_tRxkaY&t)oKw7On? z>?tHC%z2zGinb@N)%=R+=884VlI4(RuJ7{>f=^FCb|}HIaZkKDcy6n$>5oJnoxLMrrot!S`@poq2xq7PU$MRmbh+Bb9F=JZ*L#e^Gm_$Lw1eYTi zn|wb|1hpJ`AKtUh1Z&rv^VO8{xLIC9y{f7wN93tw40`bk%B>U(^E+Z;@r|~P=Vvi> zKOPZ_iWqW57Ad!r$UC+Wz96VTYkCaQQjei>r4SlAux$cJoq%B^sm+L~*T$rR)XR^b z&ksNs3NC{noa;e_1i~_(FL9i_Xk>$0@i`$4W==Li!1Y$6)?-+ z_le6c=OYeU(={Ew{W`v}(CaXbZX^viQ`6US#0%p%%{Ay*l}Ku!UB~gT=e?=^r-Y7s z%St8BDwnx`AzrXXi+;}!7qlE|r$j~PRPbd)aG8Uq1W6JkdPE+N_nySmc?NVon*OS3 zlA8-MYe4N@P0=&4Xk$_lVnmZtX& z0%(;>DMe6mD?GLxQ(f#V^GRe=DzQl583&<5Ury$NI0e|psYM%fSDCO806+ui;0v<{ z{mz!G@qeOg55@XSYq{veq@Y|bTxSGqqOn8)yLEC4oTiN zjs`tau|Hi|u&gsqbOjpnYbr&ox+EZU&|d;gJqTxh4ja8@5>z2{!mnYVmvBStBNf{& zk5ETQ$dk!mcMX0Of3F=amJ_GH5YaszHmVT!0^3pEv3dCFj~%s&O6wI95iRtmK>fY- z$Qp#r)0diO_>4Y6eW@J46nAl!>=#9^6%^SDzx3+L)?gOkIAzKmF{5abZMApqs0>R~ zDuo!Be{$_F!=A5Uv+TNHWT0`~-VXEW!7NzXQm-jOF#8nO6+hcfH@5CL?kSz&`|7Xq zc!zA`NiDoZY)#BQjJ|%kj56CDuqb>hH_nw$M;WZWpu!U;`@1B+fFDs}8-qRCEvF?g zB#pxSp;21ts$l^cnGXM}2<9rV>Ipjwh^J^0>^(PHoYK*)D1={4+Ply8r_KzrVtbDC z-=r6~FQi?mdQi5gRPKg`gLm`ekdP=GY!xs}_E=KTdUJnt8W4}-GTJbzyqc^p|+JtJVw zVvx|2ZdlXO)EW#bTRSdP=x>4z^&XQ}~GKK23$?b|-x`ud7;%08_)SOgHtW!GLqwoT!;WhNo@y zH*&FONI$*?N11t`{TO1P`v(nMLi!dNTQ0Sr&SEGDG^kj+`w3J1#kqTvb3ZAZe#7!p zcd|OygmI_b^wQ@|a|U~4wG;WLgBClmn#{34OBpR(bFo%Fj$qYz3%}EZl5%Ugj4-|A z;44%53`Y?)C-gWAdlIK}P&C3UPfCd$J!(~pxY?wKwN}@~;L(pMCle_SawO0Q=)z8u z*7dtS>9nn07*mcc;su+0#&(fWX82Am@PvlBtZAl{b^FScjU0cRpOX&VSWq2dT^-}c zu8;OZx7)6Q$oKcZDSwUwQ%F1a_9v?MpBJknm^U7ry30I&qoIU^@lYvygGObl zO`o=6SPh7Vz9!&&sxr-b3sawf?+0pPsx#3{dV(!Ut0T+E8UjrF8dK4AbLRQEXZ981 zI`ehXw2@8pTNXw}u-~xo!{cycDHzwC2V9<%1}+AnS@W`9XNX}%d+J|%CPIxFQrHN& zKYlN$=|}3+C|XD32By9h{M^#)BIZ;f8^_eCxL17t%3&k$3^)lP%Hw4K1-Net!ITps z8n+HnE5x{&*EM zdaIHIOt11xh;`iqnLIDO^2?%P+L3RR(Kv_U?~`z9Tnr221N^79G8gt8YkJ)Ci!Q&U z7AZtbP#7~ibezv1;wMP;?yI|FFuw}4i}0SV;^%#VbChm=E6$6%wkOcK6Gp#0aukFU zsHVq^nYYyu5yeGn#HyH1{;8*he=1hio|WYJuzu#s;cfSolk7zH$jEA0a~&Xqa~0%; z=c@m}RI{6i!Fj2|{X{$bV~Z4qNl)X=78&Id*MLw%=uOi_K+4^ z$!lkx5(O49KJv0=4W@j@tzbV!?$<`|o6bzKxS_lw7oe2@#TrLIP8i7eXMyTQ#}+-0 z4X1z7(J>Hga^wjpxD7XWpPU}Fz1zr_4gVq?bY*1z(nK9+5dGbl+QN8`wXr@XjcH?s z;2`~q*nQ;D5n-hnleoE92r2~TicgcmYvdi_ot-LF@&1x>W-++UAedRKQbUC8kZbfC z2kX1^z{7K|RaYC5^j!pN%-+z(QNc`tM8@9PQmV=X{UKY@w+eY3?O~_U&Cd3RXlBz| zMWsjPpJ$4QLrqaPtux1pP>W4rDbA%Wq7_*a9E3&O3j&jELgqu$jrk_)g66(6)B(-D zY4b48-)4(L8)EN~2BmVI>VDmHn-!6Mb$>X@`hHIZ9d9mj1#xyg+n3<52ZK{(_CVPL zN#G4Iz*r8RmGd53%+^g+71gk^S-zrUBC?n$&%Klg5HX7-3vUx!FwJq@@W(f@0*tMg z`|`ez#CdHS!%*+e(=i+ubNE|XzKB1{*?soyD4KO?HYy8AJoN#$Uddcz&d9!oro!$S zW&s-5wwu)+-MIxiGwlO^113RZzOO&<^@j%HrAI5)7h!@@gyC$R9~b8ul{Z_&6@>CB z#5f`*$lBCozk?E{zDm=+_o%m}rXJ-yY#39|g74`wSn1y;uJV@AcXzo+F(UvTZXexv zlh?#mN}z|nTvyg8opQ6>+I!r&%p@U)c1${mux|d|eFyClRp1rF*kFFCE|hQB`*k`S za*e?|KqH=($cDVMnJ|7HF6Y=qxs-RI%kgp%Un&-qplxa7fZ_nYR|ntRpY;_M+v-$H zyw}4F!77s$DzAGE)H)FRi<<^ceCC><2e$90p56oTpw(H4mS8sIYFNBs*ykly-P-YR z;#lRD*$Lxq`rWtzJNeq^ZyW{2SQCD{)#9(MtFaf#TD@QFWj7A1GX03{B$OwLrVuv% zIH!rWjPK_ty1pOBc>JBFiI{|+%ON*;_`BQFV&z{k8SZUI21b$eoWdg~rE?cLt*i~~ z+LRpG@ROF{YKDXzLY+<;sx*YyD__eDocJ%>laoR7TgL9XrR+l+dZ^kNvH&l4=X&Gc zCy}l^8qX*}2R=;Y@-uE(PM|aZ(NE$oNW6{!v0?clu|-%zt%DX-H-j*DILzWaj{H$1q61C<+Ni(LfD&*4fl!)D1rpOcIAB0@cXJ zVB)ze+ASLH3cC*&y_}z9OeuwoNpc;xI6ofat3AccC7O%IjS^IQ-4&-2ujx2}-Kdse zQ_Pdo!suPf3rCh#5JeNKV3BA?7sa<(FWePN5=y8F;F6mfFMK${DH|=OOuVA`L&?M9 zp1n?3%693uLtJ4u<+dCej{xPqHf@GG9u&>P#k8q7wVhcv?K6Gdi-PQVIk8hZuoI9^ zjh*W%*u!f|trGkEk5HV#>)kdZLCfzM7)V7XZXx#y1(v@3ATZ>Xi!iE#!Bxqt;xPms zqkRqNrsfdCm}(1iTjdK24}XNjC=YWtM$e87mwBhWwx!ogJt2C=kx>N<4e}=v4Ftlf zuk=)kXL>-&QGs~!Yu8Y@2WVzpq)Z^4i>}5j&)yK{ApVU@(2;0H;QlR5`B#J$j11KG z~ygb*pJi|cegduTtA%wECm?m|sL`Kp{$8|FHnv1ce2+|P@R zeU-OI|8ChyuRT4=aF*OK_G!a4_VsTXnB=n9W;StRgLb)x=4(wt@tZ3tMpOh<%a^jH*qpq)4C*YHYT3E!c zYgs}!ed2UV^RvpL;%)37sm8G;@o^yRsbVA|Gkv)DOL<Qn6hlZ z^%u*A3Q4c?V!MAUZ*Dt)YNH$9e3mJ)p7{uKA=ShE8u7UW2fl}nDe@o$V1 zp^r4e>+ie88w(V&?9?kp9wQ|vt4*>;2TNrKehMeV4sNu&U>{%+CgBZuelqt>LP@ONq%9Y?mXaE zX|So`Dh=NFynHCFDWG=x;xwsjAp5p^T@PXY7Kxg)dp(~7kj!Scz@EA-&=86lga`g92-$&fYNAs8r3$7x(ay(8m3Lp@B~cSAU` z`sC9;KNRBYFbB{yNj803yCj51en2f(w2+P|e#@`9sokt)=@qklNXtTi+gW-89BVV_4}hu{Z9$X^=5PqxC>o zxdDCr@n`~G-7oyYrl2=#H6M(7O9JX5GR?$H18`Xoc}1C-hxBs`Wqzpl);dGSc*zaETSkt7b8H<;KiQ@$Km%sEH0PzP*91W;^ zE^6XnxGG0eyTta^51)73oWAl<*5nH)*Nm&gHO6*eU3J|C;XDJ4LxJY?GR7#8i0|LT1SPs!_C{??uiOLbS}l(hkW3rXxWbEtViD8KZbw~wC{5%S z3%$SDOt5s5KLgJ@wEgIa9oj7Et3D7M8yq{m{|oGzY%z0~KKQ`2wX(erDi^o+!PaUl zxbVJ|fS{m7WHmI#a-}wniF@(;P53v@r3%o02JNZ`|6P%fmXMDGBOx0iKmHr=mog-V|+o9g3aGM0auo?Zgz+7 zOC<(L;V1@@EhW!_z%20;@(0T!-2NkYRrLkmtV}49Gin1T^n$Q)>OIEJR8w{{3*-l z(O7v#!+$dp{cN-*s*U?(9f%cYPhk4C{AOWHzJBnhk&prh$fTbAUk zbUW|%)W<<=Vgv;f98SXP1~q7}A89=y?UX~)B`fRdA||JG~v zBD(J(I=r>`?&5CL+i(Ahwm-Twkl8X0$me>yMcC{R+e5_c~tQ6ux&G%U=}Z zys98TJct-oaa)ujGTd6=?Belp|13f5Hjcbv^k{SPUkcYToWluBT-KDz zxv~kO7~!eD=5Khh96revj$=CqA3CfH98X!(BfLVUeDROpH%LsTe z74t^AkScF@WZ91$Z;YVO@(B)SM^zE_l97&+5~YKau6c6sXPnh!dT!j0r4PE?6p75N zHKN{-sP2O9`lS(CZc1=Yvq>kvp(t68y~=nlDv|o3i(8pqOWks6QwzT%kKDSr6Yf03 z(|;Q~y>efkXoi1e6hqMN*_O;~IQWa?xKp26z_go-9Um#dDB=D}B$6SOWtI4U+&9jewggjz(dH<7U4jfj9tc2!vh8A~O1=lj4XPqWE#rN(F+G28J=2d@ zH@*kj>hpAXJO{Fhp#5TWJFnLJreT0{PbMoEsZ7s=r;wJ`JYt8x)l=#v$>cs2bYQlJ z&;PkxI|ZXzU=wrrRzDjiz`9;ev>*q388nm%y@AJ_43{WYSw4oJvZ!>Szt6||oWGf& z-RbjvODLgxgA=`} zMp<1TLGiZCW;xZz*KxIsGxTG$o@_Cn>TO=Ep`pzVDe~*{IO`~O7}9FlcCpC7L*z+b z8ySK&&>J8ZP|R5cf}OiQJ%BdVLG$Rj>3Hlb^-=e2axRUSgoLzpxi?uCJ7;+mzErl5 zO@PU4jSy^`Bs71zb`RB_#`cqBAY1U3YL?YOBd6Y%Xy(Cos$g+W9YRsSbaWsrDh5{~ zimnr-dk#j<7AENIPRX3k(M&oR zY>UHQtPCW+zDn#M0+6EjZkP{kPuWynKfW$qQogQwr6d0x1V289;?HTQ1_L5{;+mKm z5lArmLfit^kh$-jp0PeQZ4gRcuhT!?w8qfr%bMI&4VOtBdTh#q5YczDfR;nFff(;| z)bp`U!&@VT!6aeDi02z4KA!Vslua^pm3LJ7k^79TU&^&YC%P9vzDc4b1Z*qprK7ck zCv;MB`Ilov&4*{P8&^GLAd6$aMOi}FQIhMsy)O2{7N6nnTFW+No8GkGL4kbgH72y&VdTZ2lkULeIMLBPP0g0i&T zeda<-EZ(E}%2B5T%Tw98C?VhHZ646pR6lW)iRENp6_1WGoW(iZ%Bn0*0)QcvT+aCo zkd7_&f$8P9yWoa`=-$kObJHz{ra~!LEO2mpkXC1dkF{`1Wl@pJ^zpp3yK7o{x!2*P zihd^SwaDAp2-zoM${IesS)VT`s;2?D07f!>-I9a9neVIVzuh^&c#$uMbg;Jzi^SQ< z*R48Gcg08R<32ClCl>FWy-sKjaJ#gpm`lAiZ1r+t6YY3Gwp<=*z4i~P|OAb z_A>@n3ezF^2?@1QbQ#s1&WAdij0~m~#Z{ zb3`_Nx|I(`(O%sSJKqC1LUQz^Vt7l#r!#Z>Mi!8Gwj zHihR4PH~O6V9CH^hkDmBDh-(HY|FVYE+g9Onc6faK0>|MF9 zyK}&sTQoN~H@c!4YJ3ok7LeTHJWiivms<*2|pedNFkFBf1SwPvsF5nH*u6}Yay z;wRrkMJB}2fu7$j0jjTx*^rTRST^(enG1YFF9_4%%y4&=?q$%Vz6Rt1{Or7UQx{;1 zAP7_+hQw501yJw$ghifj?VH`8x(5y>p}St{0?epf=4)QNSa#i`^|ez5x@ts8^c`{3 z@(mnpc-E<})1)46f!aGw+F*g^QiQ(g0Np}o7MEAS=0!%i0N27YKp9MUudF`T1o?v3 z(E&6yZxIt@llW94i>?q7ZJ%Sl_Iau8`MsE@mE+g-nW)7G%GgP}SOc;Y7#qhxU0t#a zW*C8{oRRbn^%(H1*Rpble=g~3Osl?}tDIbExF~7=VLm#zU>#F{PtazGMBYqrx| z{kaxk4xmqtu~8#hgBPeo@w40$yABE%Hy8#ZKify3zT9kWNN;;Bc|bfE(5)#Xo(sC` zfB+$FT^*=(Oujbaz%!&QZ1G2d!N#Yi&{w_h^U`0Sb`tyvN`b-G-#SXDi6F(7#_5cj zR0)>0hhB?!8fO_Id&MT}eNCGCMgTMDE%8jm!60~J}fwr-X08}4c&tA-1pDtBsu0^gGi z#}DJ`>Yrh`#GY=wE>~Bci8U$CPYm!);O56Ujav9A2`g%qKcBjnm zZAjJTj;UNFe-65;hI2I!LoUHw+}GdQZ|JnM4h{>|6DRhAv4MnP7!t{81dBEeYF9+zqh`?^HE{9qfMXju;2>^$iC4^14!L<+}G=MwY zu+5H}`_#pKv<9QF+Vgn@+f<}?n7CXsz+3PdyRz-nS(t-ardqD*wNwK|d+GybnPB;y z!hLN51Fu+&A?gSWuVeW7K0v>ViijvUYE~S14alDXue7u(?R)t?$zl5J_8jaDdVY1k zMVD_7y^t3eY+E$L&%!A7!me34j8Q<&F^pg5AMe{sF_{rF$*KZY0JPAjw7Y z!?k`fKqbSk1eubRx>Rh}d)*oEi}Z!c?sf16rRtTh$lIekpykFk3tixUzd_|NTm9nb zb0_G=D7%~ggTVWgd(_hvuH2 zcVulWc^BJ}Y=%xO{oRhQ2%O_~42N4fnHsfpz*2NUcR8o{zU+7|5@BySYxj_$xkZAd z4*u(0Wnmw5G5&9@__X)}iVX^GuKP;?zT^5xoPVekLFi`(2)G2(2@6ohwltCvzaYMi z92wXJGasK+m4J(mso2&7UFPdo0&@pJHvGC>)ppHfo|wki(6$QT?$zbu)wa_ANaN)ftCr!8JL~e1XYv*`UEsHaM#+tgX5cmHtHZ- zZr>EB+V~A-YlA}8JGkJ5P2Me(t}0h=Pe8$4`%CnxGb*6)?|ZjV%DbLHb#t6r)rP4I z6hNtLW0-)WIZMC2pa89#eBMuK4@AXDE+r;)*83&dk@TkkB2a{2d65WKMdb8#ptGgg z(X`^LvK;`C6__hK?LL?Y*R?SFAJG73f+8a@%MD6t*NlJ2FV!9yaLG+x@LC8GM}o3$ zP#<3d-IM;6T>bI=X7>u)p#?iaK$uJ4|Gu|XnK9BR%1x}?6j zF9Z5bT~psx&6&tORSlOX;yP;*qM$i#Vq%*c6x_7kGH+a-&J#Gi98K@GX*^6F2YWxN zN7BDtS6u>%?OtrRqG_*NzR{in$&k>^fXo-HfZX~2mcd^~1SuYaz|lZO@Q_#HX@tI@ zg5B%Nc$H2Vf@hIdSejTu0PvOz07&ZTbWk%_Q2IoBMV^p!OG47kX>X$+DrQBd|B=4q zcL&;n+(+;%gZkr2Y{}mXILlGZQ#@#(k@JpKJw@(4SeJxX&}BaB%7Us|8~(iCLQwDQnNp$|tSn4StQRlD1F%yMb3s3?s_HsX$QBX@ca)mR92BKnF&t$ zZL~k{r=2z8mqe~PbieZMlyfaWRS5tQklAhRnbWa?!%$x{2snzLwe@F;Bb)jEC(;M? ze}sVn5uJ`K(oqfF$fQuOjMP8o~YLo`f z3xNr^f6&DgkE*1*dLwHz3k>1?-`SL3T=}04uk;XoVyR1> zSK28&K|Xf{CEPrX9L?9I=Ku}B;r|!b!T*3N%>QW&+kf#Jf||eR(%!$&T@Ja?L;c-L zoW@&ykcB`WsS9{Fp5N*N^5gR3wg(U&18aM9QR(Yp#^S&Qur~1a&}Vt>=mUp7-gAvm zu~4MNF}ReVrzke`Q1I<5&yi6|*U-2T#I07zST~J(K=G*eg>38ySn9~e?>tal+xhnm z|6+qb1QMW*s=3Aa+x{$Qk$eE1QuI_3x@ypyUH=XKygS_*N*_3GU~vNAaW`Nz1$3)7 zf?|hsP+g+38$f=M`{a750yb&UeZ?RlP2g)I!4L7wipo$n7t}Mz6aLRPw4n`J+du&E zh8_+r1{6blqB^PGIrJyj=6Ch_j(WeP{|#Y_cZ?1EdZ9*mk=F}rkMO@0R`2U830T(c z|1ai2SN88}`}=W0iU;~!|8v?l4&dQ{!)hmhybm2XW6Sg0&>M|l+q5HC3IBHaJ@fv5 zxA~=q?sF*OzmJvP_fHQRCn-7_Iwl4d4hAMVIyxHo51kC{E}x9nQ;#?Kq+wN^BjMT@a3umZUk#ksmPc1VD$8Qq%a;?(~)`NV?IROH)y0?)w{q zLzg`Q^5}UK!YED2TrOoiPV-`Lq>m2n4TW>HNA|9;f)}5CGr#wO?=&xps^Iz~%y&@T z2^a%MRkph=5hk_#fR4ejQez(04ChskL~!k>?zvv6PSV8hX*MuNtuOrfiHYU!-kc{$ z#o-kEb8MlAr_9~E7falV&g^J&iK*wj!|NSU@W!e~K$c}n+w3t1v(~A)E_%cnc#Y7= z{E;d59%4W3lb2I={d$4Ucy1Fr-SeOs)^*%+5Am!BUTfRnJ;m{$JymbXWmWH7)6`-UG*?P!=-TP)_$KYmL z7oENQ+T&{b0jl{RO>rd{$%91=6CD?q?0}(H<6>lItEYl}2y%ome{U}5@uKn5m)Z8h z-35cuvSZ%U$vQ>K9*KqcsvpgLCvJ)xtuYk6?x24Zs{8)Hm8jp5iZbxFcWjnQx4%@; zr1+bmiG+K$8Qt_a#lngHTbj-$^lZsk=e>8^NO#+0mu^ukZwX6&jucsK{31^;Mky<9_lS%!9R#M`tbJpB;ND+CZBvOaE(;1AMEOw=1sDIcc^xEZEV5+T9&iM1(JD(JT+vcg{Z$p|33yhTAi{ z&7E4`M`z2 z_B5aUl^bQR4Gu~ev1LM zcneq$bhM_kH@kHIelW3#U;dGW#$1CLA}eJKV*&k;z zRb$Yj;FRD%Ig?O>m3Q-nA9hd9DyY1`qlm0%y8>`lHf}D^wy#Ipd_qZp1eICrG_$Wu zgSV*Bs~~q2UCYd*{#K{hQ#7|+(i*XzZr|=GGoWm>5hydD!WV)%jwnVL8^xcT!sl;n zywJtZY_UF4!sb8m0X zcP!5k#vX2|VC+016&&hMe~FP(uyv$@v90F#+p1dZc^i9|c%{C*3SI1E&9h5&!Z!_)VjB6WW6OoKO;0Jcp9WFn>RPqe>~i{n)(Kev5<)FJr+ z0K}PUX#rVt`2*CFtBPOZmm6qcg#$Dj&3@8hF1+MMI30$UKI ztEstdq0188*PgCTK_;$l0nVd#cDyP%W}p3J!x*If|1Xpo>EE-@=QgZE0bD!iI`${C z>7-oj`4^}58(Kylmdtm=bK})rQBlQQVJaE=B3^JyAC<-rpM|gPi8r(${(@b59$kEo zCcw6RR+TiaT1g(Q^+s!EKH+-sG&?{sQ}cT<$^w%2ZwYHtBb7;vyeBkx$T=JC%|m#2 zKxL}izrYq5-yF;;sZd*R{r=>J63Sp!p_jGAl$Y-%lKyw?!+gyj(L95|;2ddjGg^7v zsD;IE4szcoWr5531^RIww0<;ZfkW8W%WbU{g4+ujPkxysVnpo)zloh1yJ=GCY_Cf8 z;o~bAlP^aKqbeJ%9PYZvD|aV#b38Nt7B{P2%Go?_ojCeO^*9%4ZB9`V1F@N73F4Cz ztf^FEi;ZxR(FqkUUKnLie!$qvNJ`HL{{`GUQP$#_%P+zCr^IZ zp=|S_L^_PzhnvKR-4A%KORIp7V2*ln=!SyTp=>KW0z*ooRXobG_nlz(swq%uR{x;+ei$?g zD9#l5z{?q1qq0F?@)gm}wMoLYhX{-`O|G{fFU(|~KcjU$ybtG)511?CAzR63XcHYH zB*ZxYJ?W8bQM5F<9+&b;SJ?S(q+pQx1DEsth8l%~E@7QL3(^!3>oX2dsdoo>m{t!{ z7Ko~)q$OD-skf!CaE#_r_IK%?F0K^D#E%BI;PXP2t94ey)gnTYDUCuM8m7S7qS-;ghDrX z>wkeO4=*35U$*PtC;Gt?@XbJPAZfLRVl&5nPvPb~f!ib;7jD|Us>#UlQNOv$*Jl;J z{m{EmH8)T@OMye1Swji{+^OS}0b^s7Zp~**ZkfXoel@gy2FGIpdC|)W&S;4XZTno^ z9Qj`u%%Z;vRfM3w%0zBcobzZuAQRvzZl$@&7hyQRi^3Co-}qiX>7k<)=MZ&F+k__d zy~sqojP;PsNpmg+t>vr-oaU%ra}!U$4>h6@wGU!jEh^m*;fmQv#q2l6Z5d^w=6i9U zmxb$u%gjTPUOb}n$3m~AGm6Bh@V0y6lwZc59*S*edM^#AOMnm4;8U-(r{4wugrY}1|e2+_7uJK!uvD}*>>Ej~I z(Mj>@LG@^HIxhN(i;$Z7FB5(xiW6q4Z2{5_N6hD&$&cf>9}HETi=MupAnkb*8+U8= zt#@0Wv_tIO!Y{*5Mws0_i@6$+W-%n>9&2ZC=DypUuN4S%)K2mQj3d;zhyymYdKTty zCmiS;%+A1xcW{0$3TW8#lxOVljyELR2p|HJVh6={6l${e*Xr2ZbD4wL)$vbgx!n5k zm3-CBr=I%9J$)8oU(0WqCt6r`|VpnlD+&1qP9i3{dY_Gbth4#&~bJ(pkN?b{D^9Zcm2jut}!@z-o z+8-^~D=~V6#d0*uhpW4+uKkB1sN4Phk-h8oof7`9nV3DT)Y|q|+{7JDD__lc)Lk(_ zmU)1m4a)5Cm)weBm_&Q!1aDvO2<$B3b8Tpdi!OGsgtg^*6A84ncaaYg zAd}LQV0d~`vg>zN;kuZ&OoEVynEMt$je}$jH)B9|Ai#l;=3mfJ@T&))(=G%q%p@Jd z4d@mB(W+%X=^%f=oFIGoYeEoqRqz0mwJAbsGP+IXg!Iv8l4cEX8BLt)e4=TN7+ zH6uHkLy0X^_3e0kBP(!S!!=PA*=*y=Qdk$y$5K>{gD^A~J03H;Nu#5=JTZBD8$)wz zFq~5>0(SLhx^{E#bg$62zxPV1wg&NV z023WDVsGapda=~jJpc3p(0Yi6Rn}wNdy<9CB1PP!sd5u7uz9Q|BWgN}+*DR-qif|z zko;xOn34*e-LFT~7oz}LU;t^vF()ddQ{?@q z+4BQZ%EZ0w+h_m|J0D<2h`@;42aw^M*IWz*1&}c+-yAWupCslUi#Xi&%GrNMbo+sk zyIehldDnp?m5;FwFDq4;;bAY8;c(;5Eu)97$jF(Gz}2bF9CE8K%?`1{BIUORgi8MPkS_-8ulQQDF4azZJ$Vehuc zQIQ?XAO=rAz5UcD1xZ6X584MufjuTF$e+}00Wrf?U4u7N zriR`R5vC>OPDUxs3JmQ|)fbH;XOYFR#AAv(9z0o;K40GaMBXMjj=X3LC|BuhORiBr z{$V)GO&I*skw{9gS*Sp7b~ zlUfFiNCgz?p}!5u#mKlA4M+Q$L^ty~@b1}(I6Ze>64OY zjRmp!+S;OG?+9;WcualZ%JcW8&a&UE{iCLWfR}9uvq62s$-oAj<=I6ajP+t&JKN;T z2|S~H;Uj%RngbbEqjgj&#f65lN_Tqiy=Oqt|R_SSnw;>bkjm7tWO z&d*NH4~@~3=!u-_Y6*YZJI`CNe`*=tJbzzhSGa+Q4n#j4eM9Z2qkG zpKMjD?3I}sl*o>hc&tCByci-`innm1^1ZT;RCfwk*J?B-HSGP*5S4(-8d0xb3xB%jb*R4H(e?`bAl zJ+Sr@%V+gjTVgaZ&6}4Y8huT7M}z#SN8PbeIDm z1(B$KC8Rte9)*~H{|UvLFR2rL{XAO^lmy%;Z=YBFYGUP@j-frGG+SY5|Eqgl)3jxu zM!d8G+P@gr147NoeB2w78`I%v|Avl?;B;lGGQB=WCADu|8K6b#B7&D1CVmftP-S9l5*W!@| z`Ja_?rva`tZhP+`%9y*nPDhW2X_mQSK0lvaU&qJ)e%mYSt><^u&zvUPT4vF7&J{PL zQ|ezu(99%#Eo7dci0Uyv4zrhw%@Ghc{uO{>K_qNqR7i>UU8y>tj-3eOH<8G4(#YMn z{(GTf4e&NTfVa`@InoZAQ))lv5#`?%JytFwR-PWhO)D7b~tS~;FGZNlPSHZQ;1>R>rd+xXrJi2WSR zQm!zG#u8~BhS_SXwFQYuTyc0XkFVtOQ6Z4W1?1Bm1Tm__rFlN zi5}4p7|jb_nN=LTBWZixn~@WI8feP2=etv7uL3l}`cU_r1GWRU9;3}y_)pbjtPIT< z(`9?H0@Z7=%d>Gsq2LJwb8=B4$aik5gy9xEfw$|RuyEv&WfBR{mVi0f<0K=xWI1)Y z@gcD(od2^+9Aqd@XMfE6zr#X^f34#5KYsW1hpylAAb?khmr3YQ@JAwL0qIxQYL?eV z5AiH)z}RqZ{p?qv+Mfir_`}4RR(`q5oI!t$ypg+%VJPNerv(_NS11TJg8)kHP8LXc z7d!j7slVL1w#aYyNm|qeF>~hwwlpd3>sdU0%c7$YqN8PPVZW+5=zWPK=c8Ue>sKZ% zR_0eS;`hj|QQtd&<^6~OgGN%8=(P+Y13QSGay-+dvVS?n3x9ifr zQj*wx0^|LTin!6u2Z~~FJbA-W9w17-+)hHZcNS+t!ZInoV?k_gentJDu`{#pm=tSRH=%`_A11kyu;F@s4L`=4 zEb0fwiT)_jmZ0kwF5}k;ZFEOohg*PtNfWa7r~&8H0jc3HK#T_oUO>{$Lwi-0ZT+7V z1*v8bJxk?PKTZ0}z`!qyN2uU85|_rzLqTs%y-%K&yI}b4h4B8=+TJA|gpz+Fz`wY~ zU~YcgMCC={kAh&$5D-UHuKP)j|`!ctiA7IS9Wk*UXVdGJ^o}<>c;9|-Q7_s@2t1B z+6lFKfGM(-p+@9V2HwGM3?%b^d94s!wU6ME#0#O&NZ97m88{ zS5-YX-?5LG{i8pV!X2Q-Y}&G=Dc0X>oIOxz#^A5b?7(45{62Uy8Y^H#vUm$tLe8Qp zZWBb-m*p1s1d*8Z&<*cF0E2S)D)Yev{ifXO2!}j3;)Y;ke!6fXxA$yVa_BP7t7>!_ zk%ODv#B6uJbi1`{EOjI|YmhlQ|XN2Ir-sPY};@&$bY@Wj734OOebxcC;!P z8YAIeDDdk#62zqnO=wZ3n$e)=kwfd$xs(6vy-+^^z#$F*UH~Qh!XH|0n zGNLSs%EwUHSI|7a0{wufFb|79Vl;iZ-dJt4ctpajrT5YItY+pWm#O_nW@x$2D;B+Y zI&O(K(<%4%6f^6^eHUTi07KQ$Ur%4$mZMcl{5id*RyU9<#EDOAH?QU}%~O}GY1$8W zK3*)xr+_~;sxHTKm8o*!DLU4zVlyrOU}vh^lgxKAk4iD?`_n=o+>%phoxWamqwde- z8dkGE?&BZ*RI$N1g2<@>2vCb;xpuyM&A`nE5ndhuNA zr``NqQl2ttZ1%{t==Ar|p_=E@=_3boqT@eU<`+9^b2{r>DT*{OaV7p-lwY$LeQLqB z>1@giM+lh4Eoo9l3UuR#T>e+Aq3F!6RMU`U ze23hjl~uIp{}rrE95MbmgGDGSd1YT5BZTml=(de=$z3JRe+_sa*tKXIMF+nf{ZEOA z5S^q1>&31Qugh4RviyedA8F4YBn0wVRCF=VHD(t$6|;|(1lZIa0puH?_SC>`?#xXn zV-OwR7^`Drn@A#0F@!&f@QDER5`KLOFz~>kh!)=$lB^<+CJTZl35gc)x8Ugw(wq9g z5wPTJ^Wg=5`?BWCYaKJY>z9!Z0WPEIF2obFqY*pVa1h#ct!>e0Se)%Rj9=DvcVE^A z*B`zwH$kIYcote_jO5^@Zr=N*taYG#|5)9P$N}vdl%1GP@^$j%7ot2zM-)IC>S<8xIc`fiCs!?hZ2C$IKG$)kc6GK$p zo;bdUCF2!_(hlc?Xx{O>P2~;Gf8A+dN?)G}7xg$YjJsdydBRWE?^G8=O%pgb816Gp zDx=(zx1GYx3nCl}fbObrgj1^BfBcZ8c~@a#H(T&nUASEtc9|(3v}Q3&ZN$* zTnTWOcYi@g57P&2tpom@&Sy&^1#`FpE}P5-=Iun;`$5L|o{9M9VAAL&ix`>?J_N9A z4lV3nuJxgR54$O#SV}wXxME}R3h1mH74w@s?R*n_J3B;HP`w%Q_3Vh(U0lPAn-DX* z<0^(XpCwq8vWYh4;QAPo*2V95YtvyR{rFV(hJ;;3wrLWoWJ3sl+(eMWb-)M?axDFR zf@^dv4uKztl8Sp8IOm&&F^dCc_7dFt!_-JigS+AgaQOHFVZgj|GIX?!!>b3R&+LAX z2LwM zSFW%ff0dn%7U%?scjzrNkogBRN|MP$n9tPcJ4dw(RkASmIaE@6LSFP#=wuudY^QB9 zRC26CI+2#C(bW`_l1%G)!(cXUs;1C>6kFd!X)S170~qt(Ea}fU%hQsF7UKCjaSiG3 zT$MyhBLpoXg?*7}?mM{Nmh6n_$arSO+ld_U;Vy|8O6+Dh{p-`_RRc4v2y=v)!h=Ib zd|{zT%keo^m~!LrFSNLoTQG?|ZgJGoyXm&;fZJO0kKXq{&fw@vlW)htYvStNqDx;9 zU#&FJlj=ePlUxrlLKwob$i0C;MXmrp?`TS3MNRVLNW?2C2y+e+ulBIBwbmWaIDI%2 zLGe!y>3#tvUf;<5&tmo#^-E9qdc@8#17Agmj7hyy2cQq3KT4GVS^4oORR5smq+Syg z7x3}B5`iW(!v3|Y9*Z2Hv!8kVzrh25J`u2z(%&?8l9|#1#{s+oG*y3TrjA{> zDw&<0aj>iX#_6j*U^RW@B)kJeSydU~7TqFPJu>>Wji$0aiTjvTb}ZRL6aJBGZiVA*)ub%f{v1U zKffC-{IHSz*i?2;)lE{ml1c{5YI_MHjv~bVSJ!DPA80p?9?j3{xk76 z!UE?mMhW9bc_WLoTb2`L!+6*CGd(;$&wajiT0O}Y{5j)FIfLgihA?x$90Rw0SG3z7 z_%;EtTW;JAuU^#BsZol9gR=j2CXNncRuV?_FR{O!6ZkPbpp={91cGJd^12YN49M=e z+%fSCnOR3F_XMpwtfe;|BcSGW=e6+*{?ZM1zyZaE-PI-)P*7gQ^8utMxKuQGlBg*3 zcO=VDYWD`PREvp4EXOiuuiU)vz*)?0_^>YFj(anLU_pj2XT)=o{;oc^G{}G`9+Tm9 zceUq^O-wOqcZ_AZt9wI(Y+!g2%?@m380zeFDgAPauL^L%E;@4ZaLM_A#JZsn@-B)Y zE^$^|7RViTAm@(~Z@R!H^Tl36F53-zlsgvvQ_)>S3P8(1m1xxNCHVs?qD}`W58cwv z92fdl8SZ%d?HmT?F)8_)3Q`Ze?({#U8=-Rl=eEU*ixx-{I9+UMi7=b~N1t3I6 zKgct@RZe_u4fAtr1j`|(O4VMUE=9;j06qaOzi^%;JH}kZ=1c~IE61;+gV+01d^Db@ z$^KQ=+y^=~Ea~)CwHabF6c{$0#mVj%;i7tY(kF!`W4EqV@A#U}^qObcZJq5sz5BT4?!EOSi-^ELRu=&tKVs}}?^2o`puyVFvS z#iWndB#45LY48XW9_k1l2|{k)6vnu7?;JPj_uv1%C|q^h%@Qok5J&z(<&xyvmYee{ zMUs_%;IVk>VM-ZHs@{LRqnp$(XKYntZmS=~MKlU!!K{nNq`@P!Aa2&bAhY}b;pXuX zgtm>St6J86+tOlX6+PBOkCxf%k9oEb!;_=G;xvj}p98!l-M!Gj*wLDLbq(=4guwJ4 zm)TXNHuETy`E`8s2t)u*z9K?YNp=>>!(th~v=NyXARqt^F9IY@sGz0nMsy<|6uS0* z0Y=KztMIk>gTw30?xS!5#Z|M%EePSA{Cdq2G@#l(f0Xe%DHhnTl71oxFTw|oNuAWh z@JQkfxFc`_D(g05X&?XP$4zYYy3~4>Tq$QMZK0vnf1S5i>%-1~6nnYu?xuDY3yhe!qJukinBX2vq)pA$DX(mI23_X)Ij(406 zv%lVB>gbqbM7d>L(A;XRKcwCSUS0OOZ>MH zAZK@_?jLN%(aci$Ta|dcVO~X`{n6vt0Gt6MTO&$Tg@ zcNLW9&Z<7zEW~FFD+}5gDmnN(8L418sD=vR4&gS&@$)KFTl11FDo(_+(z+_pc;8-{ zA(KWCc$G#zu(}*NIYN z7_4?h)jrgzqQuNjN`%Upf$O;e=26XTi6|sxIrN62(d4lxKZ3}A_Iwd%re;?l5&#!9 zKOLRtEc)#x3yc5+2zu0ROpF)?;(G{be8xM-dDi0&HhQ9P%v`YJ)TT#R6@lPm7#s5} z%^YCu-VsYL9;@PznUI?$5$gPWpL@lL&wsO=MJ7HWHt?@98}{O4k0ZuqcSS;YGylAQ zOVKyuf3ga=fp?m!auZg+!vYadye64cbrRVg7n9N-OQa7uI4{Qd*3120%!NEE<7r-VVX%K9CaT~ z<^Ld&9cdi}PR2DRbX{L{2(_%WU7@9le>AI>YYJ$a_P9MXfdElPiNx4xD^!moH#u|s zPS&^7-C<2m{fn1NM^RC_@Sz!BaJ|n>7rDsQr|h?LU`;cmG$9LwYw;|pe#2^}HXl@V zntO#-Pd5o{j`3Gxv`%=5f3MxXLNRIlzb?sDLZWH(;h7s+VdCFhmOrl+#G<~fqNhJC zum{#yQRWiMOt4TUrbEKgRdx2h{m4nK^r`mJ!Ktw%gnRRhpW11yRTgFPS>m}9ENWb1 z@vtEHNff`tKKW4rkQ4cX6idM@5LvW7cU=hvT-jHay+C|-?)~}QBDYN}ZemnKvv0vO z#4A<%ijH+}Nr1jm708fL06N(_Ji4%2X+$FPzZd&60?REIqLN6{of8RL6QF7<5THxj zdxn~Vh+LJ~=6jVU+#MI4k*5>7l00jH6wC%?HDug)@>9x==zvUmgVy(RUmVhRo}!F2&1=^%R| z36+%EfVh2?1q<#@#+dGiAN{PyKhLVszFU0zHmM?)s-v`_-wYqHJ~?MQ@CVXPz)*s% zLupp$0m_7umOa3heabrlI|Z`gFn^$^nnpnBzl-7Cfef9GjvSyA1zdF3qJ2BUbiv30 z2F?7`mifu~Xv?v2^mrzGp8^WM;vU;|sFhsn34A2d$udh0Y(iLUZXj$9$iDA;gl*drTg;V{J>winlt2mwzvJvMS5fJLj2mV<#gJ3 z1B^RmrJN)yRteN9LfU8uI>lNlk$7)MIpiQ$s#{y#G8#H zpOkJ%>VVFqcCsmh+v}q&>=%BLDCXafvPB$D*P$Uv-JLQc*MVe>?~H;i_g&Tv&_@b= zT)6u>Q(SfhdRom;Ie&uPBa*7R!}6V6N+#FG!~-CEc*et}1$KwG8^|BH}CpX|HC(nS1>S{HT`k)a-rJ%Gf9(T!i^B|&c@|J z!nyBGZJoqk-9GCT-m9g-hFN#f>0|ut6SlC7V?pu8>S^C$;k>Ho(*%wmeHsvE0VCKe zjq`-4-|~#vSe4$30&Hab+nPG()gcW7N)A(opGB$3K1pBOVl%4B^?(RY`4>2CSJ#_H z8BM2M+Vn&iLVstlH^f8?=zN3E>6ReTNJ`VVA*jzhs4Xp?~}wJwK_tjYGy43 zBaoz2jeMLHUIrUAuOiBjPbAO&? z@X2I?m5s-#%pW8|dKpFhXp8qbA#5I6+U2O}hhpX6kn@UUiuFgkhi>K?}2at%h?3wu5ku z=ibmh=mGy+YcTk%dS{J8!K*~L9vq6K?<)VyXJ@9KY||s zcS2ac8&RX`SlI;F`6?Qz_AGqhNNbGg+bEP9qCsd$?HpFomLs(lHMcq@#v`SSiNjUG zEZ>Ug1y2T)ttZ_YvH5%w9B8lo_>%{u;#>Z?xV4Xz#p+}FJQX3T6+yqat3YYsTH`-Q zSaW|`Gcm}}y;{W>>m*t_o0+?BvbSPw6x-rgxBT z0iv;FyRK~kARPxE?fHxza$-|^&q^En*pm`wJvP`8@Yr&a{HF6bNhB6+jdbs@kHic{ zMrvE5UUbYmD1lLmL`o&4_+wJUo*_seASew;2fe!F@x9j2&}$-ij?}gDBOFS-h(*y= z!PJT&OKD2YXd$xFmKXZdK=T8t!$qsgC!PbxqPT3_=UJzC9NQH4s%w&$h}kxl7o6^n0Lo~ky`5av~d zId@Bfk9K}l_?B|;d#!{W7HF`Mjo>sDh%GsDCE2uZ5nlu{U`VF=? zy&9WOf%o9&LoZ<}uV{U8o<`sjUosK}jJB6sO)dHN_ZWOlw87g}a*GXlF9 zurB#`-Ot1w^HE{d55~OfS?ld_=fSA%^CjdRyEY3HU~s{Xuh0}O$qam;f8?y%=_Z8E zt$%a;sJt8ETZ2yec}A{%b~Vahy_jO&mqL-&G?pVkRj5WRpAryd^Wa}Fi2>Jwb~@>u%r5$(+O$4z|pI$6kNYYBY= zRS91$q@C|+S$R!Hp2qn457HkbRAeW5PNvVW0~i$N)3>iX=v3&MyKl4KEYY~~xc1b@ zOEI{=;eIY^Q%mKf^`)7V<=8CZwp2tS=TpbH!t(RME@yThbf}x?QoDNdyB)X6@s#~C zy8hdoIZg_l;&3A=qLPtQY&dQX8F^$pxzVC+t zCzW88@^da(Tik{C=L=7TbT05(&x-dpsb6_MLWw_z9-h5 zekBz`_XKF7eA=WzMAC{ZDv$j_)jAD>EhSl7RDB%+QP1>gKz>jiJv+AY6!DkDBuyM&VPySa!4aQ|@B!beU%ISQWf<|BG% zAaLm`or$Zic5&QFs$Ss?s$~>X(SR))*(OkRYoayRgt+@%FiByHT3wr z+Gn@Esi77D&y{rd&q{C(%cq|aGrurm9j~jP@g%lD|KzKOvvaYo@-qb-f8QyeVK8{M z#6~!1Q_i~VDK?ii42#dJJC#v%Ct=(Q8o;9IWK|xyJGDPxsqtHo3<{_`<2yK1P+ozt zuAdwaZ{IAqaLY9L+yWK8PChVJUEDMfAhDM(0pTm&P$>WOk+Rw{;obqP6%mfL-S=*{ z$FhhktB5?uje#~d$+(FlhD`WT={`kN~YryCJI8Jo%^zI<(u zi`|;`6>a-xVT5)O@<`AXzt7D*ls@^%Tc@CPr>_k;d6Z-8(0n}*0q1XsKr>BR^*c5D z(VmmT*947;IGgF}Tsxegyl)kb^q$fw7ZZp}UQEF#V(Ig(NZ4eX-am2*)uB1RJaf}zH%yVH}&vUX5Hbl|229935lM0stWzixbfsklJ zUtNi7vzF*v^nDH0Nqi#&>vx>wi@;)eF@1bhxlZZL+T*MtvZ z3U2=B6x9&_KFjgtsC9u`+LgOxu}Y1|Sagu)AGAG}lYf30mP%yxjWpnAjx&mlL)1)G z(#sZ0gjSwV9OR z9uch%pxYvP%S(mdWVc&Cmcg3#1g(?Cz$I7dNL3u(6g6%1@l7XHMN>2@AO&~a#|oJe zE}k28bnXBboQ2BZSJ#|lhh@cYMDN(uqnhIh#B1ER51%h?UCzXx zn5M}8Qpp2acYCBsS?RzTqQCAJ`yLgZGq*N}{R5p33;hR`K0xUCuMH0S$YQ`PC@9{6 z1iFNfy)|Fk{>V-E*koak@va}}y-Pl!; z-fEF6GBxI?VwMgzxcbc;x)E37Y~PK585xM=I%L6>r7{K)z~LcpSp?}#RqY3s634Ak z43}B*uMah>wT2^0FvcwPaL>R)&x(I8H4J{B zn-SG3^jObN`X7wj+Pk}Ph{_Klt=~?fRI@+9xY0k!E$#PQ}&DXr}tRcL3AZK0jz9@Fvv$O`zBUQnqPf8JS--`X5X*w9Sx{t6LdX$BP zXXh@8ckR}J7Qq_1F_FpF5K?SK+^SHM&JMKTo=j(dCuub8$JS*cLk`=UuCB-Qc|C?9 zDX4#AhRoOT@YNmbjZmWg%>H0SFH%H}>Ea9oqYrHbl#MUy`pF%%d|h>9X$EU9=g1B( z2o$U}a2_rlBbp<&gP=y{ds-zNFfQ{XHCHjkiJ0DuD?xH|74mF(8cV05BGdHh10H^s z#__YDbv%qS8rB)fjpJSN5#`9E3gJRejz|=Bif4Eo9I}U@FDWlxT}ibcYED-Wf(KUG z6@+y{9O>dLv3l*keK)n9rnCXU!roc}-Ju7&s$UapGPr|Js#+nOUGs%7P+_N|buwc& zjviW6W+!S7EXA>aiCHe7Bwb2wY!Y@BQ+Ba7QNwCNu`+5*ve-_$y!CsqO{-yp_jW>`+Uj!|7lr!*~KewpY>}3Bw|r%2&4rY-9He+wWjS z%~fxjmdgW$)9$@`a`^GSu19^%;d328m$1q#@TCya*gZ8AUo*qg=&6@@y#e*{Ti||W zfhY&g5Xrn+|G4uj(J3iP?GWLv0rT66DE7xlo~<;g@Zce}ErQFf2d9ms#;LMOlCv&* z53PN!5$K*jg(7l!X#Itqjgz%NO~C!g=89L>0{o@`r|Ew>tNy=q8#*v{N&y^Y>1|A9 zhV<6i2`+2)y7k4bn-gyawejihhRSrHKfIz=)z4u3zQlfnc7G6CzHWE3e8GEsgJjsZuiG~Ya#G~35Eqz zOq*v|U#7uu37#u{lx39P34A6^8g2Zr9ev|6v3p;6a@<06`Mf%rwk1vNvN&#q)7puY zzZ;@}u}y!S^VQ~Pwe#HvNAnhXpK;j|vJDrsg$`pq>^GJnIyK5QWZTcDtQyV+Z|7=% z?bot}jp}YEJ5A4(Do(>ng|n`X@Sgadm!`ls0X0%49`0rkIBsftn@EF-Uq@_DABlPW z3eH$Oel4l*PWFI<9un^h2zGk+g}wcq)9<@Okr?F5-l6w!gO{qRKMXOVO(r?s-9>Pz1iPvx2yxP`}- z2Sw*<9k(xVw?T$-;uZ!&xG)&uCgm<^$7i}Dp1ek+kvsJ$<8eNhF?2Y=*b`s2e zoNAjlUlWDPVhu8A1h7J7)p6D?rFJCu(WMDJXBTc3vrL^h?;WHCHawua!U?3h<`hXBIhspeN4|g{9LK%TkMs(eRowdrPSq^as3Lp*HhyOV^N`xQg{JH)>24#Bn)DjUA`SL4h z*ASClkR0=;_r?B= zW665rL*}81EwffdUrEw~2B`Rq0HqANA~WLMSieO!GD zOdypoJCP^(Uss_HK_~Ol2U!o6tB6~x#O~kg_>>Dc3nZ$ zuKbh+1NeSb5%KSMGI@WBs~EV0`$r+a-wQaiNVjwY2NDO8`z~niWTOQ;Uq{cQh`0%c zeMKgyW1_(0qfCOPq$Ar_G5AD}rk=>ci%T)`UyP~K8ao3X8Rh@I0>#Vl~$;s$vY&r%9mW^AEeaKxTPHi-(*wmwUS6;ye5!}FV!^@A|uhxucHg}axIycwOyD; zlilrzzW+hWWBI*&S%fusZ+i@#5dDxtBxPsi+HEg|E8}KtSVUq?LGs+VlU2>^Ljs4q zK`vHS{s2Qfbkiqqj?`HIgIQt^OQXP}%30b`!Cnd4Z?Pz7qdE<8DB%@!isaB)+0^L3 zg9gxLVOLsMxF{?$h})m{v@_PTNO~r_Cw2bokS#Wy;&o`))m%KXbJQp2X8m2VDLLnM zF4W#K8$OW`DNcYJF{U-Omr z;|8W#nRt3&08m!~5l!QTI&R;`P&vR^5MR$HBv6+V&A1g37Q;R7!IX8GYi$7eb^o&L zeXkEZ_t_Ij$H8*_qiCUE`Wi@{$H*(O=9qC_PiLk-+|Ps;EvCP59}$*E`&Jl7LQ9+x zz)3xFws%f&>czt;%j2^SOEW)M6Z zQv8=3rLy&{fHUzWawXI=|fNA zFf;Z6QI-pZXGw%PmpR!k@=1n%E*|eYf@Ec}3To@0BU++r5m*L>=GHrJsr#R`2JmP{ z+cDXCh&0Zbe^Cx?ppE~RzT{P)hKKBk_L}~DLV~x5_5Rk>Dy`t;O~cx+%z)?CPh1_w zj80p1aepY>v=r3K6)(i`zK;~I7Jm_O?9#FG)`DMY6o0d;1Ds_4a;b+9nxdLVo*knuh(Y zXcQi8X|BkH@U4GBe34?y$-Xn;(pMI}%lHtX@|+QwokVcxgY|6J5I@GUe zj9hrzYE-L*3k@c~Y~`@v9T{no6pA1;EPW>fLeZB$M43-)?YRyAIcimjOnW(tv=!ym ztR_Gi!WUi5#{c67HWJGx^xJHy$`8zL*cLa6FqSOd=lV#>2{Qo;1NRponOK$ zhd-q|l2IoCwPT<)dhdm;3U2&pbFMUHY)AF<)8F)%MO9~SNJ|Hv_cYLpp~@ytrHRb$ z&?K`e?;-)Eu)K?fBMK*XO7$S@72%mNBM= ze6yJxsdZv-92%!j*OQC>c42OkJth_3QO^Xz&nlCBSuLwe<$1Ml*ii?U z&z?RgBezjpG_yx5_3`LbVlEfS_uqNDNu9aUX)|_RSnTi{tRko8uY9l&?{0Pou{sTK z5Xvk<=wAQ3{Y!00xF8^f=Y5N+pY~(L^H}=;@o?CqWc~zEBMH8_?*Iv3+OFhETUytP zVu-f`gjoy3z^XRh;{x3wBOymkS4Oi+Ux}i;nMNio&u_^I>BMB_OMFYjG zVnM;{D;)uRW0Ur%3SzY%Lm5Ye%zH|S1h>iKcQYpOv`d!%F{U3gEulc$v7(yF?c|?g zB?&I@g1;l4+EI67$~&MvWuqbZkipZxsoo5BhgeGU6QMg|Q9Bl{+lmgfuTsCOYhxk`HO|210TSuZCTMDs|!AL(fHWFSJMu;3QQh^p4mk;WH zLUx#-b)~(4L{KL6Ny*u2)3G0#%rlr(FPLZjk=Jm%Kq&nkL@aksR87t51a6cmJ>uCy zIn{z^eTM4fvGNQ^P%7z?IK4X;*&ir10X=ttMJi?~E_E`MPTU@CsfSt(*R6mF88^+& zebdU+bY$$?4N-)5E33my70!kH=99n7d=(D2twAahr2LsAx;R@t&t2kJoFd8~h4nOS zx`)`y3`KFC(2@Ltd8;L%#8?(i*>I&`q58H6rVX?VviDIgjN?qx`W=02#HfCsT zM9CLRwcdt!wK9H4v=0~Sv09;JgPw%+^;^4t`zetLKlRfy%G5jwYxXI^`Ks{+?SpFw z@shr!KRGRq?RM>;}Cs9ihJ!uHK2 zu7-MvxFS#hcLHV(NP%K)`6XXwJ3uD@Z(|1#LS-6!Zejsx^vdnaPhWlRS6y?2^S+G+ z*LPZ>f(5{HE@u)JM-NwR$w;P2o8Ji78VC=8vx-^AhVaL!D4oiIfl!$BQX%->jtD*? z`sUmga6QgzVE^ExmQp`iTnN=#>r;I3_0~rVD6k*V1?bV8N}rl^>Oet46ae9w1d~2T zh`hkM@Cw$c$K!;f@sjAXf`SX~%nA*pTr;+z1fZ_A;IMr+Y*@_6}`UeV@ zXe(wdJfeyFG>|GObBcyFR+i~}h65<+O9K7atA3r(MGR~w3yZf+-7QaK8RU<-m*Ua= zjD@vXzvUM|Bxv3FuF@++;GWa9e)g&Rr>H1RLc!4W}H)1tnql{9w%`@fYcMbQD9#4I=j6>hHeI}yB~ih}%a-3`MPi3}!6TGEpW&Mj^ez$_E`X zl^PP;!ScjsM3OmTiFm zU~Ie$2UL~l#RS>eFO(|fMdfa12C;KDtICv?Y3ql)2L81ZU}oLN$PYBK?6m$}vuff| z!tQe6JKflKIF2K3IYPF$5YFYka88hG28+)RAk7CKA~dUr6`sw+2g4Gpm8Fl+!!FkE zE{C@zQg1fhrqE(v@{VO`>T(PnY4>C> zBmLr~KOHFp@ql#xdC2Gj5Q%{$WO_-S7f<)(pRR|%_pX2pFewY9rQcV=wx^b+JfQPm z?6EA)JinO~@7J9aHZDGZ(^dL;`Hi6%qE%x%P9ZMe)y0T&RU#142zW)B5U-eVW)8Wp z_=1>SHYcB{bZVx;CEWO5C&hW)2n1q9kwqU`hO&MZuH__5x1RPnfR2RHlvUr!GnM@& zF#PFT#vP0A;$8~l#KqnTz3eyy@+H6KbgNy3NK~DmVS`D&?`u6gP^1sLxUl4e6x>Nx z4I6}&o1mhMC}h3WPa3r~YWu%SV=W(#KS!?C*Wp-h`jQ#3lu23ZBFj^6N4qf4EmxIb z8Hm1w@$f;IDUlr+L?7RXz9FBk#8rD|OxIV0drOZgOYTUn#O>c|KbM-bd44l}0g{?N zUbQD&7sJaI(PjMf*-0LYx=cyq1Iif^QE(WCLBfDk>_klXhn(-Um;(XA?!LevijONu zboKLf)eGfjxuzGY6YblR2XijC52F$EOM-|4~$DI!9X6}}C_ zJTj!~5_`%}2)J#EX*AyiC>$LGJ91VI%M`7*X}p`k+QULCOq2<;x@1?S`FJ->qPcT=9RXp6TDYV|PX#MQ7{J|-jiC;<|<}mPd1lPpO0k>Ev_}!T2 zFC|!w7A-^1dJYLa-$HR+yI80r6FjP3wFTIj>Ty<4&c6Or*e5LYfoBF!N0A3YJV;cI z)y?2u#{9l<7Gzkybtg5i$6AE6>gjC07hkSq&P!e2LvoJd{gh9$ggKF{Frti-@_ttt z)yO1A(jNot9cF_4#CpbFT`6Z{; zuzMDUv0o~QwfpGe$DyNB>X{PZlUfGL(7rfrbjQ_tBN!%D1f|5-l~69GSEk!nC}OpI zpM*1q8^_sk1~;nEjLiY^3Yuhevq@ORc?{|{wXAI5S(5i#oyQzTwqK;Zf85mZGvoTom7Oj)hTg1>lFH0Iw_NY%3Z7X$5-Qn$}NZnS@dlu_OO`m_EOC+ z7);Mm%x}8m@TTN#)5X1Z-`3vr=Oe(R7~A^208IFKgcl&m0JL63SRF-`O3tT_0|)T5 zW$$x%14GCX(2Ckg9=p*o55D2s0~`MTY{|d08kJd^uGBD`UjRB>5K^#4#aF=bw&$Fq z;do#Lv^Yd$W|by1pmV3~bI;ao%?ppCIN?$%XKqL({eVTr#U40t;v3Kcj&RBy#bqVs zi|bYWJpVSVKS1vrT^1kp_2Ta2Wixp#~mtTEwI&4IIrxa@4orZ|BUGn{{&nY&4Zt#NNqLTNU`8hBl zX_ASAuSa16o!~G0GtFpVKw%Ja7a|w5r>G4 z)RmEY0+Dg&bH`Y;-sJqf(j5Xh87?J`len){TT1R|&OSV^?1xF-yjG;Yw*l{JkMf1O zQd@lQUeF!@2KYhQ{KHB}%!T`wazrPTl3opuUp3DL15^4p0Zfy9$9S9mh&0?aoF>6Tm6LBLCrWXG;3*vLoGz^&TTuIsVY1~rdt%|;@~r-wIYA5sOC4@vM?I>pvC~PT?Je_| z;mgiF;pPOxeId|H@rheN*IHjTS7*R0&NsrlP5p;7b6=I?q>))rzEuw49!|98O-wq| zP${jt;%+;Ogzv^O)RtR13==J{%c)iK35nr3Uw2f$IT>qc9)P2_X`JQ_r-w5{^4GrZ ztaFf+U@ju;6-e~yy!_}OBg;*Z4GYQm?X147Ksq&PM7YzWaOHDe-Ef`ZQBTgd&^R_` zC>Wi4B&z2Qcc4^159TXV9{W6S-rqc`wY62^-Fe3~vPjyT15Z*a|CZG@er|p8`|@bk zOTl^;?)>b9#Jz_8D<)YVm}jbcynDx1O{CB73bGgf_6hGoT8&TT1Qx8Z)|c1dqda{? z#li(792P(F^^5!am7q;v?T(|%yT_q`MT*q8qoy9?bT-2=U0c%r&yNP#AYX;;7D8IQ zrbU;n8}U;Qm2q^)DA#5qnC0MFN^7uMv8>yX@DrtcsQCwu@D0AeH0R~Xft^nxs-iyk zu%^S~+XH1HzHOUhEi8y;kT0{>S;08Y?=c_3W4Sc*=q87WrsIo({CTM3RBAd9qISz; zsQXu2L!ghDOots!4T^f)C|+3^elv(hdcefuq7>!F~gTBogQU}ykRrY35X-9@D|h4wP#^FK&OVXrh~VOt=izcqN9-^-By+RO`s9pNF3+->Sg{h2R3vb2{T5hWStmrrd){k*ItDV*|DpIJ zzZ*ZV$#1IRqu{GEpa=RJ>wWHkT2CSTW2B#xj5f&bC`F-qdF>fu z_(!l{H3oU`<)b14%+ht}V#Zoqw!hd2I!gO|BFAltxS+CZlT*)uzjl5HqMN}AkCAxw zPcC42SE>fcw!B~u>Hn$0EO}H|9RADaD_)JJh5$%H_>F9t(T2}Tf(F+?A_y4%m?e~Z zkl*GcLjr@tJfEZ=XD6mPgPejqQms=+mP39Haid20A1Djj^7Y%D1}On?2o$hn`+@Qo z;)xe)D(92-Xqm;{^`4tbEkwW9gpXCm2G6pIA&j7Ng#8%LSF*3gONz)70hzF(3cIZw z^T=bo_&MV&h3S`|+RCAH(Z&%6ul0%D@yRMYk@r5RC93B=t{GK)J~lH2n`j$=8^}f zBsE*Q!xMIrVJkyWM#BVOMnAs-|2<-s zr~zc>Jk4NP%~*m^*!6A>itE{RHRioXwJqK4mV-oo!J**&| z8{t(WGzB?NnP0ettJTpA(eUd_{p6oC67+^bI|$EfP4MVfi~YPymLwQ9ntbjL^xGP4 z2N+{o0RWt<(Fh#3J-sO6aKSeM?v1I4313*(0|8k^%dmj*uE`Hv!YhR=(*`{qj zpZt1YMO;`JJnuakUK~vm2>%dAicc*WL2Dq z!OK)3--FO1-Y0Cq0m!WYxc}nE$3&*)IN-K^{Y84>UiJ$B8AXUm=;srV0Pa6XU4MCt z*cvgnVS&9qjhfCMq*}C^0*{K9rG8B3z_i)}OyW!^mIC*V&}}EyDe);Rj<1v$m`fhZ zGnwjQ`sx{~xXth>EPR*9406+iX_eJwIaxXt%|IORz$){>;jFkD+eg$Ufl9(2&E{+T z^{(<$x2`j*t)Om?x~_u!wD*AG3FP=ts8hsqc&P3t1LqhSdpCtxlR@5QqRov|#iSn~M z(`woW?d$gG_?WLjD3=_buq(q>cT_+@av4p^4iD}6CYZE8ZxvO@zy(S6PH`8x%8xnG ze)z8iU?TAU0qP5%E3Usgt{VWxK)7T&HR8r>xgp{H!^IKiUZ-L45CL_?@*_&?G^|i> z_&d%G;dDRZEJr|0;0x5b$rh-^{q1!H{qKUuxtv$;4AOlShayqGh^iy7A2H@4;&>d+ zH~U4gY8=3BpmT}}7}d7$O=8kzOH{R8uMpXhYh(1K3aXWWumh3SjMmtOdu8#_8wRh^ z@?SjEO%YI(gbjazP@CAM-VKx`9Y^k%CKh&NdV0+G=uiegA%zLoNA8)#5}PJH4E za~xo0u>+d$S2(<44ipX7DPeinVa3nV%B8n1#1J1qUe}%?jK7Y`rqF+?0Q5>??-)V> zKlX~@>hf^0po_jdfQ9f{=#Fao3cX2AteNCiQA=X}KwWGFEDPXT^$BUVmZng8NBuzx zZ-_Wi)1`5;c5g9atm1%hDiM>?Nd~4d_j10Ufd?CD3UsS{Ko$32L$v@-oQLM$+wPOi zFGzAK%%bJopOn!5KhEAduF9|57o|f1>5!1_?w0Nb5f(^ygLF$tcXx+?bVzqfH^`z} zq&vLN;`i?N?0xRO`*ZI3Yq=WmnRAZut#N30$6a6!;j~Z^!+RuZG-aHHyd@TNiuH!sj%o(}sn-RoEHGEW zS+-Mc8flF>Yj7iH5J7&4?elr1>*N!l?>e#w^zvl@{_GTZ6s-Jw>_#9S;-^yOw6)(V zwVws|fkDi$(Nd8Vos~qwAL8lA#|V|cIX+hB`f2U>zd+8*F%KRT$Azzb`Q)opTbm_* zIevX^qmjvA-!y>v3pGYV(p-Nq_`n`|?a0mL?a2-{Lp5TO>yv+tb?$WZWJB$$ogtbr z@YyPPb=xh7^VE=CYC0ua9$q4>c75T)OyKQvS9Oo9$Bcd3`(t*m*#X88Y2=jgnhT+C zCPX_6*kT(2_*b@%q|G`y(~9Xp)*Sk&)20eE|9Nn>Z(e?PkyD?|X!nGfD=~shwj)o+ z7SZ|3Mu%$1m^@ke%Kq+xK+{n)E*vV@0%irS;bF zJI>tC(Tyd}8$$1$F+-lIU#v2h%3?zM@*_`JJ@#WuR3@K=ys=Odsvq6qT=Xg?&ASeP ztskg9Y%T=!fZZ>D{2c{21hBRf9A@F?*44@Y+0DqfGi$v-I*&Ngu{`qfCrG+8+*5ge?%V!G@PDa;>FLsOv{!T30#<{FR5|j76SP& z^0J$fV=6u|Y7W2To zrnmeyMT|HFoPetsqjysRJvD#~9Gmd(b*<3BOhA6T)=JFkH5GAxU8q?|qjena7^*CbK1tv%a0V4|%!e zadS$!0pl9ci1(J`OmrKYI5`Tj*`>eH^A*|^8ZZ3*3$=`)t8>9_K!!sAQyn>rBY?5K z=y&)PjfmG_qxZkwgbZ379QX_F^~V7& zIvH*z+P_e`|Nel{$+%%HB-WrxWHS?JMG~hTfXjnjKa4|*#zALa6i>pam`s!>ZHBpc zZvKz&oT`D}vg^b9E-Ns%FjNzqt3?g1z$w;G7e^kCok#5u9P*jvOB}3!H(b+?r~i1* zMz6M<0eULcE7MRM`FTt#bbqa|h39UjCeJi7ULPiPBE`o7Yz-D}$hbu{C zajehp(g|gDlMgmCB%4}4((vf`v`(c)Y_ylK6Z+CF2I*tjBrI1D5N_Hz18a5lRjkyH zM$#u$G{$>T?u%nZWXs|0Vh`ed_GOdQ<6||C*o&!$2B3aA0bvYa2(p}N>SoW{4nG`= zdUr=PyA}ZSyx)fung;9p`NRX$Pg^+|nst3X%4)S(88;Bp?Q12zv5V)ya!dS;Gb&&jxPPyLsr3^{_ZFjj@s_ZmrSgi80+1 zw;G%ZW$5n2%5=XExfx+wjkL(?x4Bb8``c0&WC&|pXgswgYswEK$Ai?pQG}CO8Spnt z$$z2F7zN!`KVUU{&oFdm)Z9$Nko#6!dvfxAz?EWb$LIM+yUusQA{nASCT?WhYSQca z?{>E2I7p-z?~hcHhKDhPb6|@sI%Hf1t**;#nVRO4DlHv*Z?JKkjnMRctd>xeXHxpv z0-GxOqWLsC%i7yLRm?tl^(QCZmETmN98k6~`MTt@WD}|&ubR1Y*v(RNtL|`LrDJRl zR`nACCGfYgor8~45j0wzRUn(jXhJoyj7a`n9|rL;j2$7|x*tSt<>=-_@X4g>IoE07 zn#fx7VR1jWywybyV|I}kgkjKAX2ikJqA)42FPNnTSrQf2PH!xL7^j6V>|>s zH*bxL#!F%8#DMx39%JFTQ-V?rI?f5mPf^1{VMU)8mt#@kp{GC!tXrHP+1t>~A`+o# zkf|&>VpjyLpZrO+$yiIaHB*uesS68nOh10esAJ)I9^Eb_AYa(y*%OVc=Z)I**RE*W zt#3BteFh~^-sN!C;R!r@^8#@n3ZmxT4>MNTynFVoYClNI>YekpU$Z-8cxb?lMG{?j zT1T9omq#aDJq#2X81O1=#UMoLux96^)0iURDU){y%M&NN~XdpdC%YVE1vJC z>p#M5!=LxF+dwa5+PoD_(Qew_VX?7A^!V61^%FD$oLb$lw6b$>h+a!(S~szP_|_-% zSA_$Fp7u?4yy-~fZ|)Npnkla4vC>GBq0 z*MqQHrKTkIRrJ6;O~CkBeAeUD{{mf8p)Qt=hF>y4mdzvPg8$(o0Bx58)fR9#iJidl zbtMAl9$`n7o4*_(pl`uY_rv!To{N~6df}%x0p6=Pf2NOrV(`rB8`zcu9a9l{=SfCE zYiBj~fSA^qP!2aYy}M6jL@Xe^RJ_n+l$|vUiTf|qa7iBVLDZR)Vqce|SO(o9bnH0X zx|v_TD}P;^V(Ds}Lba%oiW!+EJUOjI5{1do61vnd`Mb+jBBg%4o~iHK$;)QpyiC)| zpDQg{LbrTpj|ukxuYp@s^j|0=e-2t;BE0K~GGY$+(!sRl>?fpQvyI}|yP41G4Z3<# zO`U9ORggqB#zMVGPY96pmN&ZBgTRbH5V&MBR!Tfe`)iJT%Scpm)y6I#P*YF6oIJ_q~)r)ViXje*1=hZ0F?uZ0U37L}-Xx z=VqkfyH1a(uUXH&XSw)O0vuL6h$-2LCOd+6s`baxVQ%Om>r;^e|{BR3AxdVhR zbCp%69YX8_QUNNf;kb5UJ`e6ld~2mDKuGHO>f;0OjC8N~XO3Awo8FoeqBCmR4jmfaS1BI7eG;S!#A}=jeETK%+sbZ`m#YkZ=E?yYCvW%@PB>|F(Z6v|U@hWL+=$ zXOOtj{K6_E1^-iJUQ*#nARGqWtryK+0|7Dl6ZNc_ zbIqgciFB=}Z+Y|(`d0zhJa!`;zOYo|KNg=hy(CSkDhUTXkHkfZc+IEl_$j>^=MU z4k41B!OpV(Yzlxdh<4o3Yv0)Kh*?em_uLT>y#{KF0RcWrS}N2-_I3WMm(BKwBJD_C zaR2EDlFOzR;)<6GERGk~>E-)IX26NSYS_5Rj4wd!rr5--jO8X z;t{k#i;j89J>qlyT-Gy=u4b1v`(-*T0+=TQ&QF>rHCn@QYC5eG?uKD|w{WXOu6Yg!D|3BUH#&R@hGevugDQBg2aDzOdM zeH!yUACy#EjP8#*ioJ*AlaGbbB9O=eEA8`~C2eRG#k>n=O_jUh{0qK=JglYFp8kUo z_H{MuTUKqvClJOd64&DE6Zpot=Ukj-gp~p!p>q85dG4%Z@mvt&50u~dde9gTY>Oc^G)BDoCm@oNH@m7-fc};!g>)gz6r`9;)sYpt+{p!cWrj>CrdLyOr z>pGm&U$Rt;nx!6y2!x?nf7nxKFcJ)Iy}$L3`CN6|&!CK8?MM~su2$*!yo{W#8K0NN z*y4Hk1zN4l^9%FE*R4e|!Ql3O%bfR3MO?d!c$i^$j;i@teq~=Or^d3;t1uCv3FrCB z2aLqw>EgO=bm!jM4>=+qTB|pi;}1DoMBzy*Z#of5KdK<}Wd!%a?o}DQU3i&1|)~_dzWP`F{yOUAnhb4Z-0M}(X z^iqz#6(r_?v%fhCeslKJ@UPd&4k% zO_7Wk<%JC~hWS6-yhgDsO!!q1xx3nl^U}DrD|^CSu>68F>^g$F7oGh?XEY^;kvp+2 zfykcr3KZVojd+`kpq*hYI={R?xAi8^1#t$=i-!hfGKq z`2>WM3w{pW&^mHN@I#4~UfhxLGW($v04Q}QJGp@e;`sWCzAgm15QQ~Y-Ys0 zS&g2Qk&^sV6p4?E6ewWKk#HwbVO`)b-gM_-vh^8apiBIP%1P-IUWl7748+SJi{`PK zw4coVJ%wcLsMiqOuGQna9N?;>4%d;vHRr>-&XjLwY_*hOkaBcg^u=d{{*1? ziIRJBe_4WXyU!lq*22!&6O42Tjn&2cC}Tw(l#qA`Rw^sfPe%B~E(Y`YJR=GUca@MT zf)umykp4D`Vgm~ey~vC~t|G!x2bTi3O(Faffhn6cXi1FetxE&LvC@pVDMrZQ9RjNM zhu0$C=nD?18O9_BAH_cN@gLB2o4F89N~$2-m3%>%rgdaWMW$*_VU_dfnpK#^p`!f3 zZZM?jEt4m6+<^$s`!OW4tw6pUH%rA|^-edr+!e@Hv5g7iq(_DxjqCwe@3EP3>bYP(@vRZnKL%x$QimmO)+&SU zFnieZMJ#djjIi9WFmV=Q(%=6U%?${)KY&o^Dr?U8Nn$1)~UYjI$Pf{!q0ECn|x=*j=5n|x?7Tn3+WW4hceo4f3R?r^%}YZsHi39{B4u{3EJ_|!({<|a=ujKyO910Er1}VW@FYB#^4>py* z6as!wU&DlQ{803KV}kU1^u7XE!KF75TW9@kv$3D$v!dBt?w8<1NqMIc+*$%VlWoz~gRvurPb-^!vg zjI1R6Ni`n^i@20^QN7%ri)!{Qj=|T;B?qGsM=ews zWaIkp38aDvos=3HPz#HqL~raA3=?=Db*~E+qainR)ajK$>2X?P4Uu0lD^GjTu!7I4 z;2JkM^u#uf-`HVVvK-`pZjQxR;agRrktDm=SYKhMWwH$v$cU&e|X zz}aH$DfKrGayAKY{%)kodJ3P*_WpZd2|s62jEzSp2z2Y zqqhnb2KU#+T5c&{u8u`hG_))eIteyy51 zE4#HE5pIu@p&ehAg-W%ZT=c^yMtA>FeZ;U{Ni|$}{Uhr6H0W`YN9o9q`Lw_2KBzw@ z?C+-U2_YPT<^P`$kVOFa;3o0e+H82*IhhY4I++EKyPB6I1MY0Pd11O?La#BnyqBZf z{F}28Ko>RuLf~X~infQDTF2~80L%KLB60R{GixU3@@X2vRTUqZI5j`qh8a8ZM*&bE z9i)WV;3ob;6u1S@$fW>gU)Dlk=IITP%Tf@0A79!YBgi!`){QzPQ|QEglc<{tA6+0Z zE)_+l2kHwh94^WwN^pq7m9l6e85N6?2T`MT#P*n-GaaKriKnht~-q z4VVN0c_H_fSNfFVJA>$i27nef$Ti235c^)Trl; zQho`_sBIH04x(Z~d4Okd!yJgTED}d&UFJ(lTr!ei!cVJ6Y2V&}S@wo44TjDB$-){F zPc0!q7ITNIc(8M>7Q`N~XE&GHWN?%AkX}!?Qkad-u3K$cL~B-yhP8GEuCN;`_9+-` zr@L^R2Pgg}?DY927h?2Y=zvVIRGYu;^%xLXAnO7p^cU(w49{+1M4zH_mF<}*y=%Q0 zio)(}HKT&N(dWBUW4k*Vk@o{d`6o6C{q>y7A3H@mi9xHAH9ssSPH(M z^83-5vE&+l-44h6-MO1h@0;vHseF5pmUo@WVQdO^8n@11;|}Zl$@6#~fVWj`8#(|R zYR?eFn4E!6fMhQ3DFQE!UchIBod!)v(m>cUR>>XUdp4cVIvAG+ck&e1NYSk4*zYLN zV-v3zsyBlXeS9&(-QQW;Zbx<7@+0e^brF%F#=BzNPtdPFk9cM2{t??@i9fVn2JI&| z9Mf6@NEfyo%%J4F5-}LXNNKu)!@+9l8awnIm{6WrE3zyV74J|bTiTyInW^_{|0Sgd z(y^9H=e+n*REFylvu`WuN25^GCalk-n&DYKm@$LnhpBtSVAQl$mQ_Gxt)Lx;zNJuG-6 z7rI+Le9jF-KR%y?Mv<^&I+Gl!J?QG7w{TeTM0Ny%t&fxywOU8+awE)@SPk~lu@gR+ zqEqgZBcU0gqC?lw&whe5uB?DSK(#@vtHil!OG082a9O zAPAcq4&@S%$SayfU>Fq6>&daj;mZvC@-E2y3x(TL3jLu5p>~n4&l-DJHW|)jfOR?u ztKzH2uSm5fM@EZ*bPYCG)Pgh#UN{Z*#SGr^_-h3PvtP887F?v}JpHwkTyd|;X{n(R zpmxwEy%tUDLmf{n7ykvmCp~QJ^tM@j0j}R(s`XM?3qT0x z-q+5J(?#)#v(069TTgpI^LCRWhD_%MXf;MAS;jjbi~RjZUj`c5BdbteXC}Rc1|<0d zqWQ2Dc!XswHrC#==@(pBgMxo0+7rS}QLn5`-fw9WjJ5jGN;Y=pUG+q}b1d9wJ9()$ zI{?Q8a0E>U+wW%pfm$Gv5TEuVi0}c3eqH39P+k@IihOhrVU!7@_Bv0xU4a84t04R` zCLMs0#2~B@fYGb%8-Me@m8QvbhJi?*{;`$59amPX^YBXKA(AfjR)1MT0AxD5(RHbx z?jzy#;I6}zGtm?RU`D{g;rxCkofxssF~`p)O3_V>aZ@xa?FKyevAcGC0w_qYys@KI zr@^qmdZW!W1aR^61H@b}Ki;7HWO;O-4-=+_yiv@+#C-G;&8w8s)Ou~t$o@|j}94LjPP^d(B z3d#ViT0xXQ?^aIMI(?rWZh#xJ?>Mzvb`^s+UXXh)4=y4i1iw+Sa1Q)dEC-JXAAJEe zoMHYfpx_@Y>NtwIC?bmdR1Y z`<{K>L6a`EY`?8q2 z&tZ(bcF8(JGWB4-;QhYeF|>!hmF@3PEWGLuaL7n-s9)$TN>2}`1^Me^&?+f<%VqvQ z@5r-@wmow=75q=H`A_f0eBBA_$rfLz)NO1rN{#JD)>ZhLp6QEb;vP0)7Y-Wyem6B- z)VKfgy&NdO@SE{r%Tga#eTyR;5@L|_SIxMMxk7grOW+PIoHjxLRTp9=W<yDwBJDvB$pG`IhRx-vGQj5;@{iD=t?jp~gR-@xMN>PfGWoIJx7} zt(#g#tV@MmH(nUZ?0R7YY8%>#Tm}2|)RGrYHm%Y2zkD3L8?$fg{WqTMPkWoS9v$_y-+#}eZcZEqq}5qOYR~6l zI%ns6OP@hM&VD@Diy(gg;n?d#ACbSH?O=`^2D6cV^d*HZ+f66vx?K*Ut^*F~s^s}U z-X9x|wQJ?aFfB)tz=(U`tiZ_2r@5Z9?9LW+k9PDyD~Gn%f<=Q#%=jzmYZ3||EhNrl3L&eq;U@3aWZzOUK%$D48kA11LUxadC{wJ z*F|(;^%{GD#9zUg6J(R&kW$&h|2`YY1^rb7o9WVkC++9(Li2PhlM0!{09|oEM50Gd zgqZu#hMmyTu9=(>CfK`K6>ZO#osA{~L|_9cWZ1cc6ZXJst01wHstDa2Q=vr+Eq|dT zI=;NdLua6e#>X{8KZB+zL+W;pP17RO!24YCDsH3vcsu|_ylGSfjt!%*sUMGiv;^k1 zEU(vg|78JJ3UL{oFzg13Y@2mDyCUay5q*1&2g(eqNn=VIxDtTk!|kK9fcCc)EyJ+H zdNW>-^B}{)J59Pr__W>JhQUdnZ$ULP@u0(Pvs7m`mcebays*rRh8B--^X|`oJOn(` z1w#Y{Yrtw=^;koUDXM^|TcM1b(IXN!%(4NqyX6gwNh^|9U2~+5x3#xWDbYyP{jmK1 zF0m8E{Uybj!s^0*u$c4>*!Dz!L`&PAln>)hJ<;5fAMIpVITOwGP#xOmad8)zY-P3y z9@rqwfYKwJ?8U;QO0c7rY2)|{Ma+c#BO%{=v_=&!f!5=dty0a73iUNO6Qle<_c5l^ zR(>4$VL63itXRVSct?}PvcIS#(DJ&(V(kR%;`uhg=sB}>risU5kcIxmQmHgmesjW~ z9?P=U&sO+V;EJK9U5x19dqSi;FJJY5Zqa4CPZiel;-gG}t}`rB3c7?GjZz56nS!sx z?ZM||Lx*hP$5lGWn5^JcDdppT@9JyyGBw@GTzDD0Gh<|0q#xkw9u0^3_xzZ(4wN{5 zV^Kvh)0dg;H=O}*s8gig77UJ;{ZWa`>Ok745Q1!c2RR;^IJap?8==DC;_#(F%M|ZW zJDH!+wLe(HyoN^SML|VU?v*-aLS=abevseBT7=jhiXk@OcRP@CWk$x)F*x;uHS&0s zVLm=gI45Q-x+t`GZElX6G_Hh%VY*>J)kit_+AmOA@SQ1;bEwmbKXB-a3@{_>9P&GO zSW@7|IbejaB0!hQJhe?!J!P&ko4@zGW|;PzR%wpOxaNn*;i0fq^7a<8;?5=m z^oK`0z8tE^-^_!D!ue>l2H&+a6nWW)|A@volA+x1u-UBB_xn(~dq43>;JVTqeEGRM zyT$ETY-VcAcB+VcK;_`R$nDGB4Fvu+9Q*xU=*tHEM~_#3x`@h|<^HKNzY-4vA9yXtbG`=2!Pp|N$tq3D5 zDOw(gy;;#<=K*U*InD%{uJ#c6HH;Kh7H*(z_b5-`zy)}4Ap42JSfNW(C2)MNWt|`P^}0Qz$#iT z3%fqy@%;h05;~OeGU7Z9BW+N)rZOxW0XxywQxTaPQUnk9hJT?3h2C`2q*7E)S#Hk7 zV%T8nL@Kn*j)<)(AUM6u5P6+1!d< zQ+(+aa`88hY|R6mY~W=0V#RZ|UnO?!q2=<035C}UkHGAMi8EK3zy`KL>}a@jWmz_;Cj2;|SLt*Ldt_d1M0De&mex9Q|;osMM<+d*C3_CTd^C zQ^Hu`r20fLXA7=SJ38j#Q*zm(5E_Z9KGuowd~R3x!4j( zzE&7Wy)H4>0>qSsS!>DdRbr8Mh`C%a_@i$KzqXrjH-YQ#Q*W-zhJA$nh#7uglojz4 zA0JES0nF=*dQ)nvNB9c3hVvlFPw)`X$5n{~5Oo4#E+;AQh0^eV=X2Q-?}YxGKne1} z!#}c3fZ17C+7V~`lU@HOlcwZPBA~IH!^_41TS5>WNIR;eEAg2Vc-bT{DXU-C=F7o_ zoRa1~U|;xkY7^OmxR9fdC@kWfj=bNFT#-q$&;=oXHn>l}mY>K$I39-qU>Z4_pu~~V z8eZL#%6C~d(l3;0aLI5ya7}5X)#%iqs43J<`6SbsFWwrH8;zGQm(P55dW~Dsg=nr5 zhklCy+@t~82l$9eU-QK>MlIR_wxUMxb-`?%^ACoUBq>Y}%RNpKY`i(9QF)0}W3NdE zLy6EMpw08}fx%@a)zpAtW$Ymz_&NM1K@+3Bf4#_VQ)?=Uv(yNIP?|l|0jboqhTHKY z)$i2Qv1ZkgjTyo8mp=FKm!*f>j+ZYj=NtORpRTXs`vYtK%*SOtyV7G!re&Nry;^gT zkUAFcH({UEs+?si#_cF+T3MuGze%FPs!$|G7elMQPN9f6~tPcx65jTT{ks z(=5F^s*(px-=FM06Ch!%>oWFavFutpL40cqlGi?o)}V|RjJqtN%K*`eV=-$c7Ta2s zuK3yMJIblEi(-qBK3wHir;wW{BWj2cj6c~czgE*!<8}CswMV>}bvqWerpXH!+FmYV zn)FN1&pj=qG$Law<|?f`XRS%AS{LG}Wt&61dSbCr)Smw5SVHn|niDOKUz zUloe?H)&T4#Qo~Jv_@D6%q{!HtE@k#jc^0Zq2%a?9lergVX;z2_}Mh=i+1_l<2oH^ z5@+@)*1(Aoj+TR|M0q)$)kH{n(#OASy3y`| zt3u^~nDNEt0ukB(q$B<3?&#hVrBRFH`vN73rawTZm=yQ(s;pT`<3J9P_sAY8TK0&g zGXRJ!_%>C4rc`qVFrMKreIwG>bitVDOAbNo14y{9alQ+A2v&2uGE|R%%8)>Ud0o8JDe_W@^xpHQ3SMlKs~Xzfh9Sf(kd z=0Y`$@vzu^CH-`a*MJf~=4^?uv_m$CO&qvT^?=8RH*Q_tl^Tyy0A&1Da zaLc#`yncP{oa(3nnOc~=CYbLJk|bl9?ReC98vcLo(UlYekH0l2@;G>Q>~MtUIiWoI zDcmoFwFOIS(Oq=58eSzk)Gk(UVo>wqix;X*GrSRgYyA#fan|BJ$43x#{0;Bw2oy!Y z)_b9lTb)&HxGab-_X?ko%VCtra+&|UvrS`rW$m|1DbjdKhP9PT4BbsQYcGB#e3Wg( z?5iSj$2at*X@+iWQNp_^p|+g0W28DZt#_8P9|q#;&0<+?@%L_G0-&l>Bb`tC9&XOo zVMsI2{z4V4na)m?gP#51=MK$2*b;NhY}8lIa!mLb>wtLm) z7(rM#h`pXfxd?E270??UO~rU}Y%81IZz<=-_<2GCIv^LgD7nNCBF{c+Dxx2#*i>lkh#ylHccQSCC0qr(=ww8l1bzzhhdA@dJ+gqIG zcQ+#0?*wfLRU<{qM{VqSU9iakpIqu^JS#CQo~1eCl+8*c7K_P%vutd1rY~`!G^!W5 z4OQp`MbXKSaeNYnWpW(rx%Iiar{HQ^;iXQeXky2oY&TJitF}Dh9_~Nwz1=DqW{OIx zJWm01HCpxY#9WMyw`!~cZ<)uJSTuQ`kGE_v*V2y;S7nVDTxLlYau8vwFj?mEnSZ{d6|&438V( z*Xcdp`!|~2e@C%)^Sqc!8O3HG`Qr;Ck|A8sUCo$*EAVSLbN{Plew?UL)2ddDG?uq* zKb9^tJ8=5QLLYvdg<6sFP^A2N+y1tU$`&`ZDG9^`rOUDnIu?`=7tq>0QhcpD+uHBE zCyu_IZMigaCRfD4Y#YR*)saYwfzh1u?o6g@m8@wmg%B_QMuo)V3MGpNaf$cfBj9%> zR!_zcBgOR=iH+}?f-{Ym8CN=KeMN>aXUEyrdfwiN{T4CF*GvFj)~I{&###mt^$Or1 z?JJDk=>#jgL_v`_%76tYl9lNjm0+vpb6a!dymuUI?0(O+denSRPRIPZD0nE!W0T0} zsno)0_=PO!8C)Syx6;lCx>o+sVBkaFiGw8iPAUo0pgxoM4ZVp}l`-E8JVPLxW#5U8 zp7+6bmd5OQYGp3AJfh_v-c8BRQDRy@WIxDkcmV@96wb~|6_c;Z#H0s+QSd&3FDig8niat^^2K=n?nn%alaqYAMaA9cA!wkF+(Ik zrR{^O{UWc?G>m+*|3xIBlY+)nmPjP#*#~p{(KYKJQ;w^rfwGqJ!z=D7Sf11Tx=fk= z#LgS@i5y|?yNf;G#;GPUUD3u)7eW8e|9a5-sQNV8G)!5Il`IvPeHfvuS^&x>o`FZ* zfm#z7Rf0lm+wK|PEbcAHZ{DCqBf2XU2afzob^)AUV>@SZ$Y(08x=0b<`9V>|j>VU! z9{2MJI(6MMe`f9Wi*D(_nbMd_XDnb1;E5z0ncY8R5@}i5jW|BhR|0ybpVwB3WZ*EG ze~{Zw(~0uO4?{{qz^!`A7~y=h&W^S{Da&Kr z4Ox#RhQ3#MMBPVBfXZ1InkJ*ZoCI9;BK2TJm3I}s14^e`2+mH(i~@nbK6cCO5HtOS zLcKNPkx(GDt)cH3M{2WwW&Z~^G!0iGWaqyv?j>EvL+0h5rb~j)c^)<58zU5SMk;ar zneon3a~ z8FcN|CO|>mBQBImgCOf#bg+@(2?%atRH4qR&i%mZi(@>^nXG+<)J%3_{s+96_w+3e zEBYYAw1GMRt`aIP97SW*;8ME2EtAi`dp=}eOKS+%h>KExLtgieQTl|7>1&AKlVz67 zd5o14qud%_=Np8NUKHTUoe41g?=F1#GF!n_=Pe0+^1VcsJ5igTaUi|0^!dW-YLNIF z>hfTX9-b-2D&vyfAOr4*K5nUbDde5MP|DnK(Fv%}YaD6y9zjv53Q|l@eZvXV3Xm~i z3Dk-S(3Gxp_4tbKoBw&>d(GyLcZ~`4$ z)73-UHD-**5|Wop_#H<|dh+u=N5E9WLb!O>#3F)67jPB6VC#zKiS$H+8_;(YcuZ4_ zADh*CogH9rYcv=8Nv@7c-OHFK0$=_iqNzFz z@}RpZ^2v6Fv^*sa8$boci%z3{p`;BK@C8)Mkj5GW6m0+4w*jT|2+y_jN)OO{(5><+ zE3ax_l|J4oZUq2b)=TFt|5JVLIxoo8yhkwDljIq2V9R}Cya=%X>a7X@1tw5;_Ea_P zBS}6}CxY=LK^w??hx;S=hu6g z$WYGe+o?$=sG{U=hp~qY3D5x^W+U)_=rGjemYLY>>FYsI&H6(P%kH5et~F!x>9{}2 z+`tCpmPEWYb@53$1QeXc<%Rf)D1ofZ~cWLxnzTj2KoPqM1T@^ zkg${dIi#&5MKEjA!&YeSmlYo5Ol|g9*;CRo;QxlV(4NG6lqN}s272L0<2PDkDnB94+(f*#_@(-{d?j^Q8McmFb|0u8Q0doOSnJ;8ZVUv$ z7*bw5H@&XY$Rn8J4yx+8JmYeZZlu8~@x+i}HLRN+!J2suEG->q2Uf@`rZ@ zX`C(#d3Snj*&t(aONhzSX@pfPUU=t7HNzZaN8W4h7daQaDTu&~7ZK<-9h+F|a-CoE zR*`gtMsAUBu%BFedG+4cLc+xOVrtoM1nIaVbw09>wbQH{5mu8o)&``z6Tg1cVl zu?*E_w*1XVR^%Z}%4LKTAAN=WK+Ph$8*#s}9xa=iGwN5Yp+h$UlW z#`5E758$k3MxGXVKoII%^a(ZOq5JkkEu!J3U4f}dHO9BW*!uSxX9bb@!gi(7#asw~ zm?m_W&4AhIAwmE?Jj+wo2q%nP7T4j~o8 zWsz6FY+iS~sGoqXWg`km0aOR38F^ss1)izJ<3E%=>Sz0`+20aiQw;~`I?2c^@dnt* zB&YU2Th4yAl=+|9iJ3kLj)rKv`pJed`L>TrE{q3eZ%;eu71mGG98eyC-bCu&_cI8- zfcwEO9I4vZf_e0Y&~G9j7R+JO@^s*tAm596hQ+b#XA_t0rmLCtzBxI4!0bMubDrhh zHIy4A{GEA5Mmf*{!CM+Le@*7#kzi9_H5Nh4RO5-^*hv_vOz=OtDrMfA&f(J~By8of z1KU^^6&H%s97wViFLY+7tH`|u%i1iX63r}yjWsr(HPOf8A)o@zY-$I$GF}9gOZus- zRzX^mg!`0CpEWBUoSy+)bdl0a@-y=njL!K^NiH~DYy-urHbXQp|mF)n>iWW(5&a;!X% zkgZ6W-4U7MXpPQBK~4#IYC{)m6ym_wK~pU^IaD;!az*c`L| z^xLCqAnBLwGTRMj@ofr;A{~L<=`vl){2nqOcP<=PvCXOZxMYLZfnK3c=hiP!mj|Hz zcv^vDGz}mRlG1r!eJ+EV5JV?xw$aKLz`uyEXMzz3`)M5!z5!Z>U|!p>6EUh^THDy< zD-1yE4KRf>Ex)To>F;)%B>(qo|HUS#4b(@FYKQ@l$1CBlEklBoPT6*@{!ttt?Y=2k z>jHN0+#K>tbBIm-W8m@7HL#xp-;eV<5zzX?l^XmpayM@Z?$3ufWI+gKMAs)k>2%2& zJ+~{JtUM7J$5;>i8`#wIu~2?`nDd-kiN~{aK6<48!h|vIik2AymH`VgPJbjt#zAq- z|HYLAKZ+ara3@C5$XL%_}c%4V{g?Id|OdEF>mHddoCkg#oofvHX;v#ra@;UG@NBh9$T z{`!!d*Jz0strHaR$A|7Bsk^4NPV;zopaoov85U2buV0zgQp+Pw{+ZKV6!s+nvTJ*I$i^F7 z8FL%w60P&}%+(C1Vy61}2ut%I5w}ABY}XSY%w?p@vUNNy0(Qd6OnXdB>)}+>7zK2D zGY$91<|7cChnve>7%wOA)LWKhk(pe$EvJ2@X5xNQ`=UF} z=9^q%*~i_PlI;b!GCJyuM`cFa`eb*&4X6BsKHx+JeIcI9qQJ;I%l-tF?9k zCPNzF<0104avUJ4;X^EV%~QSJ5h!m?erDH}OiFjQBTF5sLz;~L6eJd~^EKfF(i%XN z;}BmLyF;h^gDPMHSsRqBccTEm?DhrzLS#T{4XhFU{%8JYAgkd3qAXWB=<)PD?BO;Z zr2tUYcL+wV(M9U*fNT7Pc>qeHqA;`92iy~$%y`)XGZ62`>mQYblDvRC{InnSWbRak zSC1ku9eWV$OF;@qn@BA5om3)Z5>tQ8vnZgEo1rk$v;A8B9~uD2CB+EhnYl=xWFlx< zc~p@Myby78`wLZ!8$8C9!x^vl07~*&nxbA&_~|!K4mX7251QU{Ge%4Yh}&T zNe|Ln@VzSGbq?F|3=N24l^qk!tPsn(RjuD-^w{1pE^-Tv$`~F6%zL-y1g!T&S_!vk{Yk<@^kT_Fdb^*}zt~VQOdqF@W z2#^F6Fp-(I^We*k^XO7{;DW>>`IPgb$Iw!eR{Z063%N#V2mpZ^g{kn>KPW0hyO}>4 zD#QffrQ$sF8{Ak`ht>A98K&*R`9e=^9759k9lkzg+rY%X%^6`V6Yyhc_4;6w{|kFC zyNXgLBuq!9SSF+AC2Vrbhh-yp2#w(A8KXLeyBbDlWW6U zBdr@;xK40OFOM5_`M6vETFMsi*7ifdc@gb7ZtAOV5~cX#*T?ry=|T@ncH?ykYz-4fhMAh<(t4{~OAbI!eY zrrvkvkD03Pt2!0BVRzG~SZlB6`Ps9|Wm);ZEvx_g0dxGZ{+Nst@PqA}k8jj9! z&YZ;{$clSE%Z=5msNc@@BMY;=nDzL^&j=iqDgNmj?gADG_B*|gKzc}!lTxVkG);i1 z(Ce8(Q%U8qLF-@s_T7K0-u#}D4opZs@alvMKXn0ui5KbHO&mlAgjLxmO!!8mugbr^ zePkf}AQ%f{h@FVV+Jk>pNIuvQ}I2gz|Epq~7fy6#`U zZk?aON#{LXvZ>2o5KRWgt8>@6Y?>%m}-(|VXimAG7 z7A5wv{5!W+Ya3u3V7juSorAsK)h@y)BjZ{TEkC8l;+L{C7fB!l8Iux8V9mS|AX*Q{ z^>}6P>+Q!S4fV+$CM=gYH?)FpeJbS->Eudm)P?(Ba=sVG?ZTDtx4vS6p&zjD2`~Vt zq>S)T%k4#i1rngx;5@|4>rP-__+V29v!`x@gbTrFOJLq%s*jgdl%SpTcq7R61ho?j zAK|v5#NLJf00i5Jvi8a+9^*kRT!BgA2&o~ToY|RwUZ)=7$SqQIozRb+_4obVS)QvA ziM081LRi{q3{A_3>qXASAKu+6dbIWJsLs8<6YCGt;QIeB2=2wE6^NhIC)P@CGku0) zVg0^e|J{84FLg|J`Px=_y&;NkEVAgCi5op^*1I%SwVLYd;ZM2V#(F|!g6&TG$gk@a*R4IMPsjOSPI z}u^9D?8Aj#V$WfW(*S*7Kumb z`{y51zmAprU>vCvFScDMJ~iZVkhUo%Q1ktnV(3)DWwejn_8mKIIC@xMOPhT&E`qT4 zclr$Bf^=_Y?xsaTjvZx@_1^By!U>dXN{Go`W#iu4@!ToCQWOSYi#)EMKB$u6{lpbz z-HX1;{lGZGHP?4sjAv~<(+5e}OsgD4;a)<$Xl2Vuf3rMyY|Q4mJ?bT-n>Kq{B$Y9A z^FWA@v8>q0oX8_5@=<|C3d2jaC))WmT)19`!Tr8acK(WT@?2)>#D@?Du(2Xh`11k# z@)$N~5cFUGjZ5I4-v*Pxf!iv0*`-+unv8G>N@~KD-4_k60zN?KW7a!Km{hxmAzu)q|_|1`_ z8M>_;F5P(lcW?9Zzi(kj&XW~4tMr{?B$!n=n*{6ID*z`m>=aDnFFjvp7=0ie&HZ>8b0>8_tt(zbcfKo(!CjLeURewNb4 zwuG-mB}EH8_(|y|Q^3fw%&T>oIbGiv#0W6}7*OuBqu>h^@IwLmEFX&LA@7$G@RgC_ zDkTsLwi*mMk~oPsb)zxjQzr+kqv!!9{7h5C(m_cYq0wabWz-=(@KiI^pJuV^ zG*lE8IOg)hJ1Q${2?NX6B%3?wmU;H%`7Fj|t|TB2V(5GMkEwO1#m@0V>~yIs3VSNZ zf^aSM(R^Zz`@UGdt`pghM0UYwOTtgJ9b)(t^iymZ+CcqVz7hlM7G&Ch$=gzEJ_a&L znfxZ4-!Ww8()dd6wSQ|WNb!GAFQ`sJw}`mx3l0jP{1(RWNF1YDALfc`Ri4VPD|sbH z-9PykME{SKcNdU)Gdj^%7GH{Cf_{9^JCxML0buce$^}_Xf%^u41p->Whi9sgkCs7n zW~?O}GpWKllt@Bt>qSZKrP?#cRF_fyZz+tvm>GM^F>|C|A6r>syqeT^9EwaP7r39< z@!74?sk*8tu)G=68O`ZXX0UC>HSuZ_tMzfmLHREvX zULDB)(zv|MqVlMae=p-gJr)rW)Km<$Z=c%}tt%tnw@3M2~#PFV4Wo1DKTz&CsZ_o5vS3lmV&ga5QerTz7G zBs}KL0pECEjCb##7x@IN0Tf|;KtRaV;3?43OV?=s7`V*P=sjqmOOl*vg$OJTTsNuuVwGa-V4>R3#xkW zHWdsF`y^Jy5A7ODn&P$Uw=Ol=21d%Fs=3WaJx6J&GpFC&aJKKOx%VKZRp6j=(bWU%57R0(A^S! ze&yVxvGWm=Z>@ob)1(~$JIk=Mw|7ms(m2qW60u|Bg)$rZU1E0$=MywdK)KSQF4 z9x01>)Zots52Ix5gqlI=Kq zrW|d`1Ii<=Byvj!DX(74JW4$I<=w-(pmhyuxhz4%y@&?&ffvv3VZajupjhX+H5a}I zUwsH3*Mta~tj0`yz!`kbr+Iw~FZ%K~6!JYU#l?_CL!{jmUK>ceE8O~zUh5^19- z8fR!umG!I8zaTUOs{O-~WfS|RHi#uTN>Z9rri_rJrKKz9#NG$xA;2Rp_kf-iNvnA2x~abthg=0s=hwVJMhHpotR^GG})By5q478t)@x~_nRrpT&9{C6pls z-yHsmAyL=LMB+ZNDU?DBkrZz;$VDB!D%&m_yu|HnXAF>z9BTYW4|Zk;BtEvNzrlmQAfTd6X17b@k&fn2^A6nj1Vx&@p3H|gHB(UDku>(N{zMFMp4|+`&QmIJi#Ynn)Ctq}5+e4FYC(mj(rwDo! z#$)}gMb)Z|x1?iC{;k5hr%Y#?Imn?c|FwfH+t(6E@KItUj|CLFNLGJkw6#K!+MQ>Fyry^vGMy9T0AN@2CglCCt5(bU&4wRFF^ z7mv$?y-Z7B=o!C|eUjpcrxg``>z}2gd!?&i(C=uR3z7U(jPy%yUH>%>Y&uR5BSI-8 zG;C5^i3p4v1^wr>f|?$`qcUv3t=LQ*KYOYv%k-JP(%8PRqh+Do@YmRYYjo5{z?pmQ z=XgZP!jaA;P#D*Ko5|QGpK!jz8NR)0lp5O1n`5l$eYR&aC=lyeK>-U9y&ay&YWHqM zEdQ%Ddd;_cgV|`eQJ@+=%%XAo1dOhPg}{1K>eYN7PamKpa!vN7tK>+5{ksa5H#?;+ zf(!|)f*T}Le^z|`JAb*-S9tqvm{A=SuitzB3?kt+fGwsXHZ8YIY>F1$Dv_5C$U&-F zicZ^*-wpb4#fbi1D3f5UGgzaC){V+PO@uq!dYXz8Yve?tk_+E3`{Se+X7f+D&evaS zEgDWN*@|ids|R^AkpVY$V#LxBrA6TwopQ3M5A@|#KZf+IkLE}>VepGpHQZY^u+sAE z4%aRgGe8&^?40!0lpr}1(kkITuq{pB%C;usj*Ocd8;d9V{K9v!{*P%Zc%UivH zC^%iKZ=h>5(g?K#1?VN6#Ba|)2cMGVCV}~8Ru`i}%9BC)+EdNxX-A49ZMDT{qXGLYo%tA2eThd z-?I!lqSG`J!ywbBR8EXjk=z047>N1MFtMNBrG>pWh7}h%gJRNC`KIYW8$j>$i)a$y zYTv}xQ_ssA8;cbVtXBpZno^OAtcY_wzU^ZBaHgd43O5Rk?$lxP&gGq9?m|=t5f2GE znl8G=j6Y8@bXiP>c^s!AbQ`6fx?FMI`)+&{eS8v&#VJKWPiUiKg{x+tzzx!0dLvLw$|DUdO4qbf5lr0^kY7GV*ukoxAgH5)6EVmO_wL}KVtT}DHEYXUK*w`|sX@m_ zJ98N_MT=zHsl?8H%}Tj9ceHMhs`l#@Ghh-nynI-#ibJc{rS%k0o~A{y6+RJRe#1R=v=*8$(|-Cr~XCM$>)g@ z%p=7QBuo~7wD(|u5!TxsZZ#60er6TKzXHyasg0jk{)A8_wFiGdfeOH8d(rOKL?u4F zh)C}^;Y{6PQ;*lLBI^YV!U6wD&4|lI3>-)ms*hl(ZA&0~K_vk&vG7}`g8zozL0bI{ z4!P5j;^_e|g~>m2j9bG_w-kWw>}NvT;}dmJ9e!E{h05A884#sZO6&&Ijv3j|B43&LDWTJj)Je#QVW%dOk1~K2)74QbO!NtU5i*mQE{pu&D0H*quy%-2duSF=kNOJ z(2-*#ONM{cQ#vy}(4;UCxwSewR`saCt3yhzrQ>a=8C9GJD1kUVh029o@G zjs+1_+;_4tOvnz1Qf4STiA+VE#61_G6zwcyfurZi3hDtX-#c_Nex>(dtB7KAv%mTL z35{LljmA{a5Z_yuZQ-F_P6;tyyXIh-fn_NL@8!oOwE6DV3-uOUdOL~-FQpF^{3D?l zxrVu`2Z6W+ws#Fjs1*EVu3A6@Xi>7?y{%NLW+7eVRca}kMy8}{Gcfg`86^5CfX{nR=FXSQM zQj9yuT^Sjo=i;dy)(QxHyfOZt?7;u+li7IgHZ=N{66OEZf%_l!7@&lQ($YvDGJ*oFHuDT6vG(`dziMI89)gJFV(s2Rh2Q8FS||6N|JDDU@U zExi;SiC;4{>swiF;l{SiM@w^zZXDu!Ioe*%h4>MROL5cquWkzQ$TC!jjm}2`MpDAo z1I>~*QQ2=mqGIz;+#yp1{^r}DC&_!_!X-L?rXyY*#RG9&kg+9S=%BCd6)o&MUE~Aa zh)~y%Ib~ih_&%R9O|&H6!H6q;Ql>T-#x*853jAV)8JPeVIW5<9jlmT@6%neXj>uyyu6*t#+ph-_7$ zUw!RyBM%=WmG&Q!jhpa+4%8}F9((18RXx@6(GWL{jQ6lVb{)T6{g@(QpZTFTI%uyZ zh6q+r>`f!il-cX}t3DLC4-sVA~L6zW-4P*L=XK&WyHi%QI1-i?C0&2mRu^Th|#g+W=x<>)J&U# z`_%h}5^bL_heaD!I*3A-xpDd1RD)z(yD=%D9CR|3OfRbpOf13fdqLoY6R(tC>?GFT z*zOy)yNZ3E2E|-D8?bqf<+#%q2`9lZ=lh^;cyz2Sfsy4pdjcT*=NuP{yGdd5?Ocn> zfniJeQYmz@p31?V_6J%?Uj~aCf~P%PI?G;dQ?{)p!t0v{<0*%6*bUt873pFxRui?) zrP!z{c|e{f4_x57>(%;}zj2>flW5fKImk-R*Xm!g1cx~2U6&kY(i(feOrdg+UE#O? z$GB5BVKg9KkwpvGsx{#t4g_B)iNs8?N#&r)`R~!!AbJikY$y_K6wG% zqvH5TOCS4Xx*moBnX3q&@s_5uWxV1T9`2RYv6fb#|+h|Ngl9)OuPLNs(| zas2O<@Dw90riJI2S)ha<1nd7z6D{1V4vOOHpo<`H{fCYB#A7w)T{1#{1v&h!P9C(W zNO*$lUl5D+kv@4=h;L+D9c`~<#30RiFfy(OrQu1&iyeFh-N!CdbDPlFi=wdO*a{>& zM7DT3z9J-_z6Dw>IzqQ%wj8#r7b53pD>=E+B@OBOU1K8pSg4ax9hUA z9kQWo`mi>_>mAQWRZ;g$6+X1_9BGKOFNgYoSAr%{V9byN8|&m$v57B6D)j*k7?PAl z6Xfvr$FUct@&cXv;^k6Ba`1FDKlP6e{B3j$F;*XpE=OrLgSMGf)jejfKn%PN57?_r ztY$brw(a^!+xnTpCcaCpilr&%obUuPv00qOMt+XA^QGLR_9jYc*)`-xAn3cW3t~@Q zh+BUenYtPF@hV)2*;A$B#eP4tqT@VMi)_AkE`2+dwsBQ5H{9LGbpfYHy}rfQ(ea=T zxFNy*YNd|!sEX$-YOr@qZ->ZxDu_b`#QM5r)yDIR-GJ5&D1T?l`|bjd5@Y&aIognC z7>M3Ald;{SY>Ql z2)q${uasij!S5#zO z&xO)o$vOl~*r&oI^iGtE91Atv0u5NKxuGrc(TSPg15DO>I2=QhA1p44QdGK!1I+Pi zm46<{##=eLHCb^sOdS0v!dB@X6#MaR*GHA7lkB#%ML`=NORaR;xR#ToN}4NCtsO#E zlh*@HbEG*t1uk<3_quOF$==KbdnrM|WL^O2I%Hzh$%^@gI+l;$=%g;+->>7#3>M32 zwisX9wE}Ab5`s2PkPB934_&wv_8W;jnbz2O^HXxa*=S~HXw|m`Fs1TDw)gILm5!Aw&-dySm$uKF zS=m_EgbiT6GRGqu0c%V9xv{)N()?>2a0*kI2el7(f|K2)Gds&<<`18Nknwg<0}4L- zK@YA7pZOy3?H8V}Z#+GCE4R8&Kz?f=gm~&(fmXCI06*aZsH>{J2b>gOLHy=I0v4=* zy{#Z-0%jN;WPLgSg`WX86V9m5!>s;DimOlBy|>af!P{H7l+}TCo=*?epScjTYESh) zdVYMo1Fi(s%3OAfx_UIXF#VxPMiEVbiv6$kvW8HMCAFV4bDd}SY% zV13aJHnt^FR(oyJj~5G(xzSE?^dtLIORj;H$D#`>L|&$W<1l!uIq6an9m?EG&4I0_ zqGV#?1mmYfH)F5$DP8ht3hPv(rmZWBEcAO2{q6sy_3C8C|IAcI!D2{f@ZkF*{{pmL zhu-f$Ya>8pjHA`@@m9ISD^nx<1wrL4hHb6hNA4q-=m}W%n*vQ1+ic{5qaX<y%DXF6N>GAqVO-u%r=pPN z7=s&&mBJZg-@6B$TX`(^!c|yi?L2^HZb4@mb9+oP#qXNKLn8gja+4u}f}_8(3}2Vo zSDMuw<(=yy+bN#kA!7Y{iN}(lKe~ih3BsTYoju1QaS5D`|HIx;O8R&HS z^rZP2I`At~;@1c#i2e0gb^q91*J(eSm^Lz%__MRi9m@vx*bVG@Vi$sZ9roj)|Qf^FXTOvW7)IDH@huDNa25G zuY_&SNq4elNYj5;+%(|1=9lzNeEqaxM)_nqigQDf$=Q!u)E9Cn;YfzoY6?E%&oXA) zp_jplC0#wf385Ngfu{WuF$|44%OzQJRn_5J;hcIIC7zxu9_@Q8uHqjn&ihiyLIn-y7ks@Z>=oJ@e=Yp2 zw(8gEhl28p>COY0X&!Niin0FBp7{QE!Z>)LxBa8%(l_tg7`@FrW=(8EJ;Lqe+P~}C ztVP#Nris<(3Bw!AUdkn340ID%s+sQe<<_xsmxMvCJ~w=J>43Fg%pz~)bouT0sGhho z(P4L>%-P_!nuJ?)nt0R!F=eCKsU;xA$%9;xuf1FkYSp4iLDo{<{fC#Q&$h1>>WoK#Jd4 zD6+8t|Gp7HnIzk;=l4FBa`>O}UXxybhlupJ`%MCW{-?RTh{Vz?(JsoDyF)+DfcPc- z?iY%cg9;CJ;_ujNedrdqTYVkhF23LA;rs5bgBJiK9!Hn+4#oz2WIhE^y$ZCo>wWi` z*tF6Wogj|SP33lNVU7oPWxo#g!mib9j^E1YJY*Ddct79xMON7qF z)^o8$8>_vjK8Zc+2XpBd!zWD?}7Vok2%*JAaGwtS~Yk{(WhODRRI&A(Nz zyBWukHzwu@%qt!=Xq*Y>V85>`G`=$aeR@|Kg-Uf(V6Jp2vd%#|vD!3v{Zi1 z-zC3(C++wScODDSx~){GEw~Q^vQJRYygB_O|#4r2Yc4SAn z7k}GIiPOi#Xci%iZ&r?SJHGL~D!(D+z2F&i3%$K94#c7M zGqJVGEquStFS_;j=gQdGlW77FbaZ$F z4|m)<1c=LjLBJK4eq=cyWq}pv(_s2!uJuq^39L2NTO-Poc`IS)@FsG`Q=y^r9b=>G z{C@iBkD1@ObIHO2MrPDMAlJ*!p)hXdImkh4lLmLWB8z^D@iMRd_BewGnQm-AlU#Nr z>>H_2B>W8(_EX){h69)7o)UEO8$_Vl}9g!+j=@s4axix{Z#Be6z( zajslOSqy@Z$HMET?-+|6Bx+jRP`VNISHz+xq>Jx4pdh}R!`zdWo(bL^UblZf9;+g6 zL^BRlN)2WgRr?~8os=N`nf<#O8S0G{n{`|gg6VV6WzWxOvT<|wpBcyIjq>m&2s>C0 zohJ_h{U<_w&XRJ@ssm9bxg-T z2$>cy3A&AW#yCHUz$(S&7~>U@;8o^yK}pO0qCMSIU)CS)k}qtFc;686MMmj@ay8$9 zdT}YA3D=l!)lrDaAZAR}U4M0)8OyQQ7Fctb3Q)T%J4hP5`_n+!tt8=8leZ=wr<9w}a&oq}u_SWf9^H4b^02E?7!7p-yK9%GKY)AR-q zUwf&@4XHM3O!UX)74DJs5_raris`xX6Mv>!$2CA?RD?&II6{Bb@F`IrpC3Ah9_{Cn>d! z*_qD_}hTiL`Z=&TNNxH1{BvUGhcP>`Z!L(^9WYO1qtAk?FwqQ_alh zKeOQcO(owi2Rt*qnG)&(7F1ly+=ANUgFI6GRvsijvzwxmsza+K`FUr0I=R3BEXiuC zk@tZ$3RW#qdo%op_wK$yw`bs}d2m7nFcfK16f`LQ=Gu236c3%15PAKi3<|{qst({k zKYz>%&p()8WoWgvr5_4FJ_4C|9=hBTjfM}EKrrqZ0@kFl;f~9q zbKe_L=Ec6=6pN!9fY?}jA@!i(j}N%*+~lz>F%$JLTl_x$!2r-xJa7rmN9kjY~Yn$yG;}xeQF;bQFI;l zTM;!raK4O%Qgk8I=o0GyA(!Q%<6f&sGX%f0)X}gDhtlfH`u06=KGBIU+ZfO7F?HYn zc+Hhvb}TzT*hgu=BL-XJ+TfK%m8(C!g-Af{W_At^)chBCc3qp!$eeco~L8EjCJ~xrzPO8+aN(?KaODH;Wg9K zjv@c*hd={Zpp>Y9;Hv5d(k%T`v1HQ+xg(rzSlaIU&42oKRbsK(NxJ*eVgt+*`0ozP zt*TvTEi{>W5qwCiU|5td2l|muc62bQ07j1Vj?L+8UU5UPQ&l8959k;cVkQAS)Bk)6 zz+u{m0L|L^TNVEwMN0`x|44f5cEss=ZwQisJq#c7!Cw%TWC!EUB>S`h+Jrk?4F+y` zRqrvM+o~7U{v3AeX&ilhay6(bzn=H|zy6kzT5)U^FGAk`>-YWpGk#@@d0U!K7l%g! zz0OB5b6o2!c>5NjjVgRB&T*sIyUn51wP*AogsHoF-$mktGYHr zu9#XxM_hLT2vSVC=zVZO`|@T~mO;9Vm)IY+k2LeCx4HTX?Bth0stj?xJMwF{HZX>^ zK-wbxLh^0CmCyjPp`7RggKn$S&S(nog-HbE6|zfX_sBor`1||+)t8pbmTwR(u|^mi zV?ZEP{L35s`@+uwhk^EstOqXTT^Qn--657i!%LZG&7GX_9Gyy|xE-=ba6p=KwxWUW zk?ltc^Ppa^6dc13o|YxN>kWUrHXIMSPvU_`#u+ZW==}aJ$0ojII?n26qX!1Le7XWm zh8-l+JYo-b;KS5I24lFn4iHGJ^~R>9eh-^n4YmXAt{gbP6VApWEAbhuhdl#w95lpl z4hD`kNn<)5i78_I`1qg!03kSXjqr&iG12rX=0Oj4A+(1(aau7r0#6iD%DxnuV1C?DGs+)?;f49eeWDF4NmYL4>==1{==MhwnN z`Hw56(GzFb=+~`f95GXNXvv{TSfHMFVaZCYyXGM|j9@ZFQ@qp>*qWOB^bR4m_X>wg zydYR3wHYR^ic({IR+HnY=k=G$28RdT4v<9Ph)1bcV$g}7%j zukz`ZPJuw9bP7^wHT&!&QkJdI!x^nvqZZ~y28|3E$YWVit_4ecjX6QC)>&+ z)sNeq=Q7ZHXg+g}rBXxZL_h%&+Mq7ajBl^)DFBkOPu2H6dM}82`yK$`@@r56Iw<=0 ztK;`$B6|YSquAksltoS0Y{(|UQ?@q1V^HwycD>}9?QOGYuG(KBeJ{!b?$?<^S z6R+1XVHy+jRBH(-FI1r`$LT%Rd7mxN+$h{ZXQ1P>l-s+jb+{T$;h}^t+DpF_!PH@Y zEam{m(F8X!$NiSR&pr3Vv-Vizhrn5Z_w0pIUkCVcdC+J-!ER9xzA=rQ&zRRtEE<|q z=N@6stxlPMeojeJ_jw36H!T@bv9U`AFq6&lcvfOJmQUzXTg?8ITW>Z84ISB_BL?V7Tz-Uw#KbePd-*#uLXV)%c#^it}i9su4FQoD7 z-O{OuB{t+GUp*ZD%-~YblB0%ZJ@Wn5Ol`Uo{m)ZrwVG;8E69i?x8B=II>cHwFuzb^ zZ!!FC3~)P%0MVOw7sKDKivd3?zwCpza!6KN5eSC+YLAay=raqFq-HA!iuV4?#d?s& zT`=w20ch3oK;3chR>DN@u`rda0>GtOHZ(};SJ!R;)oWkhgts#_pU_%LAgEF90CzeT zeH8DSrTbic?sT=y2Pj&GiCT(KOiqf|9%*VQ7NG>D@cwWg%Z}=vri_Xd*%J@{o*^b# zZ^cO+)OMxQ2`)5joynD1xz9cFTL~u&a6496;0rw0EgSPz+%yk41Rdj8MJ<%$_`=_E zE$CC5J5i0s(@{<(udBo-d`mYj1=+`!qTlXWy~~9?9dvekoYD%oe4L4@uVy(g2ikB6 z(H}q{gqJ!amgm9ETqrjNbLz};LjaPtzGHKaRghD56_0XniQ;vksjjg-p_m*^-P1)e zd89JdviZ3p3CU&7AcfI!^vCIzrw6w*w2H}7n^{>4_wt?rx%}Hb$u|!=oSkNWRvXqv z_^%$7nOG)mX;j=XwdniC5*Qlse4A&o%qNm6jU2O|)k?+=#pzZ`k#KJ$t@w*q_S&GC?Tz}}jz7Ov|US&-3sEwnoQ6kcX^o~xj^BCmb z2jot39{gLI;H|6z%-2}%{kOUhh5a`m&;GF12JS}6-|JI&dc1%cufk0LFe6xa4b;9) znJaSa`TZ>|1f#7uV*MNka$u<;=y`LflnkEv^?EA7Y{&_azXp+^i+#txIxULA+O{JD zEBk{|qmva5d7GKELjP)enIhA<*j7}sXYEqdmGsMzHziW1bYM5>MI#g`zF#7LWuJhR zUEFw%Nb6!EVI@B8#2oq7Ow{cXR!AYwTR8sd{pnrD$1m`yP#GX(Y(w9z(yd;{APz&6 zC5FXkUp8N)9$qKpsq|6IOMjcWjGxbN6MZMG6-#K0b;si@aXl=uo)ss?|G*|S!*DXG zx}?~4gOBHQU@Ej5mz>$nSP%~0leGGw)QoQMm%?tn)Zku{ zqC%W_7{_1WE^zkYMwS;0lNxDF$4QCG$KA!(JeX+qx5(ytd*uW(;M{vlgcq zt9KM6_4W9iplV9yoAI(?rUU5V`dnA~l#Jsd8v0!s80cu`15dKs6ct&se`JPD7`@#-@f}V+ zm*yCC<>%$%>Q(h0l$Js+fQGy&H_Uw6nwdos;qgr!kl-dUs|)SUy4T5RnClC3R-pE6 zIV&9ubG8v1T6WmsNcEld+`6S=+Br^sVB*(N++MU0N}bhaD$I$S6ISx6@uZ@N6t~{r z@5x`U*+iC<_;#b3i=K;9f@Ru!tDr}-X~LBuH>=`!(0KH{@A%GyuLQs3DR~iYT2rG) z5-%DhZac}`2;~+@HCGC8b7`1LIWx;K;ZK(HDhHvXMES`rSRH}66JT4Y?$el46)55_V(Ft-7+eQ z^35^0?othnu3ae7C=M-xxR2jFTps8d2|Nkk#B*b<<`4vhk^E4V%rNmbmN~HelVn7V zg*QRIk-FeMpGB6o%<1Uar( zd_--LHZUPTfkXcJsg`?NAf*a%3$;Y0f@%3Fk@&l9*n{Xo4oreR-?4IQ-_q)nKO2PH zy;D~M$6>~=7{);^QO+ey->-eMY*X#Vo@Yhs23=|iIUF9dIKe7K=&vSH%W$^tihJw@ zy%+4uM&|O8GttrLa0lhE+%9KNX;f(S`5wywTI1G0TWaERGAA&YQ{VBn(Gm}NuPWQr z%wUA~X(=9asR}#tS>RYHRC5vImYv+*cgxLjPnH#@xj&{J?CJ2}+aGY&(<)EgAnu?xVx=LI?U75U0Mx z@ig~~GpDPQ4;I|Fq-(aCO&=VIVpG4k;7xEsyG%Q#zB3c`f6L(l%}xRpOD>=$hR0-5 z@M~NB3vU6205G<@P1c?Q#PF49Tom4*F{Q)vkl@L#q;FfHuUL`GxJblRgmuj$`dWm} z+uVss4RbtG)P4TVwBPpj8Y>HNlBm-oTaF{tLvDU;Jf1ZUy>uZnJfGWOMY66~Rg%SR zsIXJIw3=4y839L}+hKk6*kh*n%bdmNanPDAIWqrdBkC8Fi{|mGnwcKGue8(FZO}Th za)n{&bM>b2&p+ z_ru%Xp-EI-UmdvngUG|i#TH!Z&Kg7XSq!OP@OM+|Py@4N-6eGmvyCNIgyM$*x`fZC zEBl5cEwWadKgW?b7bxt#SE+dA&js1};W7oTm_uWzsDh0-Q0F0S7*VG+4q*3oM0Uot zgR2`~^;GPN@P+2JHZ9GiVl7Pg+!R=L)t<7+czR+Q1nf>Di^d84^gAms*VqkuhN)1p zIpaMQ%0)5pY>1E;eqf&3v=*Pk;8(VB`A#@j8g~8x8s+&}IGo}vM5j>Vu311MS|}3k ztIqEQ1eL2u`t8__p;wAL^bBf^za;ctzix>B9pmTM#`K6rB%hM(ZD|O3#Vq{W@wMYy zaq@HuW94WFVp22SK-WA7Yuuz96rY-tGKqCyY=9+teW{E7$EpeBA5E4d@Qh5O@F7XD z5gd)~mkmmvctYKYVkn6`iqP45Q7kr!X7&DT80rS!qe>6>M>y|zY{L&iccChx(pXf( zU1)^AS$mC2^!tjnK8t5{r(d7vRGV0ntm|R?cTxyuYZhDK2PX;w^)yy8yXA@_u?vc; zG091yL8ea=@sOU&fMxcqlZ=P2OwX5mHc3;PB*|%F$?v)nl4FZ?IG8#Pce0TM!(iMP z-~7}72C=31OQXp`u1ErM3lP=e>eBJS3KZ)-QkQb^2(%B%;K51CNyc0%ZPR4-d$(2% zmxS{r-U%JdDs!QRTV(gf06teq@bM&MbOs!l3P$GYq5>Wks{YJgZ_K;-Spk$WsEB#7 z>4O3)xVd#EY1f7}Hf#I*83FN=dcA!y=fkNcS{$MKv3Wn%pDp{YRRm(xchQfmqVLo9 zLdL0NhW!fffNfR?yO4c5`~!TxF^#{YwD%}3C{?)WI{GgNT^x~4?Suem>Cm9~X}qnx@no?D>jGAC z#B0W$M0i!P?|6kH!VGp7O^Z%QxZk6T11EH6sXjE+={vlcW-?uw(Xz=% z=HEyfixVr(-IG*b=+0GXGUA$vWpEBWNm-_>3wanPw2E>3?pf6_X4n&rT36nd=RRy) z=VDDIb$EZb?v@Hgleh$bgNW&0x3rPS;Y;}3u;AkMZIA+IWoFU1vNE#f=bg0o4-;l5 z`%La5Ag-^Z6Ml}bq+a9P6%r*~RR-oReyRzzg9Gqm*%U{Fx%C+N)Li;40`DTvBJBY4(x%WR--FoJWyWGhSh1K(wa zak^oHdx4$SmZsceY7wMCmntZuUWRUHX;9GqR0{7tPS%($-KIDvJga)=di;n`VQaOy zxy8K;Qo#K9 z_p$R{sE0W!KyY2!=t>dYi9&Oud*b16cLd+dpdM>rD9AdP>;ju7USptnyu`w=H1*^E zW?gGE4!%8{8XQqZ9G=hDjoV`<^@kr!yV=0h5sv?JJUa_yg+20>dag3u0y2)XzgbeD zA8Qj)A@=@@5#VOg>*dUgejGsqAOk2zrmQ>lJ|On37X|}qaYYQG_RWz+&_Du@`X*%V zNiZ-O-Xrm<`YWU`ZyphmIm{g{a+4a)+Zwb3-Kpl0lR&PtBkc_}I_~at__i8Maq-jw zC3RDx#y3LJ3A!s%6A6t*R{1TRarAp{wT2_~t9s_j$!iTu98l7D4Y7*ivC7q?jVs@p z-{ka9Yp_k(is*b&c?B!XLOkhlIlba}#8$5@LjAcFU9m3)Jv-@INRra!7TKbh++Hbk z>YVz(Ko$D4yQ19d-Z*DE7*~stGK(&+n&QHizaUH-dl@tEtN#p2GBM}`7)HAmUlOX* zEPtYvYgX>Wm?WzLFKc14IxzvM&1EHR)J53dCqPu^2SDvw(#T^v*3k&Wd}UvDy?OO)do93 zzm*D?vGa=~>31f!{@OE~Uap;G+}hJN*Jol?+)GrcQM9q(U9=A)GlFM%SNQqpVz!wF zG+oPV`sA6GBVn%yfWpmK&0&93^6~F&<_Hr$Ujgvig7tuFPWV3)9fIJ}rv0or6Q(yO zfjP6FG)XJ)oCR>OQVGVGtI1104(`^@fXT2RRGZz?_WN3o*$%)5^L(T*V=;EQeMvk0 zooQZum=ZhK)XTN8p2tY=Ct(xfmP>80*hdpYB5h*mn#BB4EEc!~DP8`8=&So|>m%Py^L?PyXy~{O919kmwmqi10c!}SNBQ@FhOypRX;G8*`+S{_a8h`_ zjePBBg?F^1~9qsO(SwkbzB3p zA7JTkXA05z&QI5g{TVY`E6(=_t6D1XJ!^+zQU2iFA4p?hc)aw}D~sdF?ZaD3pD?Uz zTAS%DMFmu+n%ZWJoF^`|ipS$P2g~r16R#eX_RW`9vsxGYR9$Uf?YZl#jtw#IRDTKL zPL1@Uace3b3GK&_FXfRIC@EPrwRQq=>3wMt6Pas_Jd$=FHoE$^cn~rgF`bv5o!Mo-- z6|e0xDL}s6?IjjWU-k!riZs6wmm^}<&a@GgV7p51RwhqS+kmq1>|=~V)YdpP&(9j)J-Wxoqx5?i4#T4U2Xf5Km6w*DkQ8zi0{2GYn>UWf_nA3W z?ftrIHML(Z|G&P#Z#b@Ok}|M#Lx-m^5w$olUrNV)+# z`n~i4L!sj~7F*BfD$fUfRE`0fd#Hnj$RvxSC{GouhiyxSXDV zKBuWJHdq&0Yu0{qk3Yg(K*u(Q-y)(f!tuEB%&TH|q86dHL&+_fw?7c<| z?UuL3dHB-Ow7@4Xqdm=XBKNtrlUo)yjQc@xlk)0VFuBZbiV!N?T?+Bz|2E>gBxgZl zgMNCztG^!+(H`2OV87z8a7pX+RLfcGKR&lg{_nW(E-2wY4gP?j1jWe@*mCw*RSK=V zKW2OYW?!$5LdezT@_7jx(dYEB?`=xmNper$*iE^jWoVQXDVQsCXN$J1(A^Kz=hka-H@7y-Nji{7PaQ(TSpV3rr)i#@ zpPB!gEsg3x)tiF_og~YHM{VAnyJa0wxdF55)yBrBxRc(vE55$~Qz=iRIPM{JKz3FI zsymb218l;Ck%c zIyHH_|D6E=h+qYq^|xQF0_xHmcQ2pI8jhCSnxi_6YVJ)5)0o`#UFjW=zky$j00KrNn%qj?SAv6gZK(CZ0wO@%ll|- zu8mSC9H~LQJM2~&Vm5~Nm++w8y3E`e4||cn^7(2$L5gky>NoAPB1UiV$fjd*odnb7 zxrenp4)miM-_)?ZlR|tucnFeD8o{NeoajD%`~>_ikB0<1@DglY!;iH}@^e+C-+4TZ zo?l+;x9{gs3i{+KVVSAeTgLHXVR|!s{N`O&+mmVlIcg`CC!O`DB!pS1 z0~}}D5hA`bL38d~sw6RO&8KAHEXw3-1C}=F-gUpsq~oYFTIWc#X2&B&+fYf%s&_iM z0Lg4c$JQx=v{IAKFV$*dEwycysnp4FF*p5=6hA88OI`0~!_?{6$0LR@2gI^e*nZ!R zbnr7uLmZE`l|C)U{N7_oiJ2?%T0Wb};1&>RoXKM4S>i7y;i-L<{Gry~+1i8&o{*;* zzIB!9QC!_}QXIku_d*mdkoR+eZ$`vcInm|e9!=~2D$V`6= zPV~#{%3{80<|!s`@dP0lDvtY0xsM6}y%|uyl7j1puvt%RPiA;TEpQ*c0dWGdd`dON zo?n-D<0bgQ$$Zb=WK3@W*KkDMaX5fw;|>_E0lNOnMv%MR75%VDSX@;6D>5^Tf$$J= zj|UQfd|jHEO`guaF7m$mT-sq-b@vqs&W>#~)PD)LJHY0X!HexgrPTBAZ{dMvbB8%i zG1f4_rHPn0$g#Cq|qE_s7!%MRW&{bJ6Ze_C~CM)+INsIDwxkyS5-scxkqTo!QL* zAebt7A?=9q*O1qY>vGn9Cx<5sfc`HxRTG;(G(Bx%jkW4p_v~!cO{T4? z#Al%uLo(y&y*4=f2p`McwGgd==w8e6Nx zCZgyV5#AmJ9|Wg){mMxgmu%drsHhnD>spT{D&Lbc2=zi1ioJO-Aitdoc;bYwXZfL{ zOiJod1N^Rw5R&awQR1i|?^$;FwP?fb4lCf)P9bM}v*B=^W@ni4$bpXHb&R?}Dp9ZwsD#-WD%WBOGM4Fz^^@XAxp78Jm*Re`)AuBO?k_ znlbSDd%Gd^2qQm2E%;=5%?LhPM8&vx1*mQcFiQ`t232woHyw zQ_7E*bFE*?T`z{5W0s}^bkRDpvXVGecy$WACfMEtIOPv3(w`yLv92$AYJOYF*C~La z7U50nIHD=l*_-%CM2nN7)Txm8Ti;|esC@YL>$Bnznah0D3rgy2^(8k!Q}2vB%U>q70C(JKr2pP3HDe!~#fG6Z?HLMYFX1)L;;N zLN#jG)ib-CKuy3v3G&#yD#_TcTO*;BOU+Wli=4K#tZ|})8zLa>Mg;y;0vS+;aCJW1 zj*yhIqv2AJ8tPTj+@~%-cSL9vMPMDHwC)+zqaF_UcP4S~ZA&U z!#hQ6uT7{B#@uSlc*ytEa1ZoF`s9TYN&J`vue~;sT+Ltky=j#*Ky>?sjX|PQUSx}| z>z9K4`>3axm|u;F&hzOYS?`iv$f;ow=DLlR;UC`l&j&B0wng3x^lA{L+`xNcxi8`5 zaWjpsOpKPnzI|)t+Ys(USCg*B|H{)=QD&l^jy*95<0+Hg`i5C9)ptfYk;fD~rZiF7 zkYv?5lWKbhaSfce7>`XQoJLq$GZ^w%jot)pU>OZYCbK-z@IV+Oe(}uWD?sNXs@#acj$_9>pv2V+ro3>5+TT{%v?=n^}8B(U1$zRW6)47H^XObB0t$4H^)!)w|E zv>5uY6LIn+V+P4uvOlcM;w|1MP>xKhE4)y$z%k3G9-$o2*0y6QuC@@&cakV4mFi~h z)TQxgltpy4VV4~xbHn=_Q7#ca*1R;@Fx2R?;TWtj-$SU~uO<9SZLKfgu!ay>%8n`{ z)l+%&M<^jI`G=-dQZW}lUY82wGcgYB-ZVp}X(B`em+jg3NDeLSi)WdLVLx_q1Nbw= zq`3%B2{`Zuo^ciu8LbQ;_6woO41d5MQYI0iR?&69d?{H}mz{F}SUx{jq%R#s%-3wu z+Ue5H&{0k#KI~YTVrMkfA(FFdpSR*msfA=P1IOi4bUe#S-P~SR`f6knQpusgZ8Zy; zSb=e$FRux3(`?U*zj&K!WHEXiNrvb;kJ3S9o!RLZd?pfmeow^+ni;d%i#m(HONrhe zPmKfIa+P|v6{(;r-Vx{LRqi9V=c7_=Tg5V}W#W<0M1V%9pA3Hr(=x62>$Ug_(EWN} zob;no7EJ>q2toeW?U&A_4T*Fco;LJxHnG1ear54SmfjXb(xPsws%63Fx0s-yed*!9 zxz4k1J~`#)eFErDIs38Irq^X4MQznjK45Nd1B7D3LrfK5l4BR1X9_%cV6Z3+ycjer=IgWnM`9l0WVb1mXxhnZu)- zF1LPf`E+@m)(r%K-0~fA(eFQBQ^4UrCQ#oYjDA0^q?vEd8`SMsmwQ$XVsbKu5NmNz0WZJrint zKkCW6ylZ-#T+j+xKqft*tMeu=Xm=RXm+ovjwteM%48xWDO}oDV;Tn!Z?HUccie^Ak z?Z&$g>2-PhTAMT?q?Zz_22H(KpzBc~q3i8K8N#Z#k27x9IX9T1kBzk&?O4Kb)QFLT zFRg|2X|Sr)%3r9In5EY`ntYFiSE!`zIV7)xgB|FU6t~nd=pzyk!hhR1?U<+IXj8m> zpMyadQjr29=ovGQy2KBo(IQ^;t@ItlmWX0{Z^x60sA8>&>fOa&hJ(Vz(5%-rtuRL? zj6vokGl<5qoq(7o%3%KVP%oHN7AG+rP4c=Ye<~bZmxw*g=y@E6)kV-XBwC*L zOD0fXs=Uq`6S`%zG|mQ+7(l_cPSrm55OV3Nz1%7Ih<&zpc}S2a%wsP2u4)EQ?0#A# zJ3p_fAHU=R&7**41J2p^e*}12Ls94Fb^$&ob@%;m0A(+{{S@xNd)D!_8RREEfN{D; zOx>y8E*ZJS+TG3jbK67=Kt;c0STECRQJszO6 z-@&+^{0GvCF{ESJD-TYV7bRreBatez{lnF;+w1Hq^d>0YIdr#v5--Z?8RK8|9hR|0nktuRj z^qd{+nYI3`G1VRD0{Zce%C#NnGU=ZsyS;L?aVb{RePAYPFT5X*lgZa>g2Di7>|Q^I zS77@Vy0o+51H-?!7xG9)c$(x1`a=zRsoRg`fOMcBO>s2}nyoP}&vW4YuopeZp2( z&73(aDG4*wv>wq!+RRP}xauaP7ao!{h;w+A%{`x%m&jz{SrCD97nk6MPf(=2Jtp4}J<+@m9)Pd35*9}KbSAnN12n_SxGA_v$dqM;4=y@Z@d#>zmCJfDlZ3M22}}|X8`gV zc+Uqg@H=9Px_6FXK(PD5omIx2*&+5q7vQ!=26u!fO=xPJ;-ZTg-CBaX|FW@SD~xd2 zHp5#!WKJMIVEsU7FOS9l2L61leYT9a+0%GNluOv~thbO!RbAM7qC1&)wqYqeoA_o} z7eBl}Ik}8-@zi#h;L_vwgz@uPOT)Jet3S{hm7+>NTQ%G6g@E<~M2AO3-8ICX25F~#6x7%iCQNm4@QRB{3?(pU>+9#63M{bus^0SE_F zfoXf6AYaP0P#>}NHA!Q@oJpCPSD10KZp2QR5vTm43ES;@!=Cf6O%*P( z$c`3RD+O_L(XqGWYP%HSXM!5UCizUUYOu%SC1V%wl@{{2C~)9wsZDk;ipsv$j(Jj! zV!HV&pBwSSCbpkI^sP$j*Be_YI@xV0O|uc!&8OK50lg4THXwa}_^I z?PxRh89^>q;5}~U*&hv9Q{$`^D?*Bt6-NE|OQZMwl>mBdG|fp*N{9H0ePk5L0x;J)xW5Ozc_I z^mq|DEN!0H7YVgKPh7WkNn7lL!=B%K)OOzP<6I(6DZqBvw-*)AkYjZZ>Ro&3M>lgA zHGW{yZcO47Gh%$P{Id~XojQ%k%bc?>-dkQTYo8MK+MJWHIa^Jnx*ID=#QX;FUP-e{ zdF%OKW{YR+fDa9ydy|4 zou2#xhG&ppWVaA=Wv8n$YRs|h57n=aZ)O>;`{GR-?3I}gBzjcK=(pls=aac$bc)sr zH{23Gab_HK+UM%2N{mATKdVX~PD^-oh5%aL8hI+Vai=up=l(<4%~ z#(H+|?*m4nHbe@Y?`5fM5%21!+Vuxcr;*8%J@`lvOwaa={u^*q)8TUp1aTeFp`FZj zej>REYXg0akSV>+PV%MjpRbAD@B)Y=oEHYt!SbaER%3S8Cdml!Gr&PRc$S4nSy?}C zDxs01)<62#FzSzVRA!+ZV87jT4GD@S<)L~dp?mN1`>$Iz0#ANgZ&8N5rY6>tHS&^+A;6oOc3RTZ`W2nHpX>Y9(BsY zyFC`&jor2xVYc?AIr_oj&O9iZ*d$$!6#3?tiNgDmthn4o?vt2wiDI{yNhUVu^t!U~ z$LB+6S?3o;)h)4StWReWCasB}L+A;CCuuEOUoNVpS`0f}^1~Msdkgng<8q7mJ!_jH-r-yF$sUOb2qMDj z3#1|u8gwP7#iP$1I?EepRN~!f_C5W`>U`t!l6HI!SFd^A=K(I%QBtjw2R_<2Jv*n> z#{Q@Kqy&|hCDZaUmnE1Tz7>gea{Hf7%WGYYg$HMIi!@zZ|#gGa5q+%NYoyv-K?*Gnd6o26eoLDFZ%id0)M6*vmbMbP_<%FhOl ze83tAj+ny}+TSYTW=xgUoZy(>H20P!KXjg%rcJ!ajR6-7gyJQ1TNhXp8^Ipg^I7g4 z_jEpf11&P|>2C)BqZPVjQ1TBNJl`1^JujHfw(bObeX#w|vhwr&Ug5xVM?wUzzyUk> zbnflvBfRX;>xF4>xvkx-|GW;ULywHG??Myb*YPq|S~Y}TvHyW|t@p=~iFh9U`{m6a z$aIkTJbqXCip;Eq+Gtq7{Qf)DesN(uei?Zpj`^z+W&EJY+BOkRr+w!pw&|nB=|(Y~gyZx>ZWlL}BE>6oHqd6mWk0+l3`)mqHZXQnviJ?Nh24<0f_oyTqip{S0TK`rb-^|rW zhvC#?<@rX8AOr;R`>M*zIMWCrb`#mk8k1#<~yCm&LmDW?1@7NK?p{; zCI1gs!vFT!gXJ=^rZ@`y2_`9y;C}L9G++I4#Qw{0BNw(ZCF6HBYZ?FZfMiB9zzG0ykTJ zN|cG&^n=$8Oc5_p7FDKq3(j&SanjsA1!gd}Pl!(gp!e=mfkWTk?TeW*K0y2b3lRJR z7XLh8We!40hX51y(c+4dnD<^ z*!P8c#aFx0Z+E2n$mVR6!a^|pK)NyC%Uj2+^n5{DsgWQDa1wZu)=^@~F?Kjz5c1)C zjhq)_PblCpRftF>H|kKU1gX^|H#EDv^ZCoo93_Q~Gr;bhF+BlL?dbs%Te>f?8M$K5 zeQ^jg*7Y8Sb?hd}EO&yLdYXZXtyW^|{k%YqkPTen3>JU@On9RO)PUOoHl?yPh-X#; z+KnawU#u_9W7=F5^-jE&;2A=+xO|xk2XpFnrur{A#hllQ04s@A06T>Hh+v+nMSC)+ z$gTnUoFGU>WL7`Io;cn=Il(Z6tb{wp*WG`mDGn5ecHV7+H@z}S#`7Z1`)=+Tb2oS}|^7|KU@ zYS-n!Hm``XWG@+06ubG>P(9;GCPl+TwVQ{$!2bU(QD>fDTfx+diSkF8bX!?vr*_TjayxWms{3+OcW&4A;m$a)Mnw!o0cg$oNMjRJx;SFB>S+^ z>iq2O6p3F?d}{ocZ|H=c@Ke9uE5A>^~U>kFB?`gak{E}*Gh0W5!b9rn74cqj$rjS+Oz{sl?jts&K3rKNIusS zVL895fg5bku<*^qTYvrG$^KdanEfXEb@Q9L9USQe0y!j~=vIn7qR%S;N9Domj+*Qp zcEALbfX3kpFxWIsI9VxX7tQ1H1xt6Bku|<&j*WIR>0ST3#?dSS`rGAjc8kfE04+4w z0Z(a>Ciwk<1dSYZk44bcwiW}T#C@Z|+poYqi+-hr`N`7i>$sA?W#Li4IQa!pQ~vQy zBW^{V!8sih;)2@yuZcbr@>sH$q&Bak))m^E#Euz0(QXicMX{aLy&;Be7e5COV4YE* z|2ZlZnF>o9a;}%H!a_Q^nkiwmNcDZ|+8xj{%RJKOzazcFV1-WgCV)Tr1ph!A#Pjo*FMy$M=&PhnSkDJXT!`E}(iB?)T;jSc(_2$FpWQYOHesOYSk8LH&h?Q7NLW4uwQiE41O;MDpkNuyRV~AO(R|LA+kV$w0g(NS znsrT3aI43zdN@$z6>E(+S4dX=^i>$apD^<355IfRo`tM2D59|)lZiO?_kxE$>7#3B z#I7It7ZHx;$C?Qonvyh9U64hUYOUqvwUQ2iRS*ymnR*Ktr?UROWiq_J(Qdl9tbiUI z{r|7u{reDpP|DTN=fOn_Xi;+ntp?76I>7>K>OmnV;RrF(;~C z!(p~O zM4V)4xO2YUCU(%w*e|}(=xEX(+z9w)*7?OfRB3)f;$wN0Oym$Hstj#SW>TE|TJiei zWre`0Ka-j$dF21Y3(RQY{2A=Q(Ft14-*2?Dy~Q8Xlg0Ha_7@%fmkTaqEL_X>QdhGy z)-0s|^Utj!aBQW4{qO&b%>vej^ZgIc|L4CFbE>mh>a_vESTnVt>FR&^GyS(eUG>ZMB~g5nPcph^STsTwr6Ie?#RsL8#Ww578+`lACWnd>}KAPN`Gt199g zbfYUS#(42zzk)^;*m5%r0Q!vXjG+@>X-N9i-sV3oBuK)l8Z+L9f2!b-@R`B*__Sv^ z{0LY9&`!=tp#%U+DSu(rGuXP`2T4U|!S%8B&MG!%2biYt;9E&t&ZnL$ZPeRcK!S_< z-ve8V(Mn(fepoxQas%Jsh$!pCmvA+Y8U_Y~g2rEFXl$1iRBjPKfJS&Me?1U4uAdd* zjOwAeb;T*aYu+x^X>S98#9i_1OqHqS2)X_Hg_x-vL$RDn{O{G`W?2ZXs!bAQ!f#^u zo05ra1)`*sE5D|v-~Rnv-X|5d1CrrCkdnI(!Hf!Dqm?!&#t#64p#SpCf!A53<;bac zI=J!?iIrVw&FH!N<9>G;LZA5`6|%H1o|k*z3T)a@qnKYatv#{T|1e1>sQE-XLG-)O za&`F=$mWjbSCO!<1$BJuBn&GnnJ=1JRD%oc1 z5**$WiO2v|%GJ@*GRvdt(t#C4wMhA`6JYW{CRcsnNS2%^$51UvOcZ*4002()!x~CpCMU`q7vaA=9%5&zh#&TqC;iOzvHc-SEwRK{voroNiG zsOIR|;rno72WVz%@dw(_;GGI8z+=4#xrgl|I#A4_#kb6J=Oz4*-VqN*8F8Jdk)G9S zwfgI#nw`4>bdmm#HW$Pv?+A!afF-^5yF+oYv-qZrpJb;+$!9`9OAAkqxB(~K(<6M3 zn8n2i@WT&3HpmK(A;;{)O(52$;7tp_SiR$XkpNYy{CD_(4diw$1v|Tzy~e;mITAYs zII3XhTR=n8GT=FkT|B<@SPUOP7}Za!a5jgtGj5Z(tMgmToyL9}{((ry=VBW2iL@;L zGJEx51h>-R52Scx&xY-5Hg|{4AIQ#N=ZP)$`wjx<16>%Mk=49=LDaI^=!xOz#{&&6 zF<0r?*$aur{m!Y7?IX!iCrUbItko-=Jp znTTnt%L_D>FvQcbMv3y2qyr_dk$&1sk1B5eFQ^i2HEA&r{N1z@(aLy%^wa`EIw}j3 zTA6r`s7(L?Jq(AOlnjWhDZ9S?9yKDeK~-Jw_wLqddhNQMV#UE%?$WYcl3;FNS zfAhtpWVUS)cUD9rjKwQs>E+bo>_1xR#kIqsT!}9o0jD?sK&{#EgWga}A!`cryOXoS z4Y!x~;|!oWa=2LW|Nd`BvIhiH!F6AvnAbi)=DihQCcz6(>wwRL-zIz5>#2NRQ>ZUs z`wp@gCOHhFYVr~u>(blmwY0nGfrR;!mBpuG!N!vgU& zG3aU3Vd1fc8lYSfWPkos-?H>x`@rkk8&bfL9~H04Je5l@GUK5@JrcI4t>H)^UvI5e z8Wps`>g&i;3}+D|x0C$60KT%C7g{J>DxY8MPTa zGgagSZvO5PIygj~M9Yn8bRvyA(h;ip>Bc_VMKtGol2O}JTOUb|YBghpZ|UCU*R%NB z1X=|5S5s24Hjc~Z;Ed(n(3##FOQSeh$Vp`vUKJO$&G!urrHiC(h!xAOz(mQ+$w$I-Dg-HrDhG8KBK-T74okjg9T_mMF-A zSnWucOpJfD?{~*!Y?h+WC&C=NQ658X4r7WAVoj(}0%pATRNd{XS-n-ivMWoh^-y!E z1=z}NE8oqhsZNXCezBC{WqZ!HKak`?%U{v*| zq)(;k-HOOqdCIraKjb9}w+v@}M|VD3!l&YRctY?_+4z@!s9w|Y5M@7RPe@Zq*B4KR zEBCV3{a<4JnA6&4EP$=2aI@!YMXq(_eecfWGo}?sqOE;JL{^K1&qy-Hu9rXx>yB}0 zb{^8>aXz{Q6Ie8{B6%KWoqvmc%PM~ZfkObQo82qME`0zWY% zZICn3R_&%#(ST-#pe~EHOo`CtEF!9v#0;I&O$`OI-AVs7n7r$yupka4WFn$aVq2M? z^%^Tu;`pqV&N>5wf^O3Fw|EzJk1ZbIcvj5Us8(%0HLbqaEysI0g{p&%Yg4=w6w9Ra zOARA^EoukEMtz<)Q(g}cbf(&l44f^5>hpS4Al^k=>G{--_Gr+Su=Bjk`tQiUISkt7E^4J`I%uixKO(T#qsr_bo-nR3oZ(K?FI zpr@fIq120hxiUJ!5fyd+7?0p5eSs-QdXM;>y> z{JB|^`Eki!Gqky;Ga9kZ;=TfJoRsA2fCLSbkGUbQKT9Q>;?!8NGMf++5_6#mnsE^_ zGuJzJKvZtxPG2WS&N;9@qaj{yz7f(g=R@nd<_V@GAq!z~*y?Wz?vo955IBUe8J~*~ zwYD*yaUSfi49Sund`K~~%>*G}3@XArF>M;@et=9NM+BHFKDeyKXW!Qs+gmA1Lw`0b zYzsIT(AX{wz!1K%yeelU5`9tfKwVfXkX4CBK95X$pX7GutH|x|sjlInWpBV$7)XQx zhQo*BQR830u@u~=XCtOnLn~yZsB*}#y=z_0B8VJ8JTzLYVg^h z<}RVwIK=K=$HlnUeFF3ve;`jad9=O7S7~LGP)LsZBp2i3wdEhbAwIWr2}sgaQ~5dE zM26CckaNKrq055xyi5@S)l=rEjQq|@Jadde41qv6Z$gT25M%}fiQ1$cu$|7NiL&e; z5B>DDp+G(?MU{up($?F|FAqXi?*&fWV%M`ghqMnsaKaP#RV_2gdiznt6J4xdJ^y&f zTaJ0q{8FjeG-zK);hy(r{SYHvNt>Cbc)bY-1R?G;!|1S0Y(52z0g8e@=zkud6}PKevh5aSJ&BtvZT@z>NmJIll#dxhsCp-mmgkKnKl` zKK`J|ZKlLwu8ApoYvGozOz^`WNJPb$#0;GmO3L`qm_V)F*1qao6LbHA-K+Kw)13MB zM}}4>_1I(FhTE^$Nzpa?YkUmid>el(i|=5?wgxgJ2kToBY)PgTaIJCdu|FQ6(4X<& zvkzeN;D&8kodnnshrhsWCden+btmjzQ{#V1R54^6X?tHO0>lXAFc`_ z7NoeydKs%fNFLzTWP^>+(+@~A z-Zn<)ElLu9AZC0P4HYcaU<&AbdnZapfTCPQyPxvW^uU* zn5mu)a2U$C3@^OtJK_^Bq|4C96O`-o{<7rQSZzhMfDQWtnZRDU@%)?=YMpl)^D}zK z-H{w%Jxt=NR7H{&S%}&l@Egq3V>^WJ1e|8G4eA&zMe2e0w!(cr(OYx|x|uV%^vOJi zLYZB_D-&!#REW=-+8&2LZVLiVKK=)3GOL}#9Br0?5qwUbKoSDqgW89w2 zUo7<^P6(Z{n!7;Ec^%MG|BIZ!!(-e5R|)V6S)pGWNIX+!`Z*rd*#c-Pt!j?x-{O^c zC>?qIY6q1>0oZ^+1kh&sf`fMnoUWDkEGnLN#w=a9{ONJ;7{S=vX}E19h|Ip@w}v~d zPb_-)gP#1bf8Z4c0C5+;eC`Ic9dx`joS%HoE0UgU#?D0M1%~`OwkaG@S_o}Gudr9} z+S8>IY1q-2g9QopuvKGrjmTKdl{*tG{7k`AG4vOI%=(RqD7<~@;4x;8iK93kO}fR; z2X-We0*4XoVI5S^yaylG<5+L}t1UcvZ0z%U>>a)tych5j6TiiVkhwMA&t6*X^+2-U zEyZ}{Xa9(L>AfIX@>sN&DmM;y|Iunz$9=nCE)}2ocV=;|#7$}dPsKvTnYv+8!)yFu zCeZA`h6{$0P+fPe@!;)!DMOa#-Af@u0B0zMel*VxQc%K#!nG33SqYfX@mLQr)bq8A z6!G2t)8Dmznja5i^FG1-%t4@hbn`pFPx1sbEX=rh_4=*3kyygWjz9tC%jtDZ#s>Zd zPCL3W0vYW%5_R3a=3?M2`2zt(e-fxK4$#(^jAF?3mrmkJOV-(UfY-q*p?l2|+gJ%X$hVZh z%a1>zx;h1-y{3&)-6ivkc+lmK2&h+imLn`M?O~hNs~0}n29+o?TBj5`4|KV#JKBsO zw#A=->K(6l_^rA`X{IIGypSY*_4mHfBkDeOK|eua zZQujd(l0H-whD5yd5^YrJ7uNcOm&%!w#n8@${#CP7sv03p$0;ZLHS>Hc&6g7{ zXxKHUwRdmsok)`E`pOa?-BAF3w$_~N&}}-Rr>EATVjyRJ6J1}xG!f9F0_v<@C9dDlR-9J-OU3N?kUcA^*s3B8TgB z@^-5cCz14l3E(dX&>7%(DUf9dj$;z|so@R6A4tD$8pzKPl4a>9)~2DIw^+D@vvB%; z_-b(rc~W+ZNh-_hzV&kgEQ4odU8#j6SVMPkYB-gLpB0oync!63NQ29WYD~u?bvrho z7`}=gk|AO$x{p72C7yq`6yNI!+~csNpUOK07b39G&IH#36#kd@h6C5jUJ$vkd+iLXB{WQUJ&Zl z!;)BaB-qxBvc^Adl=de&E;l!eIXw*7&xVnC`+G2v5M(sod?;sqX>^3u=c*D;d7S5;t zC(rCEb2W5y=(us?|JG2OF@wxna5m35vOJ3;2VG9OPH$2p6icD zV8Q?w`9D_dcr^Orx+W0GYn&_-CaG}pdwPzF-T;TQ=AcKKlrB?7a8;Sy?MpEy!7!Xc z4F}dVn&k~WE1oy-oy??vZ98$T(*cM=0KXcJ^y~pO5xB!DJcVKcIgKFIllhY_Al?Jx zr~nNR_d3wOf|MX&*bg9RdGNWTDgd$_X<3Sp|5M9fB4X7YU>`^c_{stVPv;hK@=j&U z2P?iP?;d6QJYU|7(&zX%)0DOtfDo4WED@5SJD(M#A81PW-JI%;s+AJvj2eORC#is; zC{MK$&O&RiWjqMd;*3u7v(RVn@aXo1hOMe%zIt^ z{gxiFoc6V{8i?HHMtZ|m3~RV8V$U`_u1Zj%*RFa;qqajhXg235c5=iNR{db1A*n65;cV16FED2iZWLFbRqpxoI>FdL-kjGAa&SP>Q+rm{3fY$%s!Rd zo{>(5!AH%UtrIDHp5HKB*X6QM05*jiIA|t#(#v=PZg};6uE3j?FIf(@#v84w)H?$HVjPWN zp#zMX_;PXQL5|NE0C#j51Hc?ek071V)Kft>Wp-gI}1-CuP!4>MT9&jDlAYkUKiU;K~UoHNDh%$UYmq0_2pUa}r zlGCp=+oVB4Tbb~$_}ND)i)e(Y!__sqhLSd0cB?l)$5g1!_T~^q_g!>VSR3Df$hVG^ z0fA~JLU8G3m)-pN=d;eAH`9E_Q`t~W_l8eh_OjB$oc%eH+3d>nc%LyUV}*C@6xO3L z)L^bf(odOOd4Xsn}Z1TG>FxFI|&Ps_&UR-sDF!$osUBe z1lOhRjdQS?&UuzahD84ielcQIok=*+1KswsyUN-Ma2JeHCva_hyK-yE{s6G4DoG?k zr4AHe9txypnV3nCdp}42+j>B4xlP}yLvx}6k@w7czJ@yCTmEaFD5oeBUrz>_?Kg@f z?&M0q^ScU%ZQ5~bx5^->i-+0#8Zjtjr*;204sdb{q^zXml+ z5oUp{4}cwl3>($z-Wc=*7DI0n^Nr#4CNItAm%wJC=$Fgpcvje4UOP*no$*1oQDa}M zTW7=j#?+cO*$c)ZRxNp>RJW*D0bG(l4BtzyBFp9HV*Emu6g^Q(x1iUk0V~O}QNNvN zp^$iN3W1?=6@G&@6-AGVN4c-lRhzU&+&4x9Xfb}Gmk75mJ)##$eWrr{@3;s4`p3Up z375Bru1fNn##$N~0z+oMuCFB6vo^*0h&{qQjMAU87N~kuwhAnXdw$lcsA@?ek-e&W z{Nru4AQ7sMP0}exTall$3j=8o45Yf=H4FH)j|TJ z88);EkpkGpRVhYq-@V;q%>4ry@}p!$gDqt<=F<%r(nJ&LQ@kWBH2L9>e$Q1#4x2LW zSGJ!(fZbDW8DXSlj?cPmi0&K%*ynCzo&qZ<>XCY{)`xNNEKZpCZj6RmE!%Bei8u7Lrgc%H}a`C$o?Wouby=p7h zj7rdCzkOvzO^8{YgfjYw7FS7$p@J!uR>u-5JZ$nkm#pjww>QC);BWo%G$Rv~UZ@58GEYdL|fVupI+%kZZ^PeJ~lM#PL?yDg<+`oFy~xM1Et zZ`jV1TCl0QBKP`7FXG4#EZ|T2y01Wh1>8RPNyY=dfz29FO`|>ustpFyFyY2<@ImaI zWyU2YH^}_EWcyE>!=i!p<)VSrYb#^L8ziSo!p+~}N_Tg+G)Qc^LnNfTySux)yHvWR zq(Qo+rA1mgopbc--|zF>SKQa_1*;~i*8oEOr24KU*Ak1$ zIJjs6M|?1v>0`e&C{X2p6v>kT{c&v6I!5#s;U}7iAM`^JPtPbrS>rZ%@uaT;Dh+8g z1_rRv>7m^wnHw-zKWf~*A{Ge=j<{2@Q1nwU&`*`=%5!Jo4@hYswjoHdC;L^vEjgKt zx;9wi;zt>?=fOLLXsJ7Z>4IWawZW&jJv;RlmW0ySd7DFltNeTY(5<=MkE`6lGE08# zN?~za%5he6UrgWGSJbU*^|P57-KCqvEI%4~o(vRo)Ne~_QftRfp5Iv%v~1WfFlDrA z$2MgkP1#sAuYYJ!Y((~P2H^v|+}ws^cV<(rys%Oh#v!6?SbAfbql zFrjj?KZ4>yYDv$JZ{EN8z{iG3BJl%CDj-s*7gb2QE)b6Tz4$!S1oDSD_(YfxfA=?u z8nZIiDFmM5R?(Zd3n}kl;rF^X=u9FC@COeOzA97Y9Z})|lYns-5wX(qo zSLZTiti7=>ygen=AI!lE&l+(k#gqeyuq_jZYg3AcioN|A?z75U!k7`Bbk5yNNT*)S@XA8{LK<@`#$Ypy z`fNd%AyB);Sonz>7|)VNn@~^=`AKmg^}bcv8~Qh}us8SI7f`{mX8?ZUvMhGH!EZKh zIMns|A0!1rk|dCtC%PwyUgIA<{LPyKo*@S6@O1kb$XVP7=;y#W3^=gMnC~@x6M$_e zKY>S34In!`4}cBYkbM=9Ro8$=6X?i97(+ul6ns4YI`$!J9^Xy?>UY95a2Ibwq;P;~ zcg6^Qa0VJOmU`YtmxJIKIq3uj&|KkorU!kw>$W2kc4TMjtPHQ1=m%F=!kX-1M|-(G zJaUC;HytEg1R)-zR17=MP>ERX5({o#Y`m=Di9&V67qK-<_y@#>IB)Qvq!un`;9zy5 zx*r>Slhrmi6xMc==>v56i&-_6c*C1{BUn~b$=w}s4g9#TG>h2|6gR7+gkTRjGnGR8 zC&hND0!7c+v{_yuyeiCddP-UQw=ExJkPSz3fAN7u{oCGLJ>SXLy0%TTBF9ilAI=Z4 zM6~g}v(%yaJ~o6yP`rkibnu(Wfc;n5SL(yc`Gi$R7RmRq-3eTej!mN~I-5}3*hQaZ zTJOPElM3NDVjadS%GWG;;OcqSk#5dlgSyJE0ks}-zf+B*{~@a-KIMxwWnQ6QR3Jyjy$cr~BPKe2uvIM;o+VVo97QB`7E&_Il;V0#q_&PI%K z`oL#fV_2D~z*71hEGY4K!qq?^(nPEFeY#F=0US};QYpGi0QIJxQkC2_h4S5-vA}_k zgn9uN)!$He)y*9$8z)iWvGNIJnsf5+QxL91L%H_hpmB)Jp(`Rj)F8sVAGU{qa<@f8 zP*A=-AcRwp31VfD+R)1VD7h|w@a#e?&-x*%+xAMM3BAL~urp-sE2<>)1#hX;2&Izv z2e3H)A5e~%o!lDTai}Fm9xas&@|^a7E>PVJ>e!mC1Z!I-fbW<9XAI!(>vY+^yoPjEcM!u1 z&_qdJ{M~{Ap^~1Fw=dt&9;n|T{imxYgSfMo0N*muXyN!c{PO<;Iw%VlFpZgvzvjeD z8F?)c$K}6{g(1w|skDGto1}|LuNTwFs?j&h7>qmuMUW?#-SJ7x2nKC`H&Fput&?iL zHxLv4!nT>_?uQfU)*L{nGT57dq6k4M@kcbqDU&m zWmDdw1ard#M@4F|vf3BUJupg%O5J=;JN8yj)4E_=J3EQeN=*LTD6orxu78`fV@L0S z0+!|I=BU0?tA){c_k+#J%Jsa3lHIis_A@q9Z`68Qe>sMg#cA?)UddlEq$Yk?`UuA` z8k|+y{_qILk3EFxLmWb@Ni|0x(dm>3gg&An9-Xa zxuRvWBA1$=Qu>|Oh{js#=te`SIjP;T1#*R&vW;OTG@4o|JeSH35pRDzX~4aqYTNPk z_!QVQGC6}^EQXszs+m8p*)o^2Z4$r;a3-)}q)b}PQFCFmY@6_-fUN=VJZrXKbNlu) zoe>#dy}dpzR*RtC`c&}t5-Sl=e94s9Z^OdTDq(aHBH-_Kfh*KdkQm3^j40^H1*S5mSGGcWU10R+0~*d zmY%*0?NExJ$k(GWl(PQVDPEUnCMwpCdr9v^js2=A`IkEH7_6W1 zu}Fxuz@h*)474weXdV=Ki(7i?U0s$aSb?#01MMS2spKCJt2P%#-;m`A(Gx36LWT_o zNXH% zRM(sg6SvI4m((N24+_x^-lZ^Sp61oxof_A-^Cb~1g;1$w z2mQ_bxMQdcGZeDc_R*S>s1oQiTLr;xH`vLtrT)1LG}M-79S-jgP3W1=ws9Ra^VZw}nX z#YKPb6~@__lu7bWMS8rqUraDcX8@UTvo~3`?zx$P!p#`!u3HF9uU0I>K@V1jJD0@@ zfFC#Q`sM8Wcm#lHWZ=eDokF@&_Rf*UIUK`Te7gfbEHNPcI&QGs20&1MKw7~XC2DALR3mBPE7q@=$9NQynFYSk z{!}7FED2=6!|H-j_{>SMjLW>&RN=FF2RWi$8@=)b!jwShn|qm7iEzM_do^y3}#5L8C4jDzH({keWRiq2*8 zcQuFPHHK$@kJ8B4tvtRYYfl5)tPnZU+_FjenwmF^Tom< zhw^D&b6-e(b-o@fPEA>RDI1#!0$Js9@KC6fXseZ}Vc(4zs136`IG4x5nz%c;1H<9L zac5AJF*3cfQOz~)dKBh5%zR9+a4FXdcKdkEk8UmYXH*>t_Apkzn}#XTKu=%QL9eUi z-PG(Iq{&ePv0IaJHjz*|izAB^u7m8NXbVy-V)yJ)XZzTF-7CZl={JJ>e#oyLw+p2z zmMxGqZOnATd}#?WmZuPf4lNJPl5|>dVQBggJnrC%W&$eP9I%omU3F}LLoDhb){nET z>Rhbpwq9dJVASg}x&;%{&u2Tu){zy@(-q<5#x^=U9g2xXaCSJ2f&s1P=r z2xWyFa(2FQDniq5RgW0t^Xi`mFUxrfM8z#MErfzrN1zKrQ{>r6i7zvHS z2sIj?{1TvTnS9Cd@ETf;@M>r84JXD-lASk5G8H5T#lAcuO>S=)iAWAK=xmvF4#P$B z38pung{IV!Q8KkIGp`FN+01Tl&VIP%){`1UYsJ&M6>Ck7-6klbk@{~yx!AvK5CAyT zQdd*h%1rM_u^LHe1R%i96KM&SvNn6o^p;B{I|Pr^2FDs<_jv$^*-zC7{+{j9flX^W z4!@>sJ0ZH(&@q-<2sdgb_{eZ#U{L^M1BrjeigkU4&>h655X}*yHvRz-#VGs%{ndd+ z)X{+E`|hHH3}@*0$+K|xJjJEz3A!%Pp#VoHqwq1HIF0^}lfiTiDU$RWAFKdRpcRYn z-^_&m6^cYuCMKS1fvJHhtp-Jf4t2?q<0hci3)l!(rG!5r?VQyoD zZ+@ay93`L{8%cj&;hrN-!Nu?DeNHhCIL7wFvev3pJX!PMp;HW=A#C~dxEaL`1I=sg z)Ziq6IUk*;3$MipOO_IQ5q!K|1ER(nA@;6Xf3{a-4)O>Uc-FA(6W9D~G2Dg1OA5l# z`VaPB)G~+ojPIAXhVqg!(}~GG=ABHYw#n=GS*=W^@1Nzd5p|rM$@Itnq*Qt|uZduk zhI%_26c}O~!I{B=wk=^(Np|(c1V3>z(>zr(F)7D*R_%l7SS_+tBT*SNCb}3;QwpY< zNugB~)Zz^7u)$@fS;dHM!&gdZl#7DH8D01;1M7ue==ZSrao}On!q3>~V2Rq}K`bWs z)q&r+I>~r}S(3rq$O3^#G%!jxEU1y3mO-HyuqH3ktX}Ac+=Y5sKNp3D%kcS0Un3M$ ziO)3(?a1Nnj`q3#x`P;(Agaf3*4!=NDK9`7ku?#y*k1Nzxt@@X>V|Nm5Y2F*0&oCA z{8E3d&lCrw8_huI{RSjgZ5!ZDQ|(S`yKHty6S8xL;SR~(07rVY?_VB$SQtpVmx9ow zn|HrGo&rFyoF1VUe>u`k0IHd{trsNh0SuT153p)btbY2uVETm^a6$2J_ZVEcR++_8 zN)(F^hoXMSm_ntX>n+fR!>3LsG>6ZSMMxpB;+A&CE0=0vUW?tx)ud)Fk`0Yda)x?I z34$^OnSL}x%8FH`=+hWAKjgqNuBsR!Z{;irgb8zgysz3qJC)gtBau~>PqeU>?E?d> z4{jAp9PR*udxri-i+pL%vu5|+($42oig`=zb-GCrD|}RmarDc|MtUPUPM)~ya(gS( z6@5vRBNN=jO#W7(x9}_sLAk`fIKNNMS++PgQysT7hmMC)G7jYM7fm|l`>Ytn9E9w3 ztq)ql8-1p-W>Xk8mOK23Ciri?spOlg%~^OPXM1}-No3(x9^m6>NCwy0P zBPRsCY+2JUUQ$tUHP$}C4Oj#V1r=7knSG+cgk=tG#;qS3;RI=^6EoDq-)EZENTlF{ z(V>cdC1GcY!|}jUa0cY|^UR1N$xsjkqO?GpsT{~64H?^>_&W_hD8s7b)x(sI6YmG< z+T4B%MvQcO&MY+Rl+zs$Sn)EiE=g-%%ZU9aw%hn+iJqV;_$qim&;U=&BPDq#vs2MpLqmWHOg&7sE^U z3)WWVn-(edntx9=)gPD?w1yD#HTJBk4d=!Czj{%*9@a@_-0i@h%#GIe#O1fr6wr$b zfxj5iZ1UU*<7D7M$>+bSC|?!;-*GVW%r%l6VdaZFcL7~*58eYiY5h-o$2;?q;+q-M zbb|2F;NlAmsX!VD6m10FT1EsScFGw$#>ah&)WOuIFE-)^GRB>SP?)tjWnm?_+M@!x zJEsBT<7E0=i)%-b-xv#Vb0fKkMD3X?HiDNS zHxdN`6ws5_m}VrohV+Xrl>D250pCuVLlz0fr;P{Q5TECjC~eCmf*k>!hPc9?aE6^& zpFQCwx`Ciqg+ajfW|fD(ldVv!vpu!bOQD$g`6+>|+5tl40`djt0!K$V9x1TO{J9qYYVo>n}iXTk6wb+lKFXpwcA1?o6=wJ zEY<3F=`|1$&6KKO$3{FrX_=xM!8z$T{eYKLZ}G@kMcp^?D)?Fdc3e3*3R=|}pWh6M zK^ZX?Q-z#5CgS}vr+@|(M z^0;GOJj}PQ-qC>UcaIfaOkcm(H#u*{314xrZoH<5e2=#}wVw``xP3Sr$DeoHq^)&X z8qVTLGPWk*_F3QXey90xByP23@#ai6GE#$Z)qSxdFKUhp??lHVCdc=MsZoHp$KjG} zew=KOKFSIPOT<{MU&r3yz1Ne~A9sTrwCxX$>`5_i3#NgW5K}9Ahnxo`23` z{NuBmvwnF6F8Wsmy{^?Derp!qEgKPUlfh6?yfmt*Aazyg+$g?0_t~WhCJDU{uI%my z|Jz!!CRm6e#OTOorl@T++re>mlWb=yPdSv9$7Pi~g5d=jYA_wkQQJl)(?`Q11Ggyx z?(Z(#8VTK7lY=s|U2mMy=AG#(a_!(rTK`mtK$x^3AUzcl%zKjn8^&`!Jay3fFAz{I>H}9?CufkkF36l0^X+ME zPhb|ER=y(hr!JzngPzm4@VV7%^>|nh1MhzaTc=CjSv0Wj^9kbm`U4V-QJAJcVZ9*z z1L{xd*?H*OUw`f?6AW~;K;P#TWM)1RBCBx}Vgf<3+h{mW=KNK{m zF`mq>g((j6;^Bo>;4ml!WA2SX>>|@(7JD(3Eo}3i&meB{4NlaMkBk9#b!{9FpQX%l zKTp24?EvguT}TiZ8#9k}$j9!gIp^I8FK8RqedEL1_>qJ6v5O~vMQM3Z+qS)5(959O zC`WeJdV4TOKbjdA z(|H@Lt~tbKgHlr%9kDja^Ku1F=#^NeRQ@Q5%|PF?-)rR^GpvG!^G&!Xyj+T zuF$0>A~(!P3D%vCW7#K(@{B2)xUxBQ)#Oh*EjwT{^^R3#a@d2bz~@&H!+6!xh>hAB zd0VT;KZ7|gM#~|HWgXV56Ygd_6l%X8gJ^TS>^X>gGl^#R2Fmxrv08NKwg<(0YnBl) zMyij8^(#IGyDW1heO47d*cdi+BywZ(yq!7ddwz6iy^pjwgLa=tLYH$BLj8{-mItdY z)7vX6-~n)M+(wDXK7oih$u5O4&4r&#`LXI)Js8GoO|Gr$Qok z1(G1rwHBVSwVp%%9whYQUHZ6}4Wz_?BkZm+{Y~cn-T&Fx|L2^_J@eHBtPg*k4tI>0 zm?s=3+t7WzoyuKU;(+xLm#-kLNRO-l~mIW))_jJ=pAt(-6wPBCK8+Aj}%tf=cJI4PhJhRRLt zzvA#>9p`VWr!oZpRRfJPkyCGJLeOn=d^`wU_y4{OtB7`%!ldMg zn;5}OxRy$~z3$f~_f9y_Fc{+BsrkT5iL=W3p@>5CX zW(sOVkSVA?AApnD`j?BCQm?uM23r;xObWzSGj}wrM=2RUH6{`@j2I8223v$OB)N*>WMl6j`{a@GUil?$QKo_BYnZ6wI!&~h) z;O&C&LX#fdjDWp{^VJI#;t6;<_5uJB|B}7{Xz>?90L;*HE-;)4ft&$_&LCc9YeR}G zr}%;c3|lN8fXb`x!=dIZK_FVH+4Nt1$n7`2w3rs6itRQ3EoyJi8pX!lADV%JB$g*; z1gR;JkMn#oN}yei4TdfD1i=^5CJh9p*L+qy3gS9DI&Ss0tS?K|DFR*U=UXm%mWcLq<{o4#7kAq8EWv;Ca z^Taw^#o>!%l8rUSm$hm#vX#I{N=oX;$izc5CfQCZeo3}B>b!v}`c$6`-7RzwDJhn2 zjDylINUx771Sqv5sfXx{?Nr*BR3<-bO~ZK+U8shBEX#SB>pNAE|3ce0})X%w&$jK8V($ zG?E>lENGL!$$*_PpzQ-~w%cfVCndN=Q z+%3HJ9qSO~L>Uzw_o(J_@iWnQ#h9`KT-VBV1To+q-_-FIAdz2v8X@0Y`kuohh2B;- z{WE4=7 z0upj(VM*5bioarq#G$0dSlow9fXvfvzyGPD|DU@sY~5A9H%;?!mxq0&4hi}=1oY0+ zr9XJ9nEeiP%(+Ac6$(W;gzfV+k}gVY|! z70p13kd>ic<<{?OEAc%NJB6Ra#Iw|O;{%(3#=&EplM;7-Nb1*#iM<>>YT)pA&KzNS z`Ps)?Wd1KqP45rcyf(1NV@7EW|686pWAoJj6URS3ElgIoCpyH%!= z`@Jl6HMzyXj=YJ1y-1kG?^qTBs@6h5va)DW$Tw(VQjM06Q7vRb!&fqth$vvHAS&W- zk|;C>GNi)ZGoaV3Y+V>Rn^GKmqSZ0hCwtYBy);Y$U)PMmUm9*JZ$xDb*PwS}VWAa( zTEz-4lpr)ji|o`K3x4s4-!twUGhe>_oP#b*Lu>GdseyQRMR7C(>W((WFCrz=AiI8tIbG_E%awZPpz+)agI+>r8Y%z7A z7|!zviVJI>@3Ak3SBsMOu2aJ#L^x%m@%KGo!u6%z9vSFN6I;ahHhAa-e8W(W z85WIL7=wiQ=Blt#(Li)re=#qjf4)}8{C-3Me%SY zh^QKP6iJnDkVuAVj*hCf%qd^2_M&+VTAwu$sAenZjW%dQ-0FuR2(t<(HDz+`@$>WX zQ{|T2PBe%O0s;lTG7#;p9`sUp+5l@0zUu&{B1=eG(hmrV_#3j00;%LdUrgR?|UP?Zi;1e-P8V0w*a!wX< zIF&n{j}5%*i-LhX+**sEbIzcRb2>f>5gG5lvyY0mJJ#e|kS^}R>X;5<)99bRc0nUV+*ue}SNM^LCopHLmh2c_nF)Ha_E#7ZITbJR@3;#fU6wWj zp+nQ{sS{L9_3ak0o)f%V^Mdvef zREkA*cYD9GW6Q%uUs`Ush-Nv-C0wzFzQ5X1;~lO=j!osa1QwXir;A)xa}g96m#dKD z=eH^|Vy`?X7pMha+B@$wYCqJRk^JOFZmo3qIG>b?{v#BrPDxF>7xc9+&Mfpty!+zY zYVqS{{yoymGwu6S7x-bV7?Vi|rvV%-p8%88kA^h z5BP5$Ay;q7e>k=K5yZ@}+y}CQGNC6%GF)jZ*R1YeNTJ?_AW(>SO0v!Zn$A2_tlI3) zR}1(Xk)_hlYGl#2u-m_6F)-RjD72)+xO0}{p$*aC1qdWwjc^L>^pTP%XR9y<)X{>3XP*5uU)- z1n6cW(2+$H<-OFj=2)6A%xPbOQmK9g6jZN(zkOWXNix2ZLM((uEb5DaZ70YHXiTN1 zKpn-T;-pGS_nK$eT`&E{-X@C|`g6M6_yTWTBKN<)Ng0~23Pj4__Sg1?%^R=vHUy_F zaU8+{?1h82O@dfIxbwa_gvraU+fMWMFVpdi?B1rcjqJi?s*@6nRD*{bzkJ9F&(gqd zi&=jG)ev3mA92qmy&B;tTJ^Rq9{;wtHrNT1yRtDuvm6R zZZRnpe~TQWf-@vut35Y!*x+hpx|oieHz_AF8WxP{*$8dQ#{_6tfgv@gM!Np+R<`$` zD+cXlTM|W?PM5P)x&MdN3Ags3k&AX)RUWBvs<4R|sY=Bqqrf9tml0;e;rzhye7cEO zF(FQB^^4GhT^lF&D31AE#M`K1=!ub#Q;vTmQJvbp7beE^xgMV0;)}Ko9sQBDOuS^v z+R>5RsY&PT*A6Uo{thqSP0K?$RnNQ|lg(!O1l}SJ`PbMF%Rt*Qzv32k8Lds1ER^t9 zS}dy{@~-{Ml6pupWY4Wk-S5I;KeyjVLhD$IrJ0Co3G}^lozoU^>1{!L6eswoWbR+n zq>=U2fmcLV2{OIexy8ahn{QON1;ztSx3@Pu?#B=GLCGGp7}t6JTP1U2wCU& zKS(dmwsMZ=W2L`o-28>P!9}AqH_Sh#0>dV~H%bK%>$5zP0UIMwciE;C9=@c~W-fJyY~!(E9?kjVqBs_&az1C6`45XbhOF4p@h<#Q?Cm`Uh-$)wNxL5t=K^xZbQMkTg^) zGHCi^yY~LRBzsg>*}EK049f2vgPI4uSfP9?!``Y*-wDYnSm;o(e$v7OXdwMak=sKc zu6N<*i0>IiICY7N_4oaCxNg)^u<6)2$cbn`sT^y>r+5^C$dl5+6FA5MdAVfoaW-h^Sbx5?Y>qoNoM z!{2o|@;S7rWuvg8KrSVy`-)~RsZ}5=we{1PR$TDp?{^c)813G+MI%zD;8AlT*&&I? zpB8&pGYcP4bryGq>JP=p*N|n@oNgD>Lfq*r<@A5L0rGU(FJT>R7b{bl@gD33#A(-r z0=S4MrAtV>BsLK7v($ca2MFJkKlwFuVU1k zF%L&T33XUSk>=V+pz~=AD2eP>^Z-LaaB%`1^S6%$+gu#|d3PGmdw`=|Wn@i8>bDZX zXnqr?jcS=fO(bLAjV+wAnq7l}l5GO*oK-RqFptj{h~HYlcJi1oS6+D#VMEn8MlQ782f2?=5*>c%CHzdvt>1h2Ml ztkpk!-m=>?@lhL6PE~5tb-x11k{vGJc&YV|UTc!t0r69ilp{dIyW_jOCVe$J*7@XV z_}foNuosw%9-D?l_0d6;5lHCgr#HYe09g)QXD1Ad^?DQBK+FVXe87R8H0_=8A0~1( z=G@P+j&&aLEbOl(RCc>{g{><+mm}@RXsn1hVL)AH_P&drvCtX#3>iXi*NFG}KiX zgX5~#$8+jN7zyY%V3AyW$GPcyM#alMszWDGP)cs0>R+TfRpFD39QpiMB7Sfx+#lwx z$^2Z*yW$qZn@XA{#5J`xyf%OCB%=Rt^_fPf`HYPFpgNibhL%&7eui+zu3O;DS|Y#G zj;RnVD;Q1Pl4MtdEFToX!Wa38zdMd#7I@FeVl?9!l~62%{I{d5P`}Ea#CdbKh@PT> zsWIUivdW|w*f`J-b@I!1S}v}Y$ceKO z{NII|gU#;07lT=ZI`(g;tdZ(PEqJ@Va1ztgSLg9u4%HlaH$uNS^BkyireFL0f&e3N zB|(3=SHXR@kquypB=XfHjMunP%7z28kNCwp2cM8>`U{51P*S3q`)mn^`z{G!)edIDGgz`f1?s??Jc zn&bAb5LaRZxXU~+!6q0$2-i!HC)NmCLO-LX9)~EIh(slV)CU>%Z2Bll>YQY^?oc@m z|H4RQN*p(o81K<+Sn+{k*!E&MW}2435ymxC6y*ohVWcQaxkTC=8|=iE&Um_a0ZAP9 z{`|^lFEq+TyBdS@b7)lL97M=JIH|}2zbH<#M{1jQjmjcjKtJiX8kbhgq?9545NH1U z{oa7NnOY+?$u4{snt$P^PBMCs72`SfZw)*dE$txjB89<04NY z#8aXYX`}RVDMhwpV)_Lzc}KZAn(xFb$lZ?Qr1D+$a47it(P804yHM=7=7Z1UQeg>k zTyVp+GQ*-ta2)4$anGE~;3;7f5#Z9W+ux%ujztAD->3&sJ~&QkUxC?s8!t2?D-zR# zWZs{XtKqhJwtSN8+WG!b$`P~l4`?Bkl6@34YdosTee#MIzrI`?Jd&EknLO0elJ4c! z3*e1r&LGgh^%pOd@}*hdhg7^Amkg5ZsRa+uGqJ*V-Gm)a8oZINl*4#&1om3jtvW0% zAuwDS;_%_dm$qCOK0I$d3xBkndbBe8e*)K;?VOd#8qegIT#7Q|Eyc*xERVMChua6d zA$B^FXmb*H`2-{jNK7j&@3dJxn&zl__Sif%rVnaZ=?92zJ~2+a~6A zk-|e9hrlp^5J^bv)icll-iee8KYs#RN~KlV_4~5?py}xU%FoN^i(2!mgj}Z@z;qWO zql&9H-GpDh>oKuK#o2?)nvTVTC!n?dMZppOkjh^!2A-PBhcF<&Oj$^#D&;+hK(zdU z$a|53A}}r8@-?FWcBMuVl2im7zF43o43uFoJpIO(WezZV5Eu?jneWL;nur{j`~$XG z!=zI^qm9yOQ9Ld7xRF1!iTY!b^6oEoy_@+pEu61cH;% zEh}4iKW5BEB1n<*HN;3gzzsE|Ru6J&_>CXb9JwjGl<`aB95a_YyDiwM8ZcXdktZEQ zc^4a88I6rWB2TQZB59!sGG*U&4v1B6^GkBtP@?2xn5g|k$dSG0YKwEF%vZaHCX)Nc zU_`81;J2AOlxSkHGCG&?c`4~0!@Jw9`TSBM4AX+LD=ls zSFT*nP+af9k{T8{SqJZvI2^glnaMOs%AliW5uWyzMufq#C|h@{cM`2Ccxpt5)4VsLoBQ9|=d z2b+4Qb+-&NIqYHR#Z@b2{N%8UKzGeIrW9|@nXl*w9|PAAjfBMY<(D-nw|7@npDwD% zp`2HLS=HX|OF@o8nbaNrfAnl zQ%J!htQYyqy(oKFO&R=mff7eX{FrPTjq59!T5y!XPw$^|y~on$65o3!#XmG5xH4+= zDJx5<{{fYM;h*p|R8Q1KR`QG{p+gsZ7CosP(knj3S;E(*A=gHgWTn-H!+=h`B_jA} zdK;$n!BdY<>le8$`o|wXKS)`J6T+b>zgPt#z)@@}gf-AvQLm`lSdr43J!(1F8x4LhiZ-)v%XS&g2K=0b5IFWhS#z3^IPOAtFTG+-%{ z$6kQXCFMhNqAm=w8F9lqE)ld>@~#|gxohpHzxk5?e>!2ra9>YADhh7xq?yMq&j0M0 zkdqYES$7d&+%mno2`!TFH!in#rsg%MV#mEE0XO9GMGC{3A0&+vyDt0^GF5~PxpN@g z(0_zeWu!b5jN6RplvDvUqz@Hkhrk~JTSF%4uwQ``x@O30qk6j81g znGygn!?X6?dP2g{j=KmGU{Hp*ie5;gU-dj7Im{&p=Xg7?c|@l1PxfY>t)#DU+`QG|a1W4oA zZdZ}84!yiZWwfROiq*l(dDKPy^cG55a+1<-Uu8||wj1t5!D(Q_S6xthBz?JElx}+~ z7Jj)fjH6G8>2CAu&6H5t71E#roZ%hW7w(tAy)a)Y(quEahc{C*?Pjy5?d8a#+05`h z!t$t6NpjDo`J*j5Z{8R%+lkzTPog%j7vgbY6xJJ7pj3M4E!zi3bBZ{_O?UU^rK9iYBA^TgI>=IsAT*d0nYNyH1Wl}pr!AjCz5)-s zh@J5@ZeS&JWNJ#?H==eK;zjf6K{XW6d$Q4RM{>oEuuh5T8K{qYbcyhJLJ|glK#f(; zg7e@eO#$j}%`97*9jt6&rLU3E>?EtWa=((-S*wde!x(uULPxP}?^tn3&lP+U{x%-> z`VE|MC44xSppsDGH&J~_L?Nu6S{R-mNc+jw_I?uFErSUT^0USBZ?X3okyPQI3{_jn zXZuIWq=Mpu(?bLNIn^Dj1x(XtX2jJM1EM`K2%TlCI`3)K0xFPJ!Gya_nc8WR=4okd zk~*cQg&JZKPANyQ&Dig3&~vvFC&25WtLt}lrMGI8NdROvVrmre5i9?e z15uV^>(TpBi@~c~D2ltQCd08)f+w~HRyN7%2WCIuH=>v;h;Dp~J;+oDN4WffQL{qm zWp@ZB5}4$U3|pAe2{yk=s20-QO~0(oGt2mtGnUUSp~u~FAK_NxV`Gw&^3EcUlhW>% zJ6Yp#{{V^6pNr_t5Dv+6x`k8`ngK{82Ft zD=u7%jBIY620k`@MXj$H^e$N>Y_b)bxG7p!HT;HuwbzkLmMzdeTz9$n7(!$GaIKAy ziO8#{rWj3T^Re@trfpm_;Qs@v%-hJ83Uzmvk=o`hRUeR*K-X$CoWv*$zsW0}A$qJAl+O*|TVo_1sPx{*sRTE`^&PL{q8^Ep`Y9fLKrax(TVe1H#0Bw zHn6?UR_$o_^LoxDE%eo#~o4%&3LWxO*W2NkN*gOV!EwA6r8*{TvTj?X}c9PYE^ z1lw>NtPoF}hn_)n3@sWZvo4Gs<7k9%Sf~Et6^k|EA(3nRo8r589V;GYf9vDM7%OV4 zrE19%nS|IQSq|55j~uC{uskPrrG!e?8an)7EMEo!4?rfI9(5uH|8c3g&q@m3zL{rPOq%cj&{ z$G65Om4rSz*3M(SBi&(dt{;u0S=h7v{{#d6>ypMgCrDuE0$zA*Q?%Zr9S^!Oz-YLVjJ=$I3Jf6tmu^{_2k?+B0B=iGlaqe^ z1>kT}{>Sy~RBrfiooERa$f-?U{M1zMX~+j+J+A(84uF_puFP6=3GqYaI+-*)YDU-p z_OsmZobu*W+PHYu?o-)(5dj!ti2oA61TPsvScfmMY0UfJ-bO<(`UeeqeyX>=`Mbn4 z&D3a#vUQ!R&IVGlrphW^}M^L zVMVTW%!spk?vH#$thsUR^W$Y*2Hp@_Qza#SGdWdG4)2KQe#V%MtF`<(z@z>E8x~5W zHuwE$eD9lTjOLC(Sr5`?k`2ruy2XSO@p3Lvq8t@nHO!o9@QPE1i9G2EznPKz&l1%?L!;@s#ezv-;0t03Fh)cn1I{(Mo_K;+QUfzJ6xYCNnl z9WBozgx;*Mh??7njQXHX)hP6v_v4|Nj=60Sjdyc72Xd-Xd_L8w{7^T6(Hal>dR%J0 zr0zur#+u723%Zd8?!We{o2$dLp>PL?g|EK~*a{E$E za8=em{hE*IaR2UmP>h)Q0&r=6rZe@w299xnWccbmHAt^+_&Z?%a_$3d9YkLQIzSvq z%<;e5K!{8ovY%Stp*Fg2UtkoHt>>jOR<9Yry6;X% zuZutX7U=Ng!`=WR>AwOrokHDTh#}0?#eXJY0_gS=JXW8vtH5OwG*4Pz@WHHw)5-`m z*j*%IhK1ei;WEe*6=>U6KdRBG8NB~GFU(M8iWEVe>%WG=mF{~Mv}OlfoaEq8sNfs#hyn=Dtd=r$6* z!IPzC=3$V48n`vac@FY=Q81(+kP0(oc7#K31bEIFxf24wihh(+J2EBoemLyYfS~^; z|INInQo-0MDl5fj(}$0YbH1b=_eS*T}bfH0U!W5not2J zW;n^#(d&3+-lbj&g}#(dNS;3sLKBx^EKmWFQ*2<@d_F-AroY;k;-h;)^l)p*iJbK4 zG(>j|F!y{;AO*V1XaG^X-31OO2&8xxtO8@g#@M2N-5@t(^6LEPm|5?uRf?CxJpjKT2A>*D?N*pBs-V1 zpUUcD!Ta}TE4eE}%bWUn^z{UT_Zq5OWZvBMen{`Ffx$HuYDZ540d+*BavLnK#}nxj zrHp_pL$Z$?uc0WC$g2!Nrx@0BN7Y(aAw^-IF4tJv7?jGV82uuu(R!%@xfv)_YnTn5 z*M@GJ^sfzTk!(zj4)%tc6s(`e)U<$22T#+IA(tw8Q)QAKBB{v3ewCp3$3GzR*avl1 z2T848QO8rY!NV%Q22C&hY^43rp03JJQr(&X9`j8=lCVly<_`op;GOjJpZpG7Ux2dy zQR`$q`d@`W?75b*`yQ=b5Q8M3RRCRxC-DFH8i#dwUSm`NEpNFz~#vU z-Xh!=Jz)LJwBdC$xILA;PHuMUu7q`>i17LxFx%KQFqbHy_VHuN7-z{uCYSI0JiXS5 z+4Ze$vbcPI>qF`!DvI^%e$fBtF_z8@k#46(hSQPi`WCaXpJhF0D9*Tk<&+QOv5<0U zDSTWqN^F%zMUuH%^|+f3A@FKn)Y)QXQ<1=s65u#zm^@7v^BuF**$P93&8VAH`N z4G*1FmHd#QWjtxLhueG5LWvA8`dssMey<_mN4 z{0>28F0aE=RwEk>hoEx7UCQOiP9wI=SWIFD!KzQd0&Z;fMec-*+`jl%U|N&1w>39? z5W+9~Ut5=8uL8-N&wopR3HEF6_nu&7)t?iPw+`qr^9efhAuUTqxC^0_=Oi#jHx6ih z@94XKx@zXeIQ#vLC5PN9%wvI9oj_o0(vNi~y3KyzSb+e~zw6)|+l0j%;<^@YtKwn* z5AxnRD6X&D7R3_W3GPmCcY?b^@SwpxIKkcBHAq7U?jg9l1PIau*M<<>3AwxZedoPX zx86D5`SaDim0jsB*r{}{z1Ea5#~ibKL`U=wrmwmH4lu6+*b57o471QmIF$SY{4Y2A ziAzs_c=+(c=8|_`GGs-W7*|vtG{6fFNBR@dmi@`=U+Sy>?nQW<>w?l~rU$Q%l`_`0 z@vA874s{n+ zZ?cah!*Q<^pWNFwoK~!V`B6w}u{GouRn(L@w9G%+vL<6D9Qk`0lzUW50b>3-TqLtJ z#6Fd=lyM^Be^EBuh)iIvJmK7LV6HcKuSt|k`(jV&vNUV+wBT~bn%^xCsjW<>dZBVJv3wqyV( zuM$$_mYCK5h0!m)`?XrC>sF5PoQ=x)|AlFmqd642EN^x9hfK7-Wf$y(--?jhwr;dO2gSO$XW%wdW0yK*vB`+)p!y+-%mjD!<3ZPBy2e4b9WzaC} zCQ)e964XK6xdC07y3cbMhKC)TZoxf%!{8Z#OdORJJP0!ufu<8-)xraYEwq_Wdm z?(1!kQHjyEoro;{iOKuY8=OmPeqJZ%i&egQxWzl-zbQrl*XY(I9GF{?(HfSPYsFsn zFv-A22X5YwLih`l|15kA6*m6w*9MkQ0|r4A9uZSyzLs&#i3m_RZqQqr@8J)NWUUuAzcJKf?M@A*K=hGoT zII>}u|ECyg2lx`W!Hf!He-L{uNkYevfq<5ww`+^N2^U(Dt%&1DR2PNTNuFg9LG68H zx_k8}2hX#THCYD%mogmzw141y=$3$5lgI4s>o<`A!Qgp52Q-8QKW?9V49q0i>l=5F z;-4k`KJO#_Y2K9uQhwL_@4opz8oXp6`a+p3f_agVsn)?LKieLm`lkGs7v_EA4 zRNhCc1&@s%H+u9=vS)M$|HhT5!uulC|IsBMpOQ>pO|84FRXJAN*6IJqYueI(^7`t> zS_)M^b{`Eem_$m0kw>Zn@(=P4js6Rg1Dh_ueY|VV*Hi*8QuW;E&LL+d2OM6B~L!{Ip+eEwK~HXutZ1f?*+|e+a0; zA*MorI(#8&__k=Ed(|0k!-LkL#rn!q+}Xpw`eH4%|7hYPEh=Kj4&=qpBVb$6fhDVA zB6brmLjTRK|L5703U*@TV(DFnltpEf`bWFE3<;$fK7Ar|Ni&l3wH=lHlgZvS)r{&| zpes`LU!MA_Er1Wg9gsdubQr+2EL%dxst621&8`WKT3}6BeT0`5o=PhwD~;cI)Rau+ zRF=+-x_A(+a2&|mXKyB%k~5yKCoz8a8EPtZM>F29Zj;%nAhj^C^QBSiTk8$ko_E&P zqNuxY3m=_GDl3&^3Rx(f<(M121#4tEzPQfXa)q$M%)S%TVLruuKl+B=4C63 zYq=_VxWQ+=xE1a3y{rnryDgl(Pd^N;ooV1)+NgGH_r|_N?z*gF`*A4R0Y%ra&gK5; z>ZoSmFWLm)({FYfw3M4~4F;7PCmvG;T(!r%qY0AI}^?2|M z(y}DSq#)^Qgah(S>Awz>ta-Xp0f87K6e=8PaA^ZmyYY*YYKgr257pK}ufmlM9Pfb6 zf={s&OWV{Kf=BaJxUKjkI$0;GnCywf+KI4(IqN5#8of1te4WceCo znHqr;J`+ZX)I-ZS5}3v~5&VOJbUE^I5V^s<+9XP-WUW8|{_Dd$j=rhLO;IA%5=9L_ zc6vg2Tkb>yWD~8>PShBe_Q%460$>`U;yVJ7eTW)VCwKNjr~s8Y3Bmw%A=}Z@Kejf6 z;a8uX%?of|$ya}yRWFNAezT*X@_J<;-Jp$bdj)+!{nc>Oupb#ZfdC}1Z@TZd-(MJv ze_>{BllPBr_Cb!)ai;k4)aiuu*%geq^3^kO{Doh$m+!vG(j-TO7AA}Q^^Bdg#)#$RJ76P~AWl-~@vLXKc1 zO@lj-R*%-tAIN`0?CS#8-_vD-NT99HHN1(H?l zJnoinw@lcc|!;IRN8ffqn~s8E;Tk5VbY%(q^jxdw$;i66=>5(D8sVDZ`I z@1AAVSk&PB0~q(i?t$4ad2pVEzMdG|b2m@;K3=}vhsBCnUW3MoG_^G)tR?)7LfI!h z8I0+n3AeCmrf@F=UrrMK7I6*QB3h{_%Nn$X$8sH z8z#OisP@vfqyIh!QQh4->r7qC`kn_N{W6eefX=$BKy5CaUzW{Dz?(1VGY_^^!#$Y91aS@VTQola_8u^OA?;k9x2e$ZQYxIK^7n7 zvlrHz1*m8}n~Vd_%ej(Gx8X(KOb64n_NBrm=FLR=_=jh;2yVa@D!P`pR12Na1`;|) zF%k}AytR-c)Qe*ZdLckBLdALH$l!#j_E=z&MK*2MJ5gLuOiGY^Qw|?03JjSq$`3yf z!$1N$(?WbWC#7cnNb6fWyd`w!MWMuO7ul!piZ6=77hWz%?(0J~ev>lP9`z2mWyaY8 zBiAZK#BSn!a*Shz_L@N4#Os0!e!wivg|i zK!cUGvduT1g+@5eD>hkD#m4(r94a9-=F~`$Px9>|#@*;9ma`TgRQMJ;87klXAXdh8 z%?j4Eo!pq6V<%ZrZQ7izC2Ep(&AWZ)$DZ{-2H`V%0MT;XJ-v1&B`Ec~MaI=U?1&d*n@9`7vzsR~>m=mn0=6D6u7YU%&eP#Q`T2p^C^vZd=KUe@o7$0)9}^vrxt3 zo2KtI%=KvWvE?Vr?))fbd`9W_e_=)~<>(Jz6)KuaZ`oHTMs&;NN|E7KkfZ5wsN7Ua zp4Ha}b{PXUY!kt$^3;F5_oslG2^70!q!a#fPHJ6ff;c1B-RalK9;n&`ePoA)Q1liB z!}Ab2hgFe)@yPl44k#t@%Vvhat#H}I6=sayIhiRGP7$qzBDR_Xrwof*1>V!e51JAK z>^9FW5Q0s5^Pd*lM40gd!=s>g34*O^Bq`w@I<2@dXHM=*=^eWN2TkP{NEg zW4pk6jYl}cs*VZdb?DaN~!g`{)8o%e5kC?nZX>UEp+(NYqQKY=wa&xX5a3`mp429V_`9-ChBDW!ThYd!vNYbL+z230RV! z_mjdfU+HKhXfnU36T}Va+p@V(ISr*V#pYJgB95a<+8wJDif0sVLQoB%e4@NS;5Z}i zgTYIFhpJx7!{nw+ERKPGx3nOkr9kyX*>an+jM>jnM@1WpB;&z5KY`rOf}oTFRwTiz zD(W2r{S^No8kn81VAWf*lOBm;u9rHk{U!J9+EYSH1uzsYEuV%8R(o$SgCS$v`bl4O zY?tvp+z3%oK23ht&O^2bAmH>-eHv9Qxq8B)8fVLt;cyn;MM9C@@|$}?P%#%TCbO}J zi`(7nqomx)Z$oQM2QPdLKi+wOqFdRghJ4kZj0mQGWJSn^?HeUUCDlqRC*EhftcViG z5s~zA8LwOAz3ksh(qU_vx;<5&L@2sk@0Ai0q@H2wofV;g;)Fmstjfnf5bz);22*|O znM^TIsm{4N*Mh=sbRY}^hC9ulYPJn4K|_0R0s8(5p#BB1+)0Sig5LA3PK3PgVGjDc zeD9j|Z!SK=8q7dm0F}fJyyaK>r90zoXkBrpd3xaIt<+!i{6@P&h~gFfaA3~=a|Ae^ zk3bECS-s?)PB_I@@wW?27$TR1(e@npI41^D6lZEsXv~^5g_4%Xsy@qYX495tQnVTW z=V%Xy&-5;oo3H=Bq;wTJ`$!{;ViH{`HG(6t`o0X-O)tu&Z9(?c-(g~gK-95xVkmy@ zM}Nto=*uYL;i~=u30J4S`lh&UoPw*#5zP(L`ME+eOGyR3k`nGywkKnQc@`xryu)Lh zHoTFex9)Msdx(ts;mdiixrZGqn`a%;EwjCn zOU<0k(1=Ig9)4AVY?NQmki4<>+X~kvu}gc@KV0SUvg|l&Q%9=2tlLK`b2#@Y5KbTh zJw)L=>s4r9S|fK zooLk`=k)aVUI=^eBouJty@ZAP_$IYL8RerES7OQknQFTC**e=|%6{p2*=d>1pEQRF zy$bDg*h_tS6-_q^kn?71>=y%#*HCmWR*J+hOu^R8SV+C*jvPK#^Yxwpg7Z(Ot0IQv z<5wR|0N@vk^6qI_5pjivfSY~3PaULkRP!-_^tIk0nO?cgPvgu}py$(eNnl!S^|?d- zOg`h_gd3dSA9nReGo7FO0|hS-kr!ER0SP>SE7#%0@)NO^FKHq{G4 zF{f&CELse0ra?s3d=au7t-$`drxxjo!xSO7!;n=WK!8;4tNYqtm=R!}TpF__?WT5F zIuGcJ1}{P>(VSEVZwh1P2Rb6xWMcJMyrb`le_^5|dPbCFj_{}ngKb_hAUihjt2mmw zhx2-b&kxpjyu*)h52iGVr9@<*%9@zj_6V7gV2K)%?$FFUR}^|#3)kGA|1PWGeL0MQ zS_qBwRDVoQ)j;-$<>)kK+-EF8EnZXcsi@g2>?arGgtx9pu->H)>ol9=aMZalrD$PN zd_=M6J9cWY=#Eub`2{KI!(b)Qd-<6Xr%U9QZ3o(LedrXlJVs zCU`FPjk7d0NetcCJ17lTIV*9~?L+YDY=s#$C!Bq}N`o?nLj5~!PkgqAYQiTYwN2i5 zoJyur#OTGBk&_0TC@T?k%+|+BiWb_ry_h@$3^km8rIc`d7qHR?J;xiqc*$~-xyp4d z=odVmBKj<`15Dg*92>OWlbYfqnxm;7H+?)*FFyG6N8!`LDIPjZ$$U>jKzLHdYkG3t zQ{R$jB(tTPFLTa7x*uHfe>v|_<<9sL;Z`wN2u{M`h?VKgj4LQA>#afuiMEz}?2}Q0 z6-{{DcQF60ks$@!f;mjnPe!KVRccR^1GGc5`n}tfL1iUQ)fNqNmQ;@NHqE;9Bq{2> z_<1vet9N1L)VLe@kACqV%aUYCVB~vHPD=+Jhx;+K0#ljvU>benuPu5cgFT&VQFa{d zTX(%Hj!r7%Fbu`vnUtm@?LM$(5NZ`mrp&M6RmBiSP?hw*K{)!wM4KxAM?h1t!Jx@1 zxs&^=6pSyud3WoAoNSEjUU;>pMKe(i*;BbNMac=cVeeA2ZmK-3yh6=WnCppAi$q3F z;CsC9oKLLsot7k8qkjh;`gZ${3fvKg**2&`vHj7dJk;m<6gD*~Ls|HZJBTT&Nt-G| z>{yAwPM-rR z)N8O2DhccFEeRPjYIfS+DnB~I*Xlhj1$K{Nz{tFTB@Thw1_YqKva7OFOUY8v2jcj@)0 znDN|***tZ0p~E=j62mo$v5S<;SJFNZN0>y>*93pr3K1d->i!(=u0t7iQ%hp?7e?1U zo2B&YqsLhF?e=S>A(w;SEH6v3VmM5#o$UEv$@26QnlAAg8}g^iU5=y$Q*XZJ(#V26 zC<@&emK)w5%as+SN@Go=@(CY1at>1$Vp|Kr?Clk&U@jk`r|VY4yi#cIft=6AFOr8{ zgCgQ`9SSZr>E&kA^*JAvCw<`N+_6W|i{v(RJ{Tyf4=~x0Q~j z!S;@t${mgn4*g!xmA0g%={w;5zbV*e+BCWdE+02-oqWPi;`oZ!+Ab-RnXAY^?U8?8 z@_&bZ?S0!oH1V`6UKFOzczL#lLSEKBMM5)8gq_b&>CxQnJO6qm4pW|jTR;~+yrQ4k z>u12xCX;1W1taO|u4)gqXsqEJh~*vV^+MywK{s#qSb?DE2$U%CoS?k`&YNcXl#l_y z_X4gGQib0I^H8C*X*JthD7YQTPyxKmcZ7*jKn3;w!esxHc>PxIMaTQ^cnA?QN_O!m zL*60W)DD;XSbE6CX4u5kcu@7vE><1u4p8R_;QH`6m8#SIE%aeT$5%T;O4Z3soXRT+kkS<0$(s%_n0ZkM0+fCoo$>ti>;v&+2U5sPJ;EVdpE%T z6=429w^cyv6|^V)d8YL!hg7{^e7Jn{f+5iq1^ zL));=gIG5{Ir`khcVn|#u6vNrER!Zl)kiaTGOJ}JRSk6x9;e7*vXQ7O|Ml%!p#PY> z7Dwp`UU5U5NuF-mk1#W3JL74Cw7xO>z6m+wCR+DL;|%v+#I*f*#-tSqKS*F(d3gJs zW-cvF?}_30gD_s%DAJ1lcC0s(6^&bBXm*HR^R~lGf!lXLtT)8Bi#M1tlN6+C>cnb5dgHNL-WGr9mW0BGu$Xs|6&Qy#dT% zS5abd)B)pOuYfLOK!wuS@Pk*m%f-Wu!6*PX&96F(c$Isv+yL*_FrZ-J5fJUEl!slP zeq85;!cT=%vnZYkGz$UD|M5sjqUiKlE~03y#~rWj#$V$|YP^0y6e->CNrmw|i3QmK z28L-#9bbcBDpx}ij((fdNh4Q6W0z2U`Sr`*Pd#}1MBjcv1{>et0K09nVOUg27Y|WWQK)Yn}`!PyLp{zwic`+pSDHJjWk10!pEh? zeD^YtLAlNRF1;+yT%_Z(=^fVxDm*NGx6b7h>^W|ucHj4J7JGY19%T4PhRG^`1l#-= z+Mw1!_8hfmW_62^dtCe6ik{>EgTrQn`N`D_$+3K*?#X`u#6v)@@N0-Vm&q5Y5t=B< z;;}cwfY_&R?4$Jx3%H%WGOyUPuhPs-@+%fFq#x$- zmo{WNbBsW3U1usQ*nKG`4!Mwgrgn1yO-)_3j&HYgbnXx1)d14QT$y$334Fvq%Ds