From 53f2b5dbda2d036dac9b1acf95e98ac9c0de40d2 Mon Sep 17 00:00:00 2001 From: istoril <96023710+istoril@users.noreply.github.com> Date: Sat, 22 Jun 2024 22:51:17 +0300 Subject: [PATCH] 1 (#9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: precompiled contracts ABI import (#9899) * Initial implementation of precompiled contracts ABI import * Documention added * address Sobelow finding * another attempt address Sobelow finding * Apply evident suggestions from code review Co-authored-by: Kirill Fedoseev * Fix afer merge * Small inconsistency in spec * different path for different mix environment * fix for formatting issue --------- Co-authored-by: Kirill Fedoseev * Update README.md * chore: Bump floki from 0.36.1 to 0.36.2 (#9979) Bumps [floki](https://github.com/philss/floki) from 0.36.1 to 0.36.2. - [Release notes](https://github.com/philss/floki/releases) - [Changelog](https://github.com/philss/floki/blob/main/CHANGELOG.md) - [Commits](https://github.com/philss/floki/compare/v0.36.1...v0.36.2) --- updated-dependencies: - dependency-name: floki dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump redix from 1.4.1 to 1.5.0 (#9977) Bumps [redix](https://github.com/whatyouhide/redix) from 1.4.1 to 1.5.0. - [Changelog](https://github.com/whatyouhide/redix/blob/main/CHANGELOG.md) - [Commits](https://github.com/whatyouhide/redix/compare/v1.4.1...v1.5.0) --- updated-dependencies: - dependency-name: redix dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Enhance indexer memory metrics (#9984) * chore: Bump @babel/core in /apps/block_scout_web/assets (#9996) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.24.3 to 7.24.5. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.5/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump @fortawesome/fontawesome-free (#10002) Bumps [@fortawesome/fontawesome-free](https://github.com/FortAwesome/Font-Awesome) from 6.5.1 to 6.5.2. - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/6.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/6.5.1...6.5.2) --- updated-dependencies: - dependency-name: "@fortawesome/fontawesome-free" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump mixpanel-browser in /apps/block_scout_web/assets (#10000) Bumps [mixpanel-browser](https://github.com/mixpanel/mixpanel-js) from 2.49.0 to 2.50.0. - [Release notes](https://github.com/mixpanel/mixpanel-js/releases) - [Changelog](https://github.com/mixpanel/mixpanel-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/mixpanel/mixpanel-js/compare/v2.49.0...v2.50.0) --- updated-dependencies: - dependency-name: mixpanel-browser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump sweetalert2 in /apps/block_scout_web/assets (#9998) Bumps [sweetalert2](https://github.com/sweetalert2/sweetalert2) from 11.10.7 to 11.10.8. - [Release notes](https://github.com/sweetalert2/sweetalert2/releases) - [Changelog](https://github.com/sweetalert2/sweetalert2/blob/main/CHANGELOG.md) - [Commits](https://github.com/sweetalert2/sweetalert2/compare/v11.10.7...v11.10.8) --- updated-dependencies: - dependency-name: sweetalert2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump css-loader in /apps/block_scout_web/assets (#10003) Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 6.10.0 to 7.1.1. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v6.10.0...v7.1.1) --- updated-dependencies: - dependency-name: css-loader dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump @amplitude/analytics-browser in /apps/block_scout_web/assets (#10001) Bumps [@amplitude/analytics-browser](https://github.com/amplitude/Amplitude-TypeScript) from 2.6.1 to 2.7.0. - [Release notes](https://github.com/amplitude/Amplitude-TypeScript/releases) - [Commits](https://github.com/amplitude/Amplitude-TypeScript/compare/@amplitude/analytics-browser@2.6.1...@amplitude/analytics-browser@2.7.0) --- updated-dependencies: - dependency-name: "@amplitude/analytics-browser" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump @babel/preset-env in /apps/block_scout_web/assets (#9999) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.24.3 to 7.24.5. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.5/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump mini-css-extract-plugin in /apps/block_scout_web/assets (#9997) Bumps [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) from 2.8.1 to 2.9.0. - [Release notes](https://github.com/webpack-contrib/mini-css-extract-plugin/releases) - [Changelog](https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v2.8.1...v2.9.0) --- updated-dependencies: - dependency-name: mini-css-extract-plugin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump style-loader in /apps/block_scout_web/assets (#9995) Bumps [style-loader](https://github.com/webpack-contrib/style-loader) from 3.3.4 to 4.0.0. - [Release notes](https://github.com/webpack-contrib/style-loader/releases) - [Changelog](https://github.com/webpack-contrib/style-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/style-loader/compare/v3.3.4...v4.0.0) --- updated-dependencies: - dependency-name: style-loader dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump ex_cldr_units from 3.16.5 to 3.17.0 (#9931) * chore: Bump ex_cldr_units from 3.16.5 to 3.17.0 Bumps [ex_cldr_units](https://github.com/elixir-cldr/cldr_units) from 3.16.5 to 3.17.0. - [Release notes](https://github.com/elixir-cldr/cldr_units/releases) - [Changelog](https://github.com/elixir-cldr/cldr_units/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-cldr/cldr_units/commits/v3.17.0) --- updated-dependencies: - dependency-name: ex_cldr_units dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Add cldr to dialyzer ignore --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Viktor Baranov * chore: Bump ex_cldr from 2.38.0 to 2.38.1 (#10009) Bumps [ex_cldr](https://github.com/elixir-cldr/cldr) from 2.38.0 to 2.38.1. - [Release notes](https://github.com/elixir-cldr/cldr/releases) - [Changelog](https://github.com/elixir-cldr/cldr/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-cldr/cldr/compare/v2.38.0...v2.38.1) --- updated-dependencies: - dependency-name: ex_cldr dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump ex_cldr_numbers from 2.32.4 to 2.33.1 (#9978) Bumps [ex_cldr_numbers](https://github.com/elixir-cldr/cldr_numbers) from 2.32.4 to 2.33.1. - [Release notes](https://github.com/elixir-cldr/cldr_numbers/releases) - [Changelog](https://github.com/elixir-cldr/cldr_numbers/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-cldr/cldr_numbers/compare/v2.32.4...v2.33.1) --- updated-dependencies: - dependency-name: ex_cldr_numbers dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Remove update of latest tag except release CI for chains, which managed via CHAIN_TYPE * CI for Arbitrum on-demand Docker images * feat: Omit balanceOf requests for tokens that doesn't support it (#10018) * feat: Omit balanceOf requests for tokens that doesn't support it * Missing balanceOf token refactoring * Fix failed token balance error matching * feat: Detect EIP-1967 proxy pattern on unverified smart-contracts (#9864) * Detect EIP-1967 proxy even for not verified smart-contracts * put_verified_from_twin/2 function * Implement proxy implementation model * Fix test * Fix DB migration * Refactoring * Fix tests * Change schema to store implementation arrays * Refactoring * Update apps/explorer/lib/explorer/etherscan/contracts.ex Co-authored-by: nikitosing <32202610+nikitosing@users.noreply.github.com> * Process review comments * Fix call of Implementation.get_implementation_address_hash * Refactor save_implementation_data/5 to save_implementation_data/4 * Process review comment * Remove duplicate call of implementation_updated_at * Eliminate metadata_from_verified_bytecode_twin from save_implementation_data function * Fix formatting * Set non-nil smart-contract into Implementation.get_implementation_address_hash(...) * Simplify clauses in save_implementation_data/3 * Get implementation data in a single DB request * Fix tests * Set different proxy verification success message in case of single/plural implementations * Refactoring --------- Co-authored-by: nikitosing <32202610+nikitosing@users.noreply.github.com> * fix: Handle DB unavailability by PolygonZkevm.TransactionBatch fetcher (#10031) Co-authored-by: POA <33550681+poa@users.noreply.github.com> * Fix typo * feat: save smart-contract proxy type in the DB (#10033) * feat: save smart-contract proxy type in the DB * Add tests * Allow null proxy type in DB * Fix tests * Update stats.yml (#10030) Stats container env variables was not working correctly * chore: Migrate to GET variant of {{metadata_url}}/api/v1/metadata (#9994) * chore: Migrate to GET variant of {{metadata_url}}/api/v1/metadata * Fix test * fix: Don't put error to NFT metadata (#9940) * fix: Don't put error to NFT metadata * Remove unused Explorer.Helper.maybe_decode/1 * feat: add user ops indexer to docker compose configs (#10010) * feat: add user ops indexer to docker compose configs * fix: missing env in .gitignore * fix: search for long integers (#9651) * fix: search for long integers * fix: ignore negative block numbers * chore: move `safe_parse_block_number` to `Explorer.Helper` * refactor: make function name more generic * refactor: utilize `safe_parse_non_negative_integer` in `paging_options` * Show blocks range in internal transactions fetching error (#10028) * feat: Diamond proxy (EIP-2535) support (#10034) * feat: Diamond proxy (eip-2535) * Additional logic change * Refactoring & backward compatibility * Refactor specs * Remove prepare_value function * implementation_address_hash_from_db, implementation_name_from_db to plural form * Remove check implementation_address_hash_strings is list * address_hash_to_smart_contract_with_bytecode_twin function: return options param into the call of single_implementation_smart_contract_from_proxy * Remove fallback "|| [burn_address_hash_string()]" * Update spec of set_proxy_verification_result * Fix web tests * Change the order of enum values to match db enum * Remove duplicated clause in save_implementation_data/4 * Remove duplicated line * Add clause for [] to set_proxy_verification_result * chore: Update outdated links to ETH JSON RPC Specification in docstrings (#10041) * Update outdated links to ETH JSON RPC Specification in docstrings * Remove empty line * feat: MUD API support (#9869) * feat: mud support * chore: fix ci warnings * feat: skip missing schemas * ci: build redstone image * chore: fix dialyzer * chore: remove noop migration * feat: full-text table search * fix: don't show deleted records * fix: type specs and dializer fixes * feat: checksum addresses * fix: handle invalid params * chore: add missing envs * chore: Add support of Blast-specific L1 OP withdrawal events (#10049) * Add support of Blast-specific L1 OP withdrawal events * mix format --------- Co-authored-by: POA <33550681+poa@users.noreply.github.com> * feat: Improve retry NFT fetcher (#10027) * feat: Improve retry NFT fetcher * Process review comments * Fix spelling * chore: remove `has_methods` from `/addresses` (#10051) * chore: remove `has_methods_` `read`/`read_proxy`/`write`/`write_proxy` from `/addresses` * chore: move proxy contract test to `smart_contract_controller_test.exs` * refactor: test database config (#9662) * refactor: test database config * feat: configure test db with special envs * fix: prefer `url` from config over raw env * refactor: remove redundant fallback * refactor: use `ConfigHelper.init_repo_module/2` to configure `ZkSync` repo * fix: Fix Unknown UID bug at smart-contract verification (#9986) * fix: Fix Unknown UID bug * Fix credo * Fix credo * Refactoring * Fix aliases * chore: Bump ex_doc from 0.32.1 to 0.32.2 (#10061) Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.32.1 to 0.32.2. - [Release notes](https://github.com/elixir-lang/ex_doc/releases) - [Changelog](https://github.com/elixir-lang/ex_doc/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.32.1...v0.32.2) --- updated-dependencies: - dependency-name: ex_doc dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump redix from 1.5.0 to 1.5.1 (#10059) Bumps [redix](https://github.com/whatyouhide/redix) from 1.5.0 to 1.5.1. - [Changelog](https://github.com/whatyouhide/redix/blob/main/CHANGELOG.md) - [Commits](https://github.com/whatyouhide/redix/compare/v1.5.0...v1.5.1) --- updated-dependencies: - dependency-name: redix dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: Bump credo from 1.7.5 to 1.7.6 (#10060) Bumps [credo](https://github.com/rrrene/credo) from 1.7.5 to 1.7.6. - [Release notes](https://github.com/rrrene/credo/releases) - [Changelog](https://github.com/rrrene/credo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rrrene/credo/compare/v1.7.5...v1.7.6) --- updated-dependencies: - dependency-name: credo dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refactor: Refactor get_additional_sources/4 -> get_additional_sources/3 (#10046) * fix: vyper contracts re-verificaiton (#10053) * Add test case for publishing re-verified solidity contract * Add (failing) test case for publishing re-verified vyper contract * fix: allow for vyper contracts re-verification * Remove commented line * feat: Clone with immutable arguments proxy pattern (#10039) * feat: Clone with immutable arguments proxy pattern * refactor: rename unverified_proxy_only? to proxy_without_abi? * fix: Disallow batched queries in GraphQL endpoint (#10050) * Disallow multiple queries in GraphQL endpoint * Fix mix credo * Add Plug.Parsers to each pipeline * Process review comments * Process review comments * chore: Update hackney pool size: add new fetchers accounting (#9941) * feat: Blueprint contracts support (#10058) * Update smart-contract to have 'is_blueprint' flag * Store into the database 'is_blueprint' value retrieved from verification or lookup results * Make use of TestHelper module for smart_contract_controller_test * Make use of TestHelper module for verification_controller_test. Fix invalid 'is_blueprint' value in fixture * Fix spelling. Simplify Vyper.publish method * Add 'Averify' into spelling check * Add PR url to the comment with rationale behind url-encoding ':' symbol * fix: Separate indexer setup (#10032) * fix: Separate indexer setup * Configure CI for sepate images for indexer and API * Change CI for every push to master branch (build separate indexer/api images) * Add DISABLE_API env var * Indexing status improvements for api instance --------- Co-authored-by: Viktor Baranov * feat: Add optional retry of NFT metadata fetch in Indexer.Fetcher.Tok… (#10036) * feat: Add optional retry of NFT metadata fetch in Indexer.Fetcher.TokenInstance.Realtime * Rename env * Process review comments * Rename var * fix: Eliminate from_address_hash == #{address_hash} clause for transactions query in case of smart-contracts (#9469) * Eliminate from_address_hash equal to address clause for transactions query in case of smart-contracts * Fix tests * Fix web tests * Fix web tests * Process review comments * Update apps/explorer/lib/explorer/etherscan/logs.ex Co-authored-by: Kirill Fedoseev * mix format * Remove or_where import * Update smart-contract controller test --------- Co-authored-by: Kirill Fedoseev * fix: Rework revert_reason (#9212) * fix: rework revert_reason * fix: format * fix: tests * fix: chain_type_fields * chore: refactor * fix: decode functions refactor * 6.6.0 * fix: Add healthcheck endpoints for indexer-only setup (#10076) * fix: Update Vyper inner compilers list to support all compilers (#10091) Increases the number of items retrieved for Vyper releases to 100. Allows to get the oldest vyper compilers when using internal verification (i.e., sc_verifier is disabled) When not set, the default number of items retrieved is 30, which is less than total number of currently existing releases (46). This makes the oldest compilers unavailable when using vyper verificaiton method. Should fix the failing `/api/v2/smart-contracts/{address_hash}/verification/via/vyper-code success verification` test * Fix certified flag in the search API v2 endpoint (#10094) * Update CHANGELOG for 6.6.0 * Remove custom release CI for Immutable * feat: implement fetch_first_trace for Geth (#10087) * feat: implement fetch_first_trace for Geth * chore: add missing doc & spec * Update CHANGELOG * Fix GA pre-release && release workflows * Improve response of address API to return multiple implementations for Diamond proxy (#10113) * Update CHANGELOG * Indexer/API separated images for Redstone * chore: Bump ecto_sql from 3.11.1 to 3.11.2 updated-dependencies: - dependency-name: ecto_sql dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: indexer for cross level messages on Arbitrum (#9312) * Initial version of x-level messages indexer * fixes for cspell and credo * new state of x-level messages * Monitoring of new L1-to-L2 messages on L1 * new batches discovery * fetcher workers in separate modules * proper name * Fix for responses without "id", e.g. "Too Many Requests" * update DB with new batches and corresponding data * update DB with confirmed blocks * fixes for cspell and credo * tracking commitments confirmations for L1 to L2 messages * Proper usign of max function * tracking completion of L2 to L1 messages * catchup historical messages to L2 * incorrect version of committed file * catchup historical messages from L2 and completion of L1-to-L2 messages * historical batches catchup * status for historical l2-to-l1 messages * address matching issue * catchup historical executions of L2-to-L1 messages * db query to find unconfirmed blocks gaps * first changes to catchup historical confirmations * finalized catchup of historical confirmations * 4844 blobs support * fix for the issue with multiple confirmations * limit amount of batches to handle at once * Use latest L1 block by fetchers if start block is not configured * merge issue fix * missed file * historical messages discovery * reduce logs severity * first iteration to improve documentation for new functionality * second iteration to improve documentation for new functionality * third iteration to improve documentation for new functionality * fourth iteration to improve documentation for new functionality * fifth iteration to improve documentation for new functionality * final iteration to improve documentation for new functionality * merge issues addressed * code review issues addressed * code review issues addressed * fix merge issue * raising exception in the case of DB inconsistency * fix formatting issue * termination case for RollupMessagesCatchup * code review comments addressed * code review comments addressed * consistency in primary keys * dialyzer fix * code review comments addressed * missed doc comment * code review comments addressed * updated indices creation as per code review comments * fix merge issue * configuration of intervals as time variables * TODO added to reflect improvement ability * database fields refactoring * association renaming * feat: APIv2 endpoints for Arbitrum messages and batches (#9963) * Arbitrum related info in Transaction and Block views * Views to get info about batches and messages * usage of committed for batches instead of confirmed * merge issues addressed * changes after merge * formatting issue fix * code review comment addressed * associations and fields in api response renamed * format issue addressed * feat: Arbitrum-specific fields in the block and transaction API endpoints (#10067) * Arbitrum related info in Transaction and Block views * Views to get info about batches and messages * usage of committed for batches instead of confirmed * merge issues addressed * changes after merge * formatting issue fix * block and transaction views extended * code review comment addressed * associations and fields in api response renamed * format issue addressed * fix credo issue * fix tests issues * ethereumjsonrpc test fail investigation * test issues fixes * --- (#10096) updated-dependencies: - dependency-name: phoenix_ecto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * hide chain specific fields behind Map.get (#10131) * fix: Hotfix for Indexer.Fetcher.Optimism.WithdrawalEvent and EthereumJSONRPC.Receipt (#10130) * fix: Hotfix for Indexer.Fetcher.Optimism.WithdrawalEvent * Small refactoring * Small refactoring * Consider nil in game_index * Add empty handler for Optimism Fjord tx receipt fields --------- Co-authored-by: POA <33550681+poa@users.noreply.github.com> * fix: missing nil case for revert reason (#10136) * Explicit message on token balance update error (#10129) * fix: Add missing preloads to tokens endpoints (#10072) * fix: Add healthcheck endpoints for indexer-only setup (#10076) * fix: Update Vyper inner compilers list to support all compilers (#10091) Increases the number of items retrieved for Vyper releases to 100. Allows to get the oldest vyper compilers when using internal verification (i.e., sc_verifier is disabled) When not set, the default number of items retrieved is 30, which is less than total number of currently existing releases (46). This makes the oldest compilers unavailable when using vyper verificaiton method. Should fix the failing `/api/v2/smart-contracts/{address_hash}/verification/via/vyper-code success verification` test * Fix certified flag in the search API v2 endpoint (#10094) * Update CHANGELOG for 6.6.0 * Remove custom release CI for Immutable * feat: implement fetch_first_trace for Geth (#10087) * feat: implement fetch_first_trace for Geth * chore: add missing doc & spec * Update CHANGELOG * Fix GA pre-release && release workflows * Improve response of address API to return multiple implementations for Diamond proxy (#10113) * Update CHANGELOG * Indexer/API separated images for Redstone * chore: Bump ecto_sql from 3.11.1 to 3.11.2 updated-dependencies: - dependency-name: ecto_sql dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: indexer for cross level messages on Arbitrum (#9312) * Initial version of x-level messages indexer * fixes for cspell and credo * new state of x-level messages * Monitoring of new L1-to-L2 messages on L1 * new batches discovery * fetcher workers in separate modules * proper name * Fix for responses without "id", e.g. "Too Many Requests" * update DB with new batches and corresponding data * update DB with confirmed blocks * fixes for cspell and credo * tracking commitments confirmations for L1 to L2 messages * Proper usign of max function * tracking completion of L2 to L1 messages * catchup historical messages to L2 * incorrect version of committed file * catchup historical messages from L2 and completion of L1-to-L2 messages * historical batches catchup * status for historical l2-to-l1 messages * address matching issue * catchup historical executions of L2-to-L1 messages * db query to find unconfirmed blocks gaps * first changes to catchup historical confirmations * finalized catchup of historical confirmations * 4844 blobs support * fix for the issue with multiple confirmations * limit amount of batches to handle at once * Use latest L1 block by fetchers if start block is not configured * merge issue fix * missed file * historical messages discovery * reduce logs severity * first iteration to improve documentation for new functionality * second iteration to improve documentation for new functionality * third iteration to improve documentation for new functionality * fourth iteration to improve documentation for new functionality * fifth iteration to improve documentation for new functionality * final iteration to improve documentation for new functionality * merge issues addressed * code review issues addressed * code review issues addressed * fix merge issue * raising exception in the case of DB inconsistency * fix formatting issue * termination case for RollupMessagesCatchup * code review comments addressed * code review comments addressed * consistency in primary keys * dialyzer fix * code review comments addressed * missed doc comment * code review comments addressed * updated indices creation as per code review comments * fix merge issue * configuration of intervals as time variables * TODO added to reflect improvement ability * database fields refactoring * association renaming * feat: APIv2 endpoints for Arbitrum messages and batches (#9963) * Arbitrum related info in Transaction and Block views * Views to get info about batches and messages * usage of committed for batches instead of confirmed * merge issues addressed * changes after merge * formatting issue fix * code review comment addressed * associations and fields in api response renamed * format issue addressed * feat: Arbitrum-specific fields in the block and transaction API endpoints (#10067) * Arbitrum related info in Transaction and Block views * Views to get info about batches and messages * usage of committed for batches instead of confirmed * merge issues addressed * changes after merge * formatting issue fix * block and transaction views extended * code review comment addressed * associations and fields in api response renamed * format issue addressed * fix credo issue * fix tests issues * ethereumjsonrpc test fail investigation * test issues fixes * --- (#10096) updated-dependencies: - dependency-name: phoenix_ecto dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * hide chain specific fields behind Map.get (#10131) * fix: Hotfix for Indexer.Fetcher.Optimism.WithdrawalEvent and EthereumJSONRPC.Receipt (#10130) * fix: Hotfix for Indexer.Fetcher.Optimism.WithdrawalEvent * Small refactoring * Small refactoring * Consider nil in game_index * Add empty handler for Optimism Fjord tx receipt fields --------- Co-authored-by: POA <33550681+poa@users.noreply.github.com> * fix: missing nil case for revert reason (#10136) * fix: Add missing preloads to tokens endpoints --------- Signed-off-by: dependabot[bot] Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> Co-authored-by: Rim Rakhimov Co-authored-by: Victor Baranov Co-authored-by: Kirill Fedoseev Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexander Kolotov Co-authored-by: varasev <33550681+varasev@users.noreply.github.com> Co-authored-by: POA <33550681+poa@users.noreply.github.com> * feat: Add window between balance fetch retries for missing balanceOf tokens (#10142) * refactor: Remove hardcoded numResults from fetch_pending_transactions_besu (#10117) * update remove fixed value * refactor fetch_pending_transactions_besu * add PR number and revised CHANGLOG.md * remove change in CHANGELOG.md * chore(deps-dev): bump @babel/core in /apps/block_scout_web/assets (#10172) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.24.5 to 7.24.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.6/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: Fix Retry NFT fetcher (#10146) * chore(deps-dev): bump eslint-plugin-promise (#10168) Bumps [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) from 6.1.1 to 6.2.0. - [Release notes](https://github.com/eslint-community/eslint-plugin-promise/releases) - [Changelog](https://github.com/eslint-community/eslint-plugin-promise/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint-community/eslint-plugin-promise/compare/v6.1.1...v6.2.0) --- updated-dependencies: - dependency-name: eslint-plugin-promise dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump core-js in /apps/block_scout_web/assets (#10175) Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.36.1 to 3.37.1. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.37.1/packages/core-js) --- updated-dependencies: - dependency-name: core-js dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump sweetalert2 in /apps/block_scout_web/assets (#10171) Bumps [sweetalert2](https://github.com/sweetalert2/sweetalert2) from 11.10.8 to 11.11.0. - [Release notes](https://github.com/sweetalert2/sweetalert2/releases) - [Changelog](https://github.com/sweetalert2/sweetalert2/blob/main/CHANGELOG.md) - [Commits](https://github.com/sweetalert2/sweetalert2/compare/v11.10.8...v11.11.0) --- updated-dependencies: - dependency-name: sweetalert2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump mixpanel-browser in /apps/block_scout_web/assets (#10170) Bumps [mixpanel-browser](https://github.com/mixpanel/mixpanel-js) from 2.50.0 to 2.51.0. - [Release notes](https://github.com/mixpanel/mixpanel-js/releases) - [Changelog](https://github.com/mixpanel/mixpanel-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/mixpanel/mixpanel-js/compare/v2.50.0...v2.51.0) --- updated-dependencies: - dependency-name: mixpanel-browser dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump css-minimizer-webpack-plugin (#10173) Bumps [css-minimizer-webpack-plugin](https://github.com/webpack-contrib/css-minimizer-webpack-plugin) from 6.0.0 to 7.0.0. - [Release notes](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/releases) - [Changelog](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-minimizer-webpack-plugin/compare/v6.0.0...v7.0.0) --- updated-dependencies: - dependency-name: css-minimizer-webpack-plugin dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump solc from 0.8.25 to 0.8.26 in /apps/explorer (#10177) Bumps [solc](https://github.com/ethereum/solc-js) from 0.8.25 to 0.8.26. - [Commits](https://github.com/ethereum/solc-js/compare/v0.8.25...v0.8.26) --- updated-dependencies: - dependency-name: solc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @amplitude/analytics-browser (#10176) Bumps [@amplitude/analytics-browser](https://github.com/amplitude/Amplitude-TypeScript) from 2.7.0 to 2.8.1. - [Release notes](https://github.com/amplitude/Amplitude-TypeScript/releases) - [Commits](https://github.com/amplitude/Amplitude-TypeScript/compare/@amplitude/analytics-browser@2.7.0...@amplitude/analytics-browser@2.8.1) --- updated-dependencies: - dependency-name: "@amplitude/analytics-browser" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/preset-env in /apps/block_scout_web/assets (#10174) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.24.5 to 7.24.6. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.6/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump chart.js in /apps/block_scout_web/assets (#10169) Bumps [chart.js](https://github.com/chartjs/Chart.js) from 4.4.2 to 4.4.3. - [Release notes](https://github.com/chartjs/Chart.js/releases) - [Commits](https://github.com/chartjs/Chart.js/compare/v4.4.2...v4.4.3) --- updated-dependencies: - dependency-name: chart.js dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: Add a separate db url for events listener (#10164) * fix: Move auth routes to general router (#10153) * fix: Move auth routes to general router * Move account routes to the separate router * chore: Return is verified=true for verified minimal proxy pattern (#10132) * Return is verified=true for verified minimal proxy pattern * Refactor proxy object for API * chore: Exclude write methods from read tabs (#10111) * Exclude write methods from Read tab * Reverse corresponding test * chore: Refactor PendingTransactionsSanitizer to use batched requests (#10101) * fix: Add the ability to allow empty traces (#10200) * fix: Resolve flaky address_controller test for web * feat: Add Fee column to Internal transactions CSV export (#10204) * feat: Add Fee column to Internal transactions CSV export * Fix tests * Fix flaky test * fix: Filter WETH transfers in indexer + migration to delete historical incorrect WETH transfers (#10134) * feat: Set dynamic ttl of cache modules derived from MapCache (#10109) * Set dynamic ttl of cache modules derived from MapCache * Update apps/explorer/lib/explorer/chain/cache/helper.ex Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> --------- Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> * fix: excessive logging for Arbitrum batches confirmations (#10205) * revisited logging to explore start block of confirmation range * improvement of logging * feat: Batch read methods requests (#10192) * feat: Batch read methods requests * Fix tests * Process review comments * feat: Add feature toggle for WETH filtering (#10208) * feat: Add feature toggle for WETH filtering * Add new envs to docker-compose/envs/common-blockscout.env * Fix tests * perf: replace individual queries with ecto preload (#10203) * feat: Push relevant entries to the front of bound queue (#10193) * feat: Push relevant entries to the front of bound queue * Refactor realtime? parameter in async_import_remaining_block_data * feat: Get ERC-1155 token name from contractURI getter fallback (#10187) * Get ERC-1155 token name from contractURI getter fallback * Process review comments * Change doc and spec for stream_cataloged_tokens function * feat: Adding Mobula price source (#9971) * Adding Mobula as data provider * push Mobula source * add chain setup * remove useless params * remove useless functions * add mobula price history provider * adding mobula history url * add possibility to fetch_market_data_for_token_addresses with Mobula on source.ex * update chain => chain_id * mix format * mix credo * removed useless alias Helper & Chain * Adding "Mobula" to cspell.json * Adding Mobula to config_helper * Fix dialyzer * mix format * Set Mobula as a default source if the EXCHANGE_RATES_COINGECKO_API_KEY is not set * fix compilation error on config_helper * Remove Mobula fallback on config_helper exchange_rates_source * Update apps/explorer/lib/explorer/exchange_rates/source/mobula.ex Co-authored-by: Fedor Ivanov * Update mobula.ex * add Mobula to exchange_rates_market_cap_source * Adding secondary_coin support * EXCHANGE_RATES_MOBULA_PLATFORM_ID into EXCHANGE_RATES_MOBULA_CHAIN_ID * should fix mix credo * adding mobula secondary id env * update env in runtime.exs * Push requests --------- Co-authored-by: Fedor Ivanov * feat(ci): use remote arm64 builder (#9468) * feat(ci): multi-platform remote build * set arm runner secret, update runner hosts * select one builder and persist it * select one builder and persist it * find the least busy arm builder * chore: update ci configs post rebase * enable remote build in every workflow --------- Co-authored-by: aagaev * fixed the field name (#10216) * chore(deps): bump remote_ip from 1.1.0 to 1.2.0 (#10224) Bumps [remote_ip](https://github.com/ajvondrak/remote_ip) from 1.1.0 to 1.2.0. - [Release notes](https://github.com/ajvondrak/remote_ip/releases) - [Commits](https://github.com/ajvondrak/remote_ip/compare/v1.1.0...v1.2.0) --- updated-dependencies: - dependency-name: remote_ip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump cldr_utils from 2.25.0 to 2.26.0 (#10223) Bumps [cldr_utils](https://github.com/elixir-cldr/cldr_utils) from 2.25.0 to 2.26.0. - [Release notes](https://github.com/elixir-cldr/cldr_utils/releases) - [Changelog](https://github.com/elixir-cldr/cldr_utils/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-cldr/cldr_utils/compare/v2.25.0...v2.26.0) --- updated-dependencies: - dependency-name: cldr_utils dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump wallaby from 0.30.6 to 0.30.7 (#10221) Bumps [wallaby](https://github.com/elixir-wallaby/wallaby) from 0.30.6 to 0.30.7. - [Release notes](https://github.com/elixir-wallaby/wallaby/releases) - [Changelog](https://github.com/elixir-wallaby/wallaby/blob/main/CHANGELOG.md) - [Commits](https://github.com/elixir-wallaby/wallaby/compare/v0.30.6...v0.30.7) --- updated-dependencies: - dependency-name: wallaby dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: Fix unknown UID bug (#10226) * fix: Fix unknown UID bug * Fix timestamp comparison * fix: Replace empty arg names with argN (#9748) * fix: Replace empty arg names with argN * Fix dialyzer * Remove dbg * Fix dialyzer * Fix test * Fix test --------- Co-authored-by: Maxim Filonov <53992153+sl1depengwyn@users.noreply.github.com> * fix: ERC-1155 tokens metadata retrieve (#10231) * fix: cannot truncate chardata (#10227) * chore(deps-dev): bump benchee from 1.3.0 to 1.3.1 (#10222) Bumps [benchee](https://github.com/bencheeorg/benchee) from 1.3.0 to 1.3.1. - [Release notes](https://github.com/bencheeorg/benchee/releases) - [Changelog](https://github.com/bencheeorg/benchee/blob/main/CHANGELOG.md) - [Commits](https://github.com/bencheeorg/benchee/compare/1.3.0...1.3.1) --- updated-dependencies: - dependency-name: benchee dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: add proxy_implementations preloads (#10225) * fix: add proxy_implementations preloads * Add preloads to channels * Add preload to cache * fix: add smart contracts preloads to from_address (#10236) * feat: Advanced Filters (#9769) * feat: Advanced Filters * Fix query performance * Fix timestamp filtering; Fix query construction * Add csv export * Frontend integration Add search_params to response Add limit to tokens endpoint Add fee in api response Add exclusion/inclusion of from/to addresses Remove raw_input from api response * Remove comment * Add methods search; Optimize internal txs query * Fix `method_id_to_name_from_params` * Fix filtering by amount; add filter by native * Fix review comments * Handle all token types * Optimize query * Process review comments * Process review comments --------- Co-authored-by: Viktor Baranov * Fix nil abi issue in get_naive_implementation_abi and get_master_copy_pattern methods (#10239) * fix: batch transactions view recovered and support of proofs through ZkSync Hyperchain (#10234) * unified tx_hash field with Arbitrum batch transaction * Supported yet another contract function to submit batches proofs * fixed formatting issue * feat: API endpoint to re-fetch token instance metadata (#10097) * feat: Re-fetch token instance metadata * Partially process review comments * Process reviewer comments. Part 2 * Process reviewer comments. Part 3 * Process reviewer comments. Part 4 * Fix events * Add test * Remove :token preload * fix formatting * Fix tests * Remove unused aliases * Add reCAPTCHA for token instance re-fetch API endpoint * Check event on websocket at /api/v2/tokens/{address_hash}/instances/{token_id}/refetch-metadata endpoint * 6.7.0 * fix: Fix possible unknown UID bug (#10240) * Update CHANGELOG * fix: pipe through api_v2_no_forgery_protect POST requests in SmartContractsApiV2Router * fix: proper hex-encoded transaction hash recognition in ZkSync batches status checker (#10255) * proper hex-encoded transaction hash recognition * mix format --------- Co-authored-by: Viktor Baranov * fix: advanced filter contract creation transaction (#10257) * feat: Chain & explorer Prometheus metrics (#10063) * feat: Chain & explorer Prometheus metrics * Process review * Add consensus filter, account token transfers and internal transactions in active users metric * Refactor, run metrics async * Raise error on metrics query execution timed out * Move chain & explorer mterics to a separate (public) endpoint * Set 1h timeout for DB request * fix: add preloads to summary and tokens endpoints (#10259) * Update CHANGELOG * fix: add preloads for tx summary endpoint (#10261) * fix: `getsourcecode` in API v1 for verified proxy (#10273) * Update CHANGELOG * Fix ci setup repo error (#10277) * try to trim BUILDER_IP env * Revert "try to trim BUILDER_IP env" This reverts commit 9a95ce948bb723b5a256420c9fe34d71eb0e95bd. * trim BEST_BUILDER env and disable debug message * feat: Public metrics toggler (#10279) * Public metrics toggler * Update apps/explorer/lib/explorer/chain/metrics.ex Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> --------- Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> * Update CHANGELOG * Pre-release workflow for Arbitrum * Update CHANGELOG * fix: set timeout in seconds (#10283) * Update CHANGELOG * Disable weekly_active_addresses_number metric because it affects DB performance: query should be optimized in the future * Speed-up query execution for weekly_new_token_transfers_number_query (#10289) * fix: add token instances preloads (#10288) * Update CHANGELOG * fix: token instance preload (#10297) * fix: update `ex_abi` to fix type decoder for huge lists (#10294) * chore: update `ex_abi` to fix type decoder for huge lists * chore: add a todo note * fix: update `ex_abi` to parse function ABI without `outputs` field --------- Signed-off-by: dependabot[bot] Co-authored-by: Alexander Kolotov Co-authored-by: Kirill Fedoseev Co-authored-by: Victor Baranov Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Qwerty5Uiop <105209995+Qwerty5Uiop@users.noreply.github.com> Co-authored-by: nikitosing <32202610+nikitosing@users.noreply.github.com> Co-authored-by: varasev <33550681+varasev@users.noreply.github.com> Co-authored-by: POA <33550681+poa@users.noreply.github.com> Co-authored-by: Ramazan Fatih Karadeniz <61462812+ramazanfatih-karadeniz@users.noreply.github.com> Co-authored-by: Fedor Ivanov Co-authored-by: Kevin Mathew Co-authored-by: Rim Rakhimov Co-authored-by: sirawt <31649128+MASDXI@users.noreply.github.com> Co-authored-by: Maxim Filonov <53992153+sl1depengwyn@users.noreply.github.com> Co-authored-by: NBMXyeu <121313170+xyeuu@users.noreply.github.com> Co-authored-by: aagaev --- .dialyzer-ignore | 1 + .../setup-repo-and-short-sha/action.yml | 23 - .github/actions/setup-repo/action.yml | 65 +- .github/scripts/select-builder.sh | 44 + .github/workflows/config.yml | 9 +- .github/workflows/pre-release-arbitrum.yml | 97 + .github/workflows/pre-release-eth.yml | 97 + .github/workflows/pre-release-optimism.yml | 97 + .github/workflows/pre-release-shibarium.yml | 97 + .github/workflows/pre-release-zksync.yml | 97 + .../{prerelease.yml => pre-release.yml} | 103 +- .../publish-docker-image-every-push.yml | 82 +- ... => publish-docker-image-for-arbitrum.yml} | 22 +- .../publish-docker-image-for-core.yml | 10 +- .../publish-docker-image-for-eth-sepolia.yml | 56 +- .../publish-docker-image-for-eth.yml | 10 +- .../publish-docker-image-for-filecoin.yml | 10 +- .../publish-docker-image-for-fuse.yml | 12 +- .../publish-docker-image-for-gnosis-chain.yml | 12 +- .../publish-docker-image-for-l2-staging.yml | 10 +- .../publish-docker-image-for-lukso.yml | 10 +- .../publish-docker-image-for-optimism.yml | 9 +- .../publish-docker-image-for-polygon-edge.yml | 10 +- ... => publish-docker-image-for-redstone.yml} | 16 +- .../publish-docker-image-for-rootstock.yml | 10 +- .../publish-docker-image-for-shibarium.yml | 10 +- .../publish-docker-image-for-stability.yml | 10 +- .../publish-docker-image-for-suave.yml | 7 +- .../publish-docker-image-for-zetachain.yml | 10 +- .../publish-docker-image-for-zkevm.yml | 10 +- .../publish-docker-image-for-zksync.yml | 12 +- ...publish-docker-image-staging-on-demand.yml | 19 +- .github/workflows/release-arbitrum.yml | 55 +- .github/workflows/release-eth.yml | 55 +- .github/workflows/release-filecoin.yml | 55 +- .github/workflows/release-fuse.yml | 95 + .github/workflows/release-gnosis.yml | 59 +- .github/workflows/release-optimism.yml | 55 +- ...dditional.yml => release-polygon-edge.yml} | 66 +- .github/workflows/release-polygon-zkevm.yml | 95 + .github/workflows/release-redstone.yml | 97 + .github/workflows/release-rootstock.yml | 94 + .github/workflows/release-shibarium.yml | 55 +- .github/workflows/release-stability.yml | 95 + .github/workflows/release-suave.yml | 95 + .github/workflows/release-zetachain.yml | 55 +- .github/workflows/release-zksync.yml | 55 +- .github/workflows/release.yml | 76 +- CHANGELOG.md | 176 + README.md | 2 +- apps/block_scout_web/.sobelow-conf | 5 +- apps/block_scout_web/assets/package-lock.json | 3129 +++++++++-------- apps/block_scout_web/assets/package.json | 26 +- apps/block_scout_web/config/config.exs | 13 +- apps/block_scout_web/lib/block_scout_web.ex | 9 +- .../lib/block_scout_web/application.ex | 88 +- .../lib/block_scout_web/chain.ex | 12 +- .../channels/address_channel.ex | 27 +- .../block_scout_web/channels/block_channel.ex | 7 +- .../channels/token_instance_channel.ex | 26 + .../block_scout_web/channels/user_socket.ex | 1 + .../channels/user_socket_v2.ex | 1 + .../controllers/admin/setup_controller.ex | 2 +- .../api/rpc/contract_controller.ex | 30 +- .../controllers/api/rpc/rpc_translator.ex | 2 +- .../controllers/api/v1/health_controller.ex | 4 +- .../controllers/api/v2/address_controller.ex | 48 +- .../api/v2/advanced_filter_controller.ex | 372 ++ .../controllers/api/v2/arbitrum_controller.ex | 163 + .../controllers/api/v2/block_controller.ex | 77 +- .../api/v2/csv_export_controller.ex | 4 +- .../controllers/api/v2/fallback_controller.ex | 48 +- .../controllers/api/v2/import_controller.ex | 2 +- .../api/v2/main_page_controller.ex | 11 +- .../controllers/api/v2/mud_controller.ex | 261 ++ .../proxy/account_abstraction_controller.ex | 3 +- .../api/v2/smart_contract_controller.ex | 51 +- .../controllers/api/v2/token_controller.ex | 113 +- .../api/v2/transaction_controller.ex | 111 +- .../controllers/api/v2/utils_controller.ex | 7 +- .../api/v2/validator_controller.ex | 2 +- .../api/v2/withdrawal_controller.ex | 8 +- .../controllers/smart_contract_controller.ex | 4 +- .../tokens/instance/holder_controller.ex | 8 +- .../tokens/instance/metadata_controller.ex | 4 +- .../tokens/instance/transfer_controller.ex | 8 +- .../visualize_sol2uml_controller.ex | 2 +- .../lib/block_scout_web/endpoint.ex | 98 +- .../block_scout_web/graphql/body_reader.ex | 35 + .../block_scout_web/graphql/schema/types.ex | 2 - .../lib/block_scout_web/health_router.ex | 15 + .../transaction_interpretation.ex | 23 +- .../lib/block_scout_web/notifier.ex | 26 +- .../lib/block_scout_web/paging_helper.ex | 27 +- .../plug/admin/check_owner_registered.ex | 2 +- .../plug/admin/require_admin_role.ex | 2 +- .../prometheus/public_exporter.ex | 9 + .../block_scout_web/realtime_event_handler.ex | 1 + .../lib/block_scout_web/router.ex | 41 +- .../block_scout_web/routers/account_router.ex | 173 + .../{ => routers}/admin_router.ex | 11 +- .../{ => routers}/api_key_v2_router.ex | 11 +- .../{ => routers}/api_router.ex | 174 +- .../smart_contracts_api_v2_router.ex | 64 +- .../routers/tokens_api_v2_router.ex | 71 + .../{ => routers}/utils_api_v2_router.ex | 11 +- .../{ => routers}/web_router.ex | 73 +- .../templates/address/_link.html.eex | 10 +- .../address/_responsive_hash.html.eex | 10 +- .../templates/address/overview.html.eex | 4 +- .../templates/address_contract/index.html.eex | 22 +- .../new.html.eex | 2 +- .../new.html.eex | 2 +- .../new.html.eex | 2 +- .../new.html.eex | 2 +- .../templates/admin/dashboard/index.html.eex | 2 +- .../templates/api_docs/eth_rpc.html.eex | 2 +- .../templates/layout/_topnav.html.eex | 4 +- .../_function_response.html.eex | 8 +- .../smart_contract/_functions.html.eex | 4 +- .../tokens/overview/_details.html.eex | 4 +- .../templates/transaction/overview.html.eex | 6 +- .../templates/transaction_log/_logs.html.eex | 11 +- .../block_scout_web/views/access_helper.ex | 2 +- .../views/account/api/v2/user_view.ex | 6 +- .../lib/block_scout_web/views/address_view.ex | 14 +- .../views/admin/session_view.ex | 2 +- .../block_scout_web/views/admin/setup_view.ex | 2 +- .../views/api/rpc/contract_view.ex | 12 +- .../views/api/v2/address_view.ex | 85 +- .../views/api/v2/advanced_filter_view.ex | 181 + .../views/api/v2/arbitrum_view.ex | 431 +++ .../views/api/v2/block_view.ex | 10 + .../block_scout_web/views/api/v2/helper.ex | 138 +- .../block_scout_web/views/api/v2/mud_view.ex | 85 + .../views/api/v2/optimism_view.ex | 9 +- .../views/api/v2/polygon_edge_view.ex | 9 +- .../views/api/v2/search_view.ex | 1 + .../views/api/v2/shibarium_view.ex | 6 +- .../views/api/v2/smart_contract_view.ex | 50 +- .../views/api/v2/transaction_view.ex | 14 + .../views/api/v2/zksync_view.ex | 54 +- .../views/smart_contract_view.ex | 12 +- .../views/transaction_log_view.ex | 3 +- .../block_scout_web/views/transaction_view.ex | 28 +- .../views/verified_contracts_view.ex | 2 +- apps/block_scout_web/mix.exs | 28 +- .../account/api/v2/user_controller_test.exs | 14 +- .../account/custom_abi_controller_test.exs | 37 +- .../address_contract_controller_test.exs | 6 +- ...s_internal_transaction_controller_test.exs | 2 +- .../address_read_contract_controller_test.exs | 57 +- .../address_read_proxy_controller_test.exs | 57 +- .../address_token_controller_test.exs | 2 +- ...address_token_transfer_controller_test.exs | 2 +- .../address_transaction_controller_test.exs | 2 +- .../address_withdrawal_controller_test.exs | 2 +- ...address_write_contract_controller_test.exs | 57 +- .../address_write_proxy_controller_test.exs | 57 +- .../api/rpc/contract_controller_test.exs | 281 +- .../api/rpc/transaction_controller_test.exs | 173 +- .../api/v2/address_controller_test.exs | 159 +- .../v2/advanced_filter_controller_test.exs | 945 +++++ .../api/v2/search_controller_test.exs | 18 + .../api/v2/smart_contract_controller_test.exs | 421 ++- .../api/v2/token_controller_test.exs | 130 +- .../api/v2/utils_controller_test.exs | 58 +- .../api/v2/validator_controller_test.exs | 21 +- .../api/v2/verification_controller_test.exs | 76 + .../block_transaction_controller_test.exs | 2 +- .../block_withdrawal_controller_test.exs | 2 +- .../controllers/chain_controller_test.exs | 3 +- .../pending_transaction_controller_test.exs | 2 +- .../recent_transactions_controller_test.exs | 2 +- .../smart_contract_controller_test.exs | 102 +- .../tokens/read_contract_controller_test.exs | 56 +- .../transaction_controller_test.exs | 2 +- ...n_internal_transaction_controller_test.exs | 2 +- .../transaction_log_controller_test.exs | 2 +- .../transaction_state_controller_test.exs | 2 +- ...saction_token_transfer_controller_test.exs | 59 +- .../verified_contracts_controller_test.exs | 2 +- .../withdrawal_controller_test.exs | 2 +- .../features/pages/transaction_logs_page.ex | 2 +- .../views/api/v2/address_view_test.exs | 76 - .../views/transaction_view_test.exs | 98 +- .../block_scout_web/test/support/conn_case.ex | 7 +- ...r_vyper_multi_part_blueprint_response.json | 21 + apps/block_scout_web/test/test_helper.exs | 2 + .../lib/ethereum_jsonrpc/block.ex | 74 +- .../lib/ethereum_jsonrpc/block/by_hash.ex | 2 +- .../lib/ethereum_jsonrpc/block/by_nephew.ex | 2 +- .../lib/ethereum_jsonrpc/block/by_number.ex | 2 +- .../lib/ethereum_jsonrpc/blocks.ex | 9 +- .../lib/ethereum_jsonrpc/contract.ex | 2 +- .../lib/ethereum_jsonrpc/geth.ex | 53 +- .../lib/ethereum_jsonrpc/http.ex | 48 +- .../lib/ethereum_jsonrpc/log.ex | 2 +- .../lib/ethereum_jsonrpc/logs.ex | 2 +- .../lib/ethereum_jsonrpc/nethermind/trace.ex | 46 +- .../ethereum_jsonrpc/pending_transaction.ex | 12 +- .../lib/ethereum_jsonrpc/receipt.ex | 94 +- .../lib/ethereum_jsonrpc/receipts.ex | 5 +- .../trace_replay_block_transactions.ex | 6 +- .../lib/ethereum_jsonrpc/transaction.ex | 40 +- .../lib/ethereum_jsonrpc/transactions.ex | 4 +- .../lib/ethereum_jsonrpc/uncle.ex | 2 +- .../lib/ethereum_jsonrpc/uncles.ex | 2 +- apps/ethereum_jsonrpc/mix.exs | 6 +- .../test/ethereum_jsonrpc/block_test.exs | 60 +- apps/explorer/config/config.exs | 3 + apps/explorer/config/dev.exs | 5 + apps/explorer/config/prod.exs | 8 + apps/explorer/config/runtime/test.exs | 1 + apps/explorer/config/test.exs | 36 +- .../lib/explorer/account/notifier/email.ex | 2 +- apps/explorer/lib/explorer/application.ex | 12 +- apps/explorer/lib/explorer/chain.ex | 387 +- apps/explorer/lib/explorer/chain/address.ex | 16 +- .../lib/explorer/chain/address/counters.ex | 8 +- .../chain/address/current_token_balance.ex | 14 +- .../explorer/chain/address/token_balance.ex | 25 +- .../lib/explorer/chain/advanced_filter.ex | 728 ++++ .../explorer/chain/arbitrum/batch_block.ex | 53 + .../chain/arbitrum/batch_transaction.ex | 52 + .../lib/explorer/chain/arbitrum/l1_batch.ex | 62 + .../explorer/chain/arbitrum/l1_execution.ex | 46 + .../chain/arbitrum/lifecycle_transaction.ex | 54 + .../lib/explorer/chain/arbitrum/message.ex | 57 + .../lib/explorer/chain/arbitrum/reader.ex | 913 +++++ apps/explorer/lib/explorer/chain/block.ex | 59 +- .../lib/explorer/chain/cache/address_sum.ex | 5 +- .../chain/cache/address_sum_minus_burnt.ex | 5 +- .../lib/explorer/chain/cache/block.ex | 4 +- .../lib/explorer/chain/cache/gas_usage.ex | 5 +- .../lib/explorer/chain/cache/helper.ex | 49 + .../lib/explorer/chain/cache/transaction.ex | 4 +- .../lib/explorer/chain/contract_method.ex | 49 +- ...dress_internal_transaction_csv_exporter.ex | 16 +- .../address_transaction_csv_exporter.ex | 28 +- .../lib/explorer/chain/events/listener.ex | 8 + .../lib/explorer/chain/events/publisher.ex | 2 +- .../lib/explorer/chain/events/subscriber.ex | 2 +- .../runner/address/current_token_balances.ex | 10 +- .../import/runner/address/token_balances.ex | 27 +- .../import/runner/arbitrum/batch_blocks.ex | 104 + .../runner/arbitrum/batch_transactions.ex | 79 + .../import/runner/arbitrum/l1_batches.ex | 112 + .../import/runner/arbitrum/l1_executions.ex | 102 + .../runner/arbitrum/lifecycle_transactions.ex | 107 + .../chain/import/runner/arbitrum/messages.ex | 117 + .../import/runner/internal_transactions.ex | 12 +- .../chain/import/runner/transactions.ex | 88 +- .../runner/zksync/batch_transactions.ex | 4 +- .../chain/import/stage/block_referencing.ex | 16 +- .../explorer/chain/internal_transaction.ex | 39 +- apps/explorer/lib/explorer/chain/log.ex | 26 +- apps/explorer/lib/explorer/chain/metrics.ex | 85 + .../lib/explorer/chain/metrics/queries.ex | 247 ++ apps/explorer/lib/explorer/chain/mud.ex | 395 +++ .../explorer/lib/explorer/chain/mud/schema.ex | 110 + apps/explorer/lib/explorer/chain/mud/table.ex | 88 + apps/explorer/lib/explorer/chain/search.ex | 16 +- .../lib/explorer/chain/smart_contract.ex | 517 ++- .../explorer/chain/smart_contract/proxy.ex | 275 +- .../chain/smart_contract/proxy/basic.ex | 9 +- .../proxy/clone_with_immutable_arguments.ex | 55 + .../chain/smart_contract/proxy/eip_1167.ex | 19 +- .../chain/smart_contract/proxy/eip_1822.ex | 2 +- .../chain/smart_contract/proxy/eip_1967.ex | 115 +- .../chain/smart_contract/proxy/eip_2535.ex | 36 + .../chain/smart_contract/proxy/eip_930.ex | 6 +- .../chain/smart_contract/proxy/master_copy.ex | 2 +- .../proxy/models/implementation.ex | 407 +++ .../proxy/verification_status.ex | 9 +- .../smart_contract/verification_status.ex | 22 +- apps/explorer/lib/explorer/chain/token.ex | 9 +- .../lib/explorer/chain/token/instance.ex | 29 +- .../lib/explorer/chain/token_transfer.ex | 37 +- .../lib/explorer/chain/transaction.ex | 228 +- .../chain/zksync/batch_transaction.ex | 38 +- .../lib/explorer/chain_spec/genesis_data.ex | 248 +- .../lib/explorer/chain_spec/geth/importer.ex | 60 +- .../lib/explorer/etherscan/contracts.ex | 40 +- apps/explorer/lib/explorer/etherscan/logs.ex | 19 +- .../lib/explorer/exchange_rates/source.ex | 7 +- .../exchange_rates/source/coin_gecko.ex | 4 +- .../explorer/exchange_rates/source/mobula.ex | 174 + apps/explorer/lib/explorer/graphql.ex | 5 +- apps/explorer/lib/explorer/helper.ex | 71 +- .../history/source/market_cap/mobula.ex | 54 + .../market/history/source/price/mobula.ex | 48 + .../lib/explorer/market/market_history.ex | 16 + .../microservice_interfaces/metadata.ex | 15 +- ...sanitize_incorrect_weth_token_transfers.ex | 157 + .../lib/explorer/prometheus/instrumenter.ex | 74 + apps/explorer/lib/explorer/repo.ex | 52 +- .../lib/explorer/repo/config_helper.ex | 8 +- .../smart_contract/compiler_version.ex | 2 +- .../lib/explorer/smart_contract/helper.ex | 15 +- .../lib/explorer/smart_contract/reader.ex | 114 +- .../rust_verifier_interface_behaviour.ex | 12 +- .../smart_contract/solidity/publisher.ex | 36 +- .../smart_contract/vyper/publisher.ex | 59 +- .../lib/explorer/token/metadata_retriever.ex | 503 ++- .../address_contract_code_fetch_attempt.ex | 15 +- .../utility/missing_balance_of_token.ex | 125 + .../explorer/utility/missing_block_range.ex | 34 +- ...token_instance_metadata_refetch_attempt.ex | 87 + apps/explorer/lib/test_helper.ex | 153 + apps/explorer/mix.exs | 8 +- apps/explorer/package-lock.json | 14 +- apps/explorer/package.json | 2 +- .../20240201125730_create_arbitrum_tables.exs | 124 + ...58_extend_transaction_and_block_tables.exs | 15 + ...095711_add_proxy_implementations_table.exs | 13 + ...19101821_migrate_proxy_implementations.exs | 13 + ...ation_fields_from_smart_contract_table.exs | 11 + .../20240425091614_add_proxy_type_column.exs | 16 + .../20240425185705_alter_proxy_type.exs | 7 + ...y_type_clones_with_immutable_arguments.exs | 7 + ...64431_create_missing_balance_of_tokens.exs | 12 + ...08_add_nft_instance_fetcher_aux_fields.exs | 10 + ..._smart_contracts_add_is_blueprint_flag.exs | 9 + ...stance_metadata_refetch_attempts_table.exs | 15 + ...plemented_to_missing_balance_of_tokens.exs | 9 + ...814_rename_field_in_batch_transactions.exs | 7 + ...internal_transaction_csv_exporter_test.exs | 12 +- .../runner/address/token_balances_test.exs | 42 + .../explorer/test/explorer/chain/log_test.exs | 112 +- .../proxy/models/implementation_test.exs | 301 ++ .../chain/smart_contract/proxy_test.exs | 211 +- .../explorer/chain/smart_contract_test.exs | 466 --- .../test/explorer/chain/token_test.exs | 8 +- .../test/explorer/chain/transaction_test.exs | 93 +- apps/explorer/test/explorer/chain_test.exs | 103 +- ...ze_incorrect_weth_token_transfers_test.exs | 161 + .../explorer/smart_contract/helper_test.exs | 4 +- .../solidity/publisher_test.exs | 40 + .../smart_contract/vyper/publisher_test.exs | 80 + .../token/metadata_retriever_test.exs | 495 ++- apps/explorer/test/support/factory.ex | 84 +- apps/explorer/test/test_helper.exs | 1 + apps/indexer/lib/indexer/application.ex | 38 +- .../lib/indexer/block/catchup/fetcher.ex | 34 +- apps/indexer/lib/indexer/block/fetcher.ex | 60 +- .../lib/indexer/block/realtime/fetcher.ex | 34 +- apps/indexer/lib/indexer/bound_queue.ex | 18 + apps/indexer/lib/indexer/buffered_task.ex | 78 +- .../lib/indexer/fetcher/arbitrum/messaging.ex | 295 ++ .../arbitrum/rollup_messages_catchup.ex | 365 ++ .../arbitrum/tracking_batches_statuses.ex | 459 +++ .../arbitrum/tracking_messages_on_l1.ex | 223 ++ .../lib/indexer/fetcher/arbitrum/utils/db.ex | 787 +++++ .../indexer/fetcher/arbitrum/utils/helper.ex | 86 + .../indexer/fetcher/arbitrum/utils/logging.ex | 162 + .../lib/indexer/fetcher/arbitrum/utils/rpc.ex | 391 ++ .../workers/historical_messages_on_l2.ex | 284 ++ .../arbitrum/workers/l1_finalization.ex | 74 + .../fetcher/arbitrum/workers/new_batches.ex | 975 +++++ .../arbitrum/workers/new_confirmations.ex | 1099 ++++++ .../arbitrum/workers/new_l1_executions.ex | 413 +++ .../arbitrum/workers/new_messages_to_l2.ex | 346 ++ .../lib/indexer/fetcher/beacon/blob.ex | 7 +- .../lib/indexer/fetcher/block_reward.ex | 6 +- .../indexer/fetcher/coin_balance/catchup.ex | 2 +- .../indexer/fetcher/coin_balance/realtime.ex | 2 +- .../lib/indexer/fetcher/contract_code.ex | 7 +- .../indexer/fetcher/internal_transaction.ex | 16 +- .../fetcher/on_demand/contract_code.ex | 2 +- .../fetcher/on_demand/token_balance.ex | 10 +- .../token_instance_metadata_refetch.ex | 123 + apps/indexer/lib/indexer/fetcher/optimism.ex | 1 + .../fetcher/optimism/withdrawal_event.ex | 31 +- .../pending_block_operations_sanitizer.ex | 2 +- .../lib/indexer/fetcher/polygon_edge.ex | 1 + .../indexer/fetcher/polygon_zkevm/bridge.ex | 52 +- .../fetcher/polygon_zkevm/bridge_l1_tokens.ex | 2 +- .../polygon_zkevm/transaction_batch.ex | 3 +- .../indexer/fetcher/replaced_transaction.ex | 21 +- apps/indexer/lib/indexer/fetcher/token.ex | 12 +- .../lib/indexer/fetcher/token_balance.ex | 89 +- .../indexer/fetcher/token_instance/helper.ex | 55 +- .../token_instance/metadata_retriever.ex | 366 -- .../fetcher/token_instance/realtime.ex | 60 +- .../indexer/fetcher/token_instance/retry.ex | 28 +- .../lib/indexer/fetcher/token_updater.ex | 3 +- .../lib/indexer/fetcher/uncle_block.ex | 9 +- .../fetcher/zksync/discovery/batches_data.ex | 2 +- .../fetcher/zksync/status_tracking/proven.ex | 123 +- .../lib/indexer/fetcher/zksync/utils/db.ex | 2 + .../lib/indexer/fetcher/zksync/utils/rpc.ex | 80 +- apps/indexer/lib/indexer/helper.ex | 259 +- apps/indexer/lib/indexer/memory/monitor.ex | 32 + .../indexer/pending_transactions_sanitizer.ex | 57 +- .../lib/indexer/prometheus/instrumenter.ex | 6 + apps/indexer/lib/indexer/supervisor.ex | 12 + apps/indexer/lib/indexer/token_balances.ex | 4 +- .../indexer/transform/arbitrum/messaging.ex | 44 + .../lib/indexer/transform/token_transfers.ex | 33 +- .../indexer/transform/transaction_actions.ex | 74 +- apps/indexer/mix.exs | 4 +- .../indexer/block/catchup/fetcher_test.exs | 6 +- .../test/indexer/buffered_task_test.exs | 16 +- .../test/indexer/fetcher/beacon/blob_test.exs | 2 +- .../indexer/fetcher/block_reward_test.exs | 18 +- .../indexer/fetcher/contract_code_test.exs | 9 +- .../token_instance_metadata_refetch_test.exs | 181 + .../fetcher/replaced_transaction_test.exs | 17 +- .../indexer/fetcher/token_balance_test.exs | 96 +- .../fetcher/token_instance/helper_test.exs | 242 +- .../metadata_retriever_test.exs | 485 --- .../fetcher/token_instance/realtime_test.exs | 123 + .../transform/token_transfers_test.exs | 153 + config/assets/precompiles-arbitrum.json | 130 + config/config_helper.exs | 29 +- config/runtime.exs | 107 +- config/runtime/dev.exs | 20 + config/runtime/prod.exs | 16 + cspell.json | 240 +- docker-compose/README.md | 4 +- docker-compose/docker-compose.yml | 10 +- docker-compose/envs/common-blockscout.env | 20 +- .../envs/common-user-ops-indexer.env | 48 + docker-compose/erigon.yml | 8 + docker-compose/external-backend.yml | 7 + docker-compose/external-db.yml | 7 + docker-compose/external-frontend.yml | 8 + docker-compose/ganache.yml | 8 + docker-compose/geth-clique-consensus.yml | 8 + docker-compose/geth.yml | 8 + docker-compose/hardhat-network.yml | 8 + docker-compose/microservices.yml | 5 + docker-compose/services/stats.yml | 6 +- docker-compose/services/user-ops-indexer.yml | 17 + docker/Dockerfile | 3 + docker/Makefile | 2 +- mix.exs | 2 +- mix.lock | 46 +- rel/config.exs | 2 +- 440 files changed, 27111 insertions(+), 6653 deletions(-) delete mode 100644 .github/actions/setup-repo-and-short-sha/action.yml create mode 100755 .github/scripts/select-builder.sh create mode 100644 .github/workflows/pre-release-arbitrum.yml create mode 100644 .github/workflows/pre-release-eth.yml create mode 100644 .github/workflows/pre-release-optimism.yml create mode 100644 .github/workflows/pre-release-shibarium.yml create mode 100644 .github/workflows/pre-release-zksync.yml rename .github/workflows/{prerelease.yml => pre-release.yml} (53%) rename .github/workflows/{publish-docker-image-for-eth-goerli.yml => publish-docker-image-for-arbitrum.yml} (63%) rename .github/workflows/{publish-docker-image-for-immutable.yml => publish-docker-image-for-redstone.yml} (74%) create mode 100644 .github/workflows/release-fuse.yml rename .github/workflows/{release-additional.yml => release-polygon-edge.yml} (60%) create mode 100644 .github/workflows/release-polygon-zkevm.yml create mode 100644 .github/workflows/release-redstone.yml create mode 100644 .github/workflows/release-rootstock.yml create mode 100644 .github/workflows/release-stability.yml create mode 100644 .github/workflows/release-suave.yml create mode 100644 apps/block_scout_web/lib/block_scout_web/channels/token_instance_channel.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/controllers/api/v2/advanced_filter_controller.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/controllers/api/v2/arbitrum_controller.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/controllers/api/v2/mud_controller.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/graphql/body_reader.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/health_router.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/prometheus/public_exporter.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/routers/account_router.ex rename apps/block_scout_web/lib/block_scout_web/{ => routers}/admin_router.ex (83%) rename apps/block_scout_web/lib/block_scout_web/{ => routers}/api_key_v2_router.ex (65%) rename apps/block_scout_web/lib/block_scout_web/{ => routers}/api_router.ex (78%) rename apps/block_scout_web/lib/block_scout_web/{ => routers}/smart_contracts_api_v2_router.ex (51%) create mode 100644 apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex rename apps/block_scout_web/lib/block_scout_web/{ => routers}/utils_api_v2_router.ex (75%) rename apps/block_scout_web/lib/block_scout_web/{ => routers}/web_router.ex (85%) create mode 100644 apps/block_scout_web/lib/block_scout_web/views/api/v2/advanced_filter_view.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/views/api/v2/arbitrum_view.ex create mode 100644 apps/block_scout_web/lib/block_scout_web/views/api/v2/mud_view.ex create mode 100644 apps/block_scout_web/test/block_scout_web/controllers/api/v2/advanced_filter_controller_test.exs delete mode 100644 apps/block_scout_web/test/block_scout_web/views/api/v2/address_view_test.exs create mode 100644 apps/block_scout_web/test/support/fixture/smart_contract/smart_contract_verifier_vyper_multi_part_blueprint_response.json create mode 100644 apps/explorer/lib/explorer/chain/advanced_filter.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/batch_block.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/batch_transaction.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/l1_batch.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/l1_execution.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/lifecycle_transaction.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/message.ex create mode 100644 apps/explorer/lib/explorer/chain/arbitrum/reader.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/batch_blocks.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/batch_transactions.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/l1_batches.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/l1_executions.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/lifecycle_transactions.ex create mode 100644 apps/explorer/lib/explorer/chain/import/runner/arbitrum/messages.ex create mode 100644 apps/explorer/lib/explorer/chain/metrics.ex create mode 100644 apps/explorer/lib/explorer/chain/metrics/queries.ex create mode 100644 apps/explorer/lib/explorer/chain/mud.ex create mode 100644 apps/explorer/lib/explorer/chain/mud/schema.ex create mode 100644 apps/explorer/lib/explorer/chain/mud/table.ex create mode 100644 apps/explorer/lib/explorer/chain/smart_contract/proxy/clone_with_immutable_arguments.ex create mode 100644 apps/explorer/lib/explorer/chain/smart_contract/proxy/eip_2535.ex create mode 100644 apps/explorer/lib/explorer/chain/smart_contract/proxy/models/implementation.ex create mode 100644 apps/explorer/lib/explorer/exchange_rates/source/mobula.ex create mode 100644 apps/explorer/lib/explorer/market/history/source/market_cap/mobula.ex create mode 100644 apps/explorer/lib/explorer/market/history/source/price/mobula.ex create mode 100644 apps/explorer/lib/explorer/migrator/sanitize_incorrect_weth_token_transfers.ex create mode 100644 apps/explorer/lib/explorer/utility/missing_balance_of_token.ex create mode 100644 apps/explorer/lib/explorer/utility/token_instance_metadata_refetch_attempt.ex create mode 100644 apps/explorer/lib/test_helper.ex create mode 100644 apps/explorer/priv/arbitrum/migrations/20240201125730_create_arbitrum_tables.exs create mode 100644 apps/explorer/priv/arbitrum/migrations/20240510184858_extend_transaction_and_block_tables.exs create mode 100644 apps/explorer/priv/repo/migrations/20240419095711_add_proxy_implementations_table.exs create mode 100644 apps/explorer/priv/repo/migrations/20240419101821_migrate_proxy_implementations.exs create mode 100644 apps/explorer/priv/repo/migrations/20240419102345_drop_implementation_fields_from_smart_contract_table.exs create mode 100644 apps/explorer/priv/repo/migrations/20240425091614_add_proxy_type_column.exs create mode 100644 apps/explorer/priv/repo/migrations/20240425185705_alter_proxy_type.exs create mode 100644 apps/explorer/priv/repo/migrations/20240501131140_new_proxy_type_clones_with_immutable_arguments.exs create mode 100644 apps/explorer/priv/repo/migrations/20240502064431_create_missing_balance_of_tokens.exs create mode 100644 apps/explorer/priv/repo/migrations/20240503091708_add_nft_instance_fetcher_aux_fields.exs create mode 100644 apps/explorer/priv/repo/migrations/20240509014500_smart_contracts_add_is_blueprint_flag.exs create mode 100644 apps/explorer/priv/repo/migrations/20240520075414_create_token_instance_metadata_refetch_attempts_table.exs create mode 100644 apps/explorer/priv/repo/migrations/20240527152734_add_currently_implemented_to_missing_balance_of_tokens.exs create mode 100644 apps/explorer/priv/zk_sync/migrations/20240611091814_rename_field_in_batch_transactions.exs create mode 100644 apps/explorer/test/explorer/chain/smart_contract/proxy/models/implementation_test.exs create mode 100644 apps/explorer/test/explorer/migrator/sanitize_incorrect_weth_token_transfers_test.exs create mode 100644 apps/explorer/test/explorer/smart_contract/vyper/publisher_test.exs create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/messaging.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/rollup_messages_catchup.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/tracking_batches_statuses.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/tracking_messages_on_l1.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/utils/db.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/utils/helper.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/utils/logging.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/utils/rpc.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/historical_messages_on_l2.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/l1_finalization.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/new_batches.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/new_confirmations.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/new_l1_executions.ex create mode 100644 apps/indexer/lib/indexer/fetcher/arbitrum/workers/new_messages_to_l2.ex create mode 100644 apps/indexer/lib/indexer/fetcher/on_demand/token_instance_metadata_refetch.ex delete mode 100644 apps/indexer/lib/indexer/fetcher/token_instance/metadata_retriever.ex create mode 100644 apps/indexer/lib/indexer/transform/arbitrum/messaging.ex create mode 100644 apps/indexer/test/indexer/fetcher/on_demand/token_instance_metadata_refetch_test.exs delete mode 100644 apps/indexer/test/indexer/fetcher/token_instance/metadata_retriever_test.exs create mode 100644 apps/indexer/test/indexer/fetcher/token_instance/realtime_test.exs create mode 100644 config/assets/precompiles-arbitrum.json create mode 100644 docker-compose/envs/common-user-ops-indexer.env create mode 100644 docker-compose/services/user-ops-indexer.yml diff --git a/.dialyzer-ignore b/.dialyzer-ignore index 6ea02019b20d..258b2525b406 100644 --- a/.dialyzer-ignore +++ b/.dialyzer-ignore @@ -7,6 +7,7 @@ lib/phoenix/router.ex:402 lib/explorer/smart_contract/reader.ex:435 lib/explorer/exchange_rates/source.ex:139 lib/explorer/exchange_rates/source.ex:142 +lib/block_scout_web/cldr.ex:1 lib/block_scout_web/views/api/v2/transaction_view.ex:431 lib/block_scout_web/views/api/v2/transaction_view.ex:472 lib/explorer/chain/transaction.ex:171 diff --git a/.github/actions/setup-repo-and-short-sha/action.yml b/.github/actions/setup-repo-and-short-sha/action.yml deleted file mode 100644 index d3cce9891a3a..000000000000 --- a/.github/actions/setup-repo-and-short-sha/action.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: 'Setup repo and calc short SHA commit' -description: 'Setup repo: checkout/login/extract metadata, Set up Docker Buildx and calculate short SHA commit' -inputs: - docker-username: - description: 'Docker username' - required: true - docker-password: - description: 'Docker password' - required: true -runs: - using: "composite" - - steps: - - uses: actions/checkout@v4 - - name: Setup repo - uses: ./.github/actions/setup-repo - with: - docker-username: ${{ inputs.docker-username }} - docker-password: ${{ inputs.docker-password }} - - - name: Add SHORT_SHA env property with commit short sha - shell: bash - run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/actions/setup-repo/action.yml b/.github/actions/setup-repo/action.yml index 2c3533159e15..0465ac9ce2c2 100644 --- a/.github/actions/setup-repo/action.yml +++ b/.github/actions/setup-repo/action.yml @@ -7,14 +7,69 @@ inputs: docker-password: description: 'Docker password' required: true + docker-remote-multi-platform: + description: 'Docker remote multi-platform builder' + required: true + default: 'false' + docker-arm-host: + description: 'Docker remote arm builder' + required: false + docker-arm-host-key: + description: 'Docker remote arm builder ssh private key' + required: false + docker-image: + description: 'Docker image' + required: true + default: blockscout/blockscout +outputs: + docker-builder: + description: 'Docker builder' + value: ${{ steps.builder_local.outputs.name || steps.builder_multi.outputs.name }} + docker-tags: + description: 'Docker metadata tags' + value: ${{ steps.meta.outputs.tags }} + docker-labels: + description: 'Docker metadata labels' + value: ${{ steps.meta.outputs.labels }} + docker-platforms: + description: 'Docker build platforms' + value: ${{ steps.builder_local.outputs.platforms || steps.builder_multi.outputs.platforms }} runs: using: "composite" steps: - - name: Check out the repo - uses: actions/checkout@v4 + - name: Set up SSH key + shell: bash + run: | + mkdir -p ~/.ssh + echo "${{ inputs.docker-arm-host-key }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + - name: Find builder + if: ${{ inputs.docker-remote-multi-platform }} + shell: bash + run: echo "BUILDER_IP=$(./.github/scripts/select-builder.sh ${{ inputs.docker-arm-host }} ubuntu ~/.ssh/id_rsa)" >> $GITHUB_ENV + - name: Set up SSH + if: ${{ inputs.docker-remote-multi-platform }} + uses: MrSquaare/ssh-setup-action@523473d91581ccbf89565e12b40faba93f2708bd # v1.1.0 + with: + host: ${{ env.BUILDER_IP }} + private-key: ${{ inputs.docker-arm-host-key }} - name: Set up Docker Buildx + if: ${{ !inputs.docker-remote-multi-platform }} + uses: docker/setup-buildx-action@v3 + id: builder_local + with: + platforms: linux/amd64 + + - name: Set up Multi-platform Docker Buildx + if: ${{ inputs.docker-remote-multi-platform }} uses: docker/setup-buildx-action@v3 + id: builder_multi + with: + platforms: linux/amd64 + append: | + - endpoint: ssh://ubuntu@${{ env.BUILDER_IP }} + platforms: linux/arm64/v8 - name: Log in to Docker Hub uses: docker/login-action@v3 @@ -26,4 +81,8 @@ runs: id: meta uses: docker/metadata-action@v5 with: - images: blockscout/blockscout \ No newline at end of file + images: ${{ inputs.docker-image }} + + - name: Add SHORT_SHA env property with commit short sha + shell: bash + run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/scripts/select-builder.sh b/.github/scripts/select-builder.sh new file mode 100755 index 000000000000..e785109cf559 --- /dev/null +++ b/.github/scripts/select-builder.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Check if a domain is provided as an argument +if [ -z "$1" ]; then + echo "Usage: $0 " + exit 1 +fi + +DOMAIN=$1 +SSH_USER=$2 +SSH_KEY=$3 + +# Resolve A records +IP_LIST=$(dig +short A $DOMAIN) +if [ -z "$IP_LIST" ]; then + echo "No IPs found for domain $DOMAIN" + exit 1 +fi + +MIN_LA=1000000 +BEST_BUILDER="" + +for IP in $IP_LIST; do + # Check if the host is reachable via SSH + ssh -o StrictHostKeychecking=no -o ConnectTimeout=5 -o BatchMode=yes -i $SSH_KEY $SSH_USER@$IP "exit" 2>/dev/null + if [ $? -eq 0 ]; then + # Get the load average + LA=$(ssh -o StrictHostKeychecking=no -i $SSH_KEY $SSH_USER@$IP "uptime | awk -F'load average:' '{ print \$2 }' | cut -d, -f1" 2>/dev/null) + if [ $? -eq 0 ]; then + # Compare and find the minimum load average + LA=$(echo $LA | xargs) # Trim whitespace + if (( $(echo "$LA < $MIN_LA" | bc -l) )); then + MIN_LA=$LA + BEST_BUILDER=$IP + fi + fi + fi +done + +if [ -n "$BEST_BUILDER" ]; then + echo "$BEST_BUILDER" | tr -d '[:space:]' +else + echo "No reachable hosts found." +fi diff --git a/.github/workflows/config.yml b/.github/workflows/config.yml index a7f759e30465..bcf5b142e0de 100644 --- a/.github/workflows/config.yml +++ b/.github/workflows/config.yml @@ -4,10 +4,10 @@ on: push: branches: - master + - production-arbitrum - production-core - - production-eth-experimental - - production-eth-goerli - production-eth-sepolia + - production-filecoin - production-fuse - production-optimism - production-immutable @@ -29,8 +29,6 @@ on: types: [opened, synchronize, reopened, labeled] branches: - master - - production-optimism - - production-zksync env: MIX_ENV: test @@ -583,6 +581,7 @@ jobs: ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} + WETH_TOKEN_TRANSFERS_FILTERING_ENABLED: "true" test_nethermind_mox_indexer: strategy: fail-fast: false @@ -649,6 +648,7 @@ jobs: ETHEREUM_JSONRPC_CASE: "EthereumJSONRPC.Case.Nethermind.Mox" ETHEREUM_JSONRPC_WEB_SOCKET_CASE: "EthereumJSONRPC.WebSocket.Case.Mox" CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} + WETH_TOKEN_TRANSFERS_FILTERING_ENABLED: "true" test_nethermind_mox_block_scout_web: strategy: fail-fast: false @@ -749,3 +749,4 @@ jobs: ACCOUNT_REDIS_URL: "redis://localhost:6379" SOURCIFY_INTEGRATION_ENABLED: "true" CHAIN_TYPE: ${{ matrix.chain-type != 'default' && matrix.chain-type || '' }} + WETH_TOKEN_TRANSFERS_FILTERING_ENABLED: "true" diff --git a/.github/workflows/pre-release-arbitrum.yml b/.github/workflows/pre-release-arbitrum.yml new file mode 100644 index 000000000000..3bc6cd2c669b --- /dev/null +++ b/.github/workflows/pre-release-arbitrum.yml @@ -0,0 +1,97 @@ +name: Pre-release for Arbitrum + +on: + workflow_dispatch: + inputs: + number: + type: number + required: true + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Arbitrum (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum + + - name: Build and push Docker image for Arbitrum (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum + + - name: Build and push Docker image for Arbitrum (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum \ No newline at end of file diff --git a/.github/workflows/pre-release-eth.yml b/.github/workflows/pre-release-eth.yml new file mode 100644 index 000000000000..07c436f5727c --- /dev/null +++ b/.github/workflows/pre-release-eth.yml @@ -0,0 +1,97 @@ +name: Pre-release for Ethereum + +on: + workflow_dispatch: + inputs: + number: + type: number + required: true + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Ethereum (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Ethereum (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Ethereum (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/pre-release-optimism.yml b/.github/workflows/pre-release-optimism.yml new file mode 100644 index 000000000000..44683dc335c9 --- /dev/null +++ b/.github/workflows/pre-release-optimism.yml @@ -0,0 +1,97 @@ +name: Pre-release for Optimism + +on: + workflow_dispatch: + inputs: + number: + type: number + required: true + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Optimism (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + + - name: Build and push Docker image for Optimism (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + + - name: Build and push Docker image for Optimism (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism \ No newline at end of file diff --git a/.github/workflows/pre-release-shibarium.yml b/.github/workflows/pre-release-shibarium.yml new file mode 100644 index 000000000000..8258205844b7 --- /dev/null +++ b/.github/workflows/pre-release-shibarium.yml @@ -0,0 +1,97 @@ +name: Pre-release for Shibarium + +on: + workflow_dispatch: + inputs: + number: + type: number + required: true + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Shibarium (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium + + - name: Build and push Docker image for Shibarium (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium + + - name: Build and push Docker image for Shibarium (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium \ No newline at end of file diff --git a/.github/workflows/pre-release-zksync.yml b/.github/workflows/pre-release-zksync.yml new file mode 100644 index 000000000000..dc5b3b582100 --- /dev/null +++ b/.github/workflows/pre-release-zksync.yml @@ -0,0 +1,97 @@ +name: Pre-release for ZkSync + +on: + workflow_dispatch: + inputs: + number: + type: number + required: true + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for ZkSync (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync + + - name: Build and push Docker image for ZkSync (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync + + - name: Build and push Docker image for ZkSync (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync \ No newline at end of file diff --git a/.github/workflows/prerelease.yml b/.github/workflows/pre-release.yml similarity index 53% rename from .github/workflows/prerelease.yml rename to .github/workflows/pre-release.yml index 42233668dffc..2a83968a043e 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/pre-release.yml @@ -1,4 +1,4 @@ -name: Pre-release master +name: Pre-release on: workflow_dispatch: @@ -21,97 +21,72 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Ethereum + - name: Build & Push Core Docker image (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + cache-from: type=registry,ref=blockscout/blockscout:buildcache + cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max + tags: blockscout/blockscout:master, blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 + linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false - CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=ethereum - - - name: Build & Push Docker image for Shibarium - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/Dockerfile - push: true - cache-from: type=registry,ref=blockscout/blockscout-shibarium:buildcache - cache-to: type=registry,ref=blockscout/blockscout-shibarium:buildcache,mode=max - tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} - platforms: | - linux/amd64 - build-args: | - CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false API_V1_WRITE_METHODS_DISABLED=false - CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=shibarium - - - name: Build and push Docker image for ZkSync - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} - platforms: | - linux/amd64 - build-args: | CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=zksync - - name: Build and push Docker image for Optimism + - name: Build & Push Core Docker image (indexer) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + cache-from: type=registry,ref=blockscout/blockscout:buildcache + cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 + linux/arm64/v8 build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=optimism - - name: Build & Push Docker image + - name: Build & Push Core Docker image (API) uses: docker/build-push-action@v5 with: context: . @@ -119,22 +94,24 @@ jobs: push: true cache-from: type=registry,ref=blockscout/blockscout:buildcache cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max - tags: blockscout/blockscout:master, blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }}-api + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= + DISABLE_INDEXER=true + DISABLE_WEBAPP=true API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false DECODE_NOT_A_CONTRACT_CALLS=false MIXPANEL_URL= MIXPANEL_TOKEN= AMPLITUDE_URL= AMPLITUDE_API_KEY= - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-alpha.${{ inputs.number }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} diff --git a/.github/workflows/publish-docker-image-every-push.yml b/.github/workflows/publish-docker-image-every-push.yml index 6ec06ee0e85d..dea446dd47ee 100644 --- a/.github/workflows/publish-docker-image-every-push.yml +++ b/.github/workflows/publish-docker-image-every-push.yml @@ -17,25 +17,19 @@ jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest - outputs: - release-version: ${{ steps.output-step.outputs.release-version }} - short-sha: ${{ steps.output-step.outputs.short-sha }} steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - - name: Add outputs - run: | - echo "::set-output name=release-version::${{ env.NEXT_RELEASE_VERSION }}" - echo "::set-output name=short-sha::${{ env.SHORT_SHA }}" - id: output-step - - - name: Build and push Docker image + - name: Build and push Docker image (indexer + API) uses: docker/build-push-action@v5 with: context: . @@ -44,19 +38,75 @@ jobs: cache-from: type=registry,ref=blockscout/blockscout:buildcache cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max tags: blockscout/blockscout:master, blockscout/blockscout:${{ env.RELEASE_VERSION }}.commit.${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + + - name: Build and push Docker image (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}.commit.${{ env.SHORT_SHA }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false DECODE_NOT_A_CONTRACT_CALLS=false MIXPANEL_URL= MIXPANEL_TOKEN= AMPLITUDE_URL= AMPLITUDE_API_KEY= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + + - name: Build and push Docker image (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}.commit.${{ env.SHORT_SHA }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} @@ -68,6 +118,10 @@ jobs: push: true cache-from: type=registry,ref=blockscout/blockscout:buildcache tags: blockscout/blockscout:frontend-main + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-eth-goerli.yml b/.github/workflows/publish-docker-image-for-arbitrum.yml similarity index 63% rename from .github/workflows/publish-docker-image-for-eth-goerli.yml rename to .github/workflows/publish-docker-image-for-arbitrum.yml index 262802e27ec2..c870634a1751 100644 --- a/.github/workflows/publish-docker-image-for-eth-goerli.yml +++ b/.github/workflows/publish-docker-image-for-arbitrum.yml @@ -1,24 +1,28 @@ -name: ETH Goerli Publish Docker image +name: Arbitrum Publish Docker image on: workflow_dispatch: push: branches: - - production-eth-goerli + - production-arbitrum jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest env: RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} - DOCKER_CHAIN_NAME: eth-goerli + DOCKER_CHAIN_NAME: arbitrum steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -26,9 +30,12 @@ jobs: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | - CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false @@ -37,4 +44,5 @@ jobs: ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} - RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-core.yml b/.github/workflows/publish-docker-image-for-core.yml index 9f726bfbbd56..07db87141aa3 100644 --- a/.github/workflows/publish-docker-image-for-core.yml +++ b/.github/workflows/publish-docker-image-for-core.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-eth-sepolia.yml b/.github/workflows/publish-docker-image-for-eth-sepolia.yml index d63d935df4a6..b389c94ada74 100644 --- a/.github/workflows/publish-docker-image-for-eth-sepolia.yml +++ b/.github/workflows/publish-docker-image-for-eth-sepolia.yml @@ -15,18 +15,26 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image + - name: Build and push Docker image (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= @@ -37,4 +45,48 @@ jobs: ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + + - name: Build and push Docker image (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CHAIN_TYPE=ethereum + CACHE_EXCHANGE_RATES_PERIOD= + DISABLE_WEBAPP=true + DISABLE_API=true + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + + - name: Build and push Docker image (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CHAIN_TYPE=ethereum + CACHE_EXCHANGE_RATES_PERIOD= + DISABLE_WEBAPP=true + DISABLE_INDEXER=true + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-eth.yml b/.github/workflows/publish-docker-image-for-eth.yml index 3e3bed50190d..b6819c515b5f 100644 --- a/.github/workflows/publish-docker-image-for-eth.yml +++ b/.github/workflows/publish-docker-image-for-eth.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }}-experimental + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CHAIN_TYPE=ethereum CACHE_EXCHANGE_RATES_PERIOD= diff --git a/.github/workflows/publish-docker-image-for-filecoin.yml b/.github/workflows/publish-docker-image-for-filecoin.yml index ca720971fbbc..efc5fcfbd324 100644 --- a/.github/workflows/publish-docker-image-for-filecoin.yml +++ b/.github/workflows/publish-docker-image-for-filecoin.yml @@ -14,10 +14,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -26,6 +30,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-fuse.yml b/.github/workflows/publish-docker-image-for-fuse.yml index bb88fc294b50..9f19e1ef7b58 100644 --- a/.github/workflows/publish-docker-image-for-fuse.yml +++ b/.github/workflows/publish-docker-image-for-fuse.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -26,7 +30,11 @@ jobs: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | BRIDGED_TOKENS_ENABLED=true CACHE_EXCHANGE_RATES_PERIOD= diff --git a/.github/workflows/publish-docker-image-for-gnosis-chain.yml b/.github/workflows/publish-docker-image-for-gnosis-chain.yml index 86f59dfd0643..88fff9f709b6 100644 --- a/.github/workflows/publish-docker-image-for-gnosis-chain.yml +++ b/.github/workflows/publish-docker-image-for-gnosis-chain.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -26,7 +30,11 @@ jobs: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | BRIDGED_TOKENS_ENABLED=true CACHE_EXCHANGE_RATES_PERIOD= diff --git a/.github/workflows/publish-docker-image-for-l2-staging.yml b/.github/workflows/publish-docker-image-for-l2-staging.yml index 4ced3d5a35d1..c3bdc7522ad6 100644 --- a/.github/workflows/publish-docker-image-for-l2-staging.yml +++ b/.github/workflows/publish-docker-image-for-l2-staging.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-lukso.yml b/.github/workflows/publish-docker-image-for-lukso.yml index 35e01599c831..01f5238a733b 100644 --- a/.github/workflows/publish-docker-image-for-lukso.yml +++ b/.github/workflows/publish-docker-image-for-lukso.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-optimism.yml b/.github/workflows/publish-docker-image-for-optimism.yml index 13361808767f..1f3e81452252 100644 --- a/.github/workflows/publish-docker-image-for-optimism.yml +++ b/.github/workflows/publish-docker-image-for-optimism.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -26,7 +30,8 @@ jobs: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 diff --git a/.github/workflows/publish-docker-image-for-polygon-edge.yml b/.github/workflows/publish-docker-image-for-polygon-edge.yml index e5bcbf6b2a34..4bd600b778fa 100644 --- a/.github/workflows/publish-docker-image-for-polygon-edge.yml +++ b/.github/workflows/publish-docker-image-for-polygon-edge.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-immutable.yml b/.github/workflows/publish-docker-image-for-redstone.yml similarity index 74% rename from .github/workflows/publish-docker-image-for-immutable.yml rename to .github/workflows/publish-docker-image-for-redstone.yml index 21ea26f23395..c64c06b0e3eb 100644 --- a/.github/workflows/publish-docker-image-for-immutable.yml +++ b/.github/workflows/publish-docker-image-for-redstone.yml @@ -1,24 +1,28 @@ -name: Immutable Publish Docker image +name: Redstone Publish Docker image on: workflow_dispatch: push: branches: - - production-immutable + - production-redstone jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest env: RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} - DOCKER_CHAIN_NAME: immutable + DOCKER_CHAIN_NAME: redstone steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,7 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 @@ -40,4 +45,5 @@ jobs: CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta.+commit.${{ env.SHORT_SHA }} RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=polygon_edge \ No newline at end of file + CHAIN_TYPE=optimism + MUD_INDEXER_ENABLED=true \ No newline at end of file diff --git a/.github/workflows/publish-docker-image-for-rootstock.yml b/.github/workflows/publish-docker-image-for-rootstock.yml index 4a4c90e6f178..910c9ba2d1b7 100644 --- a/.github/workflows/publish-docker-image-for-rootstock.yml +++ b/.github/workflows/publish-docker-image-for-rootstock.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-shibarium.yml b/.github/workflows/publish-docker-image-for-shibarium.yml index 8496b598eec3..3b5aaa4b9f13 100644 --- a/.github/workflows/publish-docker-image-for-shibarium.yml +++ b/.github/workflows/publish-docker-image-for-shibarium.yml @@ -18,10 +18,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -30,6 +34,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-stability.yml b/.github/workflows/publish-docker-image-for-stability.yml index b5f486595e0e..d4bfd64a27b2 100644 --- a/.github/workflows/publish-docker-image-for-stability.yml +++ b/.github/workflows/publish-docker-image-for-stability.yml @@ -18,10 +18,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -30,6 +34,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-suave.yml b/.github/workflows/publish-docker-image-for-suave.yml index d7d28a9e0fa2..fccbaee55ccb 100644 --- a/.github/workflows/publish-docker-image-for-suave.yml +++ b/.github/workflows/publish-docker-image-for-suave.yml @@ -18,10 +18,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -30,6 +34,7 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 diff --git a/.github/workflows/publish-docker-image-for-zetachain.yml b/.github/workflows/publish-docker-image-for-zetachain.yml index 0abd04fe2cca..d04c69973293 100644 --- a/.github/workflows/publish-docker-image-for-zetachain.yml +++ b/.github/workflows/publish-docker-image-for-zetachain.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-zkevm.yml b/.github/workflows/publish-docker-image-for-zkevm.yml index 74ab92177a9f..30270a10c6a9 100644 --- a/.github/workflows/publish-docker-image-for-zkevm.yml +++ b/.github/workflows/publish-docker-image-for-zkevm.yml @@ -15,10 +15,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -27,6 +31,10 @@ jobs: file: ./docker/Dockerfile push: true tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-for-zksync.yml b/.github/workflows/publish-docker-image-for-zksync.yml index 7cb48f0ab8bb..bcf784f35cb0 100644 --- a/.github/workflows/publish-docker-image-for-zksync.yml +++ b/.github/workflows/publish-docker-image-for-zksync.yml @@ -14,10 +14,14 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -25,7 +29,11 @@ jobs: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:latest, blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + tags: blockscout/blockscout-${{ env.DOCKER_CHAIN_NAME }}:${{ env.RELEASE_VERSION }}-postrelease-${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/publish-docker-image-staging-on-demand.yml b/.github/workflows/publish-docker-image-staging-on-demand.yml index bf3f48c890bc..f06df3348ba7 100644 --- a/.github/workflows/publish-docker-image-staging-on-demand.yml +++ b/.github/workflows/publish-docker-image-staging-on-demand.yml @@ -18,22 +18,17 @@ jobs: push_to_registry: name: Push Docker image to Docker Hub runs-on: ubuntu-latest - outputs: - release-version: ${{ steps.output-step.outputs.release-version }} - short-sha: ${{ steps.output-step.outputs.short-sha }} steps: - uses: actions/checkout@v4 - name: Setup repo - uses: ./.github/actions/setup-repo-and-short-sha + uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Add outputs - run: | - echo "::set-output name=release-version::${{ env.NEXT_RELEASE_VERSION }}" - echo "::set-output name=short-sha::${{ env.SHORT_SHA }}" - id: output-step + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - name: Build and push Docker image uses: docker/build-push-action@v5 @@ -44,6 +39,10 @@ jobs: cache-from: type=registry,ref=blockscout/blockscout:buildcache cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max tags: blockscout/blockscout-staging:latest, blockscout/blockscout-staging:${{ env.RELEASE_VERSION }}.commit.${{ env.SHORT_SHA }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 build-args: | CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false diff --git a/.github/workflows/release-arbitrum.yml b/.github/workflows/release-arbitrum.yml index 8ba7fafae2c3..68334f9d55b0 100644 --- a/.github/workflows/release-arbitrum.yml +++ b/.github/workflows/release-arbitrum.yml @@ -18,25 +18,74 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Arbitrum + - name: Build and push Docker image for Arbitrum (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-arbitrum:latest, blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum + + - name: Build and push Docker image for Arbitrum (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=arbitrum + + - name: Build and push Docker image for Arbitrum (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-arbitrum:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= diff --git a/.github/workflows/release-eth.yml b/.github/workflows/release-eth.yml index b6d1b6743e49..bc139d870b10 100644 --- a/.github/workflows/release-eth.yml +++ b/.github/workflows/release-eth.yml @@ -18,28 +18,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Ethereum + - name: Build and push Docker image for Ethereum (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-ethereum:latest, blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Ethereum (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Ethereum (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-ethereum:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/release-filecoin.yml b/.github/workflows/release-filecoin.yml index d8b77901a75d..2992a3c2a930 100644 --- a/.github/workflows/release-filecoin.yml +++ b/.github/workflows/release-filecoin.yml @@ -18,28 +18,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Filecoin + - name: Build and push Docker image for Filecoin (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-filecoin:latest, blockscout/blockscout-filecoin:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=filecoin + + - name: Build and push Docker image for Filecoin (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-filecoin:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=filecoin + + - name: Build and push Docker image for Filecoin (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-filecoin:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=filecoin \ No newline at end of file diff --git a/.github/workflows/release-fuse.yml b/.github/workflows/release-fuse.yml new file mode 100644 index 000000000000..1a9e41004e3a --- /dev/null +++ b/.github/workflows/release-fuse.yml @@ -0,0 +1,95 @@ +name: Release for Fuse + +on: + workflow_dispatch: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Fuse (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-fuse:latest, blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true + + - name: Build and push Docker image for Fuse (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true + + - name: Build and push Docker image for Fuse (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true \ No newline at end of file diff --git a/.github/workflows/release-gnosis.yml b/.github/workflows/release-gnosis.yml index bdabb752b213..3755089991af 100644 --- a/.github/workflows/release-gnosis.yml +++ b/.github/workflows/release-gnosis.yml @@ -18,29 +18,80 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Gnosis chain + - name: Build and push Docker image for Gnosis chain (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-xdai:latest, blockscout/blockscout-xdai:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - BRIDGED_TOKENS_ENABLED=true - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Gnosis chain (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-xdai:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true + CHAIN_TYPE=ethereum + + - name: Build and push Docker image for Gnosis chain (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-xdai:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} + BRIDGED_TOKENS_ENABLED=true CHAIN_TYPE=ethereum \ No newline at end of file diff --git a/.github/workflows/release-optimism.yml b/.github/workflows/release-optimism.yml index 486d73967cfd..0f9977675978 100644 --- a/.github/workflows/release-optimism.yml +++ b/.github/workflows/release-optimism.yml @@ -18,28 +18,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Optimism + - name: Build and push Docker image for Optimism (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-optimism:latest, blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + + - name: Build and push Docker image for Optimism (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + + - name: Build and push Docker image for Optimism (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-optimism:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=optimism \ No newline at end of file diff --git a/.github/workflows/release-additional.yml b/.github/workflows/release-polygon-edge.yml similarity index 60% rename from .github/workflows/release-additional.yml rename to .github/workflows/release-polygon-edge.yml index be7db50858fa..b2a3ee4c3737 100644 --- a/.github/workflows/release-additional.yml +++ b/.github/workflows/release-polygon-edge.yml @@ -1,6 +1,7 @@ -name: Release additional +name: Release for Polygon Edge on: + workflow_dispatch: release: types: [published] @@ -18,94 +19,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Rootstock + - name: Build and push Docker image for Polygon Edge (indexer + api) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-rsk:latest, blockscout/blockscout-rsk:${{ env.RELEASE_VERSION }} + tags: blockscout/blockscout-polygon-edge:latest, blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false - CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= - BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta - RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=rsk - - - name: Build and push Docker image for Stability - uses: docker/build-push-action@v5 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: blockscout/blockscout-stability:latest, blockscout/blockscout-stability:${{ env.RELEASE_VERSION }} - platforms: | - linux/amd64 - linux/arm64/v8 - build-args: | - CACHE_EXCHANGE_RATES_PERIOD= API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=stability + CHAIN_TYPE=polygon_edge - - name: Build and push Docker image for Fuse + - name: Build and push Docker image for Polygon Edge (indexer) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-fuse:latest, blockscout/blockscout-fuse:${{ env.RELEASE_VERSION }} + tags: blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - BRIDGED_TOKENS_ENABLED=true + DISABLE_API=true + DISABLE_WEBAPP=true CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=polygon_edge - - name: Build and push Docker image for Polygon Edge + - name: Build and push Docker image for Polygon Edge (API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-polygon-edge:latest, blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }} + tags: blockscout/blockscout-polygon-edge:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=polygon_edge \ No newline at end of file diff --git a/.github/workflows/release-polygon-zkevm.yml b/.github/workflows/release-polygon-zkevm.yml new file mode 100644 index 000000000000..101068fa38bb --- /dev/null +++ b/.github/workflows/release-polygon-zkevm.yml @@ -0,0 +1,95 @@ +name: Release for Polygon zkEVM + +on: + workflow_dispatch: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Polygon zkEVM (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zkevm:latest, blockscout/blockscout-zkevm:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=polygon_zkevm + + - name: Build and push Docker image for Polygon zkEVM (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zkevm:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=polygon_zkevm + + - name: Build and push Docker image for Polygon zkEVM (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zkevm:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=polygon_zkevm \ No newline at end of file diff --git a/.github/workflows/release-redstone.yml b/.github/workflows/release-redstone.yml new file mode 100644 index 000000000000..d85d7c74dfd6 --- /dev/null +++ b/.github/workflows/release-redstone.yml @@ -0,0 +1,97 @@ +name: Release for Redstone + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Redstone + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-redstone:latest, blockscout/blockscout-redstone:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + CACHE_EXCHANGE_RATES_PERIOD= + API_V1_READ_METHODS_DISABLED=false + DISABLE_WEBAPP=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + ADMIN_PANEL_ENABLED=false + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + MUD_INDEXER_ENABLED=true + + - name: Build and push Docker image for Redstone (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-redstone:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + MUD_INDEXER_ENABLED=true + + - name: Build and push Docker image for Redstone (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-redstone:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=optimism + MUD_INDEXER_ENABLED=true \ No newline at end of file diff --git a/.github/workflows/release-rootstock.yml b/.github/workflows/release-rootstock.yml new file mode 100644 index 000000000000..a7ea06531804 --- /dev/null +++ b/.github/workflows/release-rootstock.yml @@ -0,0 +1,94 @@ +name: Release for Rootstock + +on: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Rootstock (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-rsk:latest, blockscout/blockscout-rsk:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=rsk + + - name: Build and push Docker image for Rootstock (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-rsk:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=rsk + + - name: Build and push Docker image for Rootstock (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-rsk:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=rsk diff --git a/.github/workflows/release-shibarium.yml b/.github/workflows/release-shibarium.yml index 8ed678ee7cb9..2147eb436fc3 100644 --- a/.github/workflows/release-shibarium.yml +++ b/.github/workflows/release-shibarium.yml @@ -18,28 +18,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Shibarium + - name: Build and push Docker image for Shibarium (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-shibarium:latest, blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium + + - name: Build and push Docker image for Shibarium (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=shibarium + + - name: Build and push Docker image for Shibarium (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-shibarium:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=shibarium \ No newline at end of file diff --git a/.github/workflows/release-stability.yml b/.github/workflows/release-stability.yml new file mode 100644 index 000000000000..2d6b9284b358 --- /dev/null +++ b/.github/workflows/release-stability.yml @@ -0,0 +1,95 @@ +name: Release for Stability + +on: + workflow_dispatch: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for Stability (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-stability:latest, blockscout/blockscout-stability:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=stability + + - name: Build and push Docker image for Stability (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-stability:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=stability + + - name: Build and push Docker image for Stability (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-stability:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=stability \ No newline at end of file diff --git a/.github/workflows/release-suave.yml b/.github/workflows/release-suave.yml new file mode 100644 index 000000000000..8ac9dadc3e5b --- /dev/null +++ b/.github/workflows/release-suave.yml @@ -0,0 +1,95 @@ +name: Release for SUAVE + +on: + workflow_dispatch: + release: + types: [published] + +env: + OTP_VERSION: ${{ vars.OTP_VERSION }} + ELIXIR_VERSION: ${{ vars.ELIXIR_VERSION }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + env: + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + steps: + - uses: actions/checkout@v4 + - name: Setup repo + uses: ./.github/actions/setup-repo + id: setup + with: + docker-username: ${{ secrets.DOCKER_USERNAME }} + docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} + + - name: Build and push Docker image for SUAVE (indexer + API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-suave:latest, blockscout/blockscout-suave:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false + API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=suave + + - name: Build and push Docker image for SUAVE (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-suave:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=suave + + - name: Build and push Docker image for SUAVE (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-suave:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=suave \ No newline at end of file diff --git a/.github/workflows/release-zetachain.yml b/.github/workflows/release-zetachain.yml index cd9c5abc14c9..6d497fd0536f 100644 --- a/.github/workflows/release-zetachain.yml +++ b/.github/workflows/release-zetachain.yml @@ -18,28 +18,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for Zetachain + - name: Build and push Docker image for Zetachain (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-zetachain:latest, blockscout/blockscout-zetachain:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zetachain + + - name: Build and push Docker image for Zetachain (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zetachain:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zetachain + + - name: Build and push Docker image for Zetachain (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zetachain:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=zetachain \ No newline at end of file diff --git a/.github/workflows/release-zksync.yml b/.github/workflows/release-zksync.yml index 15ed069ca941..e0d01276387e 100644 --- a/.github/workflows/release-zksync.yml +++ b/.github/workflows/release-zksync.yml @@ -19,28 +19,77 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build and push Docker image for ZkSync + - name: Build and push Docker image for ZkSync (indexer + API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true tags: blockscout/blockscout-zksync:latest, blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync + + - name: Build and push Docker image for ZkSync (indexer) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false + BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta + RELEASE_VERSION=${{ env.RELEASE_VERSION }} + CHAIN_TYPE=zksync + + - name: Build and push Docker image for ZkSync (API) + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: blockscout/blockscout-zksync:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} + platforms: | + linux/amd64 + linux/arm64/v8 + build-args: | + DISABLE_INDEXER=true + DISABLE_WEBAPP=true + CACHE_EXCHANGE_RATES_PERIOD= + CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} CHAIN_TYPE=zksync \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5b98c420728..385b836cb907 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,11 +18,15 @@ jobs: - uses: actions/checkout@v4 - name: Setup repo uses: ./.github/actions/setup-repo + id: setup with: docker-username: ${{ secrets.DOCKER_USERNAME }} docker-password: ${{ secrets.DOCKER_PASSWORD }} + docker-remote-multi-platform: true + docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }} + docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }} - - name: Build & Push Core Docker image + - name: Build & Push Core Docker image (indexer + API) uses: docker/build-push-action@v5 with: context: . @@ -31,79 +35,95 @@ jobs: cache-from: type=registry,ref=blockscout/blockscout:buildcache cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max tags: blockscout/blockscout:latest, blockscout/blockscout:${{ env.RELEASE_VERSION }} + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false DISABLE_WEBAPP=false + API_V1_READ_METHODS_DISABLED=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= + CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= ADMIN_PANEL_ENABLED=false DECODE_NOT_A_CONTRACT_CALLS=false MIXPANEL_URL= MIXPANEL_TOKEN= AMPLITUDE_URL= AMPLITUDE_API_KEY= - CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} - - name: Build and push Docker image for zkEVM + - name: Build & Push Core Docker image (indexer) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-zkevm:latest, blockscout/blockscout-zkevm:${{ env.RELEASE_VERSION }} + cache-from: type=registry,ref=blockscout/blockscout:buildcache + cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}-indexer + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | + DISABLE_API=true + DISABLE_WEBAPP=true CACHE_EXCHANGE_RATES_PERIOD= - API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false - API_V1_WRITE_METHODS_DISABLED=false CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=polygon_zkevm - - name: Build and push Docker image for SUAVE + - name: Build & Push Core Docker image (API) uses: docker/build-push-action@v5 with: context: . file: ./docker/Dockerfile push: true - tags: blockscout/blockscout-suave:latest, blockscout/blockscout-suave:${{ env.RELEASE_VERSION }} + cache-from: type=registry,ref=blockscout/blockscout:buildcache + cache-to: type=registry,ref=blockscout/blockscout:buildcache,mode=max + tags: blockscout/blockscout:${{ env.RELEASE_VERSION }}-api + labels: ${{ steps.setup.outputs.docker-labels }} platforms: | linux/amd64 linux/arm64/v8 build-args: | - CACHE_EXCHANGE_RATES_PERIOD= + DISABLE_INDEXER=true + DISABLE_WEBAPP=true API_V1_READ_METHODS_DISABLED=false - DISABLE_WEBAPP=false API_V1_WRITE_METHODS_DISABLED=false + CACHE_EXCHANGE_RATES_PERIOD= CACHE_TOTAL_GAS_USAGE_COUNTER_ENABLED= - ADMIN_PANEL_ENABLED=false CACHE_ADDRESS_WITH_BALANCES_UPDATE_INTERVAL= + ADMIN_PANEL_ENABLED=false + DECODE_NOT_A_CONTRACT_CALLS=false + MIXPANEL_URL= + MIXPANEL_TOKEN= + AMPLITUDE_URL= + AMPLITUDE_API_KEY= BLOCKSCOUT_VERSION=v${{ env.RELEASE_VERSION }}-beta RELEASE_VERSION=${{ env.RELEASE_VERSION }} - CHAIN_TYPE=suave - - name: Send release announcement to Slack workflow - id: slack - uses: slackapi/slack-github-action@v1.24.0 - with: - payload: | - { - "release-version": "${{ env.RELEASE_VERSION }}", - "release-link": "https://github.com/blockscout/blockscout/releases/tag/v${{ env.RELEASE_VERSION }}-beta" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + # - name: Send release announcement to Slack workflow + # id: slack + # uses: slackapi/slack-github-action@v1.24.0 + # with: + # payload: | + # { + # "release-version": "${{ env.RELEASE_VERSION }}", + # "release-link": "https://github.com/blockscout/blockscout/releases/tag/v${{ env.RELEASE_VERSION }}-beta" + # } + # env: + # SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # merge-master-after-release: # name: Merge 'master' to specific branch after release diff --git a/CHANGELOG.md b/CHANGELOG.md index 443947cc02b2..6c083fd9d927 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,181 @@ # Changelog +## 6.7.0 + +### 🚀 Features + +- Public metrics toggler ([#10279](https://github.com/blockscout/blockscout/issues/10279)) +- Chain & explorer Prometheus metrics ([#10063](https://github.com/blockscout/blockscout/issues/10063)) +- API endpoint to re-fetch token instance metadata ([#10097](https://github.com/blockscout/blockscout/issues/10097)) +- *(ci)* Use remote arm64 builder ([#9468](https://github.com/blockscout/blockscout/issues/9468)) +- Adding Mobula price source ([#9971](https://github.com/blockscout/blockscout/issues/9971)) +- Get ERC-1155 token name from contractURI getter fallback ([#10187](https://github.com/blockscout/blockscout/issues/10187)) +- Push relevant entries to the front of bound queue ([#10193](https://github.com/blockscout/blockscout/issues/10193)) +- Add feature toggle for WETH filtering ([#10208](https://github.com/blockscout/blockscout/issues/10208)) +- Batch read methods requests ([#10192](https://github.com/blockscout/blockscout/issues/10192)) +- Set dynamic ttl of cache modules derived from MapCache ([#10109](https://github.com/blockscout/blockscout/issues/10109)) +- Add Fee column to Internal transactions CSV export ([#10204](https://github.com/blockscout/blockscout/issues/10204)) +- Add window between balance fetch retries for missing balanceOf tokens ([#10142](https://github.com/blockscout/blockscout/issues/10142)) +- Indexer for cross level messages on Arbitrum ([#9312](https://github.com/blockscout/blockscout/issues/9312)) + +### 🐛 Bug Fixes + +- Add token instances preloads ([#10288](https://github.com/blockscout/blockscout/issues/10288)) +- Set timeout in seconds ([#10283](https://github.com/blockscout/blockscout/issues/10283)) +- Fix ci setup repo error ([#10277](https://github.com/blockscout/blockscout/issues/10277)) +- `getsourcecode` in API v1 for verified proxy ([#10273](https://github.com/blockscout/blockscout/issues/10273)) +- Add preloads for tx summary endpoint ([#10261](https://github.com/blockscout/blockscout/issues/10261)) +- Add preloads to summary and tokens endpoints ([#10259](https://github.com/blockscout/blockscout/issues/10259)) +- Advanced filter contract creation transaction ([#10257](https://github.com/blockscout/blockscout/issues/10257)) +- Proper hex-encoded transaction hash recognition in ZkSync batches status checker ([#10255](https://github.com/blockscout/blockscout/issues/10255)) +- Pipe through api_v2_no_forgery_protect POST requests in SmartContractsApiV2Router +- Fix possible unknown UID bug ([#10240](https://github.com/blockscout/blockscout/issues/10240)) +- Batch transactions view recovered and support of proofs through ZkSync Hyperchain ([#10234](https://github.com/blockscout/blockscout/issues/10234)) +- Fix nil abi issue in get_naive_implementation_abi and get_master_copy_pattern methods ([#10239](https://github.com/blockscout/blockscout/issues/10239)) +- Add smart contracts preloads to from_address ([#10236](https://github.com/blockscout/blockscout/issues/10236)) +- Add proxy_implementations preloads ([#10225](https://github.com/blockscout/blockscout/issues/10225)) +- Cannot truncate chardata ([#10227](https://github.com/blockscout/blockscout/issues/10227)) +- ERC-1155 tokens metadata retrieve ([#10231](https://github.com/blockscout/blockscout/issues/10231)) +- Replace empty arg names with argN ([#9748](https://github.com/blockscout/blockscout/issues/9748)) +- Fix unknown UID bug ([#10226](https://github.com/blockscout/blockscout/issues/10226)) +- Fixed the field name ([#10216](https://github.com/blockscout/blockscout/issues/10216)) +- Excessive logging for Arbitrum batches confirmations ([#10205](https://github.com/blockscout/blockscout/issues/10205)) +- Filter WETH transfers in indexer + migration to delete historical incorrect WETH transfers ([#10134](https://github.com/blockscout/blockscout/issues/10134)) +- Fix flaky test +- Resolve flaky address_controller test for web +- Add the ability to allow empty traces ([#10200](https://github.com/blockscout/blockscout/issues/10200)) +- Move auth routes to general router ([#10153](https://github.com/blockscout/blockscout/issues/10153)) +- Add a separate db url for events listener ([#10164](https://github.com/blockscout/blockscout/issues/10164)) +- Fix Retry NFT fetcher ([#10146](https://github.com/blockscout/blockscout/issues/10146)) +- Add missing preloads to tokens endpoints ([#10072](https://github.com/blockscout/blockscout/issues/10072)) +- Missing nil case for revert reason ([#10136](https://github.com/blockscout/blockscout/issues/10136)) +- Hotfix for Indexer.Fetcher.Optimism.WithdrawalEvent and EthereumJSONRPC.Receipt ([#10130](https://github.com/blockscout/blockscout/issues/10130)) + +### 🚜 Refactor + +- Remove hardcoded numResults from fetch_pending_transactions_besu ([#10117](https://github.com/blockscout/blockscout/issues/10117)) + +### ⚡ Performance + +- Replace individual queries with ecto preload ([#10203](https://github.com/blockscout/blockscout/issues/10203)) + +### ⚙️ Miscellaneous Tasks + +- Refactor PendingTransactionsSanitizer to use batched requests ([#10101](https://github.com/blockscout/blockscout/issues/10101)) +- Exclude write methods from read tabs ([#10111](https://github.com/blockscout/blockscout/issues/10111)) +- Return is verified=true for verified minimal proxy pattern ([#10132](https://github.com/blockscout/blockscout/issues/10132)) +- Bump ecto_sql from 3.11.1 to 3.11.2 + +### New ENV Variables + +| Variable | Required | Description | Default | Version | Need recompile | Application | +| -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------- | -------------- | --- | +| `DATABASE_EVENT_URL` | | Variable to define the Postgres Database endpoint that will be used by event listener process. Applicable for separate indexer and API setup. More info in related PR. Implemented in [#10164](https://github.com/blockscout/blockscout/pull/10164). | (empty) | v6.7.0+ | | API | +| `INDEXER_TOKEN_INSTANCE_RETRY_MAX_REFETCH_INTERVAL` | | Maximum interval between attempts to fetch token instance metadata. [Time format](env-variables.md#time-format). Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `168h` | v6.7.0+ | | Indexer | +| `INDEXER_TOKEN_INSTANCE_RETRY_EXPONENTIAL_TIMEOUT_BASE` | | Base to calculate exponential timeout. Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `2` | v6.7.0+ | | Indexer | +| `INDEXER_TOKEN_INSTANCE_RETRY_EXPONENTIAL_TIMEOUT_COEFF` | | Coefficient to calculate exponential timeout. Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `100` | v6.7.0+ | | Indexer | +| `MISSING_BALANCE_OF_TOKENS_WINDOW_SIZE` | | Minimal blocks count until the next token balance request will be executed for tokens that doesn't implement `balanceOf` function. Implemented in [#10142](https://github.com/blockscout/blockscout/pull/10142) | 100 | v6.7.0+ | | Indexer | +| `ETHEREUM_JSONRPC_GETH_ALLOW_EMPTY_TRACES` | | Allow transactions to not have internal transactions. Implemented in [#10200](https://github.com/blockscout/blockscout/pull/10200) | `false` | v6.7.0+ | | Indexer | +| `SANITIZE_INCORRECT_WETH_BATCH_SIZE` | | Number of token transfers to sanitize in the batch. Implemented in [#10134](https://github.com/blockscout/blockscout/pull/10134) | 100 | v6.7.0+ | | API, Indexer | +| `SANITIZE_INCORRECT_WETH_CONCURRENCY` | | Number of parallel sanitizing token transfer batches processing. Implemented in [#10134](https://github.com/blockscout/blockscout/pull/10134) | 1 | v6.7.0+ | | API, Indexer | +| `EXCHANGE_RATES_MOBULA_SECONDARY_COIN_ID` | | Explicitly set Mobula coin ID for secondary coin market chart. | (empty) | v6.7.0+ | | API, Indexer | +| `EXCHANGE_RATES_MOBULA_API_KEY` | | Mobula API key. | (empty) | v6.7.0+ | | API, Indexer | +| `EXCHANGE_RATES_MOBULA_CHAIN_ID` | | [Mobula](https://www.mobula.io/) chain id for which token prices are fetched, see full list in the [`Documentation`](https://docs.mobula.io/blockchains/intro-blockchains). | ethereum | v6.7.0+ | | API, Indexer | +| `TOKEN_INSTANCE_METADATA_REFETCH_ON_DEMAND_FETCHER_THRESHOLD` | | An initial threshold (for exponential backoff) to re-fetch token instance's metadata on-demand. [Time format](env-variables.md#time-format). Implemented in [#10097](https://github.com/blockscout/blockscout/pull/10097). | 5s | v6.7.0+ | | API, Indexer | +| `WHITELISTED_WETH_CONTRACTS` | | Comma-separated list of smart-contract addresses hashes of WETH-like tokens which deposit and withdrawal events you'd like to index. Implemented in [#10134](https://github.com/blockscout/blockscout/pull/10134) | (empty) | v6.7.0+ | | API, Indexer| +| `WETH_TOKEN_TRANSFERS_FILTERING_ENABLED` | | Toggle for WETH token transfers filtering which was introduced in [#10134](https://github.com/blockscout/blockscout/pull/10134). Implemented in [#10208](https://github.com/blockscout/blockscout/pull/10208) | false | v6.7.0+ | | API, Indexer| + +## 6.6.0 + +### 🚀 Features + +- Implement fetch_first_trace for Geth ([#10087](https://github.com/blockscout/blockscout/issues/10087)) +- Add optional retry of NFT metadata fetch in Indexer.Fetcher.Tok… ([#10036](https://github.com/blockscout/blockscout/issues/10036)) +- Blueprint contracts support ([#10058](https://github.com/blockscout/blockscout/issues/10058)) +- Clone with immutable arguments proxy pattern ([#10039](https://github.com/blockscout/blockscout/issues/10039)) +- Improve retry NFT fetcher ([#10027](https://github.com/blockscout/blockscout/issues/10027)) +- MUD API support ([#9869](https://github.com/blockscout/blockscout/issues/9869)) +- Diamond proxy (EIP-2535) support ([#10034](https://github.com/blockscout/blockscout/issues/10034)) +- Add user ops indexer to docker compose configs ([#10010](https://github.com/blockscout/blockscout/issues/10010)) +- Save smart-contract proxy type in the DB ([#10033](https://github.com/blockscout/blockscout/issues/10033)) +- Detect EIP-1967 proxy pattern on unverified smart-contracts ([#9864](https://github.com/blockscout/blockscout/issues/9864)) +- Omit balanceOf requests for tokens that doesn't support it ([#10018](https://github.com/blockscout/blockscout/issues/10018)) +- Precompiled contracts ABI import ([#9899](https://github.com/blockscout/blockscout/issues/9899)) +- Add ENS category to search result; Add ENS to check-redirect ([#9779](https://github.com/blockscout/blockscout/issues/9779)) + +### 🐛 Bug Fixes + +- Fix certified flag in the search API v2 endpoint ([#10094](https://github.com/blockscout/blockscout/issues/10094)) +- Update Vyper inner compilers list to support all compilers ([#10091](https://github.com/blockscout/blockscout/issues/10091)) +- Add healthcheck endpoints for indexer-only setup ([#10076](https://github.com/blockscout/blockscout/issues/10076)) +- Rework revert_reason ([#9212](https://github.com/blockscout/blockscout/issues/9212)) +- Eliminate from_address_hash == #{address_hash} clause for transactions query in case of smart-contracts ([#9469](https://github.com/blockscout/blockscout/issues/9469)) +- Separate indexer setup ([#10032](https://github.com/blockscout/blockscout/issues/10032)) +- Disallow batched queries in GraphQL endpoint ([#10050](https://github.com/blockscout/blockscout/issues/10050)) +- Vyper contracts re-verificaiton ([#10053](https://github.com/blockscout/blockscout/issues/10053)) +- Fix Unknown UID bug at smart-contract verification ([#9986](https://github.com/blockscout/blockscout/issues/9986)) +- Search for long integers ([#9651](https://github.com/blockscout/blockscout/issues/9651)) +- Don't put error to NFT metadata ([#9940](https://github.com/blockscout/blockscout/issues/9940)) +- Handle DB unavailability by PolygonZkevm.TransactionBatch fetcher ([#10031](https://github.com/blockscout/blockscout/issues/10031)) +- Fix WebSocketClient reconnect ([#9937](https://github.com/blockscout/blockscout/issues/9937)) +- Fix incorrect image_url parsing from NFT meta ([#9956](https://github.com/blockscout/blockscout/issues/9956)) + +### 🚜 Refactor + +- Improve response of address API to return multiple implementations for Diamond proxy ([#10113](https://github.com/blockscout/blockscout/pull/10113)) +- Refactor get_additional_sources/4 -> get_additional_sources/3 ([#10046](https://github.com/blockscout/blockscout/issues/10046)) +- Test database config ([#9662](https://github.com/blockscout/blockscout/issues/9662)) + +### ⚙️ Miscellaneous Tasks + +- Update hackney pool size: add new fetchers accounting ([#9941](https://github.com/blockscout/blockscout/issues/9941)) +- Bump credo from 1.7.5 to 1.7.6 ([#10060](https://github.com/blockscout/blockscout/issues/10060)) +- Bump redix from 1.5.0 to 1.5.1 ([#10059](https://github.com/blockscout/blockscout/issues/10059)) +- Bump ex_doc from 0.32.1 to 0.32.2 ([#10061](https://github.com/blockscout/blockscout/issues/10061)) +- Remove `has_methods` from `/addresses` ([#10051](https://github.com/blockscout/blockscout/issues/10051)) +- Add support of Blast-specific L1 OP withdrawal events ([#10049](https://github.com/blockscout/blockscout/issues/10049)) +- Update outdated links to ETH JSON RPC Specification in docstrings ([#10041](https://github.com/blockscout/blockscout/issues/10041)) +- Migrate to GET variant of {{metadata_url}}/api/v1/metadata ([#9994](https://github.com/blockscout/blockscout/issues/9994)) +- Bump ex_cldr_numbers from 2.32.4 to 2.33.1 ([#9978](https://github.com/blockscout/blockscout/issues/9978)) +- Bump ex_cldr from 2.38.0 to 2.38.1 ([#10009](https://github.com/blockscout/blockscout/issues/10009)) +- Bump ex_cldr_units from 3.16.5 to 3.17.0 ([#9931](https://github.com/blockscout/blockscout/issues/9931)) +- Bump style-loader in /apps/block_scout_web/assets ([#9995](https://github.com/blockscout/blockscout/issues/9995)) +- Bump mini-css-extract-plugin in /apps/block_scout_web/assets ([#9997](https://github.com/blockscout/blockscout/issues/9997)) +- Bump @babel/preset-env in /apps/block_scout_web/assets ([#9999](https://github.com/blockscout/blockscout/issues/9999)) +- Bump @amplitude/analytics-browser in /apps/block_scout_web/assets ([#10001](https://github.com/blockscout/blockscout/issues/10001)) +- Bump css-loader in /apps/block_scout_web/assets ([#10003](https://github.com/blockscout/blockscout/issues/10003)) +- Bump sweetalert2 in /apps/block_scout_web/assets ([#9998](https://github.com/blockscout/blockscout/issues/9998)) +- Bump mixpanel-browser in /apps/block_scout_web/assets ([#10000](https://github.com/blockscout/blockscout/issues/10000)) +- Bump @fortawesome/fontawesome-free ([#10002](https://github.com/blockscout/blockscout/issues/10002)) +- Bump @babel/core in /apps/block_scout_web/assets ([#9996](https://github.com/blockscout/blockscout/issues/9996)) +- Enhance indexer memory metrics ([#9984](https://github.com/blockscout/blockscout/issues/9984)) +- Bump redix from 1.4.1 to 1.5.0 ([#9977](https://github.com/blockscout/blockscout/issues/9977)) +- Bump floki from 0.36.1 to 0.36.2 ([#9979](https://github.com/blockscout/blockscout/issues/9979)) +- (old UI) Replace old Twitter icon with new 'X' ([#9641](https://github.com/blockscout/blockscout/issues/9641)) + +### New ENV Variables + +| Variable | Required | Description | Default | Version | Need recompile | +| -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------- | -------------- | +| `DISABLE_API` | | If `true`, endpoint is not started. Set this if you want to use an indexer-only setup. Implemented in [#10032](https://github.com/blockscout/blockscout/pull/10032) | `false` | v6.6.0+ | | +| `INDEXER_TOKEN_INSTANCE_RETRY_MAX_REFETCH_INTERVAL` | | Maximum interval between attempts to fetch token instance metadata. [Time format](env-variables.md#time-format). Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `168h` | v6.6.0+ | +| `INDEXER_TOKEN_INSTANCE_RETRY_EXPONENTIAL_TIMEOUT_BASE` | | Base to calculate exponential timeout. Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `2` | v6.6.0+ | +| `INDEXER_TOKEN_INSTANCE_RETRY_EXPONENTIAL_TIMEOUT_COEFF` | | Coefficient to calculate exponential timeout. Implemented in [#10027](https://github.com/blockscout/blockscout/pull/10027). | `100` | v6.6.0+ | +| `INDEXER_TOKEN_INSTANCE_REALTIME_RETRY_ENABLED` | | If `true`, `realtime` token instance fetcher will retry once on 404 and 500 error. Implemented in [#10036](https://github.com/blockscout/blockscout/pull/10036). | `false` | v6.6.0+ | +| `INDEXER_TOKEN_INSTANCE_REALTIME_RETRY_TIMEOUT` | | Timeout for retry set by `INDEXER_TOKEN_INSTANCE_REALTIME_RETRY_ENABLED`. [Time format](env-variables.md#time-format). Implemented in [#10036](https://github.com/blockscout/blockscout/pull/10036). | `5s` | v6.6.0+ | +| `TEST_DATABASE_URL` | | Variable to define the endpoint of the Postgres Database that is used during testing. Implemented in [#9662](https://github.com/blockscout/blockscout/pull/9662). | (empty) | v6.6.0+ | | +| `TEST_DATABASE_READ_ONLY_API_URL` | | Variable to define the endpoint of the Postgres Database read-only replica that is used during testing. If it is provided, most of the read queries from API v2 and UI would go through this endpoint. Implemented in [#9662](https://github.com/blockscout/blockscout/pull/9662). | (empty) | v6.6.0+ | | +| `MUD_INDEXER_ENABLED` | | If `true`, integration with [MUD](https://mud.dev/services/indexer#schemaless-indexing-with-postgresql-via-docker) is enabled. Implemented in [#9869](https://github.com/blockscout/blockscout/pull/9869) | (empty) | v6.6.0+ | | +| `MUD_DATABASE_URL` | | MUD indexer DB connection URL. | value from `DATABASE_URL` | v6.6.0+ | | +| `MUD_POOL_SIZE` | | MUD indexer DB `pool_size` | 50 | v6.6.0+ | | + +### Deprecated ENV Variables + +| Variable | Required | Description | Default | Version | Need recompile | Deprecated in Version | +| ----------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------- | -------------- | --------------------- | +| `INDEXER_TOKEN_INSTANCE_RETRY_REFETCH_INTERVAL` | | Interval between attempts to fetch token instance metadata. [Time format](env-variables.md#time-format). Implemented in [#7286](https://github.com/blockscout/blockscout/pull/7286). | `24h` | v5.1.4+ | | v6.6.0 | +| `INDEXER_INTERNAL_TRANSACTIONS_INDEXING_FINISHED_THRESHOLD` | | In the case when the 1st tx in the chain already has internal transactions, If the number of blocks in pending\_block\_operations is less than the value in this env var, Blockscout will consider, that indexing of internal transactions finished, otherwise, it will consider, that indexing is still taking place and the indexing banner will appear at the top. Implemented in [#7576](https://github.com/blockscout/blockscout/pull/7576). | 1000 | v5.2.0+ | | v6.6.0 | + ## 6.5.0 ### 🚀 Features diff --git a/README.md b/README.md index 678d7f78d118..3216456d710d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ See the [project documentation](https://docs.blockscout.com/) for instructions: ## Acknowledgements -We would like to thank the [EthPrize foundation](http://ethprize.io/) for their funding support. +We would like to thank the EthPrize foundation for their funding support. ## Contributing diff --git a/apps/block_scout_web/.sobelow-conf b/apps/block_scout_web/.sobelow-conf index 1604d1f66daf..70a8e7b0104f 100644 --- a/apps/block_scout_web/.sobelow-conf +++ b/apps/block_scout_web/.sobelow-conf @@ -7,7 +7,8 @@ format: "compact", ignore: ["Config.Headers", "Config.CSWH", "XSS.SendResp", "XSS.Raw"], ignore_files: [ - "apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex", - "apps/block_scout_web/lib/block_scout_web/utils_api_v2_router.ex" + "apps/block_scout_web/lib/block_scout_web/routers/smart_contracts_api_v2_router.ex", + "apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex", + "apps/block_scout_web/lib/block_scout_web/routers/utils_api_v2_router.ex" ] ] diff --git a/apps/block_scout_web/assets/package-lock.json b/apps/block_scout_web/assets/package-lock.json index 9dad321ad147..f13ee11fad65 100644 --- a/apps/block_scout_web/assets/package-lock.json +++ b/apps/block_scout_web/assets/package-lock.json @@ -7,17 +7,17 @@ "name": "blockscout", "license": "GPL-3.0", "dependencies": { - "@amplitude/analytics-browser": "^2.6.1", - "@fortawesome/fontawesome-free": "^6.5.1", + "@amplitude/analytics-browser": "^2.8.1", + "@fortawesome/fontawesome-free": "^6.5.2", "@tarekraafat/autocomplete.js": "^10.2.7", "@walletconnect/web3-provider": "^1.8.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bootstrap": "^4.6.0", - "chart.js": "^4.4.2", + "chart.js": "^4.4.3", "chartjs-adapter-luxon": "^1.3.1", "clipboard": "^2.0.11", - "core-js": "^3.36.1", + "core-js": "^3.37.1", "crypto-browserify": "^3.12.0", "dropzone": "^5.9.3", "eth-net-props": "^1.0.41", @@ -46,7 +46,7 @@ "lodash.reduce": "^4.6.0", "luxon": "^3.4.4", "malihu-custom-scrollbar-plugin": "3.1.5", - "mixpanel-browser": "^2.49.0", + "mixpanel-browser": "^2.51.0", "moment": "^2.30.1", "nanomorph": "^5.4.0", "numeral": "^2.0.6", @@ -61,7 +61,7 @@ "redux": "^5.0.1", "stream-browserify": "^3.0.0", "stream-http": "^3.1.1", - "sweetalert2": "^11.10.7", + "sweetalert2": "^11.11.0", "urijs": "^1.19.11", "url": "^0.11.3", "util": "^0.12.5", @@ -71,27 +71,27 @@ "xss": "^1.0.15" }, "devDependencies": { - "@babel/core": "^7.24.3", - "@babel/preset-env": "^7.24.3", + "@babel/core": "^7.24.6", + "@babel/preset-env": "^7.24.6", "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", - "css-loader": "^6.10.0", - "css-minimizer-webpack-plugin": "^6.0.0", + "css-loader": "^7.1.1", + "css-minimizer-webpack-plugin": "^7.0.0", "eslint": "^8.57.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-promise": "^6.2.0", "file-loader": "^6.2.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "mini-css-extract-plugin": "^2.8.1", + "mini-css-extract-plugin": "^2.9.0", "postcss": "^8.4.38", "postcss-loader": "^8.1.1", "sass": "^1.72.0", "sass-loader": "^14.1.1", - "style-loader": "^3.3.4", + "style-loader": "^4.0.0", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" }, @@ -116,15 +116,14 @@ } }, "node_modules/@amplitude/analytics-browser": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.6.1.tgz", - "integrity": "sha512-mGHPW5gGbYJhJOskYd9t4TPpf8v5jkDB2ndCmWipSm/OXHVCcQucRGUrJdmQIRrW+5aB4ertYCK0t2m/yzj2zw==", - "dependencies": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", - "@amplitude/plugin-page-view-tracking-browser": "^2.2.5", - "@amplitude/plugin-web-attribution-browser": "^2.1.6", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.8.1.tgz", + "integrity": "sha512-gvCvGQUbHjrmQQma5qBDQo25TD/p+TCoWX20XfGJC0rR51MCWacbYQZ6CQrECXte7c6XNzc11hC6Kf50bO0Sxw==", + "dependencies": { + "@amplitude/analytics-client-common": "^2.2.1", + "@amplitude/analytics-core": "^2.2.8", + "@amplitude/analytics-types": "^2.5.1", + "@amplitude/plugin-page-view-tracking-browser": "^2.2.13", "tslib": "^2.4.1" } }, @@ -134,13 +133,13 @@ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" }, "node_modules/@amplitude/analytics-client-common": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.1.2.tgz", - "integrity": "sha512-ekDMrXk7G15NPUGGcyB2x8WtBnzR6jRPRgW4vRToed7e3PVGzIWRSVyO9ymJZepQ+TCZ3ChlsBS1YonuTE0r2Q==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.2.1.tgz", + "integrity": "sha512-JXpLjKgP7LiBMZF5eMjtiPiSPW8FxvF4bHubDg26Ck2buBUQvrBq6D4VyOky0m1zG7WA4vOoLANu3sWfF02/7Q==", "dependencies": { "@amplitude/analytics-connector": "^1.4.8", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-core": "^2.2.8", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" } }, @@ -155,11 +154,11 @@ "integrity": "sha512-T8mOYzB9RRxckzhL0NTHwdge9xuFxXEOplC8B1Y3UX3NHa3BLh7DlBUZlCOwQgMc2nxDfnSweDL5S3bhC+W90g==" }, "node_modules/@amplitude/analytics-core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.3.tgz", - "integrity": "sha512-rtA7TSqie6Jgcvax3tEHaZUzOJM5Hdd5/+JYFIJK2gPgHsWZj3jDF75fL8BSn4uBiA2zcZ0vbCHORMVqXg5pRw==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.8.tgz", + "integrity": "sha512-T4ZFk1LUD+4z02XMSWK4qPvMREUTgNtEoYQc6BvNyfOx1Ih21qyJLFcdSw05gL26JuuuYZWFkpHxxKm8IoZh8Q==", "dependencies": { - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" } }, @@ -169,17 +168,17 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/@amplitude/analytics-types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.0.tgz", - "integrity": "sha512-aY69WxUvVlaCU+9geShjTsAYdUTvegEXH9i4WK/97kNbNLl4/7qUuIPe4hNireDeKLuQA9SA3H7TKynuNomDxw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.1.tgz", + "integrity": "sha512-xGuLiHRLv5z3RSAHiICjzHK4TjUZJ7aHr/jM0XhSgD/V1YdmG/s8y1UAWGI2Stsxm2x0DWNOyEpjYkGohlnXtA==" }, "node_modules/@amplitude/plugin-page-view-tracking-browser": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.5.tgz", - "integrity": "sha512-uhX1bP57DrvkV3KYWR0NwyTTSBXU3m+LbwBm/0vm4YRLLM1I8dEle+Wb3mN3inbIYOOVyEd3ARR+NS8Xf/hEeQ==", + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.13.tgz", + "integrity": "sha512-EYvG4RTyNqIGlq3J+UnrTRRj75xp3nOSETeInPQbnHhiPaCzxTjWrb9URkzy2IYSyBSn4KEQkZegmzhWXxlvvw==", "dependencies": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-client-common": "^2.2.1", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" } }, @@ -188,22 +187,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/@amplitude/plugin-web-attribution-browser": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.6.tgz", - "integrity": "sha512-3Nds/vfLTBXFi5rLOUF78TL2OkzBAXzJuslSFfSHl7C8psGcpkWTnWcxPakfLHuev3yteknCkWaevdio+GMljg==", - "dependencies": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", - "tslib": "^2.4.1" - } - }, - "node_modules/@amplitude/plugin-web-attribution-browser/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -229,11 +212,11 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", + "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.6", "picocolors": "^1.0.0" }, "engines": { @@ -241,28 +224,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", - "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", + "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", - "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", + "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.1", - "@babel/parser": "^7.24.1", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helpers": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/traverse": "^7.24.6", + "@babel/types": "^7.24.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -283,11 +266,11 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", + "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -297,35 +280,35 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", + "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz", + "integrity": "sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", + "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", + "@babel/compat-data": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -348,19 +331,19 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", - "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz", + "integrity": "sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "semver": "^6.3.1" }, "engines": { @@ -371,12 +354,12 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz", + "integrity": "sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-annotate-as-pure": "^7.24.6", "regexpu-core": "^5.3.1", "semver": "^6.3.1" }, @@ -404,69 +387,69 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz", + "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz", + "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", + "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz", + "integrity": "sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==", "dev": true, "dependencies": { - "@babel/types": "^7.23.0" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", + "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", "dependencies": { - "@babel/types": "^7.24.0" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", + "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -476,34 +459,34 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz", + "integrity": "sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", + "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz", + "integrity": "sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-wrap-function": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -513,14 +496,14 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz", + "integrity": "sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -530,96 +513,95 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", + "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz", + "integrity": "sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", + "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", + "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", + "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", + "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz", + "integrity": "sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/helper-function-name": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", - "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", + "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", "dependencies": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", + "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.6", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -629,9 +611,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", + "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", "bin": { "parser": "bin/babel-parser.js" }, @@ -639,13 +621,29 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.6.tgz", + "integrity": "sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.6.tgz", + "integrity": "sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -655,14 +653,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.6.tgz", + "integrity": "sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -672,13 +670,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.6.tgz", + "integrity": "sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -775,12 +773,12 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz", + "integrity": "sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -790,12 +788,12 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz", + "integrity": "sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -977,12 +975,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz", + "integrity": "sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -992,14 +990,14 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.6.tgz", + "integrity": "sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6", "@babel/plugin-syntax-async-generators": "^7.8.4" }, "engines": { @@ -1010,14 +1008,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.6.tgz", + "integrity": "sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1027,12 +1025,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz", + "integrity": "sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1042,12 +1040,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", - "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz", + "integrity": "sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1057,13 +1055,13 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz", + "integrity": "sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1073,13 +1071,13 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", - "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz", + "integrity": "sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-class-static-block": "^7.14.5" }, "engines": { @@ -1090,18 +1088,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz", + "integrity": "sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "globals": "^11.1.0" }, "engines": { @@ -1112,13 +1110,13 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz", + "integrity": "sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/template": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1128,12 +1126,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz", + "integrity": "sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1143,13 +1141,13 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz", + "integrity": "sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1159,12 +1157,12 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz", + "integrity": "sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1174,12 +1172,12 @@ } }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz", + "integrity": "sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { @@ -1190,13 +1188,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz", + "integrity": "sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1206,12 +1204,12 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz", + "integrity": "sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" }, "engines": { @@ -1222,13 +1220,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz", + "integrity": "sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1238,14 +1236,14 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz", + "integrity": "sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1255,12 +1253,12 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz", + "integrity": "sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-json-strings": "^7.8.3" }, "engines": { @@ -1271,12 +1269,12 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz", + "integrity": "sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1286,12 +1284,12 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz", + "integrity": "sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { @@ -1302,12 +1300,12 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz", + "integrity": "sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1317,13 +1315,13 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz", + "integrity": "sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1333,14 +1331,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz", + "integrity": "sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1350,15 +1348,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz", + "integrity": "sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1368,13 +1366,13 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz", + "integrity": "sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1384,13 +1382,13 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz", + "integrity": "sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1400,12 +1398,12 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz", + "integrity": "sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1415,12 +1413,12 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz", + "integrity": "sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { @@ -1431,12 +1429,12 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz", + "integrity": "sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" }, "engines": { @@ -1447,15 +1445,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz", + "integrity": "sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==", "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" + "@babel/plugin-transform-parameters": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1465,13 +1463,13 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz", + "integrity": "sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1481,12 +1479,12 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz", + "integrity": "sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, "engines": { @@ -1497,13 +1495,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz", + "integrity": "sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { @@ -1514,12 +1512,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz", + "integrity": "sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1529,13 +1527,13 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz", + "integrity": "sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1545,14 +1543,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz", + "integrity": "sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1563,12 +1561,12 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz", + "integrity": "sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1578,12 +1576,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz", + "integrity": "sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1594,12 +1592,12 @@ } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz", + "integrity": "sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1640,12 +1638,12 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz", + "integrity": "sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1655,13 +1653,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz", + "integrity": "sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1671,12 +1669,12 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz", + "integrity": "sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1686,12 +1684,12 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz", + "integrity": "sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1701,12 +1699,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz", + "integrity": "sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1716,12 +1714,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz", + "integrity": "sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1731,13 +1729,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz", + "integrity": "sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1747,13 +1745,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz", + "integrity": "sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1763,13 +1761,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz", + "integrity": "sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" }, "engines": { "node": ">=6.9.0" @@ -1779,26 +1777,27 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", - "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.6.tgz", + "integrity": "sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.6", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-assertions": "^7.24.6", + "@babel/plugin-syntax-import-attributes": "^7.24.6", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -1810,54 +1809,54 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.1", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.1", - "@babel/plugin-transform-classes": "^7.24.1", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/plugin-transform-arrow-functions": "^7.24.6", + "@babel/plugin-transform-async-generator-functions": "^7.24.6", + "@babel/plugin-transform-async-to-generator": "^7.24.6", + "@babel/plugin-transform-block-scoped-functions": "^7.24.6", + "@babel/plugin-transform-block-scoping": "^7.24.6", + "@babel/plugin-transform-class-properties": "^7.24.6", + "@babel/plugin-transform-class-static-block": "^7.24.6", + "@babel/plugin-transform-classes": "^7.24.6", + "@babel/plugin-transform-computed-properties": "^7.24.6", + "@babel/plugin-transform-destructuring": "^7.24.6", + "@babel/plugin-transform-dotall-regex": "^7.24.6", + "@babel/plugin-transform-duplicate-keys": "^7.24.6", + "@babel/plugin-transform-dynamic-import": "^7.24.6", + "@babel/plugin-transform-exponentiation-operator": "^7.24.6", + "@babel/plugin-transform-export-namespace-from": "^7.24.6", + "@babel/plugin-transform-for-of": "^7.24.6", + "@babel/plugin-transform-function-name": "^7.24.6", + "@babel/plugin-transform-json-strings": "^7.24.6", + "@babel/plugin-transform-literals": "^7.24.6", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.6", + "@babel/plugin-transform-member-expression-literals": "^7.24.6", + "@babel/plugin-transform-modules-amd": "^7.24.6", + "@babel/plugin-transform-modules-commonjs": "^7.24.6", + "@babel/plugin-transform-modules-systemjs": "^7.24.6", + "@babel/plugin-transform-modules-umd": "^7.24.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.6", + "@babel/plugin-transform-new-target": "^7.24.6", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.6", + "@babel/plugin-transform-numeric-separator": "^7.24.6", + "@babel/plugin-transform-object-rest-spread": "^7.24.6", + "@babel/plugin-transform-object-super": "^7.24.6", + "@babel/plugin-transform-optional-catch-binding": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6", + "@babel/plugin-transform-parameters": "^7.24.6", + "@babel/plugin-transform-private-methods": "^7.24.6", + "@babel/plugin-transform-private-property-in-object": "^7.24.6", + "@babel/plugin-transform-property-literals": "^7.24.6", + "@babel/plugin-transform-regenerator": "^7.24.6", + "@babel/plugin-transform-reserved-words": "^7.24.6", + "@babel/plugin-transform-shorthand-properties": "^7.24.6", + "@babel/plugin-transform-spread": "^7.24.6", + "@babel/plugin-transform-sticky-regex": "^7.24.6", + "@babel/plugin-transform-template-literals": "^7.24.6", + "@babel/plugin-transform-typeof-symbol": "^7.24.6", + "@babel/plugin-transform-unicode-escapes": "^7.24.6", + "@babel/plugin-transform-unicode-property-regex": "^7.24.6", + "@babel/plugin-transform-unicode-regex": "^7.24.6", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", @@ -1946,31 +1945,31 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", + "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", + "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "dependencies": { + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1979,12 +1978,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", + "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2558,9 +2557,9 @@ } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz", - "integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz", + "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==", "hasInstallScript": true, "engines": { "node": ">=6" @@ -3417,6 +3416,14 @@ "node": ">= 8" } }, + "node_modules/@rrweb/types": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/@rrweb/types/-/types-2.0.0-alpha.14.tgz", + "integrity": "sha512-H0qKW75SdsZM4/4116fQDDC3QkUxbP7A9AY5PK2nyUV56KReAQ1sH8ZHu9tomvn0kFJUXhtvjv2H6G6xxSJNqA==", + "dependencies": { + "rrweb-snapshot": "^2.0.0-alpha.14" + } + }, "node_modules/@scure/base": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", @@ -3596,6 +3603,11 @@ "@types/responselike": "^1.0.0" } }, + "node_modules/@types/css-font-loading-module": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", + "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==" + }, "node_modules/@types/eslint": { "version": "8.4.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", @@ -4188,6 +4200,11 @@ } } }, + "node_modules/@xstate/fsm": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz", + "integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==" + }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -4985,6 +5002,14 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -5570,9 +5595,9 @@ } }, "node_modules/chart.js": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz", - "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", "dependencies": { "@kurkle/color": "^0.3.0" }, @@ -5949,9 +5974,9 @@ } }, "node_modules/core-js": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", - "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==", + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6225,9 +6250,9 @@ } }, "node_modules/css-declaration-sorter": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.1.1.tgz", - "integrity": "sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==", + "version": "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==", "dev": true, "engines": { "node": "^14 || ^16 || >=18" @@ -6237,22 +6262,22 @@ } }, "node_modules/css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz", + "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==", "dev": true, "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.5.4" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -6260,7 +6285,7 @@ }, "peerDependencies": { "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" + "webpack": "^5.27.0" }, "peerDependenciesMeta": { "@rspack/core": { @@ -6287,15 +6312,15 @@ } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-6.0.0.tgz", - "integrity": "sha512-BLpR9CCDkKvhO3i0oZQgad6v9pCxUuhSc5RT6iUEy9M8hBXi4TJb5vqF2GQ2deqYHmRi3O6IR9hgAZQWg0EBwA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.0.tgz", + "integrity": "sha512-niy66jxsQHqO+EYbhPuIhqRQ1mNcNVUHrMnkzzir9kFOERJUaQDDRhh7dKDz33kBpkWMF9M8Vx0QlDbc5AHOsw==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.21", - "cssnano": "^6.0.3", + "@jridgewell/trace-mapping": "^0.3.25", + "cssnano": "^7.0.1", "jest-worker": "^29.7.0", - "postcss": "^8.4.33", + "postcss": "^8.4.38", "schema-utils": "^4.2.0", "serialize-javascript": "^6.0.2" }, @@ -6438,16 +6463,16 @@ "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" }, "node_modules/cssnano": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz", - "integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.1.tgz", + "integrity": "sha512-917Mej/4SdI7b55atsli3sU4MOJ9XDoKgnlCtQtXYj8XUFcM3riTuYHyqBBnnskawW+zWwp0KxJzpEUodlpqUg==", "dev": true, "dependencies": { - "cssnano-preset-default": "^6.0.3", - "lilconfig": "^3.0.0" + "cssnano-preset-default": "^7.0.1", + "lilconfig": "^3.1.1" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "funding": { "type": "opencollective", @@ -6458,55 +6483,56 @@ } }, "node_modules/cssnano-preset-default": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.3.tgz", - "integrity": "sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^7.1.1", - "cssnano-utils": "^4.0.1", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.0.2", - "postcss-convert-values": "^6.0.2", - "postcss-discard-comments": "^6.0.1", - "postcss-discard-duplicates": "^6.0.1", - "postcss-discard-empty": "^6.0.1", - "postcss-discard-overridden": "^6.0.1", - "postcss-merge-longhand": "^6.0.2", - "postcss-merge-rules": "^6.0.3", - "postcss-minify-font-values": "^6.0.1", - "postcss-minify-gradients": "^6.0.1", - "postcss-minify-params": "^6.0.2", - "postcss-minify-selectors": "^6.0.2", - "postcss-normalize-charset": "^6.0.1", - "postcss-normalize-display-values": "^6.0.1", - "postcss-normalize-positions": "^6.0.1", - "postcss-normalize-repeat-style": "^6.0.1", - "postcss-normalize-string": "^6.0.1", - "postcss-normalize-timing-functions": "^6.0.1", - "postcss-normalize-unicode": "^6.0.2", - "postcss-normalize-url": "^6.0.1", - "postcss-normalize-whitespace": "^6.0.1", - "postcss-ordered-values": "^6.0.1", - "postcss-reduce-initial": "^6.0.2", - "postcss-reduce-transforms": "^6.0.1", - "postcss-svgo": "^6.0.2", - "postcss-unique-selectors": "^6.0.2" - }, - "engines": { - "node": "^14 || ^16 || >=18.0" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.1.tgz", + "integrity": "sha512-Fumyr+uZMcjYQeuHssAZxn0cKj3cdQc5GcxkBcmEzISGB+UW9CLNlU4tBOJbJGcPukFDlicG32eFbrc8K9V5pw==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.0", + "postcss-calc": "^10.0.0", + "postcss-colormin": "^7.0.0", + "postcss-convert-values": "^7.0.0", + "postcss-discard-comments": "^7.0.0", + "postcss-discard-duplicates": "^7.0.0", + "postcss-discard-empty": "^7.0.0", + "postcss-discard-overridden": "^7.0.0", + "postcss-merge-longhand": "^7.0.0", + "postcss-merge-rules": "^7.0.0", + "postcss-minify-font-values": "^7.0.0", + "postcss-minify-gradients": "^7.0.0", + "postcss-minify-params": "^7.0.0", + "postcss-minify-selectors": "^7.0.0", + "postcss-normalize-charset": "^7.0.0", + "postcss-normalize-display-values": "^7.0.0", + "postcss-normalize-positions": "^7.0.0", + "postcss-normalize-repeat-style": "^7.0.0", + "postcss-normalize-string": "^7.0.0", + "postcss-normalize-timing-functions": "^7.0.0", + "postcss-normalize-unicode": "^7.0.0", + "postcss-normalize-url": "^7.0.0", + "postcss-normalize-whitespace": "^7.0.0", + "postcss-ordered-values": "^7.0.0", + "postcss-reduce-initial": "^7.0.0", + "postcss-reduce-transforms": "^7.0.0", + "postcss-svgo": "^7.0.0", + "postcss-unique-selectors": "^7.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/cssnano-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.1.tgz", - "integrity": "sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.0.tgz", + "integrity": "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" @@ -7645,15 +7671,18 @@ } }, "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.2.0.tgz", + "integrity": "sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-scope": { @@ -8794,6 +8823,11 @@ "bser": "2.1.1" } }, + "node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -12373,12 +12407,15 @@ } }, "node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true, "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -12848,9 +12885,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", - "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, "dependencies": { "schema-utils": "^4.0.0", @@ -12916,10 +12953,18 @@ "minipass": "^2.9.0" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "node_modules/mixpanel-browser": { - "version": "2.49.0", - "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.49.0.tgz", - "integrity": "sha512-RZJCO7XXuuHBAWG5fd9Mavz994M7v7W3Qiaq8NzmN631pa4BQ0vNZQtRFqKcCCOBn4xqOZbX2GkuC7ZkQoL4cQ==" + "version": "2.51.0", + "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.51.0.tgz", + "integrity": "sha512-cNjvvhlRkSlqW1w4nxRpK5y4R3QcfhY7H/ZfvZ4jLeiBUNeeuwyQTgOAk/mYiBDOonWEdeN7h3EkL2BdqKd2Sw==", + "dependencies": { + "rrweb": "2.0.0-alpha.13" + } }, "node_modules/mkdirp": { "version": "3.0.1", @@ -13785,98 +13830,98 @@ } }, "node_modules/postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.0.0.tgz", + "integrity": "sha512-OmjhudoNTP0QleZCwl1i6NeBwN+5MZbY5ersLZz69mjJiDVv/p57RjRuKDkHeDWr4T+S97wQfsqRTNoDHB2e3g==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.11", + "postcss-selector-parser": "^6.0.16", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12 || ^20.9 || >=22.0" }, "peerDependencies": { - "postcss": "^8.2.2" + "postcss": "^8.4.38" } }, "node_modules/postcss-colormin": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.2.tgz", - "integrity": "sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.0.tgz", + "integrity": "sha512-5CN6fqtsEtEtwf3mFV3B4UaZnlYljPpzmGeDB4yCK067PnAtfLe9uX2aFZaEwxHE7HopG5rUkW8gyHrNAesHEg==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "colord": "^2.9.1", + "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-convert-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.2.tgz", - "integrity": "sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.0.tgz", + "integrity": "sha512-bMuzDgXBbFbByPgj+/r6va8zNuIDUaIIbvAFgdO1t3zdgJZ77BZvu6dfWyd6gHEJnYzmeVr9ayUsAQL3/qLJ0w==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-discard-comments": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.1.tgz", - "integrity": "sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.0.tgz", + "integrity": "sha512-xpSdzRqYmy4YIVmjfGyYXKaI1SRnK6CTr+4Zmvyof8ANwvgfZgGdVtmgAvzh59gJm808mJCWQC9tFN0KF5dEXA==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-discard-duplicates": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.1.tgz", - "integrity": "sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.0.tgz", + "integrity": "sha512-bAnSuBop5LpAIUmmOSsuvtKAAKREB6BBIYStWUTGq8oG5q9fClDMMuY8i4UPI/cEcDx2TN+7PMnXYIId20UVDw==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-discard-empty": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.1.tgz", - "integrity": "sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.0.tgz", + "integrity": "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-discard-overridden": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.1.tgz", - "integrity": "sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.0.tgz", + "integrity": "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" @@ -13929,107 +13974,107 @@ } }, "node_modules/postcss-merge-longhand": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.2.tgz", - "integrity": "sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.0.tgz", + "integrity": "sha512-0X8I4/9+G03X5/5NnrfopG/YEln2XU8heDh7YqBaiq2SeaKIG3n66ShZPjIolmVuLBQ0BEm3yS8o1mlCLHdW7A==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.0.2" + "stylehacks": "^7.0.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-merge-rules": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.3.tgz", - "integrity": "sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.0.tgz", + "integrity": "sha512-Zty3VlOsD6VSjBMu6PiHCVpLegtBT/qtZRVBcSeyEZ6q1iU5qTYT0WtEoLRV+YubZZguS5/ycfP+NRiKfjv6aw==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.1", - "postcss-selector-parser": "^6.0.15" + "cssnano-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-minify-font-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.1.tgz", - "integrity": "sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.0.tgz", + "integrity": "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-minify-gradients": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.1.tgz", - "integrity": "sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.0.tgz", + "integrity": "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==", "dev": true, "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^4.0.1", + "colord": "^2.9.3", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-minify-params": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.2.tgz", - "integrity": "sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.0.tgz", + "integrity": "sha512-XOJAuX8Q/9GT1sGxlUvaFEe2H9n50bniLZblXXsAT/BwSfFYvzSZeFG7uupwc0KbKpTnflnQ7aMwGzX6JUWliQ==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", - "cssnano-utils": "^4.0.1", + "browserslist": "^4.23.0", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-minify-selectors": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.2.tgz", - "integrity": "sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.0.tgz", + "integrity": "sha512-f00CExZhD6lNw2vTZbcnmfxVgaVKzUw6IRsIFX3JTT8GdsoABc1WnhhGwL1i8YPJ3sSWw39fv7XPtvLb+3Uitw==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.15" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, "engines": { "node": "^10 || ^12 || >= 14" @@ -14039,9 +14084,9 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, "dependencies": { "icss-utils": "^5.0.0", @@ -14056,9 +14101,9 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", - "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.4" @@ -14086,189 +14131,189 @@ } }, "node_modules/postcss-normalize-charset": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.1.tgz", - "integrity": "sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz", + "integrity": "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==", "dev": true, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-display-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.1.tgz", - "integrity": "sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.0.tgz", + "integrity": "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-positions": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.1.tgz", - "integrity": "sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.0.tgz", + "integrity": "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-repeat-style": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.1.tgz", - "integrity": "sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.0.tgz", + "integrity": "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-string": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.1.tgz", - "integrity": "sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.0.tgz", + "integrity": "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-timing-functions": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.1.tgz", - "integrity": "sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.0.tgz", + "integrity": "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-unicode": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.2.tgz", - "integrity": "sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.0.tgz", + "integrity": "sha512-OnKV52/VFFDAim4n0pdI+JAhsolLBdnCKxE6VV5lW5Q/JeVGFN8UM8ur6/A3EAMLsT1ZRm3fDHh/rBoBQpqi2w==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.1.tgz", - "integrity": "sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.0.tgz", + "integrity": "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-whitespace": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.1.tgz", - "integrity": "sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.0.tgz", + "integrity": "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-ordered-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.1.tgz", - "integrity": "sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.0.tgz", + "integrity": "sha512-KROvC63A8UQW1eYDljQe1dtwc1E/M+mMwDT6z7khV/weHYLWTghaLRLunU7x1xw85lWFwVZOAGakxekYvKV+0w==", "dev": true, "dependencies": { - "cssnano-utils": "^4.0.1", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-initial": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.2.tgz", - "integrity": "sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.0.tgz", + "integrity": "sha512-iqGgmBxY9LrblZ0BKLjmrA1mC/cf9A/wYCCqSmD6tMi+xAyVl0+DfixZIHSVDMbCPRPjNmVF0DFGth/IDGelFQ==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-transforms": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.1.tgz", - "integrity": "sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.0.tgz", + "integrity": "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -14279,31 +14324,31 @@ } }, "node_modules/postcss-svgo": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.2.tgz", - "integrity": "sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.0.tgz", + "integrity": "sha512-Xj5DRdvA97yRy3wjbCH2NKXtDUwEnph6EHr5ZXszsBVKCNrKXYBjzAXqav7/Afz5WwJ/1peZoTguCEJIg7ytmA==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^3.2.0" }, "engines": { - "node": "^14 || ^16 || >= 18" + "node": "^18.12.0 || ^20.9.0 || >= 18" }, "peerDependencies": { "postcss": "^8.4.31" } }, "node_modules/postcss-unique-selectors": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.2.tgz", - "integrity": "sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.0.tgz", + "integrity": "sha512-NYFqcft7vVQMZlQPsMdMPy+qU/zDpy95Malpw4GeA9ZZjM6dVXDshXtDmLc0m4WCD6XeZCJqjTfPT1USsdt+rA==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.15" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" @@ -15130,6 +15175,34 @@ "rlp": "bin/rlp" } }, + "node_modules/rrdom": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/rrdom/-/rrdom-2.0.0-alpha.14.tgz", + "integrity": "sha512-aEDi8MNfKWRnWHM1Mhfx535EtHHYHg6L17PC3rvMUJMgHLcyMQsmI+OMeWt5RzXw1J2fdwhMV0grpp5VDTqRaA==", + "dependencies": { + "rrweb-snapshot": "^2.0.0-alpha.14" + } + }, + "node_modules/rrweb": { + "version": "2.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/rrweb/-/rrweb-2.0.0-alpha.13.tgz", + "integrity": "sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==", + "dependencies": { + "@rrweb/types": "^2.0.0-alpha.13", + "@types/css-font-loading-module": "0.0.7", + "@xstate/fsm": "^1.4.0", + "base64-arraybuffer": "^1.0.1", + "fflate": "^0.4.4", + "mitt": "^3.0.0", + "rrdom": "^2.0.0-alpha.13", + "rrweb-snapshot": "^2.0.0-alpha.13" + } + }, + "node_modules/rrweb-snapshot": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-2.0.0-alpha.14.tgz", + "integrity": "sha512-HuJd7iZauzhf7XI5FFtCGeUXkHk1mgc8yvH9Km9zB09Yk2cr0bW4eKx9fWQhRFiry9yXf/vOMkUy403xTLPIrQ==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -15922,19 +15995,19 @@ } }, "node_modules/style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "dev": true, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^5.0.0" + "webpack": "^5.27.0" } }, "node_modules/styled-components": { @@ -15967,16 +16040,16 @@ } }, "node_modules/stylehacks": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.2.tgz", - "integrity": "sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.0.tgz", + "integrity": "sha512-47Nw4pQ6QJb4CA6dzF2m9810sjQik4dfk4UwAm5wlwhrW3syzZKF8AR4/cfO3Cr6lsFgAoznQq0Wg57qhjTA2A==", "dev": true, "dependencies": { - "browserslist": "^4.22.2", - "postcss-selector-parser": "^6.0.15" + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "peerDependencies": { "postcss": "^8.4.31" @@ -16005,9 +16078,9 @@ } }, "node_modules/svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dev": true, "dependencies": { "@trysound/sax": "0.2.0", @@ -16119,9 +16192,9 @@ } }, "node_modules/sweetalert2": { - "version": "11.10.7", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", - "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.11.0.tgz", + "integrity": "sha512-wKCTtoE6lQVDKaJ5FFq+znk/YykJmJlD8RnLZps8C7DyivctCoRlVeeOwnKfgwKS+QJYon7s++3dmNi3/am1tw==", "funding": { "type": "individual", "url": "https://github.com/sponsors/limonte" @@ -17899,15 +17972,14 @@ "dev": true }, "@amplitude/analytics-browser": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.6.1.tgz", - "integrity": "sha512-mGHPW5gGbYJhJOskYd9t4TPpf8v5jkDB2ndCmWipSm/OXHVCcQucRGUrJdmQIRrW+5aB4ertYCK0t2m/yzj2zw==", - "requires": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", - "@amplitude/plugin-page-view-tracking-browser": "^2.2.5", - "@amplitude/plugin-web-attribution-browser": "^2.1.6", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-browser/-/analytics-browser-2.8.1.tgz", + "integrity": "sha512-gvCvGQUbHjrmQQma5qBDQo25TD/p+TCoWX20XfGJC0rR51MCWacbYQZ6CQrECXte7c6XNzc11hC6Kf50bO0Sxw==", + "requires": { + "@amplitude/analytics-client-common": "^2.2.1", + "@amplitude/analytics-core": "^2.2.8", + "@amplitude/analytics-types": "^2.5.1", + "@amplitude/plugin-page-view-tracking-browser": "^2.2.13", "tslib": "^2.4.1" }, "dependencies": { @@ -17919,13 +17991,13 @@ } }, "@amplitude/analytics-client-common": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.1.2.tgz", - "integrity": "sha512-ekDMrXk7G15NPUGGcyB2x8WtBnzR6jRPRgW4vRToed7e3PVGzIWRSVyO9ymJZepQ+TCZ3ChlsBS1YonuTE0r2Q==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-client-common/-/analytics-client-common-2.2.1.tgz", + "integrity": "sha512-JXpLjKgP7LiBMZF5eMjtiPiSPW8FxvF4bHubDg26Ck2buBUQvrBq6D4VyOky0m1zG7WA4vOoLANu3sWfF02/7Q==", "requires": { "@amplitude/analytics-connector": "^1.4.8", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-core": "^2.2.8", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" }, "dependencies": { @@ -17942,11 +18014,11 @@ "integrity": "sha512-T8mOYzB9RRxckzhL0NTHwdge9xuFxXEOplC8B1Y3UX3NHa3BLh7DlBUZlCOwQgMc2nxDfnSweDL5S3bhC+W90g==" }, "@amplitude/analytics-core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.3.tgz", - "integrity": "sha512-rtA7TSqie6Jgcvax3tEHaZUzOJM5Hdd5/+JYFIJK2gPgHsWZj3jDF75fL8BSn4uBiA2zcZ0vbCHORMVqXg5pRw==", + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-core/-/analytics-core-2.2.8.tgz", + "integrity": "sha512-T4ZFk1LUD+4z02XMSWK4qPvMREUTgNtEoYQc6BvNyfOx1Ih21qyJLFcdSw05gL26JuuuYZWFkpHxxKm8IoZh8Q==", "requires": { - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" }, "dependencies": { @@ -17958,35 +18030,17 @@ } }, "@amplitude/analytics-types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.0.tgz", - "integrity": "sha512-aY69WxUvVlaCU+9geShjTsAYdUTvegEXH9i4WK/97kNbNLl4/7qUuIPe4hNireDeKLuQA9SA3H7TKynuNomDxw==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@amplitude/analytics-types/-/analytics-types-2.5.1.tgz", + "integrity": "sha512-xGuLiHRLv5z3RSAHiICjzHK4TjUZJ7aHr/jM0XhSgD/V1YdmG/s8y1UAWGI2Stsxm2x0DWNOyEpjYkGohlnXtA==" }, "@amplitude/plugin-page-view-tracking-browser": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.5.tgz", - "integrity": "sha512-uhX1bP57DrvkV3KYWR0NwyTTSBXU3m+LbwBm/0vm4YRLLM1I8dEle+Wb3mN3inbIYOOVyEd3ARR+NS8Xf/hEeQ==", - "requires": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-types": "^2.5.0", - "tslib": "^2.4.1" - }, - "dependencies": { - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - } - } - }, - "@amplitude/plugin-web-attribution-browser": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@amplitude/plugin-web-attribution-browser/-/plugin-web-attribution-browser-2.1.6.tgz", - "integrity": "sha512-3Nds/vfLTBXFi5rLOUF78TL2OkzBAXzJuslSFfSHl7C8psGcpkWTnWcxPakfLHuev3yteknCkWaevdio+GMljg==", + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/@amplitude/plugin-page-view-tracking-browser/-/plugin-page-view-tracking-browser-2.2.13.tgz", + "integrity": "sha512-EYvG4RTyNqIGlq3J+UnrTRRj75xp3nOSETeInPQbnHhiPaCzxTjWrb9URkzy2IYSyBSn4KEQkZegmzhWXxlvvw==", "requires": { - "@amplitude/analytics-client-common": "^2.1.2", - "@amplitude/analytics-core": "^2.2.3", - "@amplitude/analytics-types": "^2.5.0", + "@amplitude/analytics-client-common": "^2.2.1", + "@amplitude/analytics-types": "^2.5.1", "tslib": "^2.4.1" }, "dependencies": { @@ -18018,34 +18072,34 @@ } }, "@babel/code-frame": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz", - "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", + "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", "requires": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.6", "picocolors": "^1.0.0" } }, "@babel/compat-data": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz", - "integrity": "sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", + "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==" }, "@babel/core": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz", - "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", + "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", "requires": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.1", - "@babel/parser": "^7.24.1", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helpers": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/traverse": "^7.24.6", + "@babel/types": "^7.24.6", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -18061,40 +18115,40 @@ } }, "@babel/generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.1.tgz", - "integrity": "sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", + "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", "requires": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, "@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", + "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz", + "integrity": "sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==", "dev": true, "requires": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.24.6" } }, "@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", + "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", "requires": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", + "@babel/compat-data": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", "browserslist": "^4.22.2", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -18116,29 +18170,29 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.1.tgz", - "integrity": "sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz", + "integrity": "sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "semver": "^6.3.1" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz", + "integrity": "sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-annotate-as-pure": "^7.24.6", "regexpu-core": "^5.3.1", "semver": "^6.3.1" } @@ -18157,197 +18211,206 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz", + "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==" }, "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz", + "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==", "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" } }, "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", + "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz", + "integrity": "sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==", "dev": true, "requires": { - "@babel/types": "^7.23.0" + "@babel/types": "^7.24.6" } }, "@babel/helper-module-imports": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz", - "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", + "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", "requires": { - "@babel/types": "^7.24.0" + "@babel/types": "^7.24.6" } }, "@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", + "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" } }, "@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz", + "integrity": "sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", + "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==" }, "@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz", + "integrity": "sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-wrap-function": "^7.24.6" } }, "@babel/helper-replace-supers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz", - "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz", + "integrity": "sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6" } }, "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", + "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz", + "integrity": "sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", + "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.6" } }, "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", + "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==" }, "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", + "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==" }, "@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", + "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==" }, "@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz", + "integrity": "sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/helper-function-name": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" } }, "@babel/helpers": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.1.tgz", - "integrity": "sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", + "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", "requires": { - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" } }, "@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", + "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", "requires": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.6", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "@babel/parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz", - "integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==" + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", + "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==" + }, + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.6.tgz", + "integrity": "sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + } }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz", - "integrity": "sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.6.tgz", + "integrity": "sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz", - "integrity": "sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.6.tgz", + "integrity": "sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6" } }, "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz", - "integrity": "sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.6.tgz", + "integrity": "sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-proposal-private-property-in-object": { @@ -18412,21 +18475,21 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz", - "integrity": "sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz", + "integrity": "sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-syntax-import-attributes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz", - "integrity": "sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz", + "integrity": "sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-syntax-import-meta": { @@ -18548,401 +18611,401 @@ } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz", - "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz", + "integrity": "sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-async-generator-functions": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz", - "integrity": "sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.6.tgz", + "integrity": "sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6", "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz", - "integrity": "sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.6.tgz", + "integrity": "sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz", - "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz", + "integrity": "sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.1.tgz", - "integrity": "sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz", + "integrity": "sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-class-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz", - "integrity": "sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz", + "integrity": "sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-class-static-block": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.1.tgz", - "integrity": "sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz", + "integrity": "sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz", + "integrity": "sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz", - "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz", + "integrity": "sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/template": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/template": "^7.24.6" } }, "@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz", + "integrity": "sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz", - "integrity": "sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz", + "integrity": "sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz", - "integrity": "sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz", + "integrity": "sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-dynamic-import": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz", - "integrity": "sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz", + "integrity": "sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz", - "integrity": "sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz", + "integrity": "sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-export-namespace-from": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz", - "integrity": "sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz", + "integrity": "sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-transform-for-of": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz", - "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz", + "integrity": "sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" } }, "@babel/plugin-transform-function-name": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz", - "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz", + "integrity": "sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-json-strings": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz", - "integrity": "sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz", + "integrity": "sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-transform-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz", - "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz", + "integrity": "sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz", - "integrity": "sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz", + "integrity": "sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz", - "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz", + "integrity": "sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz", - "integrity": "sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz", + "integrity": "sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz", - "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz", + "integrity": "sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz", - "integrity": "sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz", + "integrity": "sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz", - "integrity": "sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz", + "integrity": "sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz", + "integrity": "sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-new-target": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz", - "integrity": "sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz", + "integrity": "sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz", - "integrity": "sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz", + "integrity": "sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-transform-numeric-separator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz", - "integrity": "sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz", + "integrity": "sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz", + "integrity": "sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==", "dev": true, "requires": { - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" + "@babel/plugin-transform-parameters": "^7.24.6" } }, "@babel/plugin-transform-object-super": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz", - "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz", + "integrity": "sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-replace-supers": "^7.24.1" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6" } }, "@babel/plugin-transform-optional-catch-binding": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz", - "integrity": "sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz", + "integrity": "sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz", + "integrity": "sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz", + "integrity": "sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-private-methods": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz", - "integrity": "sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz", + "integrity": "sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz", + "integrity": "sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, "@babel/plugin-transform-property-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz", - "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz", + "integrity": "sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-regenerator": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz", - "integrity": "sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz", + "integrity": "sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.6", "regenerator-transform": "^0.15.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz", - "integrity": "sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz", + "integrity": "sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-runtime": { @@ -18970,111 +19033,112 @@ } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz", - "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz", + "integrity": "sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz", - "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz", + "integrity": "sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz", - "integrity": "sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz", + "integrity": "sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-template-literals": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz", - "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz", + "integrity": "sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz", + "integrity": "sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz", - "integrity": "sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz", + "integrity": "sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-unicode-property-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz", - "integrity": "sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz", + "integrity": "sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz", - "integrity": "sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz", + "integrity": "sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/plugin-transform-unicode-sets-regex": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz", - "integrity": "sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz", + "integrity": "sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" } }, "@babel/preset-env": { - "version": "7.24.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.3.tgz", - "integrity": "sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.24.1", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.6.tgz", + "integrity": "sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.6", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.24.1", - "@babel/plugin-syntax-import-attributes": "^7.24.1", + "@babel/plugin-syntax-import-assertions": "^7.24.6", + "@babel/plugin-syntax-import-attributes": "^7.24.6", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -19086,54 +19150,54 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.24.1", - "@babel/plugin-transform-async-generator-functions": "^7.24.3", - "@babel/plugin-transform-async-to-generator": "^7.24.1", - "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.1", - "@babel/plugin-transform-class-properties": "^7.24.1", - "@babel/plugin-transform-class-static-block": "^7.24.1", - "@babel/plugin-transform-classes": "^7.24.1", - "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", - "@babel/plugin-transform-dotall-regex": "^7.24.1", - "@babel/plugin-transform-duplicate-keys": "^7.24.1", - "@babel/plugin-transform-dynamic-import": "^7.24.1", - "@babel/plugin-transform-exponentiation-operator": "^7.24.1", - "@babel/plugin-transform-export-namespace-from": "^7.24.1", - "@babel/plugin-transform-for-of": "^7.24.1", - "@babel/plugin-transform-function-name": "^7.24.1", - "@babel/plugin-transform-json-strings": "^7.24.1", - "@babel/plugin-transform-literals": "^7.24.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.24.1", - "@babel/plugin-transform-member-expression-literals": "^7.24.1", - "@babel/plugin-transform-modules-amd": "^7.24.1", - "@babel/plugin-transform-modules-commonjs": "^7.24.1", - "@babel/plugin-transform-modules-systemjs": "^7.24.1", - "@babel/plugin-transform-modules-umd": "^7.24.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.24.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", - "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", - "@babel/plugin-transform-object-super": "^7.24.1", - "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", - "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", - "@babel/plugin-transform-property-literals": "^7.24.1", - "@babel/plugin-transform-regenerator": "^7.24.1", - "@babel/plugin-transform-reserved-words": "^7.24.1", - "@babel/plugin-transform-shorthand-properties": "^7.24.1", - "@babel/plugin-transform-spread": "^7.24.1", - "@babel/plugin-transform-sticky-regex": "^7.24.1", - "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", - "@babel/plugin-transform-unicode-escapes": "^7.24.1", - "@babel/plugin-transform-unicode-property-regex": "^7.24.1", - "@babel/plugin-transform-unicode-regex": "^7.24.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.24.1", + "@babel/plugin-transform-arrow-functions": "^7.24.6", + "@babel/plugin-transform-async-generator-functions": "^7.24.6", + "@babel/plugin-transform-async-to-generator": "^7.24.6", + "@babel/plugin-transform-block-scoped-functions": "^7.24.6", + "@babel/plugin-transform-block-scoping": "^7.24.6", + "@babel/plugin-transform-class-properties": "^7.24.6", + "@babel/plugin-transform-class-static-block": "^7.24.6", + "@babel/plugin-transform-classes": "^7.24.6", + "@babel/plugin-transform-computed-properties": "^7.24.6", + "@babel/plugin-transform-destructuring": "^7.24.6", + "@babel/plugin-transform-dotall-regex": "^7.24.6", + "@babel/plugin-transform-duplicate-keys": "^7.24.6", + "@babel/plugin-transform-dynamic-import": "^7.24.6", + "@babel/plugin-transform-exponentiation-operator": "^7.24.6", + "@babel/plugin-transform-export-namespace-from": "^7.24.6", + "@babel/plugin-transform-for-of": "^7.24.6", + "@babel/plugin-transform-function-name": "^7.24.6", + "@babel/plugin-transform-json-strings": "^7.24.6", + "@babel/plugin-transform-literals": "^7.24.6", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.6", + "@babel/plugin-transform-member-expression-literals": "^7.24.6", + "@babel/plugin-transform-modules-amd": "^7.24.6", + "@babel/plugin-transform-modules-commonjs": "^7.24.6", + "@babel/plugin-transform-modules-systemjs": "^7.24.6", + "@babel/plugin-transform-modules-umd": "^7.24.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.6", + "@babel/plugin-transform-new-target": "^7.24.6", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.6", + "@babel/plugin-transform-numeric-separator": "^7.24.6", + "@babel/plugin-transform-object-rest-spread": "^7.24.6", + "@babel/plugin-transform-object-super": "^7.24.6", + "@babel/plugin-transform-optional-catch-binding": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6", + "@babel/plugin-transform-parameters": "^7.24.6", + "@babel/plugin-transform-private-methods": "^7.24.6", + "@babel/plugin-transform-private-property-in-object": "^7.24.6", + "@babel/plugin-transform-property-literals": "^7.24.6", + "@babel/plugin-transform-regenerator": "^7.24.6", + "@babel/plugin-transform-reserved-words": "^7.24.6", + "@babel/plugin-transform-shorthand-properties": "^7.24.6", + "@babel/plugin-transform-spread": "^7.24.6", + "@babel/plugin-transform-sticky-regex": "^7.24.6", + "@babel/plugin-transform-template-literals": "^7.24.6", + "@babel/plugin-transform-typeof-symbol": "^7.24.6", + "@babel/plugin-transform-unicode-escapes": "^7.24.6", + "@babel/plugin-transform-unicode-property-regex": "^7.24.6", + "@babel/plugin-transform-unicode-regex": "^7.24.6", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.6", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", "babel-plugin-polyfill-corejs3": "^0.10.4", @@ -19203,39 +19267,39 @@ } }, "@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", + "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6" } }, "@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", - "requires": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", + "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "requires": { + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6", "debug": "^4.3.1", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", + "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6", "to-fast-properties": "^2.0.0" } }, @@ -19585,9 +19649,9 @@ } }, "@fortawesome/fontawesome-free": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz", - "integrity": "sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==" + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz", + "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==" }, "@humanwhocodes/config-array": { "version": "0.11.14", @@ -20236,6 +20300,14 @@ "fastq": "^1.6.0" } }, + "@rrweb/types": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/@rrweb/types/-/types-2.0.0-alpha.14.tgz", + "integrity": "sha512-H0qKW75SdsZM4/4116fQDDC3QkUxbP7A9AY5PK2nyUV56KReAQ1sH8ZHu9tomvn0kFJUXhtvjv2H6G6xxSJNqA==", + "requires": { + "rrweb-snapshot": "^2.0.0-alpha.14" + } + }, "@scure/base": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.5.tgz", @@ -20374,6 +20446,11 @@ "@types/responselike": "^1.0.0" } }, + "@types/css-font-loading-module": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", + "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==" + }, "@types/eslint": { "version": "8.4.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz", @@ -20927,6 +21004,11 @@ "dev": true, "requires": {} }, + "@xstate/fsm": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-1.6.5.tgz", + "integrity": "sha512-b5o1I6aLNeYlU/3CPlj/Z91ybk1gUsKT+5NAJI+2W4UjvS5KLG28K9v5UvNoFVjHV8PajVZ00RH3vnjyQO7ZAw==" + }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -21539,6 +21621,11 @@ "safe-buffer": "^5.0.1" } }, + "base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -21972,9 +22059,9 @@ "dev": true }, "chart.js": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz", - "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz", + "integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==", "requires": { "@kurkle/color": "^0.3.0" } @@ -22270,9 +22357,9 @@ } }, "core-js": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz", - "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==" + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz", + "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==" }, "core-js-compat": { "version": "3.36.1", @@ -22481,23 +22568,23 @@ "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" }, "css-declaration-sorter": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.1.1.tgz", - "integrity": "sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==", + "version": "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==", "dev": true, "requires": {} }, "css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.1.tgz", + "integrity": "sha512-OxIR5P2mjO1PSXk44bWuQ8XtMK4dpEqpIyERCx3ewOo3I8EmbcxMPUc5ScLtQfgXtOojoMv57So4V/C02HQLsw==", "dev": true, "requires": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.5.4" @@ -22515,15 +22602,15 @@ } }, "css-minimizer-webpack-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-6.0.0.tgz", - "integrity": "sha512-BLpR9CCDkKvhO3i0oZQgad6v9pCxUuhSc5RT6iUEy9M8hBXi4TJb5vqF2GQ2deqYHmRi3O6IR9hgAZQWg0EBwA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.0.tgz", + "integrity": "sha512-niy66jxsQHqO+EYbhPuIhqRQ1mNcNVUHrMnkzzir9kFOERJUaQDDRhh7dKDz33kBpkWMF9M8Vx0QlDbc5AHOsw==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.21", - "cssnano": "^6.0.3", + "@jridgewell/trace-mapping": "^0.3.25", + "cssnano": "^7.0.1", "jest-worker": "^29.7.0", - "postcss": "^8.4.33", + "postcss": "^8.4.38", "schema-utils": "^4.2.0", "serialize-javascript": "^6.0.2" }, @@ -22608,56 +22695,57 @@ "integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4=" }, "cssnano": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.0.3.tgz", - "integrity": "sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.1.tgz", + "integrity": "sha512-917Mej/4SdI7b55atsli3sU4MOJ9XDoKgnlCtQtXYj8XUFcM3riTuYHyqBBnnskawW+zWwp0KxJzpEUodlpqUg==", "dev": true, "requires": { - "cssnano-preset-default": "^6.0.3", - "lilconfig": "^3.0.0" + "cssnano-preset-default": "^7.0.1", + "lilconfig": "^3.1.1" } }, "cssnano-preset-default": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.0.3.tgz", - "integrity": "sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^7.1.1", - "cssnano-utils": "^4.0.1", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.0.2", - "postcss-convert-values": "^6.0.2", - "postcss-discard-comments": "^6.0.1", - "postcss-discard-duplicates": "^6.0.1", - "postcss-discard-empty": "^6.0.1", - "postcss-discard-overridden": "^6.0.1", - "postcss-merge-longhand": "^6.0.2", - "postcss-merge-rules": "^6.0.3", - "postcss-minify-font-values": "^6.0.1", - "postcss-minify-gradients": "^6.0.1", - "postcss-minify-params": "^6.0.2", - "postcss-minify-selectors": "^6.0.2", - "postcss-normalize-charset": "^6.0.1", - "postcss-normalize-display-values": "^6.0.1", - "postcss-normalize-positions": "^6.0.1", - "postcss-normalize-repeat-style": "^6.0.1", - "postcss-normalize-string": "^6.0.1", - "postcss-normalize-timing-functions": "^6.0.1", - "postcss-normalize-unicode": "^6.0.2", - "postcss-normalize-url": "^6.0.1", - "postcss-normalize-whitespace": "^6.0.1", - "postcss-ordered-values": "^6.0.1", - "postcss-reduce-initial": "^6.0.2", - "postcss-reduce-transforms": "^6.0.1", - "postcss-svgo": "^6.0.2", - "postcss-unique-selectors": "^6.0.2" + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.1.tgz", + "integrity": "sha512-Fumyr+uZMcjYQeuHssAZxn0cKj3cdQc5GcxkBcmEzISGB+UW9CLNlU4tBOJbJGcPukFDlicG32eFbrc8K9V5pw==", + "dev": true, + "requires": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.0", + "postcss-calc": "^10.0.0", + "postcss-colormin": "^7.0.0", + "postcss-convert-values": "^7.0.0", + "postcss-discard-comments": "^7.0.0", + "postcss-discard-duplicates": "^7.0.0", + "postcss-discard-empty": "^7.0.0", + "postcss-discard-overridden": "^7.0.0", + "postcss-merge-longhand": "^7.0.0", + "postcss-merge-rules": "^7.0.0", + "postcss-minify-font-values": "^7.0.0", + "postcss-minify-gradients": "^7.0.0", + "postcss-minify-params": "^7.0.0", + "postcss-minify-selectors": "^7.0.0", + "postcss-normalize-charset": "^7.0.0", + "postcss-normalize-display-values": "^7.0.0", + "postcss-normalize-positions": "^7.0.0", + "postcss-normalize-repeat-style": "^7.0.0", + "postcss-normalize-string": "^7.0.0", + "postcss-normalize-timing-functions": "^7.0.0", + "postcss-normalize-unicode": "^7.0.0", + "postcss-normalize-url": "^7.0.0", + "postcss-normalize-whitespace": "^7.0.0", + "postcss-ordered-values": "^7.0.0", + "postcss-reduce-initial": "^7.0.0", + "postcss-reduce-transforms": "^7.0.0", + "postcss-svgo": "^7.0.0", + "postcss-unique-selectors": "^7.0.0" } }, "cssnano-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.1.tgz", - "integrity": "sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.0.tgz", + "integrity": "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==", "dev": true, "requires": {} }, @@ -23663,9 +23751,9 @@ } }, "eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.2.0.tgz", + "integrity": "sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA==", "dev": true, "requires": {} }, @@ -24515,6 +24603,11 @@ "bser": "2.1.1" } }, + "fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==" + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -27177,9 +27270,9 @@ } }, "lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", "dev": true }, "lines-and-columns": { @@ -27588,9 +27681,9 @@ } }, "mini-css-extract-plugin": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", - "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, "requires": { "schema-utils": "^4.0.0", @@ -27645,10 +27738,18 @@ "minipass": "^2.9.0" } }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, "mixpanel-browser": { - "version": "2.49.0", - "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.49.0.tgz", - "integrity": "sha512-RZJCO7XXuuHBAWG5fd9Mavz994M7v7W3Qiaq8NzmN631pa4BQ0vNZQtRFqKcCCOBn4xqOZbX2GkuC7ZkQoL4cQ==" + "version": "2.51.0", + "resolved": "https://registry.npmjs.org/mixpanel-browser/-/mixpanel-browser-2.51.0.tgz", + "integrity": "sha512-cNjvvhlRkSlqW1w4nxRpK5y4R3QcfhY7H/ZfvZ4jLeiBUNeeuwyQTgOAk/mYiBDOonWEdeN7h3EkL2BdqKd2Sw==", + "requires": { + "rrweb": "2.0.0-alpha.13" + } }, "mkdirp": { "version": "3.0.1", @@ -28269,62 +28370,62 @@ } }, "postcss-calc": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.0.0.tgz", + "integrity": "sha512-OmjhudoNTP0QleZCwl1i6NeBwN+5MZbY5ersLZz69mjJiDVv/p57RjRuKDkHeDWr4T+S97wQfsqRTNoDHB2e3g==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.11", + "postcss-selector-parser": "^6.0.16", "postcss-value-parser": "^4.2.0" } }, "postcss-colormin": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.0.2.tgz", - "integrity": "sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.0.tgz", + "integrity": "sha512-5CN6fqtsEtEtwf3mFV3B4UaZnlYljPpzmGeDB4yCK067PnAtfLe9uX2aFZaEwxHE7HopG5rUkW8gyHrNAesHEg==", "dev": true, "requires": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "colord": "^2.9.1", + "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" } }, "postcss-convert-values": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.0.2.tgz", - "integrity": "sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.0.tgz", + "integrity": "sha512-bMuzDgXBbFbByPgj+/r6va8zNuIDUaIIbvAFgdO1t3zdgJZ77BZvu6dfWyd6gHEJnYzmeVr9ayUsAQL3/qLJ0w==", "dev": true, "requires": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" } }, "postcss-discard-comments": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.1.tgz", - "integrity": "sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.0.tgz", + "integrity": "sha512-xpSdzRqYmy4YIVmjfGyYXKaI1SRnK6CTr+4Zmvyof8ANwvgfZgGdVtmgAvzh59gJm808mJCWQC9tFN0KF5dEXA==", "dev": true, "requires": {} }, "postcss-discard-duplicates": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.1.tgz", - "integrity": "sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.0.tgz", + "integrity": "sha512-bAnSuBop5LpAIUmmOSsuvtKAAKREB6BBIYStWUTGq8oG5q9fClDMMuY8i4UPI/cEcDx2TN+7PMnXYIId20UVDw==", "dev": true, "requires": {} }, "postcss-discard-empty": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.1.tgz", - "integrity": "sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.0.tgz", + "integrity": "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==", "dev": true, "requires": {} }, "postcss-discard-overridden": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.1.tgz", - "integrity": "sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.0.tgz", + "integrity": "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==", "dev": true, "requires": {} }, @@ -28351,78 +28452,78 @@ } }, "postcss-merge-longhand": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.2.tgz", - "integrity": "sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.0.tgz", + "integrity": "sha512-0X8I4/9+G03X5/5NnrfopG/YEln2XU8heDh7YqBaiq2SeaKIG3n66ShZPjIolmVuLBQ0BEm3yS8o1mlCLHdW7A==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^6.0.2" + "stylehacks": "^7.0.0" } }, "postcss-merge-rules": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.0.3.tgz", - "integrity": "sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.0.tgz", + "integrity": "sha512-Zty3VlOsD6VSjBMu6PiHCVpLegtBT/qtZRVBcSeyEZ6q1iU5qTYT0WtEoLRV+YubZZguS5/ycfP+NRiKfjv6aw==", "dev": true, "requires": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "cssnano-utils": "^4.0.1", - "postcss-selector-parser": "^6.0.15" + "cssnano-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.16" } }, "postcss-minify-font-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.0.1.tgz", - "integrity": "sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.0.tgz", + "integrity": "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-minify-gradients": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.1.tgz", - "integrity": "sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.0.tgz", + "integrity": "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==", "dev": true, "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^4.0.1", + "colord": "^2.9.3", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" } }, "postcss-minify-params": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.0.2.tgz", - "integrity": "sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.0.tgz", + "integrity": "sha512-XOJAuX8Q/9GT1sGxlUvaFEe2H9n50bniLZblXXsAT/BwSfFYvzSZeFG7uupwc0KbKpTnflnQ7aMwGzX6JUWliQ==", "dev": true, "requires": { - "browserslist": "^4.22.2", - "cssnano-utils": "^4.0.1", + "browserslist": "^4.23.0", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" } }, "postcss-minify-selectors": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.2.tgz", - "integrity": "sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.0.tgz", + "integrity": "sha512-f00CExZhD6lNw2vTZbcnmfxVgaVKzUw6IRsIFX3JTT8GdsoABc1WnhhGwL1i8YPJ3sSWw39fv7XPtvLb+3Uitw==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.15" + "postcss-selector-parser": "^6.0.16" } }, "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, "requires": {} }, "postcss-modules-local-by-default": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dev": true, "requires": { "icss-utils": "^5.0.0", @@ -28431,9 +28532,9 @@ } }, "postcss-modules-scope": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", - "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dev": true, "requires": { "postcss-selector-parser": "^6.0.4" @@ -28449,118 +28550,118 @@ } }, "postcss-normalize-charset": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.1.tgz", - "integrity": "sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz", + "integrity": "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==", "dev": true, "requires": {} }, "postcss-normalize-display-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.1.tgz", - "integrity": "sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.0.tgz", + "integrity": "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-positions": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.1.tgz", - "integrity": "sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.0.tgz", + "integrity": "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-repeat-style": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.1.tgz", - "integrity": "sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.0.tgz", + "integrity": "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-string": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.1.tgz", - "integrity": "sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.0.tgz", + "integrity": "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-timing-functions": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.1.tgz", - "integrity": "sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.0.tgz", + "integrity": "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-unicode": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.2.tgz", - "integrity": "sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.0.tgz", + "integrity": "sha512-OnKV52/VFFDAim4n0pdI+JAhsolLBdnCKxE6VV5lW5Q/JeVGFN8UM8ur6/A3EAMLsT1ZRm3fDHh/rBoBQpqi2w==", "dev": true, "requires": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-url": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.1.tgz", - "integrity": "sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.0.tgz", + "integrity": "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-normalize-whitespace": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.1.tgz", - "integrity": "sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.0.tgz", + "integrity": "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-ordered-values": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.1.tgz", - "integrity": "sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.0.tgz", + "integrity": "sha512-KROvC63A8UQW1eYDljQe1dtwc1E/M+mMwDT6z7khV/weHYLWTghaLRLunU7x1xw85lWFwVZOAGakxekYvKV+0w==", "dev": true, "requires": { - "cssnano-utils": "^4.0.1", + "cssnano-utils": "^5.0.0", "postcss-value-parser": "^4.2.0" } }, "postcss-reduce-initial": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.0.2.tgz", - "integrity": "sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.0.tgz", + "integrity": "sha512-iqGgmBxY9LrblZ0BKLjmrA1mC/cf9A/wYCCqSmD6tMi+xAyVl0+DfixZIHSVDMbCPRPjNmVF0DFGth/IDGelFQ==", "dev": true, "requires": { - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0" } }, "postcss-reduce-transforms": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.1.tgz", - "integrity": "sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.0.tgz", + "integrity": "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -28568,9 +28669,9 @@ } }, "postcss-svgo": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.2.tgz", - "integrity": "sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.0.tgz", + "integrity": "sha512-Xj5DRdvA97yRy3wjbCH2NKXtDUwEnph6EHr5ZXszsBVKCNrKXYBjzAXqav7/Afz5WwJ/1peZoTguCEJIg7ytmA==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0", @@ -28578,12 +28679,12 @@ } }, "postcss-unique-selectors": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.2.tgz", - "integrity": "sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.0.tgz", + "integrity": "sha512-NYFqcft7vVQMZlQPsMdMPy+qU/zDpy95Malpw4GeA9ZZjM6dVXDshXtDmLc0m4WCD6XeZCJqjTfPT1USsdt+rA==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.15" + "postcss-selector-parser": "^6.0.16" } }, "postcss-value-parser": { @@ -29220,6 +29321,34 @@ "bn.js": "^5.2.0" } }, + "rrdom": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/rrdom/-/rrdom-2.0.0-alpha.14.tgz", + "integrity": "sha512-aEDi8MNfKWRnWHM1Mhfx535EtHHYHg6L17PC3rvMUJMgHLcyMQsmI+OMeWt5RzXw1J2fdwhMV0grpp5VDTqRaA==", + "requires": { + "rrweb-snapshot": "^2.0.0-alpha.14" + } + }, + "rrweb": { + "version": "2.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/rrweb/-/rrweb-2.0.0-alpha.13.tgz", + "integrity": "sha512-a8GXOCnzWHNaVZPa7hsrLZtNZ3CGjiL+YrkpLo0TfmxGLhjNZbWY2r7pE06p+FcjFNlgUVTmFrSJbK3kO7yxvw==", + "requires": { + "@rrweb/types": "^2.0.0-alpha.13", + "@types/css-font-loading-module": "0.0.7", + "@xstate/fsm": "^1.4.0", + "base64-arraybuffer": "^1.0.1", + "fflate": "^0.4.4", + "mitt": "^3.0.0", + "rrdom": "^2.0.0-alpha.13", + "rrweb-snapshot": "^2.0.0-alpha.13" + } + }, + "rrweb-snapshot": { + "version": "2.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/rrweb-snapshot/-/rrweb-snapshot-2.0.0-alpha.14.tgz", + "integrity": "sha512-HuJd7iZauzhf7XI5FFtCGeUXkHk1mgc8yvH9Km9zB09Yk2cr0bW4eKx9fWQhRFiry9yXf/vOMkUy403xTLPIrQ==" + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -29805,9 +29934,9 @@ "dev": true }, "style-loader": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.4.tgz", - "integrity": "sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "dev": true, "requires": {} }, @@ -29829,13 +29958,13 @@ } }, "stylehacks": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.0.2.tgz", - "integrity": "sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.0.tgz", + "integrity": "sha512-47Nw4pQ6QJb4CA6dzF2m9810sjQik4dfk4UwAm5wlwhrW3syzZKF8AR4/cfO3Cr6lsFgAoznQq0Wg57qhjTA2A==", "dev": true, "requires": { - "browserslist": "^4.22.2", - "postcss-selector-parser": "^6.0.15" + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" } }, "supports-color": { @@ -29852,9 +29981,9 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, "svgo": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", - "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dev": true, "requires": { "@trysound/sax": "0.2.0", @@ -29937,9 +30066,9 @@ } }, "sweetalert2": { - "version": "11.10.7", - "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.7.tgz", - "integrity": "sha512-5Jlzrmaitay6KzU+2+LhYu9q+L4v/dZ8oZyEDH14ep0C/QilCnFLHmqAyD/Lhq/lm5DiwsOs6Tr58iv8k3wyGg==" + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.11.0.tgz", + "integrity": "sha512-wKCTtoE6lQVDKaJ5FFq+znk/YykJmJlD8RnLZps8C7DyivctCoRlVeeOwnKfgwKS+QJYon7s++3dmNi3/am1tw==" }, "symbol-tree": { "version": "3.2.4", diff --git a/apps/block_scout_web/assets/package.json b/apps/block_scout_web/assets/package.json index 5d5ae6ebae04..1bebf8a8ce42 100644 --- a/apps/block_scout_web/assets/package.json +++ b/apps/block_scout_web/assets/package.json @@ -19,17 +19,17 @@ "eslint": "eslint js/**" }, "dependencies": { - "@fortawesome/fontawesome-free": "^6.5.1", - "@amplitude/analytics-browser": "^2.6.1", + "@fortawesome/fontawesome-free": "^6.5.2", + "@amplitude/analytics-browser": "^2.8.1", "@tarekraafat/autocomplete.js": "^10.2.7", "@walletconnect/web3-provider": "^1.8.0", "assert": "^2.1.0", "bignumber.js": "^9.1.2", "bootstrap": "^4.6.0", - "chart.js": "^4.4.2", + "chart.js": "^4.4.3", "chartjs-adapter-luxon": "^1.3.1", "clipboard": "^2.0.11", - "core-js": "^3.36.1", + "core-js": "^3.37.1", "crypto-browserify": "^3.12.0", "dropzone": "^5.9.3", "eth-net-props": "^1.0.41", @@ -58,7 +58,7 @@ "lodash.reduce": "^4.6.0", "luxon": "^3.4.4", "malihu-custom-scrollbar-plugin": "3.1.5", - "mixpanel-browser": "^2.49.0", + "mixpanel-browser": "^2.51.0", "moment": "^2.30.1", "nanomorph": "^5.4.0", "numeral": "^2.0.6", @@ -73,7 +73,7 @@ "redux": "^5.0.1", "stream-browserify": "^3.0.0", "stream-http": "^3.1.1", - "sweetalert2": "^11.10.7", + "sweetalert2": "^11.11.0", "urijs": "^1.19.11", "url": "^0.11.3", "util": "^0.12.5", @@ -83,27 +83,27 @@ "xss": "^1.0.15" }, "devDependencies": { - "@babel/core": "^7.24.3", - "@babel/preset-env": "^7.24.3", + "@babel/core": "^7.24.6", + "@babel/preset-env": "^7.24.6", "autoprefixer": "^10.4.19", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", - "css-loader": "^6.10.0", - "css-minimizer-webpack-plugin": "^6.0.0", + "css-loader": "^7.1.1", + "css-minimizer-webpack-plugin": "^7.0.0", "eslint": "^8.57.0", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-promise": "^6.2.0", "file-loader": "^6.2.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "mini-css-extract-plugin": "^2.8.1", + "mini-css-extract-plugin": "^2.9.0", "postcss": "^8.4.38", "postcss-loader": "^8.1.1", "sass": "^1.72.0", "sass-loader": "^14.1.1", - "style-loader": "^3.3.4", + "style-loader": "^4.0.0", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" }, diff --git a/apps/block_scout_web/config/config.exs b/apps/block_scout_web/config/config.exs index aa3a4616a6a3..7467a51f3c1a 100644 --- a/apps/block_scout_web/config/config.exs +++ b/apps/block_scout_web/config/config.exs @@ -22,6 +22,9 @@ config :block_scout_web, config :block_scout_web, admin_panel_enabled: ConfigHelper.parse_bool_env_var("ADMIN_PANEL_ENABLED") +config :block_scout_web, + disable_api?: ConfigHelper.parse_bool_env_var("DISABLE_API") + config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true config :block_scout_web, BlockScoutWeb.Counters.InternalTransactionsIndexedCounter, enabled: true @@ -72,6 +75,12 @@ config :logger, :api_v2, block_number step count error_count shrunk import_id transaction_id)a, metadata_filter: [application: :api_v2] +config :prometheus, BlockScoutWeb.Prometheus.PublicExporter, + path: "/public-metrics", + format: :auto, + registry: :public, + auth: false + config :prometheus, BlockScoutWeb.Prometheus.PhoenixInstrumenter, # override default for Phoenix 1.4 compatibility # * `:transport_name` to `:transport` @@ -84,11 +93,11 @@ config :prometheus, BlockScoutWeb.Prometheus.PhoenixInstrumenter, config :spandex_phoenix, tracer: BlockScoutWeb.Tracer -config :block_scout_web, BlockScoutWeb.ApiRouter, +config :block_scout_web, BlockScoutWeb.Routers.ApiRouter, writing_enabled: !ConfigHelper.parse_bool_env_var("API_V1_WRITE_METHODS_DISABLED"), reading_enabled: !ConfigHelper.parse_bool_env_var("API_V1_READ_METHODS_DISABLED") -config :block_scout_web, BlockScoutWeb.WebRouter, enabled: !ConfigHelper.parse_bool_env_var("DISABLE_WEBAPP") +config :block_scout_web, BlockScoutWeb.Routers.WebRouter, enabled: !ConfigHelper.parse_bool_env_var("DISABLE_WEBAPP") config :block_scout_web, BlockScoutWeb.CSPHeader, mixpanel_url: System.get_env("MIXPANEL_URL", "https://api-js.mixpanel.com"), diff --git a/apps/block_scout_web/lib/block_scout_web.ex b/apps/block_scout_web/lib/block_scout_web.ex index c56ab8c116fa..7cdc6b3633c4 100644 --- a/apps/block_scout_web/lib/block_scout_web.ex +++ b/apps/block_scout_web/lib/block_scout_web.ex @@ -24,12 +24,13 @@ defmodule BlockScoutWeb do import BlockScoutWeb.Controller import BlockScoutWeb.Router.Helpers - import BlockScoutWeb.WebRouter.Helpers, except: [static_path: 2] + import BlockScoutWeb.Routers.WebRouter.Helpers, except: [static_path: 2] import BlockScoutWeb.Gettext import BlockScoutWeb.ErrorHelper + import BlockScoutWeb.Routers.AccountRouter.Helpers, except: [static_path: 2] import Plug.Conn - alias BlockScoutWeb.AdminRouter.Helpers, as: AdminRoutes + alias BlockScoutWeb.Routers.AdminRouter.Helpers, as: AdminRoutes end end @@ -56,9 +57,11 @@ defmodule BlockScoutWeb do WeiHelper } + import BlockScoutWeb.Routers.AccountRouter.Helpers, except: [static_path: 2] + import Explorer.Chain.CurrencyHelper, only: [divide_decimals: 2] - import BlockScoutWeb.WebRouter.Helpers, except: [static_path: 2] + import BlockScoutWeb.Routers.WebRouter.Helpers, except: [static_path: 2] end end diff --git a/apps/block_scout_web/lib/block_scout_web/application.ex b/apps/block_scout_web/lib/block_scout_web/application.ex index 6c33c11900a6..b96ea10c6fc3 100644 --- a/apps/block_scout_web/lib/block_scout_web/application.ex +++ b/apps/block_scout_web/lib/block_scout_web/application.ex @@ -5,46 +5,18 @@ defmodule BlockScoutWeb.Application do use Application - alias BlockScoutWeb.API.APILogger - alias BlockScoutWeb.Counters.{BlocksIndexedCounter, InternalTransactionsIndexedCounter} - alias BlockScoutWeb.Prometheus.{Exporter, PhoenixInstrumenter} - alias BlockScoutWeb.{Endpoint, MainPageRealtimeEventHandler, RealtimeEventHandler, SmartContractRealtimeEventHandler} - alias BlockScoutWeb.Utility.EventHandlersMetrics + alias BlockScoutWeb.Endpoint + alias BlockScoutWeb.Prometheus.Exporter, as: PrometheusExporter + alias BlockScoutWeb.Prometheus.PublicExporter, as: PrometheusPublicExporter def start(_type, _args) do - import Supervisor - - PhoenixInstrumenter.setup() - Exporter.setup() - - APILogger.message( - "Current global API rate limit #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit])} reqs/sec" - ) - - APILogger.message( - "Current API rate limit by key #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:limit_by_key])} reqs/sec" - ) - - APILogger.message( - "Current API rate limit by IP #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:limit_by_ip])} reqs/sec" - ) - - # Define workers and child supervisors to be supervised - children = [ - # Start the endpoint when the application starts - {Phoenix.PubSub, name: BlockScoutWeb.PubSub}, - child_spec(Endpoint, []), - {Absinthe.Subscription, Endpoint}, - {MainPageRealtimeEventHandler, name: MainPageRealtimeEventHandler}, - {RealtimeEventHandler, name: RealtimeEventHandler}, - {SmartContractRealtimeEventHandler, name: SmartContractRealtimeEventHandler}, - {BlocksIndexedCounter, name: BlocksIndexedCounter}, - {InternalTransactionsIndexedCounter, name: InternalTransactionsIndexedCounter}, - {EventHandlersMetrics, []} - ] - + base_children = [Supervisor.child_spec(Endpoint, [])] + api_children = setup_and_define_children() + all_children = base_children ++ api_children opts = [strategy: :one_for_one, name: BlockScoutWeb.Supervisor, max_restarts: 1_000] - Supervisor.start_link(children, opts) + PrometheusExporter.setup() + PrometheusPublicExporter.setup() + Supervisor.start_link(all_children, opts) end # Tell Phoenix to update the endpoint configuration @@ -53,4 +25,46 @@ defmodule BlockScoutWeb.Application do Endpoint.config_change(changed, removed) :ok end + + if Application.compile_env(:block_scout_web, :disable_api?) do + defp setup_and_define_children, do: [] + else + defp setup_and_define_children do + alias BlockScoutWeb.API.APILogger + alias BlockScoutWeb.Counters.{BlocksIndexedCounter, InternalTransactionsIndexedCounter} + alias BlockScoutWeb.Prometheus.{Exporter, PhoenixInstrumenter} + alias BlockScoutWeb.{MainPageRealtimeEventHandler, RealtimeEventHandler, SmartContractRealtimeEventHandler} + alias BlockScoutWeb.Utility.EventHandlersMetrics + alias Explorer.Chain.Metrics, as: ChainMetrics + + PhoenixInstrumenter.setup() + Exporter.setup() + + APILogger.message( + "Current global API rate limit #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:global_limit])} reqs/sec" + ) + + APILogger.message( + "Current API rate limit by key #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:limit_by_key])} reqs/sec" + ) + + APILogger.message( + "Current API rate limit by IP #{inspect(Application.get_env(:block_scout_web, :api_rate_limit)[:limit_by_ip])} reqs/sec" + ) + + # Define workers and child supervisors to be supervised + [ + # Start the endpoint when the application starts + {Phoenix.PubSub, name: BlockScoutWeb.PubSub}, + {Absinthe.Subscription, Endpoint}, + {MainPageRealtimeEventHandler, name: MainPageRealtimeEventHandler}, + {RealtimeEventHandler, name: RealtimeEventHandler}, + {SmartContractRealtimeEventHandler, name: SmartContractRealtimeEventHandler}, + {BlocksIndexedCounter, name: BlocksIndexedCounter}, + {InternalTransactionsIndexedCounter, name: InternalTransactionsIndexedCounter}, + {EventHandlersMetrics, []}, + {ChainMetrics, []} + ] + end + end end diff --git a/apps/block_scout_web/lib/block_scout_web/chain.ex b/apps/block_scout_web/lib/block_scout_web/chain.ex index 8125942f7f98..f17fc6b5d357 100644 --- a/apps/block_scout_web/lib/block_scout_web/chain.ex +++ b/apps/block_scout_web/lib/block_scout_web/chain.ex @@ -433,7 +433,11 @@ defmodule BlockScoutWeb.Chain do end end - # clause for Polygon Edge Deposits and Withdrawals and for account's entities pagination + # clause for pagination of entities: + # - Account's entities + # - Polygon Edge Deposits + # - Polygon Edge Withdrawals + # - Arbitrum cross chain messages def paging_options(%{"id" => id_string}) when is_binary(id_string) do case Integer.parse(id_string) do {id, ""} -> @@ -444,7 +448,11 @@ defmodule BlockScoutWeb.Chain do end end - # clause for Polygon Edge Deposits and Withdrawals and for account's entities pagination + # clause for pagination of entities: + # - Account's entities + # - Polygon Edge Deposits + # - Polygon Edge Withdrawals + # - Arbitrum cross chain messages def paging_options(%{"id" => id}) when is_integer(id) do [paging_options: %{@default_paging_options | key: {id}}] end diff --git a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex index 8f95108bb2be..4ea5943e0c4f 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/address_channel.ex @@ -146,6 +146,7 @@ defmodule BlockScoutWeb.AddressChannel do {:noreply, socket} end + # TODO: fix or remove, "internal_transaction.json" clause does not exist def handle_out( "internal_transaction", %{address: _address, internal_transaction: internal_transaction}, @@ -330,7 +331,19 @@ defmodule BlockScoutWeb.AddressChannel do event ) when is_list(transactions) do - transaction_json = TransactionViewAPI.render("transactions.json", %{transactions: transactions, conn: nil}) + transaction_json = + TransactionViewAPI.render("transactions.json", %{ + transactions: + transactions + |> Repo.preload([ + [ + from_address: [:names, :smart_contract, :proxy_implementations], + to_address: [:names, :smart_contract, :proxy_implementations], + created_contract_address: [:names, :smart_contract, :proxy_implementations] + ] + ]), + conn: nil + }) push(socket, event, %{transactions: transaction_json}) @@ -375,7 +388,17 @@ defmodule BlockScoutWeb.AddressChannel do ) when is_list(token_transfers) do token_transfer_json = - TransactionViewAPI.render("token_transfers.json", %{token_transfers: token_transfers, conn: nil}) + TransactionViewAPI.render("token_transfers.json", %{ + token_transfers: + token_transfers + |> Repo.preload([ + [ + from_address: [:names, :smart_contract, :proxy_implementations], + to_address: [:names, :smart_contract, :proxy_implementations] + ] + ]), + conn: nil + }) push(socket, event, %{token_transfers: token_transfer_json}) diff --git a/apps/block_scout_web/lib/block_scout_web/channels/block_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/block_channel.ex index 560a1d4d96c2..2340ab38121a 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/block_channel.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/block_channel.ex @@ -6,6 +6,7 @@ defmodule BlockScoutWeb.BlockChannel do alias BlockScoutWeb.API.V2.BlockView, as: BlockViewAPI alias BlockScoutWeb.{BlockView, ChainView} + alias Explorer.Repo alias Phoenix.View alias Timex.Duration @@ -24,7 +25,11 @@ defmodule BlockScoutWeb.BlockChannel do %{block: block, average_block_time: average_block_time}, %Phoenix.Socket{handler: BlockScoutWeb.UserSocketV2} = socket ) do - rendered_block = BlockViewAPI.render("block.json", %{block: block, socket: nil}) + rendered_block = + BlockViewAPI.render("block.json", %{ + block: block |> Repo.preload(miner: [:names, :smart_contract, :proxy_implementations]), + socket: nil + }) push(socket, "new_block", %{ average_block_time: to_string(Duration.to_milliseconds(average_block_time)), diff --git a/apps/block_scout_web/lib/block_scout_web/channels/token_instance_channel.ex b/apps/block_scout_web/lib/block_scout_web/channels/token_instance_channel.ex new file mode 100644 index 000000000000..5a556eb87434 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/channels/token_instance_channel.ex @@ -0,0 +1,26 @@ +defmodule BlockScoutWeb.TokenInstanceChannel do + @moduledoc """ + Establishes pub/sub channel for live updates of token instances events. + """ + use BlockScoutWeb, :channel + + intercept(["fetched_token_instance_metadata"]) + + def join("fetched_token_instance_metadata", _params, socket) do + {:ok, %{}, socket} + end + + def join("token_instances:" <> _token_contract_address_hash, _params, socket) do + {:ok, %{}, socket} + end + + def handle_out( + "fetched_token_instance_metadata", + res, + %Phoenix.Socket{handler: BlockScoutWeb.UserSocketV2} = socket + ) do + push(socket, "fetched_token_instance_metadata", res) + + {:noreply, socket} + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex b/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex index 7f1b4993a184..5d51597e359e 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/user_socket.ex @@ -9,6 +9,7 @@ defmodule BlockScoutWeb.UserSocket do channel("rewards:*", BlockScoutWeb.RewardChannel) channel("transactions:*", BlockScoutWeb.TransactionChannel) channel("tokens:*", BlockScoutWeb.TokenChannel) + channel("token_instances:*", BlockScoutWeb.TokenInstanceChannel) def connect(%{"locale" => locale}, socket) do {:ok, assign(socket, :locale, locale)} diff --git a/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex b/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex index 740b716dc322..8ac5295d60af 100644 --- a/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex +++ b/apps/block_scout_web/lib/block_scout_web/channels/user_socket_v2.ex @@ -11,6 +11,7 @@ defmodule BlockScoutWeb.UserSocketV2 do channel("rewards:*", BlockScoutWeb.RewardChannel) channel("transactions:*", BlockScoutWeb.TransactionChannel) channel("tokens:*", BlockScoutWeb.TokenChannel) + channel("token_instances:*", BlockScoutWeb.TokenInstanceChannel) channel("zkevm_batches:*", BlockScoutWeb.PolygonZkevmConfirmedBatchChannel) def connect(_params, socket) do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/admin/setup_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/admin/setup_controller.ex index 9005fe358723..1d0f82f4d696 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/admin/setup_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/admin/setup_controller.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.Admin.SetupController do use BlockScoutWeb, :controller - import BlockScoutWeb.AdminRouter.Helpers + import BlockScoutWeb.Routers.AdminRouter.Helpers alias BlockScoutWeb.Endpoint alias Explorer.Accounts.User.Registration diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex index 595b6116535b..c37f0c4e4bf4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/contract_controller.ex @@ -6,6 +6,7 @@ defmodule BlockScoutWeb.API.RPC.ContractController do alias BlockScoutWeb.API.RPC.{AddressController, Helper} alias Explorer.Chain alias Explorer.Chain.{Address, Hash, SmartContract} + alias Explorer.Chain.SmartContract.Proxy.Models.Implementation alias Explorer.Chain.SmartContract.Proxy.VerificationStatus, as: ProxyVerificationStatus alias Explorer.Chain.SmartContract.VerificationStatus alias Explorer.Etherscan.Contracts @@ -230,13 +231,13 @@ defmodule BlockScoutWeb.API.RPC.ContractController do api?: true ), {:not_found, false} <- {:not_found, is_nil(smart_contract)}, + implementation_updated_at <- Implementation.get_proxy_implementation_updated_at(address_hash, []), {:time_interval, true} <- - {:time_interval, - SmartContract.check_implementation_refetch_necessity(smart_contract.implementation_fetched_at)}, + {:time_interval, Implementation.check_implementation_refetch_necessity(implementation_updated_at)}, uid <- ProxyVerificationStatus.generate_uid(address_hash) do ProxyVerificationStatus.insert_status(uid, :pending, address_hash) - SmartContract.get_implementation_address_hash(smart_contract, + Implementation.get_implementation(smart_contract, timeout: 0, uid: uid, callback: &ProxyVerificationStatus.set_proxy_verification_result/2 @@ -254,7 +255,7 @@ defmodule BlockScoutWeb.API.RPC.ContractController do render(conn, :error, error: @restricted_access) {:time_interval, false} -> - render(conn, :error, error: "Only one attempt in #{SmartContract.get_fresh_time_distance()}ms") + render(conn, :error, error: "Only one attempt in #{Implementation.get_fresh_time_distance()}ms") end end @@ -266,9 +267,20 @@ defmodule BlockScoutWeb.API.RPC.ContractController do render(conn, :show, %{result: "Verification in progress"}) :pass -> + implementation_address_hashes = + Implementation.get_proxy_implementations(submission.contract_address_hash, []).address_hashes + + result = + if Enum.count(implementation_address_hashes) == 1 do + implementation_address_hash = Enum.at(implementation_address_hashes, 0) + + "The proxy's (#{submission.contract_address_hash}) implementation contract is found at #{implementation_address_hash} and is successfully updated." + else + "The proxy's (#{submission.contract_address_hash}) implementation contracts are found at #{inspect(implementation_address_hashes)} and they've been successfully updated." + end + render(conn, :show, %{ - result: - "The proxy's (#{submission.contract_address_hash}) implementation contract is found at #{SmartContract.address_hash_to_smart_contract(submission.contract_address_hash).implementation_address_hash} and is successfully updated." + result: result }) :fail -> @@ -586,11 +598,11 @@ defmodule BlockScoutWeb.API.RPC.ContractController do _ = PublishHelper.check_and_verify(Hash.to_string(address_hash)) result = - case SmartContract.address_hash_to_smart_contract(address_hash) do - nil -> + case SmartContract.address_hash_to_smart_contract_with_bytecode_twin(address_hash) do + {nil, _} -> :not_found - contract -> + {contract, _} -> {:ok, SmartContract.preload_decompiled_smart_contract(contract)} end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/rpc_translator.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/rpc_translator.ex index 0263abd96da9..17fd203f6cb9 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/rpc_translator.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/rpc_translator.ex @@ -110,7 +110,7 @@ defmodule BlockScoutWeb.API.RPC.RPCTranslator do end defp action_accessed?(action, write_actions) do - conf = Application.get_env(:block_scout_web, BlockScoutWeb.ApiRouter) + conf = Application.get_env(:block_scout_web, BlockScoutWeb.Routers.ApiRouter) if action in write_actions do conf[:writing_enabled] || {:error, :no_action} diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/health_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/health_controller.ex index f65bfcd3b5d9..991c4936ca10 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/health_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v1/health_controller.ex @@ -1,5 +1,7 @@ defmodule BlockScoutWeb.API.V1.HealthController do - use BlockScoutWeb, :controller + use Phoenix.Controller, namespace: BlockScoutWeb + + import Plug.Conn alias Explorer.Chain alias Timex.Duration diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex index 10c0d44a18d9..dd6a721d6bf2 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex @@ -36,23 +36,18 @@ defmodule BlockScoutWeb.API.V2.AddressController do @transaction_necessity_by_association [ necessity_by_association: %{ - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - :block => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + :block => :optional }, api?: true ] @token_transfer_necessity_by_association [ necessity_by_association: %{ - [to_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :names] => :optional, - [from_address: :names] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, :block => :optional, :transaction => :optional, :token => :optional @@ -63,7 +58,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do @address_options [ necessity_by_association: %{ :names => :optional, - :token => :optional + :token => :optional, + :proxy_implementations => :optional }, api?: true ] @@ -71,7 +67,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do @contract_address_preloads [ :smart_contract, :contracts_creation_internal_transaction, - :contracts_creation_transaction + :contracts_creation_transaction, + :proxy_implementations ] @nft_necessity_by_association [ @@ -171,10 +168,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do options = [ necessity_by_association: %{ - [to_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :names] => :optional, - [from_address: :names] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, :block => :optional, :token => :optional, :transaction => :optional @@ -245,12 +240,9 @@ defmodule BlockScoutWeb.API.V2.AddressController do full_options = [ necessity_by_association: %{ - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] |> Keyword.merge(paging_options(params)) @@ -279,7 +271,14 @@ defmodule BlockScoutWeb.API.V2.AddressController do formatted_topic = if String.starts_with?(prepared_topic, "0x"), do: prepared_topic, else: "0x" <> prepared_topic - options = params |> paging_options() |> Keyword.merge(topic: formatted_topic) |> Keyword.merge(@api_true) + options = + params + |> paging_options() + |> Keyword.merge(topic: formatted_topic) + |> Keyword.merge( + necessity_by_association: %{[address: [:names, :smart_contract, :proxy_implementations]] => :optional} + ) + |> Keyword.merge(@api_true) results_plus_one = Chain.address_to_logs(address_hash, false, options) @@ -322,6 +321,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do full_options = [ necessity_by_association: %{ + [miner: :proxy_implementations] => :optional, miner: :required, nephews: :optional, transactions: :optional, diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/advanced_filter_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/advanced_filter_controller.ex new file mode 100644 index 000000000000..a3c2f332a26f --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/advanced_filter_controller.ex @@ -0,0 +1,372 @@ +defmodule BlockScoutWeb.API.V2.AdvancedFilterController do + use BlockScoutWeb, :controller + + import BlockScoutWeb.Chain, only: [default_paging_options: 0, split_list_by_page: 1, next_page_params: 4] + + alias BlockScoutWeb.API.V2.{AdvancedFilterView, CSVExportController, TransactionView} + alias Explorer.{Chain, PagingOptions} + alias Explorer.Chain.{AdvancedFilter, ContractMethod, Data, Token, Transaction} + alias Explorer.Chain.CSVExport.Helper, as: CSVHelper + alias Plug.Conn + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @api_true [api?: true] + + @methods [ + %{method_id: "0xa9059cbb", name: "transfer"}, + %{method_id: "0xa0712d68", name: "mint"}, + %{method_id: "0x095ea7b3", name: "approve"}, + %{method_id: "0x40993b26", name: "buy"}, + %{method_id: "0x3593564c", name: "execute"}, + %{method_id: "0x3ccfd60b", name: "withdraw"}, + %{method_id: "0xd0e30db0", name: "deposit"}, + %{method_id: "0x0a19b14a", name: "trade"}, + %{method_id: "0x4420e486", name: "register"}, + %{method_id: "0x5f575529", name: "swap"}, + %{method_id: "0xd9627aa4", name: "sellToUniswap"}, + %{method_id: "0xe9e05c42", name: "depositTransaction"}, + %{method_id: "0x23b872dd", name: "transferFrom"}, + %{method_id: "0xa22cb465", name: "setApprovalForAll"}, + %{method_id: "0x2e7ba6ef", name: "claim"}, + %{method_id: "0x0502b1c5", name: "unoswap"}, + %{method_id: "0xb2267a7b", name: "sendMessage"}, + %{method_id: "0x9871efa4", name: "unxswapByOrderId"}, + %{method_id: "0xbf6eac2f", name: "stake"}, + %{method_id: "0x3ce33bff", name: "bridge"}, + %{method_id: "0xeb672419", name: "requestL2Transaction"}, + %{method_id: "0xe449022e", name: "uniswapV3Swap"}, + %{method_id: "0x0162e2d0", name: "swapETHForExactTokens"} + ] + + @methods_id_to_name_map Map.new(@methods, fn %{method_id: method_id, name: name} -> {method_id, name} end) + @methods_name_to_id_map Map.new(@methods, fn %{method_id: method_id, name: name} -> {name, method_id} end) + + @methods_filter_limit 20 + @tokens_filter_limit 20 + + @doc """ + Function responsible for `api/v2/advanced-filters/` endpoint. + """ + @spec list(Plug.Conn.t(), map()) :: Plug.Conn.t() + def list(conn, params) do + full_options = params |> extract_filters() |> Keyword.merge(paging_options(params)) |> Keyword.merge(@api_true) + + advanced_filters_plus_one = AdvancedFilter.list(full_options) + + {advanced_filters, next_page} = split_list_by_page(advanced_filters_plus_one) + + {decoded_transactions, _abi_acc, methods_acc} = + advanced_filters + |> Enum.map(fn af -> %Transaction{to_address: af.to_address, input: af.input, hash: af.hash} end) + |> TransactionView.decode_transactions(true) + + next_page_params = + next_page |> next_page_params(advanced_filters, Map.take(params, ["items_count"]), &paging_params/1) + + render(conn, :advanced_filters, + advanced_filters: advanced_filters, + decoded_transactions: decoded_transactions, + search_params: %{ + method_ids: method_id_to_name_from_params(full_options[:methods] || [], methods_acc), + tokens: contract_address_hash_to_token_from_params(full_options[:token_contract_address_hashes]) + }, + next_page_params: next_page_params + ) + end + + @doc """ + Function responsible for `api/v2/advanced-filters/csv` endpoint. + """ + @spec list_csv(Plug.Conn.t(), map()) :: Plug.Conn.t() + def list_csv(conn, params) do + with {:recaptcha, true} <- + {:recaptcha, + Application.get_env(:block_scout_web, :recaptcha)[:is_disabled] || + CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])} do + full_options = + params + |> extract_filters() + |> Keyword.merge(paging_options(params)) + |> Keyword.update(:paging_options, %PagingOptions{page_size: CSVHelper.limit()}, fn paging_options -> + %PagingOptions{paging_options | page_size: CSVHelper.limit()} + end) + + full_options + |> AdvancedFilter.list() + |> AdvancedFilterView.to_csv_format() + |> CSVHelper.dump_to_stream() + |> Enum.reduce_while(CSVExportController.put_resp_params(conn), fn chunk, conn -> + case Conn.chunk(conn, chunk) do + {:ok, conn} -> + {:cont, conn} + + {:error, :closed} -> + {:halt, conn} + end + end) + end + end + + @doc """ + Function responsible for `api/v2/advanced-filters/methods` endpoint, + including `api/v2/advanced-filters/methods/?q=:search_string`. + """ + @spec list_methods(Plug.Conn.t(), map()) :: {:method, nil | Explorer.Chain.ContractMethod.t()} | Plug.Conn.t() + def list_methods(conn, %{"q" => query}) do + case {@methods_id_to_name_map[query], @methods_name_to_id_map[query]} do + {name, _} when is_binary(name) -> + render(conn, :methods, methods: [%{method_id: query, name: name}]) + + {_, id} when is_binary(id) -> + render(conn, :methods, methods: [%{method_id: id, name: query}]) + + _ -> + mb_contract_method = + case Data.cast(query) do + {:ok, %Data{bytes: <<_::bytes-size(4)>> = binary_method_id}} -> + ContractMethod.find_contract_method_by_selector_id(binary_method_id, @api_true) + + _ -> + ContractMethod.find_contract_method_by_name(query, @api_true) + end + + with {:method, %ContractMethod{abi: %{"name" => name}, identifier: identifier}} <- {:method, mb_contract_method} do + render(conn, :methods, methods: [%{method_id: "0x" <> Base.encode16(identifier, case: :lower), name: name}]) + end + end + end + + def list_methods(conn, _params) do + render(conn, :methods, methods: @methods) + end + + defp method_id_to_name_from_params(prepared_method_ids, methods_acc) do + {decoded_method_ids, method_ids_to_find} = + Enum.reduce(prepared_method_ids, {%{}, []}, fn method_id, {decoded, to_decode} -> + {:ok, method_id_hash} = Data.cast(method_id) + + case {Map.get(@methods_id_to_name_map, method_id), + methods_acc + |> Map.get(method_id_hash.bytes, []) + |> Enum.find( + &match?(%ContractMethod{abi: %{"type" => "function", "name" => name}} when is_binary(name), &1) + )} do + {name, _} when is_binary(name) -> + {Map.put(decoded, method_id, name), to_decode} + + {_, %ContractMethod{abi: %{"type" => "function", "name" => name}}} when is_binary(name) -> + {Map.put(decoded, method_id, name), to_decode} + + {nil, nil} -> + {decoded, [method_id_hash.bytes | to_decode]} + end + end) + + method_ids_to_find + |> ContractMethod.find_contract_methods(@api_true) + |> Enum.reduce(%{}, fn contract_method, acc -> + case contract_method do + %ContractMethod{abi: %{"name" => name}, identifier: identifier} when is_binary(name) -> + Map.put(acc, "0x" <> Base.encode16(identifier, case: :lower), name) + + _ -> + acc + end + end) + |> Map.merge(decoded_method_ids) + end + + defp contract_address_hash_to_token_from_params(tokens) do + token_contract_address_hashes_to_include = tokens[:include] || [] + + token_contract_address_hashes_to_exclude = tokens[:exclude] || [] + + token_contract_address_hashes_to_include + |> Kernel.++(token_contract_address_hashes_to_exclude) + |> Enum.reject(&(&1 == "native")) + |> Enum.uniq() + |> Enum.take(@tokens_filter_limit) + |> Token.get_by_contract_address_hashes(@api_true) + |> Map.new(fn token -> {token.contract_address_hash, token} end) + end + + defp extract_filters(params) do + [ + tx_types: prepare_tx_types(params["tx_types"]), + methods: params["methods"] |> prepare_methods(), + age: prepare_age(params["age_from"], params["age_to"]), + from_address_hashes: + prepare_include_exclude_address_hashes( + params["from_address_hashes_to_include"], + params["from_address_hashes_to_exclude"], + &prepare_address_hash/1 + ), + to_address_hashes: + prepare_include_exclude_address_hashes( + params["to_address_hashes_to_include"], + params["to_address_hashes_to_exclude"], + &prepare_address_hash/1 + ), + address_relation: prepare_address_relation(params["address_relation"]), + amount: prepare_amount(params["amount_from"], params["amount_to"]), + token_contract_address_hashes: + params["token_contract_address_hashes_to_include"] + |> prepare_include_exclude_address_hashes( + params["token_contract_address_hashes_to_exclude"], + &prepare_token_address_hash/1 + ) + |> Enum.map(fn + {key, value} when is_list(value) -> {key, Enum.take(value, @tokens_filter_limit)} + key_value -> key_value + end) + ] + end + + @allowed_tx_types ~w(COIN_TRANSFER ERC-20 ERC-404 ERC-721 ERC-1155) + + defp prepare_tx_types(tx_types) when is_binary(tx_types) do + tx_types + |> String.upcase() + |> String.split(",") + |> Enum.filter(&(&1 in @allowed_tx_types)) + end + + defp prepare_tx_types(_), do: nil + + defp prepare_methods(methods) when is_binary(methods) do + methods + |> String.downcase() + |> String.split(",") + |> Enum.filter(fn + "0x" <> method_id when byte_size(method_id) == 8 -> + case Base.decode16(method_id, case: :mixed) do + {:ok, _} -> true + _ -> false + end + + _ -> + false + end) + |> Enum.uniq() + |> Enum.take(@methods_filter_limit) + end + + defp prepare_methods(_), do: nil + + defp prepare_age(from, to), do: [from: parse_date(from), to: parse_date(to)] + + defp parse_date(string_date) do + case string_date && DateTime.from_iso8601(string_date) do + {:ok, date, _utc_offset} -> date + _ -> nil + end + end + + defp prepare_address_hashes(address_hashes, map_filter_function) + when is_binary(address_hashes) do + address_hashes + |> String.split(",") + |> Enum.flat_map(&map_filter_function.(&1)) + end + + defp prepare_address_hashes(_, _), do: nil + + defp prepare_address_hash(maybe_address_hash) do + case Chain.string_to_address_hash(maybe_address_hash) do + {:ok, address_hash} -> [address_hash] + _ -> [] + end + end + + defp prepare_token_address_hash(token_address_hash) do + case String.downcase(token_address_hash) do + "native" -> ["native"] + _ -> prepare_address_hash(token_address_hash) + end + end + + defp prepare_address_relation(relation) do + case relation && String.downcase(relation) do + r when r in [nil, "or"] -> :or + "and" -> :and + _ -> nil + end + end + + defp prepare_amount(from, to), do: [from: parse_decimal(from), to: parse_decimal(to)] + + defp parse_decimal(string_decimal) do + case string_decimal && Decimal.parse(string_decimal) do + {decimal, ""} -> decimal + _ -> nil + end + end + + defp prepare_include_exclude_address_hashes(include, exclude, map_filter_function) do + [ + include: prepare_address_hashes(include, map_filter_function), + exclude: prepare_address_hashes(exclude, map_filter_function) + ] + end + + # Paging + + defp paging_options(%{ + "block_number" => block_number_string, + "transaction_index" => tx_index_string, + "internal_transaction_index" => internal_tx_index_string, + "token_transfer_index" => token_transfer_index_string, + "token_transfer_batch_index" => token_transfer_batch_index_string + }) do + with {block_number, ""} <- block_number_string && Integer.parse(block_number_string), + {tx_index, ""} <- tx_index_string && Integer.parse(tx_index_string), + {:ok, internal_tx_index} <- parse_nullable_integer_paging_parameter(internal_tx_index_string), + {:ok, token_transfer_index} <- parse_nullable_integer_paging_parameter(token_transfer_index_string), + {:ok, token_transfer_batch_index} <- parse_nullable_integer_paging_parameter(token_transfer_batch_index_string) do + [ + paging_options: %{ + default_paging_options() + | key: %{ + block_number: block_number, + transaction_index: tx_index, + internal_transaction_index: internal_tx_index, + token_transfer_index: token_transfer_index, + token_transfer_batch_index: token_transfer_batch_index + } + } + ] + else + _ -> [paging_options: default_paging_options()] + end + end + + defp paging_options(_), do: [paging_options: default_paging_options()] + + defp parse_nullable_integer_paging_parameter(""), do: {:ok, nil} + + defp parse_nullable_integer_paging_parameter(string) when is_binary(string) do + case Integer.parse(string) do + {integer, ""} -> {:ok, integer} + _ -> {:error, :invalid_paging_parameter} + end + end + + defp parse_nullable_integer_paging_parameter(_), do: {:error, :invalid_paging_parameter} + + defp paging_params(%AdvancedFilter{ + block_number: block_number, + transaction_index: tx_index, + internal_transaction_index: internal_tx_index, + token_transfer_index: token_transfer_index, + token_transfer_batch_index: token_transfer_batch_index + }) do + %{ + block_number: block_number, + transaction_index: tx_index, + internal_transaction_index: internal_tx_index, + token_transfer_index: token_transfer_index, + token_transfer_batch_index: token_transfer_batch_index + } + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/arbitrum_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/arbitrum_controller.ex new file mode 100644 index 000000000000..3230371b2da8 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/arbitrum_controller.ex @@ -0,0 +1,163 @@ +defmodule BlockScoutWeb.API.V2.ArbitrumController do + use BlockScoutWeb, :controller + + import BlockScoutWeb.Chain, + only: [ + next_page_params: 4, + paging_options: 1, + split_list_by_page: 1 + ] + + alias Explorer.PagingOptions + alias Explorer.Chain.Arbitrum.{L1Batch, Message, Reader} + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @batch_necessity_by_association %{:commitment_transaction => :optional} + + @doc """ + Function to handle GET requests to `/api/v2/arbitrum/messages/:direction` endpoint. + """ + @spec messages(Plug.Conn.t(), map()) :: Plug.Conn.t() + def messages(conn, %{"direction" => direction} = params) do + options = + params + |> paging_options() + |> Keyword.put(:api?, true) + + {messages, next_page} = + direction + |> Reader.messages(options) + |> split_list_by_page() + + next_page_params = + next_page_params( + next_page, + messages, + params, + fn %Message{message_id: msg_id} -> %{"id" => msg_id} end + ) + + conn + |> put_status(200) + |> render(:arbitrum_messages, %{ + messages: messages, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/arbitrum/messages/:direction/count` endpoint. + """ + @spec messages_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def messages_count(conn, %{"direction" => direction} = _params) do + conn + |> put_status(200) + |> render(:arbitrum_messages_count, %{count: Reader.messages_count(direction, api?: true)}) + end + + @doc """ + Function to handle GET requests to `/api/v2/arbitrum/batches/:batch_number` endpoint. + """ + @spec batch(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batch(conn, %{"batch_number" => batch_number} = _params) do + case Reader.batch( + batch_number, + necessity_by_association: @batch_necessity_by_association, + api?: true + ) do + {:ok, batch} -> + conn + |> put_status(200) + |> render(:arbitrum_batch, %{batch: batch}) + + {:error, :not_found} = res -> + res + end + end + + @doc """ + Function to handle GET requests to `/api/v2/arbitrum/batches/count` endpoint. + """ + @spec batches_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches_count(conn, _params) do + conn + |> put_status(200) + |> render(:arbitrum_batches_count, %{count: Reader.batches_count(api?: true)}) + end + + @doc """ + Function to handle GET requests to `/api/v2/arbitrum/batches` endpoint. + """ + @spec batches(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches(conn, params) do + {batches, next_page} = + params + |> paging_options() + |> Keyword.put(:necessity_by_association, @batch_necessity_by_association) + |> Keyword.put(:api?, true) + |> Reader.batches() + |> split_list_by_page() + + next_page_params = + next_page_params( + next_page, + batches, + params, + fn %L1Batch{number: number} -> %{"number" => number} end + ) + + conn + |> put_status(200) + |> render(:arbitrum_batches, %{ + batches: batches, + next_page_params: next_page_params + }) + end + + @doc """ + Function to handle GET requests to `/api/v2/main-page/arbitrum/batches/committed` endpoint. + """ + @spec batches_committed(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batches_committed(conn, _params) do + batches = + [] + |> Keyword.put(:necessity_by_association, @batch_necessity_by_association) + |> Keyword.put(:api?, true) + |> Keyword.put(:committed?, true) + |> Reader.batches() + + conn + |> put_status(200) + |> render(:arbitrum_batches, %{batches: batches}) + end + + @doc """ + Function to handle GET requests to `/api/v2/main-page/arbitrum/batches/latest-number` endpoint. + """ + @spec batch_latest_number(Plug.Conn.t(), map()) :: Plug.Conn.t() + def batch_latest_number(conn, _params) do + conn + |> put_status(200) + |> render(:arbitrum_batch_latest_number, %{number: batch_latest_number()}) + end + + defp batch_latest_number do + case Reader.batch(:latest, api?: true) do + {:ok, batch} -> batch.number + {:error, :not_found} -> 0 + end + end + + @doc """ + Function to handle GET requests to `/api/v2/main-page/arbitrum/messages/to-rollup` endpoint. + """ + @spec recent_messages_to_l2(Plug.Conn.t(), map()) :: Plug.Conn.t() + def recent_messages_to_l2(conn, _params) do + messages = Reader.relayed_l1_to_l2_messages(paging_options: %PagingOptions{page_size: 6}, api?: true) + + conn + |> put_status(200) + |> render(:arbitrum_messages, %{messages: messages}) + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex index 4bc20eb21fa4..0395d6080344 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/block_controller.ex @@ -19,6 +19,7 @@ defmodule BlockScoutWeb.API.V2.BlockController do alias BlockScoutWeb.API.V2.{TransactionView, WithdrawalView} alias Explorer.Chain + alias Explorer.Chain.Arbitrum.Reader, as: ArbitrumReader alias Explorer.Chain.InternalTransaction case Application.compile_env(:explorer, :chain_type) do @@ -39,6 +40,14 @@ defmodule BlockScoutWeb.API.V2.BlockController do :zksync_execute_transaction => :optional } + :arbitrum -> + @chain_type_transaction_necessity_by_association %{} + @chain_type_block_necessity_by_association %{ + :arbitrum_batch => :optional, + :arbitrum_commitment_transaction => :optional, + :arbitrum_confirmation_transaction => :optional + } + _ -> @chain_type_transaction_necessity_by_association %{} @chain_type_block_necessity_by_association %{} @@ -47,25 +56,19 @@ defmodule BlockScoutWeb.API.V2.BlockController do @transaction_necessity_by_association [ necessity_by_association: %{ - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - :block => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + :block => :optional } |> Map.merge(@chain_type_transaction_necessity_by_association) ] @internal_transaction_necessity_by_association [ necessity_by_association: %{ - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] @@ -74,21 +77,7 @@ defmodule BlockScoutWeb.API.V2.BlockController do @block_params [ necessity_by_association: %{ - [miner: :names] => :optional, - :uncles => :optional, - :nephews => :optional, - :rewards => :optional, - :transactions => :optional, - :withdrawals => :optional - } - |> Map.merge(@chain_type_block_necessity_by_association), - api?: true - ] - - @block_params [ - necessity_by_association: - %{ - [miner: :names] => :optional, + [miner: [:names, :smart_contract, :proxy_implementations]] => :optional, :uncles => :optional, :nephews => :optional, :rewards => :optional, @@ -155,6 +144,33 @@ defmodule BlockScoutWeb.API.V2.BlockController do }) end + @doc """ + Function to handle GET requests to `/api/v2/blocks/arbitrum-batch/:batch_number` endpoint. + It renders the list of L2 blocks bound to the specified batch. + """ + @spec arbitrum_batch(Plug.Conn.t(), any()) :: Plug.Conn.t() + def arbitrum_batch(conn, %{"batch_number" => batch_number} = params) do + full_options = + params + |> select_block_type() + |> Keyword.merge(paging_options(params)) + |> Keyword.merge(@api_true) + + {blocks, next_page} = + batch_number + |> ArbitrumReader.batch_blocks(full_options) + |> split_list_by_page() + + next_page_params = next_page |> next_page_params(blocks, delete_parameters_from_next_page_params(params)) + + conn + |> put_status(200) + |> render(:blocks, %{ + blocks: blocks |> maybe_preload_ens() |> maybe_preload_metadata(), + next_page_params: next_page_params + }) + end + @doc """ Function to handle GET requests to `/api/v2/blocks/:block_hash_or_number/transactions` endpoint. """ @@ -235,7 +251,10 @@ defmodule BlockScoutWeb.API.V2.BlockController do def withdrawals(conn, %{"block_hash_or_number" => block_hash_or_number} = params) do with {:ok, block} <- block_param_to_block(block_hash_or_number) do full_options = - [necessity_by_association: %{address: :optional}, api?: true] + [ + necessity_by_association: %{[address: [:names, :smart_contract, :proxy_implementations]] => :optional}, + api?: true + ] |> Keyword.merge(paging_options(params)) withdrawals_plus_one = Chain.block_to_withdrawals(block.hash, full_options) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex index 1c2c3844033e..d8ef80f8f834 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/csv_export_controller.ex @@ -20,11 +20,11 @@ defmodule BlockScoutWeb.API.V2.CSVExportController do def export_token_holders(conn, %{"address_hash_param" => address_hash_string} = params) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), - {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, {:recaptcha, true} <- {:recaptcha, Application.get_env(:block_scout_web, :recaptcha)[:is_disabled] || - CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])} do + CSVHelper.captcha_helper().recaptcha_passed?(params["recaptcha_response"])}, + {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)} do token_holders = Chain.fetch_token_holders_from_token_hash_for_csv(address_hash, @options) token_holders diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex index 373704ccb03a..19448ad5fa79 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/fallback_controller.ex @@ -7,7 +7,6 @@ defmodule BlockScoutWeb.API.V2.FallbackController do alias BlockScoutWeb.API.V2.ApiView alias Ecto.Changeset - @verification_failed "API v2 smart-contract verification failed" @invalid_parameters "Invalid parameter(s)" @invalid_address_hash "Invalid address hash" @invalid_hash "Invalid hash" @@ -36,7 +35,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:format, _params}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_parameters}"] + ["#{@invalid_parameters}"] end) conn @@ -47,7 +46,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:format_address, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_address_hash}"] + ["#{@invalid_address_hash}"] end) conn @@ -58,7 +57,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:format_url, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_url}"] + ["#{@invalid_url}"] end) conn @@ -69,7 +68,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:not_found, _, :empty_items_with_next_page_params}) do Logger.error(fn -> - ["#{@verification_failed}: :empty_items_with_next_page_params"] + [":empty_items_with_next_page_params"] end) conn @@ -78,7 +77,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:not_found, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@not_found}"] + ["#{@not_found}"] end) conn @@ -89,7 +88,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:contract_interaction_disabled, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@contract_interaction_disabled}"] + ["#{@contract_interaction_disabled}"] end) conn @@ -100,7 +99,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:error, {:invalid, :hash}}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_hash}"] + ["#{@invalid_hash}"] end) conn @@ -111,7 +110,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:error, {:invalid, :number}}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_number}"] + ["#{@invalid_number}"] end) conn @@ -122,7 +121,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:error, :not_found}) do Logger.error(fn -> - ["#{@verification_failed}: :not_found"] + [":not_found"] end) conn @@ -138,7 +137,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:restricted_access, true}) do Logger.error(fn -> - ["#{@verification_failed}: #{@restricted_access}"] + ["#{@restricted_access}"] end) conn @@ -149,7 +148,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:already_verified, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@already_verified}"] + ["#{@already_verified}"] end) conn @@ -159,7 +158,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:no_json_file, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@json_not_found}"] + ["#{@json_not_found}"] end) conn @@ -169,7 +168,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:file_error, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@error_while_reading_json}"] + ["#{@error_while_reading_json}"] end) conn @@ -179,7 +178,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:libs_format, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@error_in_libraries}"] + ["#{@error_in_libraries}"] end) conn @@ -189,7 +188,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:lost_consensus, {:ok, block}}) do Logger.error(fn -> - ["#{@verification_failed}: #{@block_lost_consensus}"] + ["#{@block_lost_consensus}"] end) conn @@ -199,7 +198,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:lost_consensus, {:error, :not_found}}) do Logger.error(fn -> - ["#{@verification_failed}: #{@block_lost_consensus}"] + ["#{@block_lost_consensus}"] end) conn @@ -208,7 +207,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:recaptcha, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@invalid_captcha_resp}"] + ["#{@invalid_captcha_resp}"] end) conn @@ -219,7 +218,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:auth, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@unauthorized}"] + ["#{@unauthorized}"] end) conn @@ -230,7 +229,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:sensitive_endpoints_api_key, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@not_configured_api_key}"] + ["#{@not_configured_api_key}"] end) conn @@ -241,7 +240,7 @@ defmodule BlockScoutWeb.API.V2.FallbackController do def call(conn, {:api_key, _}) do Logger.error(fn -> - ["#{@verification_failed}: #{@wrong_api_key}"] + ["#{@wrong_api_key}"] end) conn @@ -278,6 +277,13 @@ defmodule BlockScoutWeb.API.V2.FallbackController do |> render(:message, %{message: @unverified_smart_contract}) end + def call(conn, {:method, _}) do + conn + |> put_status(:not_found) + |> put_view(ApiView) + |> render(:message, %{message: @not_found}) + end + def call(conn, {:is_empty_response, true}) do conn |> put_status(500) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex index c570d9608692..b38a513fc45e 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/import_controller.ex @@ -73,7 +73,7 @@ defmodule BlockScoutWeb.API.V2.ImportController do {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:not_found, {:ok, address}} <- {:not_found, Chain.hash_to_address(address_hash, @api_true, false)}, {:already_verified, smart_contract} when is_nil(smart_contract) <- - {:already_verified, SmartContract.address_hash_to_smart_contract_without_twin(address_hash, @api_true)} do + {:already_verified, SmartContract.address_hash_to_smart_contract(address_hash, @api_true)} do creation_tx_input = contract_creation_input(address.hash) with {:ok, %{"sourceType" => type} = source} <- diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex index 8a39c3e36804..ecfaebd16f5c 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/main_page_controller.ex @@ -13,12 +13,9 @@ defmodule BlockScoutWeb.API.V2.MainPageController do @transactions_options [ necessity_by_association: %{ :block => :required, - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional }, paging_options: %PagingOptions{page_size: 6}, api?: true @@ -30,7 +27,7 @@ defmodule BlockScoutWeb.API.V2.MainPageController do blocks = [paging_options: %PagingOptions{page_size: 4}, api?: true] |> Chain.list_blocks() - |> Repo.replica().preload([[miner: :names], :transactions, :rewards]) + |> Repo.replica().preload([[miner: [:names, :smart_contract, :proxy_implementations]], :transactions, :rewards]) conn |> put_status(200) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/mud_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/mud_controller.ex new file mode 100644 index 000000000000..8f9d0810841a --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/mud_controller.ex @@ -0,0 +1,261 @@ +defmodule BlockScoutWeb.API.V2.MudController do + use BlockScoutWeb, :controller + + import BlockScoutWeb.Chain, + only: [ + next_page_params: 4, + split_list_by_page: 1, + default_paging_options: 0 + ] + + import BlockScoutWeb.PagingHelper, only: [mud_records_sorting: 1] + + alias Explorer.Chain.{Data, Hash, Mud, Mud.Schema.FieldSchema, Mud.Table} + + action_fallback(BlockScoutWeb.API.V2.FallbackController) + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds` endpoint. + """ + @spec worlds(Plug.Conn.t(), map()) :: Plug.Conn.t() + def worlds(conn, params) do + {worlds, next_page} = + params + |> mud_paging_options(["world"], [Hash.Address]) + |> Mud.worlds_list() + |> split_list_by_page() + + next_page_params = + next_page_params(next_page, worlds, conn.query_params, fn item -> + %{"world" => item} + end) + + conn + |> put_status(200) + |> render(:worlds, %{worlds: worlds, next_page_params: next_page_params}) + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/count` endpoint. + """ + @spec worlds_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def worlds_count(conn, _params) do + count = Mud.worlds_count() + + conn + |> put_status(200) + |> render(:count, %{count: count}) + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/:world/tables` endpoint. + """ + @spec world_tables(Plug.Conn.t(), map()) :: Plug.Conn.t() + def world_tables(conn, %{"world" => world_param} = params) do + with {:format, {:ok, world}} <- {:format, Hash.Address.cast(world_param)} do + options = params |> mud_paging_options(["table_id"], [Hash.Full]) |> Keyword.merge(mud_tables_filter(params)) + + {tables, next_page} = + world + |> Mud.world_tables(options) + |> split_list_by_page() + + next_page_params = + next_page_params(next_page, tables, conn.query_params, fn item -> + %{"table_id" => item |> elem(0)} + end) + + conn + |> put_status(200) + |> render(:tables, %{tables: tables, next_page_params: next_page_params}) + end + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/:world/tables/count` endpoint. + """ + @spec world_tables_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def world_tables_count(conn, %{"world" => world_param} = params) do + with {:format, {:ok, world}} <- {:format, Hash.Address.cast(world_param)} do + options = params |> mud_tables_filter() + + count = Mud.world_tables_count(world, options) + + conn + |> put_status(200) + |> render(:count, %{count: count}) + end + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/:world/tables/:table_id/records` endpoint. + """ + @spec world_table_records(Plug.Conn.t(), map()) :: Plug.Conn.t() + def world_table_records(conn, %{"world" => world_param, "table_id" => table_id_param} = params) do + with {:format, {:ok, world}} <- {:format, Hash.Address.cast(world_param)}, + {:format, {:ok, table_id}} <- {:format, Hash.Full.cast(table_id_param)}, + {:ok, schema} <- Mud.world_table_schema(world, table_id) do + options = + params + |> mud_paging_options(["key_bytes", "key0", "key1"], [Data, Hash.Full, Hash.Full]) + |> Keyword.merge(mud_records_filter(params, schema)) + |> Keyword.merge(mud_records_sorting(params)) + + {records, next_page} = world |> Mud.world_table_records(table_id, options) |> split_list_by_page() + + blocks = Mud.preload_records_timestamps(records) + + next_page_params = + next_page_params(next_page, records, conn.query_params, fn item -> + keys = [item.key_bytes, item.key0, item.key1] |> Enum.filter(&(!is_nil(&1))) + ["key_bytes", "key0", "key1"] |> Enum.zip(keys) |> Enum.into(%{}) + end) + + conn + |> put_status(200) + |> render(:records, %{ + records: records, + table_id: table_id, + schema: schema, + blocks: blocks, + next_page_params: next_page_params + }) + end + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/:world/tables/:table_id/records/count` endpoint. + """ + @spec world_table_records_count(Plug.Conn.t(), map()) :: Plug.Conn.t() + def world_table_records_count(conn, %{"world" => world_param, "table_id" => table_id_param} = params) do + with {:format, {:ok, world}} <- {:format, Hash.Address.cast(world_param)}, + {:format, {:ok, table_id}} <- {:format, Hash.Full.cast(table_id_param)}, + {:ok, schema} <- Mud.world_table_schema(world, table_id) do + options = params |> mud_records_filter(schema) + + count = Mud.world_table_records_count(world, table_id, options) + + conn + |> put_status(200) + |> render(:count, %{count: count}) + end + end + + @doc """ + Function to handle GET requests to `/api/v2/mud/worlds/:world/tables/:table_id/records/:record_id` endpoint. + """ + @spec world_table_record(Plug.Conn.t(), map()) :: Plug.Conn.t() + def world_table_record( + conn, + %{"world" => world_param, "table_id" => table_id_param, "record_id" => record_id_param} = _params + ) do + with {:format, {:ok, world}} <- {:format, Hash.Address.cast(world_param)}, + {:format, {:ok, table_id}} <- {:format, Hash.Full.cast(table_id_param)}, + {:format, {:ok, record_id}} <- {:format, Data.cast(record_id_param)}, + {:ok, schema} <- Mud.world_table_schema(world, table_id), + {:ok, record} <- Mud.world_table_record(world, table_id, record_id) do + blocks = Mud.preload_records_timestamps([record]) + + conn + |> put_status(200) + |> render(:record, %{record: record, table_id: table_id, schema: schema, blocks: blocks}) + end + end + + defp mud_tables_filter(params) do + Enum.reduce(params, [], fn {key, value}, acc -> + case key do + "filter_namespace" -> + Keyword.put(acc, :filter_namespace, parse_namespace_string(value)) + + "q" -> + Keyword.put(acc, :filter_search, parse_search_string(value)) + + _ -> + acc + end + end) + end + + defp parse_namespace_string(namespace) do + filter = + case namespace do + nil -> {:ok, nil} + "0x" <> hex -> Base.decode16(hex, case: :mixed) + str -> {:ok, str} + end + + case filter do + {:ok, ns} when is_binary(ns) and byte_size(ns) <= 14 -> + ns |> String.pad_trailing(14, <<0>>) + + _ -> + nil + end + end + + defp parse_search_string(q) do + # If the search string looks like hex-encoded table id or table full name, + # we try to parse and filter by that table id directly. + # Otherwise we do a full-text search of given string inside table id. + with :error <- Hash.Full.cast(q), + :error <- Table.table_full_name_to_table_id(q) do + q + else + {:ok, table_id} -> table_id + end + end + + defp mud_records_filter(params, schema) do + Enum.reduce(params, [], fn {key, value}, acc -> + case key do + "filter_key0" -> Keyword.put(acc, :filter_key0, encode_filter(value, schema, 0)) + "filter_key1" -> Keyword.put(acc, :filter_key1, encode_filter(value, schema, 1)) + _ -> acc + end + end) + end + + defp encode_filter(value, schema, field_idx) do + case value do + "false" -> + <<0::256>> + + "true" -> + <<1::256>> + + "0x" <> hex -> + bin = Base.decode16!(hex, case: :mixed) + # addresses are padded to 32 bytes with zeros on the right + if FieldSchema.type_of(schema.key_schema, field_idx) == 97 do + <<0::size(256 - byte_size(bin) * 8), bin::binary>> + else + <> + end + + dec -> + num = dec |> Integer.parse() |> elem(0) + <> + end + end + + defp mud_paging_options(params, keys, types) do + page_key = + keys + |> Enum.zip(types) + |> Enum.reduce(%{}, fn {key, type}, acc -> + with param when param != nil <- Map.get(params, key), + {:ok, val} <- type.cast(param) do + acc |> Map.put(String.to_existing_atom(key), val) + else + _ -> acc + end + end) + + if page_key == %{} do + [paging_options: default_paging_options()] + else + [paging_options: %{default_paging_options() | key: page_key}] + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex index 5565f003b5e8..1b0bacf4a578 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex @@ -157,7 +157,8 @@ defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do |> Chain.hashes_to_addresses( necessity_by_association: %{ :names => :optional, - :smart_contract => :optional + :smart_contract => :optional, + :proxy_implementations => :optional }, api?: true ) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex index 9dbc80236b08..03d33589e1d8 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/smart_contract_controller.ex @@ -6,7 +6,6 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do import BlockScoutWeb.PagingHelper, only: [current_filter: 1, delete_parameters_from_next_page_params: 1, search_query: 1, smart_contracts_sorting: 1] - import Explorer.Chain.SmartContract, only: [burn_address_hash_string: 0] import Explorer.SmartContract.Solidity.Verifier, only: [parse_boolean: 1] alias BlockScoutWeb.{AccessHelper, AddressView} @@ -14,6 +13,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do alias Explorer.Chain alias Explorer.Chain.{Address, SmartContract} alias Explorer.Chain.SmartContract.AuditReport + alias Explorer.Chain.SmartContract.Proxy.Models.Implementation alias Explorer.SmartContract.{Reader, Writer} alias Explorer.SmartContract.Solidity.PublishHelper alias Explorer.ThirdPartyIntegrations.SolidityScan @@ -100,16 +100,25 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do {:not_found, {:ok, address}} <- {:not_found, Chain.find_contract_address(address_hash, @smart_contract_address_options)}, {:not_found, false} <- {:not_found, is_nil(address.smart_contract)} do - implementation_address_hash_string = + implementation_address_hash_strings = address.smart_contract - |> SmartContract.get_implementation_address_hash(@api_true) + |> Implementation.get_implementation(@api_true) |> Tuple.to_list() - |> List.first() || burn_address_hash_string() + |> List.first() + + functions = + implementation_address_hash_strings + |> Enum.reduce([], fn implementation_address_hash_string, acc -> + functions_from_implementation = + Reader.read_only_functions_proxy(address_hash, implementation_address_hash_string, nil, @api_true) + + acc ++ functions_from_implementation + end) conn |> put_status(200) |> render(:read_functions, %{ - functions: Reader.read_only_functions_proxy(address_hash, implementation_address_hash_string, nil, @api_true) + functions: functions }) end end @@ -122,17 +131,26 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do {:not_found, {:ok, address}} <- {:not_found, Chain.find_contract_address(address_hash, @smart_contract_address_options)}, {:not_found, false} <- {:not_found, is_nil(address.smart_contract)} do - implementation_address_hash_string = + implementation_address_hash_strings = address.smart_contract - |> SmartContract.get_implementation_address_hash(@api_true) + |> Implementation.get_implementation(@api_true) |> Tuple.to_list() - |> List.first() || burn_address_hash_string() + |> List.first() + + functions = + implementation_address_hash_strings + |> Enum.reduce([], fn implementation_address_hash_string, acc -> + functions_from_implementation = + implementation_address_hash_string + |> Writer.write_functions_proxy(@api_true) + + acc ++ functions_from_implementation + end) conn |> put_status(200) |> json( - implementation_address_hash_string - |> Writer.write_functions_proxy(@api_true) + functions |> Reader.get_abi_with_method_id() ) end @@ -204,7 +222,7 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), {:address, {:ok, address}} <- {:address, Chain.hash_to_address(address_hash)}, {:is_smart_contract, true} <- {:is_smart_contract, Address.smart_contract?(address)}, - smart_contract = SmartContract.address_hash_to_smart_contract_without_twin(address_hash, @api_true), + smart_contract = SmartContract.address_hash_to_smart_contract(address_hash, @api_true), {:is_verified_smart_contract, true} <- {:is_verified_smart_contract, !is_nil(smart_contract)}, {:is_vyper_contract, false} <- {:is_vyper_contract, smart_contract.is_vyper_contract}, response = SolidityScan.solidityscan_request(address_hash_string), @@ -217,7 +235,12 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do def smart_contracts_list(conn, params) do full_options = - [necessity_by_association: %{[address: :token] => :optional, [address: :names] => :optional, address: :required}] + [ + necessity_by_association: %{ + [address: [:token, :names, :proxy_implementations]] => :optional, + address: :required + } + ] |> Keyword.merge(paging_options(params)) |> Keyword.merge(current_filter(params)) |> Keyword.merge(search_query(params)) @@ -304,8 +327,8 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do defp validate_smart_contract(params, address_hash_string) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), - {:not_found, smart_contract} when not is_nil(smart_contract) <- - {:not_found, SmartContract.address_hash_to_smart_contract(address_hash, @api_true)} do + {:not_found, {smart_contract, _}} when not is_nil(smart_contract) <- + {:not_found, SmartContract.address_hash_to_smart_contract_with_bytecode_twin(address_hash, @api_true)} do {:ok, address_hash, smart_contract} end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex index 6d212582423a..a233488080ca 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/token_controller.ex @@ -1,10 +1,13 @@ defmodule BlockScoutWeb.API.V2.TokenController do + alias Explorer.PagingOptions use BlockScoutWeb, :controller alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.API.V2.{AddressView, TransactionView} - alias Explorer.{Chain, Repo} + alias Explorer.{Chain, Helper} alias Explorer.Chain.{Address, BridgedToken, Token, Token.Instance} + alias Explorer.Chain.CSVExport.Helper, as: CSVHelper + alias Indexer.Fetcher.OnDemand.TokenInstanceMetadataRefetch, as: TokenInstanceMetadataRefetchOnDemand alias Indexer.Fetcher.OnDemand.TokenTotalSupply, as: TokenTotalSupplyOnDemand import BlockScoutWeb.Chain, @@ -14,7 +17,8 @@ defmodule BlockScoutWeb.API.V2.TokenController do next_page_params: 3, token_transfers_next_page_params: 3, unique_tokens_paging_options: 1, - unique_tokens_next_page: 3 + unique_tokens_next_page: 3, + default_paging_options: 0 ] import BlockScoutWeb.PagingHelper, @@ -134,7 +138,10 @@ defmodule BlockScoutWeb.API.V2.TokenController do {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, {:format, {:ok, holder_address_hash}} <- {:format, Chain.string_to_address_hash(holder_address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(holder_address_hash_string, params) do - holder_address = Repo.get_by(Address, hash: holder_address_hash) + holder_address = Address.get(holder_address_hash, @api_true) + + holder_address_with_proxy_implementations = + holder_address && %Address{holder_address | proxy_implementations: nil} results_plus_one = Instance.token_instances_by_holder_address_hash( @@ -154,7 +161,7 @@ defmodule BlockScoutWeb.API.V2.TokenController do |> put_status(200) |> put_view(AddressView) |> render(:nft_list, %{ - token_instances: token_instances |> put_owner(holder_address), + token_instances: token_instances |> put_owner(holder_address_with_proxy_implementations), next_page_params: next_page_params, token: token }) @@ -183,29 +190,13 @@ defmodule BlockScoutWeb.API.V2.TokenController do end end - def instance(conn, %{"address_hash_param" => address_hash_string, "token_id" => token_id_str} = params) do + def instance(conn, %{"address_hash_param" => address_hash_string, "token_id" => token_id_string} = params) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, - {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_str)} do - token_instance = - case Chain.nft_instance_from_token_id_and_token_address(token_id, address_hash, @api_true) do - {:ok, token_instance} -> - token_instance - |> Chain.select_repo(@api_true).preload(:owner) - |> Chain.put_owner_to_token_instance(token, @api_true) - - {:error, :not_found} -> - %Instance{ - token_id: Decimal.new(token_id), - metadata: nil, - owner: nil, - token_contract_address_hash: address_hash - } - |> Instance.put_is_unique(token, @api_true) - |> Chain.put_owner_to_token_instance(token, @api_true) - end + {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_string)} do + token_instance = token_instance_from_token_id_and_token_address(token_id, address_hash, token) conn |> put_status(200) @@ -216,12 +207,15 @@ defmodule BlockScoutWeb.API.V2.TokenController do end end - def transfers_by_instance(conn, %{"address_hash_param" => address_hash_string, "token_id" => token_id_str} = params) do + def transfers_by_instance( + conn, + %{"address_hash_param" => address_hash_string, "token_id" => token_id_string} = params + ) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, - {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_str)} do + {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_string)} do paging_options = paging_options(params) results = @@ -246,12 +240,12 @@ defmodule BlockScoutWeb.API.V2.TokenController do end end - def holders_by_instance(conn, %{"address_hash_param" => address_hash_string, "token_id" => token_id_str} = params) do + def holders_by_instance(conn, %{"address_hash_param" => address_hash_string, "token_id" => token_id_string} = params) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, - {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_str)} do + {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_string)} do paging_options = paging_options(params) results = @@ -279,13 +273,13 @@ defmodule BlockScoutWeb.API.V2.TokenController do def transfers_count_by_instance( conn, - %{"address_hash_param" => address_hash_string, "token_id" => token_id_str} = params + %{"address_hash_param" => address_hash_string, "token_id" => token_id_string} = params ) do with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, - {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_str)} do + {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_string)} do conn |> put_status(200) |> json(%{ @@ -300,6 +294,12 @@ defmodule BlockScoutWeb.API.V2.TokenController do options = params |> paging_options() + |> Keyword.update(:paging_options, default_paging_options(), fn %PagingOptions{ + page_size: page_size + } = paging_options -> + mb_parsed_limit = Helper.parse_integer(params["limit"]) + %PagingOptions{paging_options | page_size: min(page_size, mb_parsed_limit && abs(mb_parsed_limit))} + end) |> Keyword.merge(token_transfers_types_options(params)) |> Keyword.merge(tokens_sorting(params)) |> Keyword.merge(@api_true) @@ -332,6 +332,61 @@ defmodule BlockScoutWeb.API.V2.TokenController do |> render(:bridged_tokens, %{tokens: tokens, next_page_params: next_page_params}) end + def refetch_metadata( + conn, + params + ) do + address_hash_string = params["address_hash_param"] + token_id_string = params["token_id"] + recaptcha_response = params["recaptcha_response"] + + with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)}, + {:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params), + {:recaptcha, true} <- {:recaptcha, CSVHelper.captcha_helper().recaptcha_passed?(recaptcha_response)}, + {:not_found, {:ok, token}} <- {:not_found, Chain.token_from_address_hash(address_hash, @api_true)}, + {:not_found, false} <- {:not_found, Chain.erc_20_token?(token)}, + {:format, {token_id, ""}} <- {:format, Integer.parse(token_id_string)}, + {:ok, token_instance} <- Chain.nft_instance_from_token_id_and_token_address(token_id, address_hash, @api_true) do + token_instance_with_token = + token_instance + |> put_token_to_instance(token) + + TokenInstanceMetadataRefetchOnDemand.trigger_refetch(token_instance_with_token) + + conn + |> put_status(200) + |> json(%{message: "OK"}) + end + end + defp put_owner(token_instances, holder_address), do: Enum.map(token_instances, fn token_instance -> %Instance{token_instance | owner: holder_address} end) + + defp token_instance_from_token_id_and_token_address(token_id, address_hash, token) do + case Chain.nft_instance_from_token_id_and_token_address(token_id, address_hash, @api_true) do + {:ok, token_instance} -> + token_instance + |> Chain.select_repo(@api_true).preload(owner: [:names, :smart_contract, :proxy_implementations]) + |> Chain.put_owner_to_token_instance(token, @api_true) + + {:error, :not_found} -> + %Instance{ + token_id: Decimal.new(token_id), + metadata: nil, + owner: nil, + token: nil, + token_contract_address_hash: address_hash + } + |> Instance.put_is_unique(token, @api_true) + |> Chain.put_owner_to_token_instance(token, @api_true) + end + end + + @spec put_token_to_instance(Instance.t(), Token.t()) :: Instance.t() + defp put_token_to_instance( + token_instance, + token + ) do + %{token_instance | token: token} + end end diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex index 51989d4431ad..3312fc6e2c2f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/transaction_controller.ex @@ -32,6 +32,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do alias BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation, as: TransactionInterpretationService alias BlockScoutWeb.Models.TransactionStateHelper alias Explorer.Chain + alias Explorer.Chain.Arbitrum.Reader, as: ArbitrumReader alias Explorer.Chain.Beacon.Reader, as: BeaconReader alias Explorer.Chain.{Hash, InternalTransaction, Transaction} alias Explorer.Chain.PolygonZkevm.Reader, as: PolygonZkevmReader @@ -54,38 +55,36 @@ defmodule BlockScoutWeb.API.V2.TransactionController do # TODO might be redundant to preload blob fields in some of the endpoints @transaction_necessity_by_association %{ :block => :optional, - [created_contract_address: :names] => :optional, - [created_contract_address: :token] => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [to_address: :smart_contract] => :optional + [ + created_contract_address: [ + :names, + :token, + :smart_contract, + :proxy_implementations + ] + ] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => + :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } |> Map.merge(@chain_type_transaction_necessity_by_association) @token_transfers_necessity_by_association %{ - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } @token_transfers_in_tx_necessity_by_association %{ - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, token: :required } @internal_transaction_necessity_by_association [ necessity_by_association: %{ - [created_contract_address: :names] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, - [created_contract_address: :smart_contract] => :optional, - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional + [created_contract_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] @@ -114,6 +113,14 @@ defmodule BlockScoutWeb.API.V2.TransactionController do |> Map.put(:zksync_prove_transaction, :optional) |> Map.put(:zksync_execute_transaction, :optional) + :arbitrum -> + necessity_by_association_with_actions + |> Map.put(:arbitrum_batch, :optional) + |> Map.put(:arbitrum_commitment_transaction, :optional) + |> Map.put(:arbitrum_confirmation_transaction, :optional) + |> Map.put(:arbitrum_message_to_l2, :optional) + |> Map.put(:arbitrum_message_from_l2, :optional) + :suave -> necessity_by_association_with_actions |> Map.put(:logs, :optional) @@ -194,7 +201,35 @@ defmodule BlockScoutWeb.API.V2.TransactionController do It renders the list of L2 transactions bound to the specified batch. """ @spec zksync_batch(Plug.Conn.t(), map()) :: Plug.Conn.t() - def zksync_batch(conn, %{"batch_number" => batch_number} = params) do + def zksync_batch(conn, params) do + handle_batch_transactions(conn, params, &ZkSyncReader.batch_transactions/2) + end + + @doc """ + Function to handle GET requests to `/api/v2/transactions/arbitrum-batch/:batch_number` endpoint. + It renders the list of L2 transactions bound to the specified batch. + """ + @spec arbitrum_batch(Plug.Conn.t(), map()) :: Plug.Conn.t() + def arbitrum_batch(conn, params) do + handle_batch_transactions(conn, params, &ArbitrumReader.batch_transactions/2) + end + + # Processes and renders transactions for a specified batch into an HTTP response. + # + # This function retrieves a list of transactions for a given batch using a specified function, + # then extracts the transaction hashes. These hashes are used to retrieve the corresponding + # `Explorer.Chain.Transaction` records according to the given pagination options. It formats + # these transactions into an HTTP response. + # + # ## Parameters + # - `conn`: The connection object. + # - `params`: Parameters from the request, including the batch number. + # - `batch_transactions_fun`: A function to fetch transaction descriptions for the given batch. + # + # ## Returns + # - Updated connection object with the transactions data rendered. + @spec handle_batch_transactions(Plug.Conn.t(), map(), function()) :: Plug.Conn.t() + defp handle_batch_transactions(conn, %{"batch_number" => batch_number} = params, batch_transactions_fun) do full_options = [ necessity_by_association: @transaction_necessity_by_association @@ -206,13 +241,13 @@ defmodule BlockScoutWeb.API.V2.TransactionController do # it will require to re-implement all pagination logic existing in Explorer.Chain.Transaction # In order to simplify the code, all transaction are requested from the batch and then # only subset of them is returned from `hashes_to_transactions`. - raw_transactions_list = + transactions_plus_one = batch_number - |> ZkSyncReader.batch_transactions(api?: true) - |> Enum.map(fn tx -> tx.hash end) + |> batch_transactions_fun.(@api_true) + |> Enum.map(fn tx -> tx.tx_hash end) |> Chain.hashes_to_transactions(full_options) - {transactions, next_page} = split_list_by_page(raw_transactions_list) + {transactions, next_page} = split_list_by_page(transactions_plus_one) next_page_params = next_page |> next_page_params(transactions, delete_parameters_from_next_page_params(params)) conn @@ -350,9 +385,7 @@ defmodule BlockScoutWeb.API.V2.TransactionController do full_options = [ necessity_by_association: %{ - [address: :names] => :optional, - [address: :smart_contract] => :optional, - address: :optional + [address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] |> Keyword.merge(paging_options(params)) @@ -384,7 +417,9 @@ defmodule BlockScoutWeb.API.V2.TransactionController do with {:ok, transaction, _transaction_hash} <- validate_transaction(transaction_hash_string, params, necessity_by_association: - Map.merge(@transaction_necessity_by_association, %{[block: [miner: :names]] => :optional}), + Map.merge(@transaction_necessity_by_association, %{ + [block: [miner: [:names, :smart_contract, :proxy_implementations]]] => :optional + }), api?: true ) do state_changes_plus_next_page = @@ -433,7 +468,14 @@ defmodule BlockScoutWeb.API.V2.TransactionController do def summary(conn, %{"transaction_hash_param" => transaction_hash_string, "just_request_body" => "true"} = params) do with {:tx_interpreter_enabled, true} <- {:tx_interpreter_enabled, TransactionInterpretationService.enabled?()}, - {:ok, transaction, _transaction_hash} <- validate_transaction(transaction_hash_string, params) do + {:ok, transaction, _transaction_hash} <- + validate_transaction(transaction_hash_string, params, + necessity_by_association: %{ + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional + }, + api?: true + ) do conn |> json(TransactionInterpretationService.get_request_body(transaction)) end @@ -450,7 +492,14 @@ defmodule BlockScoutWeb.API.V2.TransactionController do | Plug.Conn.t() def summary(conn, %{"transaction_hash_param" => transaction_hash_string} = params) do with {:tx_interpreter_enabled, true} <- {:tx_interpreter_enabled, TransactionInterpretationService.enabled?()}, - {:ok, transaction, _transaction_hash} <- validate_transaction(transaction_hash_string, params) do + {:ok, transaction, _transaction_hash} <- + validate_transaction(transaction_hash_string, params, + necessity_by_association: %{ + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional + }, + api?: true + ) do {response, code} = case TransactionInterpretationService.interpret(transaction) do {:ok, response} -> {response, 200} diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/utils_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/utils_controller.ex index 90a10cff5900..9de0d519a0d3 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/utils_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/utils_controller.ex @@ -18,7 +18,12 @@ defmodule BlockScoutWeb.API.V2.UtilsController do address_hash <- params["address_hash"] && Chain.string_to_address_hash(params["address_hash"]), {:format, true} <- {:format, match?({:ok, _hash}, address_hash) || is_nil(address_hash)} do smart_contract = - if address_hash, do: SmartContract.address_hash_to_smart_contract(elem(address_hash, 1), @api_true) + if address_hash do + {updated_smart_contract, _} = + SmartContract.address_hash_to_smart_contract_with_bytecode_twin(elem(address_hash, 1), @api_true) + + updated_smart_contract + end {decoded_input, _abi_acc, _methods_acc} = Transaction.decoded_input_data( diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex index 4c7883502814..78736763dbc2 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/validator_controller.ex @@ -28,7 +28,7 @@ defmodule BlockScoutWeb.API.V2.ValidatorController do options = [ necessity_by_association: %{ - :address => :optional + [address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] |> Keyword.merge(@api_true) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex index f9f9e17e9be9..a58a84ed1599 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/v2/withdrawal_controller.ex @@ -12,7 +12,13 @@ defmodule BlockScoutWeb.API.V2.WithdrawalController do def withdrawals_list(conn, params) do full_options = - [necessity_by_association: %{address: :optional, block: :optional}, api?: true] + [ + necessity_by_association: %{ + [address: [:names, :smart_contract, :proxy_implementations]] => :optional, + block: :optional + }, + api?: true + ] |> Keyword.merge(paging_options(params)) withdrawals_plus_one = Chain.list_withdrawals(full_options) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex index 6b333af67cf6..87eaf6bd7824 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/smart_contract_controller.ex @@ -4,6 +4,7 @@ defmodule BlockScoutWeb.SmartContractController do alias BlockScoutWeb.AddressView alias Explorer.Chain alias Explorer.Chain.SmartContract + alias Explorer.Chain.SmartContract.Proxy.Models.Implementation alias Explorer.SmartContract.{Reader, Writer} import Explorer.SmartContract.Solidity.Verifier, only: [parse_boolean: 1] @@ -27,8 +28,9 @@ defmodule BlockScoutWeb.SmartContractController do implementation_address_hash_string = if contract_type == "proxy" do address.smart_contract - |> SmartContract.get_implementation_address_hash() + |> Implementation.get_implementation() |> Tuple.to_list() + |> List.first() |> List.first() || burn_address_hash_string() else burn_address_hash_string() diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex index 2b2eab99b7ef..4f227cb3f136 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/holder_controller.ex @@ -9,11 +9,11 @@ defmodule BlockScoutWeb.Tokens.Instance.HolderController do import BlockScoutWeb.Chain, only: [split_list_by_page: 1, paging_options: 1, next_page_params: 3] - def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_str, "type" => "JSON"} = params) do + def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(address_hash), false <- Chain.erc_20_token?(token), - {token_id, ""} <- Integer.parse(token_id_str), + {token_id, ""} <- Integer.parse(token_id_string), token_holders <- Chain.fetch_token_holders_from_token_hash_and_token_id(address_hash, token_id, paging_options(params)) do {token_holders_paginated, next_page} = split_list_by_page(token_holders) @@ -53,13 +53,13 @@ defmodule BlockScoutWeb.Tokens.Instance.HolderController do end end - def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_str}) do + def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_string}) do options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), false <- Chain.erc_20_token?(token), - {token_id, ""} <- Integer.parse(token_id_str) do + {token_id, ""} <- Integer.parse(token_id_string) do case Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do {:ok, token_instance} -> Helper.render(conn, token_instance, hash, token_id, token) {:error, :not_found} -> Helper.render(conn, nil, hash, token_id, token) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex index 0036a95563ca..84dd18da5370 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/metadata_controller.ex @@ -4,13 +4,13 @@ defmodule BlockScoutWeb.Tokens.Instance.MetadataController do alias BlockScoutWeb.Tokens.Instance.Helper alias Explorer.Chain - def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_str}) do + def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_string}) do options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), false <- Chain.erc_20_token?(token), - {token_id, ""} <- Integer.parse(token_id_str), + {token_id, ""} <- Integer.parse(token_id_string), {:ok, token_instance} <- Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do if token_instance.metadata do diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex index 30a8212a75f9..62c9c4638617 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/instance/transfer_controller.ex @@ -13,11 +13,11 @@ defmodule BlockScoutWeb.Tokens.Instance.TransferController do {:ok, burn_address_hash} = Chain.string_to_address_hash(burn_address_hash_string()) @burn_address_hash burn_address_hash - def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_str, "type" => "JSON"} = params) do + def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_string, "type" => "JSON"} = params) do with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash), false <- Chain.erc_20_token?(token), - {token_id, ""} <- Integer.parse(token_id_str), + {token_id, ""} <- Integer.parse(token_id_string), token_transfers <- Chain.fetch_token_transfers_from_token_hash_and_token_id(hash, token_id, paging_options(params)) do {token_transfers_paginated, next_page} = split_list_by_page(token_transfers) @@ -56,13 +56,13 @@ defmodule BlockScoutWeb.Tokens.Instance.TransferController do end end - def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_str}) do + def index(conn, %{"token_id" => token_address_hash, "instance_id" => token_id_string}) do options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] with {:ok, hash} <- Chain.string_to_address_hash(token_address_hash), {:ok, token} <- Chain.token_from_address_hash(hash, options), false <- Chain.erc_20_token?(token), - {token_id, ""} <- Integer.parse(token_id_str) do + {token_id, ""} <- Integer.parse(token_id_string) do case Chain.nft_instance_from_token_id_and_token_address(token_id, hash) do {:ok, token_instance} -> Helper.render(conn, token_instance, hash, token_id, token) {:error, :not_found} -> Helper.render(conn, nil, hash, token_id, token) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/visualize_sol2uml_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/visualize_sol2uml_controller.ex index 78c4d225f381..bb77a765ec79 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/visualize_sol2uml_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/visualize_sol2uml_controller.ex @@ -13,7 +13,7 @@ defmodule BlockScoutWeb.VisualizeSol2umlController do if Sol2uml.enabled?() do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), {:ok, address} <- Chain.find_contract_address(address_hash, address_options, true), - # check that contract is verified. partial and twin verification is ok for this case + # check that contract is verified. partial and bytecode twin verification is ok for this case false <- is_nil(address.smart_contract) do sources = address.smart_contract.smart_contract_additional_sources diff --git a/apps/block_scout_web/lib/block_scout_web/endpoint.ex b/apps/block_scout_web/lib/block_scout_web/endpoint.ex index 10d8d99f36b6..dfb2f2b84434 100644 --- a/apps/block_scout_web/lib/block_scout_web/endpoint.ex +++ b/apps/block_scout_web/lib/block_scout_web/endpoint.ex @@ -6,19 +6,22 @@ defmodule BlockScoutWeb.Endpoint do plug(Phoenix.Ecto.SQL.Sandbox, repo: Explorer.Repo) end - socket("/socket", BlockScoutWeb.UserSocket, websocket: [timeout: 45_000]) - socket("/socket/v2", BlockScoutWeb.UserSocketV2, websocket: [timeout: 45_000]) + if Application.compile_env(:block_scout_web, :disable_api?) do + plug(BlockScoutWeb.HealthRouter) + else + socket("/socket", BlockScoutWeb.UserSocket, websocket: [timeout: 45_000]) + socket("/socket/v2", BlockScoutWeb.UserSocketV2, websocket: [timeout: 45_000]) - # Serve at "/" the static files from "priv/static" directory. - # - # You should set gzip to true if you are running phoenix.digest - # when deploying your static files in production. - plug( - Plug.Static, - at: "/", - from: :block_scout_web, - gzip: true, - only: ~w( + # Serve at "/" the static files from "priv/static" directory. + # + # You should set gzip to true if you are running phoenix.digest + # when deploying your static files in production. + plug( + Plug.Static, + at: "/", + from: :block_scout_web, + gzip: true, + only: ~w( css fonts images @@ -30,54 +33,47 @@ defmodule BlockScoutWeb.Endpoint do mstile-150x150.png safari-pinned-tab.svg ), - only_matching: ~w(manifest) - ) + only_matching: ~w(manifest) + ) - # Code reloading can be explicitly enabled under the - # :code_reloader configuration of your endpoint. - if code_reloading? do - socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) - plug(Phoenix.LiveReloader) - plug(Phoenix.CodeReloader) - end - - plug(Plug.RequestId) + # Code reloading can be explicitly enabled under the + # :code_reloader configuration of your endpoint. + if code_reloading? do + socket("/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket) + plug(Phoenix.LiveReloader) + plug(Phoenix.CodeReloader) + end - plug( - Plug.Parsers, - parsers: [:urlencoded, :multipart, :json], - length: 20_000_000, - query_string_length: 1_000_000, - pass: ["*/*"], - json_decoder: Poison - ) + plug(Plug.RequestId) - plug(Plug.MethodOverride) - plug(Plug.Head) + plug(Plug.MethodOverride) + plug(Plug.Head) - # The session will be stored in the cookie and signed, - # this means its contents can be read but not tampered with. - # Set :encryption_salt if you would also like to encrypt it. + # The session will be stored in the cookie and signed, + # this means its contents can be read but not tampered with. + # Set :encryption_salt if you would also like to encrypt it. - plug( - Plug.Session, - store: BlockScoutWeb.Plug.RedisCookie, - key: "_explorer_key", - signing_salt: "iC2ksJHS", - same_site: "Lax", - http_only: false, - domain: Application.compile_env(:block_scout_web, :cookie_domain), - max_age: Application.compile_env(:block_scout_web, :session_cookie_ttl) - ) + plug( + Plug.Session, + store: BlockScoutWeb.Plug.RedisCookie, + key: "_explorer_key", + signing_salt: "iC2ksJHS", + same_site: "Lax", + http_only: false, + domain: Application.compile_env(:block_scout_web, :cookie_domain), + max_age: Application.compile_env(:block_scout_web, :session_cookie_ttl) + ) - use SpandexPhoenix + use SpandexPhoenix - plug(BlockScoutWeb.Prometheus.Exporter) + plug(BlockScoutWeb.Prometheus.Exporter) + plug(BlockScoutWeb.Prometheus.PublicExporter) - # 'x-apollo-tracing' header for https://www.graphqlbin.com to work with our GraphQL endpoint - plug(CORSPlug, headers: ["x-apollo-tracing" | CORSPlug.defaults()[:headers]]) + # 'x-apollo-tracing' header for https://www.graphqlbin.com to work with our GraphQL endpoint + plug(CORSPlug, headers: ["x-apollo-tracing" | CORSPlug.defaults()[:headers]]) - plug(BlockScoutWeb.Router) + plug(BlockScoutWeb.Router) + end def init(_key, config) do if config[:load_from_system_env] do diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/body_reader.ex b/apps/block_scout_web/lib/block_scout_web/graphql/body_reader.ex new file mode 100644 index 000000000000..fe12ebfb1ca1 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/graphql/body_reader.ex @@ -0,0 +1,35 @@ +defmodule BlockScoutWeb.GraphQL.BodyReader do + @moduledoc """ + This module is responsible for reading the body of a graphql request and counting the number of queries in the body. + """ + + alias Plug.Conn + + @max_number_of_queries 1 + + def read_body(conn, opts) do + {:ok, body, conn} = Conn.read_body(conn, opts) + updated_conn = update_in(conn.assigns[:raw_body], &[body | &1 || []]) + + json_body = Jason.decode!(body) + + json_body_length = + if is_list(json_body) do + Enum.count(json_body) + else + 1 + end + + error = %{errors: [%{message: "Max batch size is 1"}]} + + if json_body_length > @max_number_of_queries do + {:ok, "", + updated_conn + |> Conn.put_resp_content_type("application/json") + |> Conn.resp(400, Jason.encode!(error)) + |> Conn.halt()} + else + {:ok, body, updated_conn} + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex b/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex index 27bd81ae4fb0..22b1d26e8239 100644 --- a/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex +++ b/apps/block_scout_web/lib/block_scout_web/graphql/schema/types.ex @@ -116,8 +116,6 @@ defmodule BlockScoutWeb.GraphQL.Schema.Types do field(:file_path, :string) field(:is_vyper_contract, :boolean) field(:is_changed_bytecode, :boolean) - field(:implementation_name, :string) - field(:implementation_address_hash, :address_hash) field(:compiler_settings, :json) field(:verified_via_eth_bytecode_db, :boolean) end diff --git a/apps/block_scout_web/lib/block_scout_web/health_router.ex b/apps/block_scout_web/lib/block_scout_web/health_router.ex new file mode 100644 index 000000000000..746bae3dbcf6 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/health_router.ex @@ -0,0 +1,15 @@ +defmodule BlockScoutWeb.HealthRouter do + @moduledoc """ + Router for health checks in case of indexer-only setup + """ + + use BlockScoutWeb, :router + + alias BlockScoutWeb.API.V1.HealthController + + scope "/api/v1/health" do + get("/", HealthController, :health) + get("/liveness", HealthController, :liveness) + get("/readiness", HealthController, :readiness) + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex b/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex index 4ea71d7a9e61..9f89707e6f7b 100644 --- a/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex +++ b/apps/block_scout_web/lib/block_scout_web/microservice_interfaces/transaction_interpretation.ex @@ -139,10 +139,8 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do full_options = [ necessity_by_association: %{ - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] |> Keyword.merge(@api_true) @@ -158,9 +156,7 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do log_options = [ necessity_by_association: %{ - [address: :names] => :optional, - [address: :smart_contract] => :optional, - address: :optional + [address: [:names, :smart_contract, :proxy_implementations]] => :optional }, limit: @items_limit ] @@ -180,10 +176,8 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do token_transfer_options = [ necessity_by_association: %{ - [from_address: :smart_contract] => :optional, - [to_address: :smart_contract] => :optional, - [from_address: :names] => :optional, - [to_address: :names] => :optional, + [from_address: [:names, :smart_contract, :proxy_implementations]] => :optional, + [to_address: [:names, :smart_contract, :proxy_implementations]] => :optional, :token => :optional } ] @@ -203,9 +197,7 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do full_options = [ necessity_by_association: %{ - [address: :names] => :optional, - [address: :smart_contract] => :optional, - address: :optional + [address: [:names, :smart_contract, :proxy_implementations]] => :optional } ] |> Keyword.merge(@api_true) @@ -253,7 +245,8 @@ defmodule BlockScoutWeb.MicroserviceInterfaces.TransactionInterpretation do [ necessity_by_association: %{ :names => :optional, - :smart_contract => :optional + :smart_contract => :optional, + :proxy_implementations => :optional }, api?: true ], diff --git a/apps/block_scout_web/lib/block_scout_web/notifier.ex b/apps/block_scout_web/lib/block_scout_web/notifier.ex index 724c1e7e5bc1..951579c042c9 100644 --- a/apps/block_scout_web/lib/block_scout_web/notifier.ex +++ b/apps/block_scout_web/lib/block_scout_web/notifier.ex @@ -175,10 +175,8 @@ defmodule BlockScoutWeb.Notifier do DenormalizationHelper.extend_transaction_preload([ :token, :transaction, - from_address: :smart_contract, - to_address: :smart_contract, - from_address: :names, - to_address: :names + from_address: [:names, :smart_contract, :proxy_implementations], + to_address: [:names, :smart_contract, :proxy_implementations] ]) )) ) @@ -202,12 +200,9 @@ defmodule BlockScoutWeb.Notifier do def handle_event({:chain_event, :transactions, :realtime, transactions}) do base_preloads = [ :block, - created_contract_address: :names, - from_address: :names, - to_address: :names, - created_contract_address: :smart_contract, - from_address: :smart_contract, - to_address: :smart_contract + created_contract_address: [:names, :smart_contract, :proxy_implementations], + from_address: [:names, :smart_contract, :proxy_implementations], + to_address: [:names, :smart_contract, :proxy_implementations] ] preloads = if API_V2.enabled?(), do: [:token_transfers | base_preloads], else: base_preloads @@ -248,6 +243,17 @@ defmodule BlockScoutWeb.Notifier do Endpoint.broadcast("addresses:#{to_string(address_hash)}", "fetched_bytecode", %{fetched_bytecode: fetched_bytecode}) end + def handle_event( + {:chain_event, :fetched_token_instance_metadata, :on_demand, + [token_contract_address_hash_string, token_id, fetched_token_instance_metadata]} + ) do + Endpoint.broadcast( + "token_instances:#{token_contract_address_hash_string}", + "fetched_token_instance_metadata", + %{token_id: token_id, fetched_metadata: fetched_token_instance_metadata} + ) + end + def handle_event({:chain_event, :changed_bytecode, :on_demand, [address_hash]}) do Endpoint.broadcast("addresses:#{to_string(address_hash)}", "changed_bytecode", %{}) end diff --git a/apps/block_scout_web/lib/block_scout_web/paging_helper.ex b/apps/block_scout_web/lib/block_scout_web/paging_helper.ex index d3e11c498de8..bcf159686983 100644 --- a/apps/block_scout_web/lib/block_scout_web/paging_helper.ex +++ b/apps/block_scout_web/lib/block_scout_web/paging_helper.ex @@ -40,8 +40,8 @@ defmodule BlockScoutWeb.PagingHelper do def allowed_stability_validators_states, do: @allowed_stability_validators_states def paging_options(%{"block_number" => block_number_string, "index" => index_string}, [:validated | _]) do - with {block_number, ""} <- Integer.parse(block_number_string), - {index, ""} <- Integer.parse(index_string) do + with {:ok, block_number} <- Helper.safe_parse_non_negative_integer(block_number_string), + {:ok, index} <- Helper.safe_parse_non_negative_integer(index_string) do [paging_options: %{@default_paging_options | key: {block_number, index}}] else _ -> @@ -158,7 +158,7 @@ defmodule BlockScoutWeb.PagingHelper do [ necessity_by_association: %{ :transactions => :optional, - [miner: :names] => :optional, + [miner: [:names, :smart_contract, :proxy_implementations]] => :optional, :nephews => :required, :rewards => :optional }, @@ -169,7 +169,7 @@ defmodule BlockScoutWeb.PagingHelper do [ necessity_by_association: %{ :transactions => :optional, - [miner: :names] => :optional, + [miner: [:names, :smart_contract, :proxy_implementations]] => :optional, :rewards => :optional }, block_type: "Reorg" @@ -184,7 +184,7 @@ defmodule BlockScoutWeb.PagingHelper do do: [ necessity_by_association: %{ :transactions => :optional, - [miner: :names] => :optional, + [miner: [:names, :smart_contract, :proxy_implementations]] => :optional, :rewards => :optional }, block_type: "Block" @@ -303,4 +303,21 @@ defmodule BlockScoutWeb.PagingHelper do do: [{:dynamic, :blocks_validated, :desc_nulls_last, ValidatorStability.dynamic_validated_blocks()}] defp do_validators_stability_sorting(_, _), do: [] + + @spec mud_records_sorting(%{required(String.t()) => String.t()}) :: [ + {:sorting, SortingHelper.sorting_params()} + ] + def mud_records_sorting(%{"sort" => sort_field, "order" => order}) do + [sorting: do_mud_records_sorting(sort_field, order)] + end + + def mud_records_sorting(_), do: [] + + defp do_mud_records_sorting("key_bytes", "asc"), do: [asc_nulls_first: :key_bytes] + defp do_mud_records_sorting("key_bytes", "desc"), do: [desc_nulls_last: :key_bytes] + defp do_mud_records_sorting("key0", "asc"), do: [asc_nulls_first: :key0] + defp do_mud_records_sorting("key0", "desc"), do: [desc_nulls_last: :key0] + defp do_mud_records_sorting("key1", "asc"), do: [asc_nulls_first: :key1] + defp do_mud_records_sorting("key1", "desc"), do: [desc_nulls_last: :key1] + defp do_mud_records_sorting(_, _), do: [] end diff --git a/apps/block_scout_web/lib/block_scout_web/plug/admin/check_owner_registered.ex b/apps/block_scout_web/lib/block_scout_web/plug/admin/check_owner_registered.ex index b15fd168f5f2..b1ff8053269b 100644 --- a/apps/block_scout_web/lib/block_scout_web/plug/admin/check_owner_registered.ex +++ b/apps/block_scout_web/lib/block_scout_web/plug/admin/check_owner_registered.ex @@ -9,7 +9,7 @@ defmodule BlockScoutWeb.Plug.Admin.CheckOwnerRegistered do import Phoenix.Controller, only: [redirect: 2] import Plug.Conn - alias BlockScoutWeb.AdminRouter.Helpers, as: AdminRoutes + alias BlockScoutWeb.Routers.AdminRouter.Helpers, as: AdminRoutes alias Explorer.Admin alias Plug.Conn diff --git a/apps/block_scout_web/lib/block_scout_web/plug/admin/require_admin_role.ex b/apps/block_scout_web/lib/block_scout_web/plug/admin/require_admin_role.ex index bd11cd550963..2a70d8a0e0bf 100644 --- a/apps/block_scout_web/lib/block_scout_web/plug/admin/require_admin_role.ex +++ b/apps/block_scout_web/lib/block_scout_web/plug/admin/require_admin_role.ex @@ -7,7 +7,7 @@ defmodule BlockScoutWeb.Plug.Admin.RequireAdminRole do import Phoenix.Controller, only: [redirect: 2] - alias BlockScoutWeb.AdminRouter.Helpers, as: AdminRoutes + alias BlockScoutWeb.Routers.AdminRouter.Helpers, as: AdminRoutes alias Explorer.Admin def init(opts), do: opts diff --git a/apps/block_scout_web/lib/block_scout_web/prometheus/public_exporter.ex b/apps/block_scout_web/lib/block_scout_web/prometheus/public_exporter.ex new file mode 100644 index 000000000000..620af0e0f0ff --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/prometheus/public_exporter.ex @@ -0,0 +1,9 @@ +defmodule BlockScoutWeb.Prometheus.PublicExporter do + @moduledoc """ + Exports `Prometheus` metrics at `/public-metrics` + """ + + @dialyzer :no_match + + use Prometheus.PlugExporter +end diff --git a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex index dc956b249f74..b19ead1cc046 100644 --- a/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex +++ b/apps/block_scout_web/lib/block_scout_web/realtime_event_handler.ex @@ -28,6 +28,7 @@ defmodule BlockScoutWeb.RealtimeEventHandler do Subscriber.to(:token_total_supply, :on_demand) Subscriber.to(:changed_bytecode, :on_demand) Subscriber.to(:fetched_bytecode, :on_demand) + Subscriber.to(:fetched_token_instance_metadata, :on_demand) Subscriber.to(:eth_bytecode_db_lookup_started, :on_demand) Subscriber.to(:zkevm_confirmed_batches, :realtime) # Does not come from the indexer diff --git a/apps/block_scout_web/lib/block_scout_web/router.ex b/apps/block_scout_web/lib/block_scout_web/router.ex index 86da395f13cf..07300fd79bbd 100644 --- a/apps/block_scout_web/lib/block_scout_web/router.ex +++ b/apps/block_scout_web/lib/block_scout_web/router.ex @@ -2,13 +2,24 @@ defmodule BlockScoutWeb.Router do use BlockScoutWeb, :router alias BlockScoutWeb.Plug.{GraphQL, RateLimit} - alias BlockScoutWeb.{ApiRouter, WebRouter} + alias BlockScoutWeb.Routers.{AccountRouter, ApiRouter, WebRouter} + + @max_query_string_length 5_000 if Application.compile_env(:block_scout_web, :admin_panel_enabled) do - forward("/admin", BlockScoutWeb.AdminRouter) + forward("/admin", BlockScoutWeb.Routers.AdminRouter) end pipeline :browser do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 100_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :block_scout_web) plug(:accepts, ["html"]) plug(:fetch_session) @@ -18,16 +29,34 @@ defmodule BlockScoutWeb.Router do end pipeline :api do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api) plug(:accepts, ["json"]) end pipeline :api_v1_graphql do + plug( + Plug.Parsers, + parsers: [:json, Absinthe.Plug.Parser], + json_decoder: Poison, + body_reader: {BlockScoutWeb.GraphQL.BodyReader, :read_body, []} + ) + plug(BlockScoutWeb.Plug.Logger, application: :api) plug(:accepts, ["json"]) plug(RateLimit, graphql?: true) end + match(:*, "/auth/*path", AccountRouter, []) + forward("/api", ApiRouter) scope "/graphiql" do @@ -66,12 +95,6 @@ defmodule BlockScoutWeb.Router do end if Application.compile_env(:block_scout_web, WebRouter)[:enabled] do - forward("/", BlockScoutWeb.WebRouter) - else - scope "/", BlockScoutWeb do - pipe_through(:browser) - - forward("/", APIDocsController, :index) - end + forward("/", BlockScoutWeb.Routers.WebRouter) end end diff --git a/apps/block_scout_web/lib/block_scout_web/routers/account_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/account_router.ex new file mode 100644 index 000000000000..6263aa6d7965 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/routers/account_router.ex @@ -0,0 +1,173 @@ +defmodule BlockScoutWeb.Routers.AccountRouter do + @moduledoc """ + Router for account-related requests + """ + use BlockScoutWeb, :router + + alias BlockScoutWeb.Account.Api.V2.{AuthenticateController, EmailController, TagsController, UserController} + alias BlockScoutWeb.Plug.{CheckAccountAPI, CheckAccountWeb} + + @max_query_string_length 5_000 + + pipeline :account_web do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 100_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :block_scout_web) + plug(:accepts, ["html"]) + plug(:fetch_session) + plug(:fetch_flash) + plug(CheckAccountWeb) + plug(:protect_from_forgery) + plug(BlockScoutWeb.CSPHeader) + plug(BlockScoutWeb.ChecksumAddress) + end + + pipeline :account_api do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 100_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :api) + plug(:accepts, ["json"]) + plug(:fetch_session) + plug(:protect_from_forgery) + plug(CheckAccountAPI) + end + + pipeline :api do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :api) + plug(:accepts, ["json"]) + end + + scope "/auth", BlockScoutWeb do + pipe_through(:account_web) + + get("/profile", Account.AuthController, :profile) + get("/logout", Account.AuthController, :logout) + get("/:provider", Account.AuthController, :request) + get("/:provider/callback", Account.AuthController, :callback) + end + + scope "/", BlockScoutWeb do + pipe_through(:account_web) + + resources("/tag_address", Account.TagAddressController, + only: [:index, :new, :create, :delete], + as: :tag_address + ) + + resources("/tag_transaction", Account.TagTransactionController, + only: [:index, :new, :create, :delete], + as: :tag_transaction + ) + + resources("/watchlist", Account.WatchlistController, + only: [:show], + singleton: true, + as: :watchlist + ) + + resources("/watchlist_address", Account.WatchlistAddressController, + only: [:new, :create, :edit, :update, :delete], + as: :watchlist_address + ) + + resources("/api_key", Account.ApiKeyController, + only: [:new, :create, :edit, :update, :delete, :index], + as: :api_key + ) + + resources("/custom_abi", Account.CustomABIController, + only: [:new, :create, :edit, :update, :delete, :index], + as: :custom_abi + ) + + resources("/public_tags_request", Account.PublicTagsRequestController, + only: [:new, :create, :edit, :update, :delete, :index], + as: :public_tags_request + ) + end + + scope "/v2", as: :account_v2 do + pipe_through(:account_api) + + get("/authenticate", AuthenticateController, :authenticate_get) + post("/authenticate", AuthenticateController, :authenticate_post) + + get("/get_csrf", UserController, :get_csrf) + + scope "/email" do + get("/resend", EmailController, :resend_email) + end + + scope "/user" do + get("/info", UserController, :info) + + get("/watchlist", UserController, :watchlist) + delete("/watchlist/:id", UserController, :delete_watchlist) + post("/watchlist", UserController, :create_watchlist) + put("/watchlist/:id", UserController, :update_watchlist) + + get("/api_keys", UserController, :api_keys) + delete("/api_keys/:api_key", UserController, :delete_api_key) + post("/api_keys", UserController, :create_api_key) + put("/api_keys/:api_key", UserController, :update_api_key) + + get("/custom_abis", UserController, :custom_abis) + delete("/custom_abis/:id", UserController, :delete_custom_abi) + post("/custom_abis", UserController, :create_custom_abi) + put("/custom_abis/:id", UserController, :update_custom_abi) + + get("/public_tags", UserController, :public_tags_requests) + delete("/public_tags/:id", UserController, :delete_public_tags_request) + post("/public_tags", UserController, :create_public_tags_request) + put("/public_tags/:id", UserController, :update_public_tags_request) + + scope "/tags" do + get("/address/", UserController, :tags_address) + get("/address/:id", UserController, :tags_address) + delete("/address/:id", UserController, :delete_tag_address) + post("/address/", UserController, :create_tag_address) + put("/address/:id", UserController, :update_tag_address) + + get("/transaction/", UserController, :tags_transaction) + get("/transaction/:id", UserController, :tags_transaction) + delete("/transaction/:id", UserController, :delete_tag_transaction) + post("/transaction/", UserController, :create_tag_transaction) + put("/transaction/:id", UserController, :update_tag_transaction) + end + end + end + + scope "/v2" do + pipe_through(:api) + pipe_through(:account_api) + + scope "/tags" do + get("/address/:address_hash", TagsController, :tags_address) + + get("/transaction/:transaction_hash", TagsController, :tags_transaction) + end + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/admin_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/admin_router.ex similarity index 83% rename from apps/block_scout_web/lib/block_scout_web/admin_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/admin_router.ex index 7a1c328ba355..d452980ae9ff 100644 --- a/apps/block_scout_web/lib/block_scout_web/admin_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/admin_router.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.AdminRouter do +defmodule BlockScoutWeb.Routers.AdminRouter do @moduledoc """ Router for admin pages. """ @@ -9,6 +9,15 @@ defmodule BlockScoutWeb.AdminRouter do alias BlockScoutWeb.Plug.Admin.{CheckOwnerRegistered, RequireAdminRole} pipeline :browser do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 10_000, + query_string_length: 5_000, + pass: ["*/*"], + json_decoder: Poison + ) + plug(:accepts, ["html"]) plug(:fetch_session) plug(:fetch_flash) diff --git a/apps/block_scout_web/lib/block_scout_web/api_key_v2_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/api_key_v2_router.ex similarity index 65% rename from apps/block_scout_web/lib/block_scout_web/api_key_v2_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/api_key_v2_router.ex index a1b9943f9bc8..8c656e6cedab 100644 --- a/apps/block_scout_web/lib/block_scout_web/api_key_v2_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/api_key_v2_router.ex @@ -1,4 +1,4 @@ -defmodule BlockScoutWeb.APIKeyV2Router do +defmodule BlockScoutWeb.Routers.APIKeyV2Router do @moduledoc """ Router for /api/v2/key. This route has separate router in order to avoid rate limiting """ @@ -6,6 +6,15 @@ defmodule BlockScoutWeb.APIKeyV2Router do alias BlockScoutWeb.Plug.{CheckApiV2, Logger} pipeline :api_v2 do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 10_000, + query_string_length: 5_000, + pass: ["*/*"], + json_decoder: Poison + ) + plug(Logger, application: :api_v2) plug(:accepts, ["json"]) plug(CheckApiV2) diff --git a/apps/block_scout_web/lib/block_scout_web/api_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/api_router.ex similarity index 78% rename from apps/block_scout_web/lib/block_scout_web/api_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/api_router.ex index 939e55297c26..a2f6bd9d4b83 100644 --- a/apps/block_scout_web/lib/block_scout_web/api_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/api_router.ex @@ -8,30 +8,47 @@ defmodule RPCTranslatorForwarder do defdelegate call(conn, opts), to: RPCTranslator end -defmodule BlockScoutWeb.ApiRouter do +defmodule BlockScoutWeb.Routers.ApiRouter do @moduledoc """ Router for API """ use BlockScoutWeb, :router - alias BlockScoutWeb.{AddressTransactionController, APIKeyV2Router, SmartContractsApiV2Router, UtilsApiV2Router} - alias BlockScoutWeb.Plug.{CheckAccountAPI, CheckApiV2, RateLimit} + alias BlockScoutWeb.AddressTransactionController + alias BlockScoutWeb.Routers.{APIKeyV2Router, SmartContractsApiV2Router, TokensApiV2Router, UtilsApiV2Router} + alias BlockScoutWeb.Plug.{CheckApiV2, RateLimit} + alias BlockScoutWeb.Routers.AccountRouter + + @max_query_string_length 5_000 forward("/v2/smart-contracts", SmartContractsApiV2Router) + forward("/v2/tokens", TokensApiV2Router) + forward("/v2/key", APIKeyV2Router) forward("/v2/utils", UtilsApiV2Router) pipeline :api do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api) plug(:accepts, ["json"]) end - pipeline :account_api do - plug(:fetch_session) - plug(:protect_from_forgery) - plug(CheckAccountAPI) - end - pipeline :api_v2 do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) plug(:accepts, ["json"]) plug(CheckApiV2) @@ -41,6 +58,14 @@ defmodule BlockScoutWeb.ApiRouter do end pipeline :api_v2_no_session do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) plug(:accepts, ["json"]) plug(CheckApiV2) @@ -48,76 +73,21 @@ defmodule BlockScoutWeb.ApiRouter do end pipeline :api_v1_graphql do + plug( + Plug.Parsers, + parsers: [:json, Absinthe.Plug.Parser], + json_decoder: Poison, + body_reader: {BlockScoutWeb.GraphQL.BodyReader, :read_body, []} + ) + plug(BlockScoutWeb.Plug.Logger, application: :api) plug(:accepts, ["json"]) plug(RateLimit, graphql?: true) end - alias BlockScoutWeb.Account.Api.V2.{AuthenticateController, EmailController, TagsController, UserController} alias BlockScoutWeb.API.V2 - scope "/account/v2", as: :account_v2 do - pipe_through(:api) - pipe_through(:account_api) - - get("/authenticate", AuthenticateController, :authenticate_get) - post("/authenticate", AuthenticateController, :authenticate_post) - - get("/get_csrf", UserController, :get_csrf) - - scope "/email" do - get("/resend", EmailController, :resend_email) - end - - scope "/user" do - get("/info", UserController, :info) - - get("/watchlist", UserController, :watchlist) - delete("/watchlist/:id", UserController, :delete_watchlist) - post("/watchlist", UserController, :create_watchlist) - put("/watchlist/:id", UserController, :update_watchlist) - - get("/api_keys", UserController, :api_keys) - delete("/api_keys/:api_key", UserController, :delete_api_key) - post("/api_keys", UserController, :create_api_key) - put("/api_keys/:api_key", UserController, :update_api_key) - - get("/custom_abis", UserController, :custom_abis) - delete("/custom_abis/:id", UserController, :delete_custom_abi) - post("/custom_abis", UserController, :create_custom_abi) - put("/custom_abis/:id", UserController, :update_custom_abi) - - get("/public_tags", UserController, :public_tags_requests) - delete("/public_tags/:id", UserController, :delete_public_tags_request) - post("/public_tags", UserController, :create_public_tags_request) - put("/public_tags/:id", UserController, :update_public_tags_request) - - scope "/tags" do - get("/address/", UserController, :tags_address) - get("/address/:id", UserController, :tags_address) - delete("/address/:id", UserController, :delete_tag_address) - post("/address/", UserController, :create_tag_address) - put("/address/:id", UserController, :update_tag_address) - - get("/transaction/", UserController, :tags_transaction) - get("/transaction/:id", UserController, :tags_transaction) - delete("/transaction/:id", UserController, :delete_tag_transaction) - post("/transaction/", UserController, :create_tag_transaction) - put("/transaction/:id", UserController, :update_tag_transaction) - end - end - end - - scope "/account/v2" do - pipe_through(:api) - pipe_through(:account_api) - - scope "/tags" do - get("/address/:address_hash", TagsController, :tags_address) - - get("/transaction/:transaction_hash", TagsController, :tags_transaction) - end - end + forward("/account", AccountRouter) scope "/v2/import" do pipe_through(:api_v2_no_session) @@ -152,6 +122,10 @@ defmodule BlockScoutWeb.ApiRouter do get("/zksync-batch/:batch_number", V2.TransactionController, :zksync_batch) end + if Application.compile_env(:explorer, :chain_type) == :arbitrum do + get("/arbitrum-batch/:batch_number", V2.TransactionController, :arbitrum_batch) + end + if Application.compile_env(:explorer, :chain_type) == :suave do get("/execution-node/:execution_node_hash_param", V2.TransactionController, :execution_node) end @@ -175,6 +149,10 @@ defmodule BlockScoutWeb.ApiRouter do get("/:block_hash_or_number/transactions", V2.BlockController, :transactions) get("/:block_hash_or_number/internal-transactions", V2.BlockController, :internal_transactions) get("/:block_hash_or_number/withdrawals", V2.BlockController, :withdrawals) + + if Application.compile_env(:explorer, :chain_type) == :arbitrum do + get("/arbitrum-batch/:batch_number", V2.BlockController, :arbitrum_batch) + end end scope "/addresses" do @@ -196,24 +174,6 @@ defmodule BlockScoutWeb.ApiRouter do get("/:address_hash_param/nft/collections", V2.AddressController, :nft_collections) end - scope "/tokens" do - if Application.compile_env(:explorer, Explorer.Chain.BridgedToken)[:enabled] do - get("/bridged", V2.TokenController, :bridged_tokens_list) - end - - get("/", V2.TokenController, :tokens_list) - get("/:address_hash_param", V2.TokenController, :token) - get("/:address_hash_param/counters", V2.TokenController, :counters) - get("/:address_hash_param/transfers", V2.TokenController, :transfers) - get("/:address_hash_param/holders", V2.TokenController, :holders) - get("/:address_hash_param/holders/csv", V2.CSVExportController, :export_token_holders) - get("/:address_hash_param/instances", V2.TokenController, :instances) - get("/:address_hash_param/instances/:token_id", V2.TokenController, :instance) - get("/:address_hash_param/instances/:token_id/transfers", V2.TokenController, :transfers_by_instance) - get("/:address_hash_param/instances/:token_id/holders", V2.TokenController, :holders_by_instance) - get("/:address_hash_param/instances/:token_id/transfers-count", V2.TokenController, :transfers_count_by_instance) - end - scope "/main-page" do get("/blocks", V2.MainPageController, :blocks) get("/transactions", V2.MainPageController, :transactions) @@ -233,6 +193,12 @@ defmodule BlockScoutWeb.ApiRouter do get("/zksync/batches/confirmed", V2.ZkSyncController, :batches_confirmed) get("/zksync/batches/latest-number", V2.ZkSyncController, :batch_latest_number) end + + if Application.compile_env(:explorer, :chain_type) == :arbitrum do + get("/arbitrum/messages/to-rollup", V2.ArbitrumController, :recent_messages_to_l2) + get("/arbitrum/batches/committed", V2.ArbitrumController, :batches_committed) + get("/arbitrum/batches/latest-number", V2.ArbitrumController, :batch_latest_number) + end end scope "/stats" do @@ -346,6 +312,34 @@ defmodule BlockScoutWeb.ApiRouter do get("/batches/:batch_number", V2.ZkSyncController, :batch) end end + + scope "/mud" do + if Application.compile_env(:explorer, Explorer.Chain.Mud)[:enabled] do + get("/worlds", V2.MudController, :worlds) + get("/worlds/count", V2.MudController, :worlds_count) + get("/worlds/:world/tables", V2.MudController, :world_tables) + get("/worlds/:world/tables/count", V2.MudController, :world_tables_count) + get("/worlds/:world/tables/:table_id/records", V2.MudController, :world_table_records) + get("/worlds/:world/tables/:table_id/records/count", V2.MudController, :world_table_records_count) + get("/worlds/:world/tables/:table_id/records/:record_id", V2.MudController, :world_table_record) + end + end + + scope "/arbitrum" do + if Application.compile_env(:explorer, :chain_type) == :arbitrum do + get("/messages/:direction", V2.ArbitrumController, :messages) + get("/messages/:direction/count", V2.ArbitrumController, :messages_count) + get("/batches", V2.ArbitrumController, :batches) + get("/batches/count", V2.ArbitrumController, :batches_count) + get("/batches/:batch_number", V2.ArbitrumController, :batch) + end + end + + scope "/advanced-filters" do + get("/", V2.AdvancedFilterController, :list) + get("/csv", V2.AdvancedFilterController, :list_csv) + get("/methods", V2.AdvancedFilterController, :list_methods) + end end scope "/v1/graphql" do diff --git a/apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/smart_contracts_api_v2_router.ex similarity index 51% rename from apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/smart_contracts_api_v2_router.ex index aad961f117f5..1a0e8922cb51 100644 --- a/apps/block_scout_web/lib/block_scout_web/smart_contracts_api_v2_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/smart_contracts_api_v2_router.ex @@ -1,12 +1,41 @@ # This file in ignore list of `sobelow`, be careful while adding new endpoints here -defmodule BlockScoutWeb.SmartContractsApiV2Router do +defmodule BlockScoutWeb.Routers.SmartContractsApiV2Router do @moduledoc """ Router for /api/v2/smart-contracts. This route has separate router in order to ignore sobelow's warning about missing CSRF protection """ use BlockScoutWeb, :router + alias BlockScoutWeb.API.V2 alias BlockScoutWeb.Plug.{CheckApiV2, RateLimit} + @max_query_string_length 5_000 + + pipeline :api_v2 do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) + plug(:accepts, ["json"]) + plug(CheckApiV2) + plug(:fetch_session) + plug(:protect_from_forgery) + plug(RateLimit) + end + pipeline :api_v2_no_forgery_protect do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: 5_000, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) plug(:accepts, ["json"]) plug(CheckApiV2) @@ -15,9 +44,7 @@ defmodule BlockScoutWeb.SmartContractsApiV2Router do end scope "/", as: :api_v2 do - pipe_through(:api_v2_no_forgery_protect) - - alias BlockScoutWeb.API.V2 + pipe_through(:api_v2) get("/", V2.SmartContractController, :smart_contracts_list) get("/counters", V2.SmartContractController, :smart_contracts_counters) @@ -26,21 +53,28 @@ defmodule BlockScoutWeb.SmartContractsApiV2Router do get("/:address_hash/methods-write", V2.SmartContractController, :methods_write) get("/:address_hash/methods-read-proxy", V2.SmartContractController, :methods_read_proxy) get("/:address_hash/methods-write-proxy", V2.SmartContractController, :methods_write_proxy) - post("/:address_hash/query-read-method", V2.SmartContractController, :query_read_method) get("/:address_hash/solidityscan-report", V2.SmartContractController, :solidityscan_report) - post("/:address_hash/audit-reports", V2.SmartContractController, :audit_report_submission) get("/:address_hash/audit-reports", V2.SmartContractController, :audit_reports_list) get("/verification/config", V2.VerificationController, :config) + end + + scope "/", as: :api_v2 do + pipe_through(:api_v2_no_forgery_protect) + + post("/:address_hash/query-read-method", V2.SmartContractController, :query_read_method) + post("/:address_hash/audit-reports", V2.SmartContractController, :audit_report_submission) + end + + scope "/:address_hash/verification/via", as: :api_v2 do + pipe_through(:api_v2_no_forgery_protect) - scope "/:address_hash/verification/via" do - post("/flattened-code", V2.VerificationController, :verification_via_flattened_code) - post("/standard-input", V2.VerificationController, :verification_via_standard_input) - post("/sourcify", V2.VerificationController, :verification_via_sourcify) - post("/multi-part", V2.VerificationController, :verification_via_multi_part) - post("/vyper-code", V2.VerificationController, :verification_via_vyper_code) - post("/vyper-multi-part", V2.VerificationController, :verification_via_vyper_multipart) - post("/vyper-standard-input", V2.VerificationController, :verification_via_vyper_standard_input) - end + post("/flattened-code", V2.VerificationController, :verification_via_flattened_code) + post("/standard-input", V2.VerificationController, :verification_via_standard_input) + post("/sourcify", V2.VerificationController, :verification_via_sourcify) + post("/multi-part", V2.VerificationController, :verification_via_multi_part) + post("/vyper-code", V2.VerificationController, :verification_via_vyper_code) + post("/vyper-multi-part", V2.VerificationController, :verification_via_vyper_multipart) + post("/vyper-standard-input", V2.VerificationController, :verification_via_vyper_standard_input) end end diff --git a/apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex new file mode 100644 index 000000000000..c9506cfc84e2 --- /dev/null +++ b/apps/block_scout_web/lib/block_scout_web/routers/tokens_api_v2_router.ex @@ -0,0 +1,71 @@ +# This file in ignore list of `sobelow`, be careful while adding new endpoints here +defmodule BlockScoutWeb.Routers.TokensApiV2Router do + @moduledoc """ + Router for /api/v2/tokens. This route has separate router in order to ignore sobelow's warning about missing CSRF protection + """ + use BlockScoutWeb, :router + alias BlockScoutWeb.API.V2 + alias BlockScoutWeb.Plug.{CheckApiV2, RateLimit} + + @max_query_string_length 5_000 + + pipeline :api_v2 do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) + plug(:accepts, ["json"]) + plug(CheckApiV2) + plug(:fetch_session) + plug(:protect_from_forgery) + plug(RateLimit) + end + + pipeline :api_v2_no_forgery_protect do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: 5_000, + pass: ["*/*"], + json_decoder: Poison + ) + + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) + plug(:accepts, ["json"]) + plug(CheckApiV2) + plug(RateLimit) + plug(:fetch_session) + end + + scope "/", as: :api_v2 do + pipe_through(:api_v2_no_forgery_protect) + + patch("/:address_hash_param/instances/:token_id/refetch-metadata", V2.TokenController, :refetch_metadata) + end + + scope "/", as: :api_v2 do + pipe_through(:api_v2) + + if Application.compile_env(:explorer, Explorer.Chain.BridgedToken)[:enabled] do + get("/bridged", V2.TokenController, :bridged_tokens_list) + end + + get("/", V2.TokenController, :tokens_list) + get("/:address_hash_param", V2.TokenController, :token) + get("/:address_hash_param/counters", V2.TokenController, :counters) + get("/:address_hash_param/transfers", V2.TokenController, :transfers) + get("/:address_hash_param/holders", V2.TokenController, :holders) + get("/:address_hash_param/holders/csv", V2.CSVExportController, :export_token_holders) + get("/:address_hash_param/instances", V2.TokenController, :instances) + get("/:address_hash_param/instances/:token_id", V2.TokenController, :instance) + get("/:address_hash_param/instances/:token_id/transfers", V2.TokenController, :transfers_by_instance) + get("/:address_hash_param/instances/:token_id/holders", V2.TokenController, :holders_by_instance) + get("/:address_hash_param/instances/:token_id/transfers-count", V2.TokenController, :transfers_count_by_instance) + end +end diff --git a/apps/block_scout_web/lib/block_scout_web/utils_api_v2_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/utils_api_v2_router.ex similarity index 75% rename from apps/block_scout_web/lib/block_scout_web/utils_api_v2_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/utils_api_v2_router.ex index 572133156dd5..2e9b8ef66fd3 100644 --- a/apps/block_scout_web/lib/block_scout_web/utils_api_v2_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/utils_api_v2_router.ex @@ -1,5 +1,5 @@ # This file in ignore list of `sobelow`, be careful while adding new endpoints here -defmodule BlockScoutWeb.UtilsApiV2Router do +defmodule BlockScoutWeb.Routers.UtilsApiV2Router do @moduledoc """ Router for /api/v2/utils. This route has separate router in order to ignore sobelow's warning about missing CSRF protection """ @@ -7,6 +7,15 @@ defmodule BlockScoutWeb.UtilsApiV2Router do alias BlockScoutWeb.Plug.{CheckApiV2, RateLimit} pipeline :api_v2_no_forgery_protect do + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 100_000, + query_string_length: 5_000, + pass: ["*/*"], + json_decoder: Poison + ) + plug(BlockScoutWeb.Plug.Logger, application: :api_v2) plug(:accepts, ["json"]) plug(CheckApiV2) diff --git a/apps/block_scout_web/lib/block_scout_web/web_router.ex b/apps/block_scout_web/lib/block_scout_web/routers/web_router.ex similarity index 85% rename from apps/block_scout_web/lib/block_scout_web/web_router.ex rename to apps/block_scout_web/lib/block_scout_web/routers/web_router.ex index 3f3dbed7d10e..2e8bce57fc60 100644 --- a/apps/block_scout_web/lib/block_scout_web/web_router.ex +++ b/apps/block_scout_web/lib/block_scout_web/routers/web_router.ex @@ -1,28 +1,28 @@ -defmodule BlockScoutWeb.WebRouter do +defmodule BlockScoutWeb.Routers.WebRouter do @moduledoc """ Router for web app """ use BlockScoutWeb, :router require Ueberauth - alias BlockScoutWeb.Plug.CheckAccountWeb + alias BlockScoutWeb.Routers.AccountRouter + + @max_query_string_length 5_000 pipeline :browser do - plug(BlockScoutWeb.Plug.Logger, application: :block_scout_web) - plug(:accepts, ["html"]) - plug(:fetch_session) - plug(:fetch_flash) - plug(:protect_from_forgery) - plug(BlockScoutWeb.CSPHeader) - plug(BlockScoutWeb.ChecksumAddress) - end + plug( + Plug.Parsers, + parsers: [:urlencoded, :multipart, :json], + length: 20_000_000, + query_string_length: @max_query_string_length, + pass: ["*/*"], + json_decoder: Poison + ) - pipeline :account do plug(BlockScoutWeb.Plug.Logger, application: :block_scout_web) plug(:accepts, ["html"]) plug(:fetch_session) plug(:fetch_flash) - plug(CheckAccountWeb) plug(:protect_from_forgery) plug(BlockScoutWeb.CSPHeader) plug(BlockScoutWeb.ChecksumAddress) @@ -32,54 +32,7 @@ defmodule BlockScoutWeb.WebRouter do forward("/sent_emails", Bamboo.SentEmailViewerPlug) end - scope "/auth", BlockScoutWeb do - pipe_through(:account) - - get("/profile", Account.AuthController, :profile) - get("/logout", Account.AuthController, :logout) - get("/:provider", Account.AuthController, :request) - get("/:provider/callback", Account.AuthController, :callback) - end - - scope "/account", BlockScoutWeb do - pipe_through(:account) - - resources("/tag_address", Account.TagAddressController, - only: [:index, :new, :create, :delete], - as: :tag_address - ) - - resources("/tag_transaction", Account.TagTransactionController, - only: [:index, :new, :create, :delete], - as: :tag_transaction - ) - - resources("/watchlist", Account.WatchlistController, - only: [:show], - singleton: true, - as: :watchlist - ) - - resources("/watchlist_address", Account.WatchlistAddressController, - only: [:new, :create, :edit, :update, :delete], - as: :watchlist_address - ) - - resources("/api_key", Account.ApiKeyController, - only: [:new, :create, :edit, :update, :delete, :index], - as: :api_key - ) - - resources("/custom_abi", Account.CustomABIController, - only: [:new, :create, :edit, :update, :delete, :index], - as: :custom_abi - ) - - resources("/public_tags_request", Account.PublicTagsRequestController, - only: [:new, :create, :edit, :update, :delete, :index], - as: :public_tags_request - ) - end + forward("/account", AccountRouter) # Disallows Iframes (write routes) scope "/", BlockScoutWeb do diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex index d28be9224205..43c95a808547 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex @@ -1,6 +1,14 @@ +<% implementation_names = Implementation.names(@address) %> +<% implementation_name = + if Enum.empty?(implementation_names) do + nil + else + implementation_names |> Enum.at(0) + end +%> <%= if @address do %> <%= if assigns[:show_full_hash] do %> - <%= if name = if assigns[:ignore_implementation_name], do: primary_name(@address), else: implementation_name(@address) || primary_name(@address) do %> + <%= if name = if assigns[:ignore_implementation_name], do: primary_name(@address), else: implementation_name || primary_name(@address) do %> <%= name %> | <% end %> <%= link to: address_path(BlockScoutWeb.Endpoint, :show, @address), "data-test": "address_hash_link", class: assigns[:class] do %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex index c3dc9af56103..b602d96e7d37 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex @@ -1,5 +1,13 @@ +<% implementation_names = Implementation.names(@address) %> +<% implementation_name = + if Enum.empty?(implementation_names) do + nil + else + implementation_names |> Enum.at(0) + end +%> - <%= if name = if assigns[:ignore_implementation_name], do: primary_name(@address), else: implementation_name(@address) || primary_name(@address) do %> + <%= if name = if assigns[:ignore_implementation_name], do: primary_name(@address), else: implementation_name || primary_name(@address) do %> <%= if assigns[:no_tooltip] do %> <%= if @use_custom_tooltip == true do %> <%= name %> (<%= short_hash(@address) %>...) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index 005508956e65..dfc00f704859 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -124,7 +124,9 @@ <% end %> <%= if @is_proxy do %> - <% {implementation_address_, name} = SmartContract.get_implementation_address_hash(@address.smart_contract) %> + <% {implementation_addresses, implementation_names} = Implementation.get_implementation(@address.smart_contract) %> + <% implementation_address_ = Enum.at(implementation_addresses, 0) %> + <% name = Enum.at(implementation_names, 0) %> <% implementation_address = implementation_address_ || "0x0000000000000000000000000000000000000000" %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex index 4a052b2fa539..d5b804f42b3f 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract/index.html.eex @@ -1,9 +1,9 @@ <% contract_creation_code = contract_creation_code(@address) %> -<% minimal_proxy_template = EIP1167.get_implementation_address(@address.hash) %> -<% metadata_for_verification = minimal_proxy_template || SmartContract.get_address_verified_twin_contract(@address.hash).verified_contract %> +<% minimal_proxy_template = EIP1167.get_implementation_smart_contract(@address.hash) %> +<% implementation_or_bytecode_twin_contract = minimal_proxy_template || SmartContract.get_address_verified_bytecode_twin_contract(@address.hash).verified_contract %> <% smart_contract_verified = BlockScoutWeb.AddressView.smart_contract_verified?(@address) %> <% fully_verified = SmartContract.verified_with_full_match?(@address.hash)%> -<% additional_sources = BlockScoutWeb.API.V2.SmartContractView.additional_sources(@address.smart_contract, smart_contract_verified, minimal_proxy_template, SmartContract.get_address_verified_twin_contract(@address.hash)) %> +<% additional_sources = BlockScoutWeb.API.V2.SmartContractView.get_additional_sources(@address.smart_contract, smart_contract_verified, implementation_or_bytecode_twin_contract) %> <% visualize_sol2uml_enabled = Explorer.Visualize.Sol2uml.enabled?() %>
<% is_proxy = BlockScoutWeb.AddressView.smart_contract_is_proxy?(@address) %> @@ -15,16 +15,16 @@
<%= unless smart_contract_verified do %> <%= if minimal_proxy_template do %> - <%= render BlockScoutWeb.CommonComponentsView, "_minimal_proxy_pattern.html", address_hash: metadata_for_verification.address_hash, conn: @conn %> + <%= render BlockScoutWeb.CommonComponentsView, "_minimal_proxy_pattern.html", address_hash: implementation_or_bytecode_twin_contract.address_hash, conn: @conn %> <% else %> - <%= if metadata_for_verification do %> + <%= if implementation_or_bytecode_twin_contract do %> <% path = address_verify_contract_path(@conn, :new, @address.hash) %>
<%= render BlockScoutWeb.CommonComponentsView, "_info.html" %> <%= gettext("Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB") %> <%= link( - metadata_for_verification.address_hash, - to: address_contract_path(@conn, :index, metadata_for_verification.address_hash)) %>.
<%= gettext("All metadata displayed below is from that contract. In order to verify current contract, click") %> <%= gettext("Verify & Publish") %> <%= gettext("button") %>
+ implementation_or_bytecode_twin_contract.address_hash, + to: address_contract_path(@conn, :index, implementation_or_bytecode_twin_contract.address_hash)) %>.
<%= gettext("All metadata displayed below is from that contract. In order to verify current contract, click") %> <%= gettext("Verify & Publish") %> <%= gettext("button") %>
<%= link(gettext("Verify & Publish"), to: path, class: "button button-primary button-sm float-right ml-3", "data-test": "verify_and_publish") %>
@@ -40,8 +40,8 @@
<% end %> <% end %> - <%= if smart_contract_verified || (!smart_contract_verified && metadata_for_verification) do %> - <% target_contract = if smart_contract_verified, do: @address.smart_contract, else: metadata_for_verification %> + <%= if smart_contract_verified || (!smart_contract_verified && implementation_or_bytecode_twin_contract) do %> + <% target_contract = if smart_contract_verified, do: @address.smart_contract, else: implementation_or_bytecode_twin_contract %> <%= if @address.smart_contract && @address.smart_contract.verified_via_sourcify && @address.smart_contract.partially_verified && smart_contract_verified do %>
<%= gettext("This contract has been partially verified via Sourcify.") %> @@ -240,8 +240,8 @@ <% end %>
- <%= if smart_contract_verified || (!smart_contract_verified && metadata_for_verification) do %> - <% target_contract = if smart_contract_verified, do: @address.smart_contract, else: metadata_for_verification %> + <%= if smart_contract_verified || (!smart_contract_verified && implementation_or_bytecode_twin_contract) do %> + <% target_contract = if smart_contract_verified, do: @address.smart_contract, else: implementation_or_bytecode_twin_contract %> <%= if target_contract.external_libraries && target_contract.external_libraries != [] do %>
diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_flattened_code/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_flattened_code/new.html.eex index b0a22d4bace6..8cc9b6cfb3e0 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_flattened_code/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_flattened_code/new.html.eex @@ -1,4 +1,4 @@ -<% metadata_for_verification = if assigns[:retrying], do: nil, else: SmartContract.get_address_verified_twin_contract(@address_hash).verified_contract %> +<% metadata_for_verification = if assigns[:retrying], do: nil, else: SmartContract.get_address_verified_bytecode_twin_contract(@address_hash).verified_contract %> <% changeset = (if assigns[:retrying], do: @changeset, else: SmartContract.merge_twin_contract_with_changeset(metadata_for_verification, @changeset)) |> SmartContract.address_to_checksum_address() %> <% fetch_constructor_arguments_automatically = if metadata_for_verification, do: true, else: changeset.changes[:autodetect_constructor_args] || true %> <% display_constructor_arguments_text_area = if fetch_constructor_arguments_automatically, do: "none", else: "block" %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex index 938631b3e1aa..94bcac97ac1e 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_multi_part_files/new.html.eex @@ -1,4 +1,4 @@ -<% metadata_for_verification = if assigns[:retrying], do: nil, else: SmartContract.get_address_verified_twin_contract(@address_hash).verified_contract %> +<% metadata_for_verification = if assigns[:retrying], do: nil, else: SmartContract.get_address_verified_bytecode_twin_contract(@address_hash).verified_contract %> <% changeset = (if assigns[:retrying], do: @changeset, else: SmartContract.merge_twin_contract_with_changeset(metadata_for_verification, @changeset)) |> SmartContract.address_to_checksum_address() %>
<%= render BlockScoutWeb.CommonComponentsView, "_channel_disconnected_message.html", text: gettext("Connection Lost") %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_standard_json_input/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_standard_json_input/new.html.eex index a1fb8db78646..d83939f91f4d 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_standard_json_input/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_via_standard_json_input/new.html.eex @@ -1,4 +1,4 @@ -<% metadata_for_verification = SmartContract.get_address_verified_twin_contract(@address_hash).verified_contract %> +<% metadata_for_verification = SmartContract.get_address_verified_bytecode_twin_contract(@address_hash).verified_contract %> <% changeset = (if assigns[:retrying], do: @changeset, else: SmartContract.merge_twin_contract_with_changeset(metadata_for_verification, @changeset)) |> SmartContract.address_to_checksum_address() %> <% fetch_constructor_arguments_automatically = if metadata_for_verification, do: true, else: changeset.changes[:autodetect_constructor_args] || true %> <% display_constructor_arguments_text_area = if fetch_constructor_arguments_automatically, do: "none", else: "block" %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_vyper/new.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_vyper/new.html.eex index a98282193b15..e65c32794602 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_vyper/new.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_contract_verification_vyper/new.html.eex @@ -1,4 +1,4 @@ -<% metadata_for_verification = SmartContract.get_address_verified_twin_contract(@address_hash).verified_contract %> +<% metadata_for_verification = SmartContract.get_address_verified_bytecode_twin_contract(@address_hash).verified_contract %> <% changeset = (if assigns[:retrying], do: @changeset, else: SmartContract.merge_twin_vyper_contract_with_changeset(metadata_for_verification, @changeset)) |> SmartContract.address_to_checksum_address() %>
<%= render BlockScoutWeb.CommonComponentsView, "_channel_disconnected_message.html", text: gettext("Connection Lost") %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/admin/dashboard/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/admin/dashboard/index.html.eex index 77140e58439a..af91a9122baf 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/admin/dashboard/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/admin/dashboard/index.html.eex @@ -17,7 +17,7 @@

-