From 739389137f1fbaf68ba4edf93a80356bbff12c29 Mon Sep 17 00:00:00 2001
From: "Jason M. Hasperhoven" <martijn.hasperhoven@gmail.com>
Date: Tue, 10 Sep 2024 23:13:46 +0400
Subject: [PATCH] Implement Linting, TS Config + CI (#48)

* Add trade page w/ new layout

* Add recent swaps to explorer page

* Add swaps component

* Add PairSelector component

* Setup eslint, prettier + tsconfig

* Cleanup backup files

* Add ci workflow

* Add pnpm version

* Remove unknown option for ci.yml

* Fix linting issues

* Add disable rules for older files

* Cleanup files

* Fix lint warnings for now

* Fix strict lints

---------

Co-authored-by: Lucas Meier <lucas@cronokirby.com>
---
 .github/workflows/ci.yml                      |   70 +
 .gitignore                                    |    4 +
 eslint.config.js                              |   31 +
 next-env.d.ts                                 |    2 +-
 next.config.mjs                               |    8 +-
 package.json                                  |   19 +-
 pnpm-lock.yaml                                | 1391 ++++++++++++++---
 prettier.config.js                            |    3 +
 scripts/disable-lint-for-tmp-excludes.js      |   28 +
 scripts/tmp-lint-excludes.js                  |   67 +
 src/components/blockTimestamp.tsx             |    5 +-
 src/components/blocks/index.tsx               |   89 +-
 src/components/charts/buySellChart.tsx        |   48 +-
 src/components/charts/depthChart.tsx          |   26 +-
 src/components/charts/ohlcChart.tsx           |   60 +-
 src/components/copiedTx.tsx                   |    2 +
 .../executionHistory/blockDetails.tsx         |    6 +-
 .../executionHistory/blockSummary.tsx         |    4 +-
 src/components/layout.tsx                     |    2 +
 .../liquidityPositions/closedStatus.tsx       |    6 +-
 .../liquidityPositions/currentStatus.tsx      |   34 +-
 .../liquidityPositions/executionEvent.tsx     |    2 +
 .../liquidityPositions/openStatus.tsx         |    6 +-
 .../liquidityPositions/timelinePosition.tsx   |    8 +-
 .../liquidityPositions/withdrawnStatus.tsx    |    6 +-
 src/components/lpAssetView.tsx                |   11 +-
 src/components/lpSearchBar.tsx                |    2 +
 src/components/navbar.tsx                     |    2 +
 src/components/pairSelector.tsx               |   87 +-
 src/components/swaps/index.tsx                |    9 +-
 src/components/util/loadingSpinner.tsx        |    2 +
 src/constants/configConstants.ts              |    8 +-
 src/pages/_app.tsx                            |    2 +
 src/pages/api/arbs/[...params].ts             |   51 +-
 src/pages/api/blockTimestamps/[...params].js  |   14 +-
 src/pages/api/blocks/[...params].js           |   30 +-
 src/pages/api/lp/[lp_nft_id].js               |    2 +
 src/pages/api/lp/[lp_nft_id]/position.ts      |    4 +-
 src/pages/api/lp/[lp_nft_id]/trades.js        |    2 +
 src/pages/api/lp/block/[...params].js         |    2 +
 .../api/lp/positionsByPrice/[...params].ts    |    8 +-
 src/pages/api/ohlc/[...params].ts             |   10 +-
 src/pages/api/shieldedPool/[token_inner].ts   |    4 +-
 src/pages/api/simulations/[...params].ts      |   10 +-
 src/pages/api/swaps/[...params].ts            |    4 +-
 src/pages/block/[block_height].tsx            |   50 +-
 src/pages/explorer/index.tsx                  |    2 +
 src/pages/index.tsx                           |    3 +-
 src/pages/lp/[lp_nft_id].tsx                  |    4 +-
 src/pages/lp/utils.tsx                        |    2 +
 src/pages/pair/[...params].tsx                |   28 +-
 src/pages/pair/index.tsx                      |    6 +-
 src/pages/trade/[[...params]].tsx             |   28 +-
 src/pages/trades.tsx                          |   44 +-
 src/utils/indexer/connector.tsx               |    6 +-
 src/utils/indexer/types/lps.tsx               |   16 +-
 src/utils/math/base64.ts                      |    4 +-
 src/utils/math/bech32.ts                      |    2 +
 src/utils/math/hex.ts                         |    8 +-
 src/utils/math/hiLo.ts                        |    2 +
 .../protos/services/app/shielded-pool.ts      |    4 +-
 .../services/dex/dex-query-service-client.ts  |   44 +-
 .../protos/services/dex/simulated-trades.ts   |    2 +
 src/utils/protos/types/ShieldedPoolQuerier.ts |    2 +
 src/utils/protos/types/SimulationQuerier.ts   |    2 +
 src/utils/token/tokenFetch.tsx                |   20 +-
 src/utils/types/block.tsx                     |   10 +-
 src/utils/types/token.tsx                     |   13 +-
 tsconfig.json                                 |   40 +-
 69 files changed, 1854 insertions(+), 679 deletions(-)
 create mode 100644 .github/workflows/ci.yml
 create mode 100644 eslint.config.js
 create mode 100644 prettier.config.js
 create mode 100644 scripts/disable-lint-for-tmp-excludes.js
 create mode 100644 scripts/tmp-lint-excludes.js

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..f9974ed8
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,70 @@
+name: CI
+on:
+  workflow_call:
+  workflow_dispatch:
+  pull_request:
+  push:
+    branches:
+      - main
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  lint:
+    name: Lint
+    runs-on: buildjet-8vcpu-ubuntu-2204
+    steps:
+      - uses: actions/checkout@v4
+      - id: lint
+        uses: buildjet/cache@v4
+        with:
+          path: .next
+          key: $${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-lint
+          restore-keys: $${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-compiled
+      - uses: pnpm/action-setup@v4
+      - uses: buildjet/setup-node@v4
+        with:
+          node-version: "18"
+          cache: "pnpm"
+      - run: pnpm install --frozen-lockfile
+      - run: pnpm lint:strict
+
+  build:
+    name: Build
+    runs-on: buildjet-8vcpu-ubuntu-2204
+    steps:
+      - uses: actions/checkout@v4
+      - id: build
+        uses: buildjet/cache@v4
+        with:
+          path: .next
+          key: ${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-built
+          restore-keys: ${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-compiled
+      - uses: pnpm/action-setup@v4
+      - uses: buildjet/setup-node@v4
+        with:
+          node-version: "18"
+          cache: "pnpm"
+      - run: pnpm install --frozen-lockfile
+      - run: pnpm build
+
+  # test:
+  #   name: test
+  #   runs-on: buildjet-4vcpu-ubuntu-2204
+  #   steps:
+  #     - uses: actions/checkout@v4
+  #     - id: tested
+  #       uses: buildjet/cache@v4
+  #       with:
+  #         path: .next
+  #         key: ${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-test
+  #         restore-keys: ${{ hashFiles('pnpm-lock.yaml') }}-${{ github.ref }}-${{ github.sha }}-compiled
+  #     - uses: pnpm/action-setup@v4
+  #     - uses: buildjet/setup-node@v4
+  #       with:
+  #         node-version: "22"
+  #         cache: "pnpm"
+  #     - run: pnpm install --frozen-lockfile
+  #     - run: pnpm test
diff --git a/.gitignore b/.gitignore
index 7aafb9ba..01d96b5a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,8 @@
 /build
 
 # misc
+.vscode
+.idea
 .DS_Store
 .vscode
 
@@ -36,3 +38,5 @@ yarn-error.log*
 # webpack
 /dist
 .vercel
+
+tsconfig.tsbuildinfo
\ No newline at end of file
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 00000000..cf7e656a
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,31 @@
+import eslintConfig from 'configs/eslint';
+import { FlatCompat } from '@eslint/eslintrc';
+import { fileURLToPath } from 'url';
+import path from 'path';
+
+// mimic CommonJS variables -- not needed if using CommonJS
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+const compat = new FlatCompat({
+  baseDirectory: __dirname,
+});
+
+const excludePlugins = eslintConfig.flatMap(config => Object.keys(config.plugins || {}));
+
+export default [
+  ...compat
+    .extends('next/core-web-vitals')
+    .filter(config =>
+      Object.keys(config.plugins || {}).every(plugin => !excludePlugins.includes(plugin)),
+    ),
+
+  ...eslintConfig.filter(config => config.name !== 'custom:turbo-config'),
+
+  {
+    name: 'ignore-old-ts-files',
+    rules: {
+      '@typescript-eslint/ban-ts-comment': 'off',
+    },
+  },
+];
diff --git a/next-env.d.ts b/next-env.d.ts
index 4f11a03d..a4a7b3f5 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -2,4 +2,4 @@
 /// <reference types="next/image-types/global" />
 
 // NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
+// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
diff --git a/next.config.mjs b/next.config.mjs
index a3731ec0..4d943b64 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -7,6 +7,12 @@ const nextConfig = {
     return config;
   },
   output: "standalone",
+  eslint: {
+    ignoreDuringBuilds: true,
+  },
+  typescript: {
+    ignoreBuildErrors: true,
+  },
 };
 
-export default nextConfig;
\ No newline at end of file
+export default nextConfig;
diff --git a/package.json b/package.json
index 1394b3ce..c13ce2f9 100644
--- a/package.json
+++ b/package.json
@@ -7,11 +7,15 @@
   "engines": {
     "node": ">=18"
   },
+  "packageManager": "pnpm@9.7.0+sha512.dc09430156b427f5ecfc79888899e1c39d2d690f004be70e05230b72cb173d96839587545d09429b55ac3c429c801b4dc3c0e002f653830a420fa2dd4e3cf9cf",
   "scripts": {
     "build": "next build",
     "dev": "next dev",
     "start": "next start",
-    "lint": "next lint"
+    "lint": "eslint src",
+    "lint:fix": "eslint src --fix",
+    "lint:strict": "tsc --noEmit && pnpm lint --max-warnings 0",
+    "lint:strict2": "tsc --noEmit && pnpm lint --max-warnings 0"
   },
   "dependencies": {
     "@bufbuild/protobuf": "^1.10.0",
@@ -29,6 +33,8 @@
     "@penumbra-zone/wasm": "^26.2.0",
     "@radix-ui/react-icons": "^1.3.0",
     "@styled-icons/octicons": "^10.47.0",
+    "@tsconfig/strictest": "^2.0.5",
+    "@tsconfig/vite-react": "^3.0.2",
     "@vercel/analytics": "^1.3.1",
     "@vercel/speed-insights": "^1.0.12",
     "bech32": "^2.0.0",
@@ -38,6 +44,8 @@
     "chartjs-chart-financial": "^0.2.1",
     "chartjs-plugin-annotation": "^3.0.1",
     "chartjs-plugin-zoom": "^2.0.1",
+    "configs": "https://github.com/prax-wallet/configs.git#main",
+    "date-fns": "^3.6.0",
     "echarts": "^5.5.1",
     "echarts-for-react": "^3.0.2",
     "framer-motion": "^11.3.31",
@@ -59,7 +67,11 @@
     "@babel/preset-env": "^7.25.4",
     "@babel/preset-react": "^7.24.7",
     "@babel/preset-typescript": "^7.24.7",
+    "@chakra-ui/react-types": "^2.0.6",
+    "@eslint/js": "^9.10.0",
+    "@types/date-fns": "^2.6.0",
     "@types/lodash": "^4.17.7",
+    "@types/node": "^22.5.4",
     "@types/pg": "^8.11.8",
     "@types/react": "^18.3.5",
     "@types/react-dom": "^18.3.0",
@@ -67,7 +79,10 @@
     "babel-loader": "^9.1.3",
     "eslint": "8.57.0",
     "eslint-config-next": "14.2.3",
+    "eslint-plugin-react": "^7.35.2",
+    "globals": "^15.9.0",
     "ts-loader": "^9.5.1",
-    "typescript": "^5.5.4"
+    "typescript": "^5.5.4",
+    "typescript-eslint": "^8.4.0"
   }
 }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 59bc569f..f1c49366 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -16,7 +16,7 @@ importers:
         version: 2.1.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/react':
         specifier: ^2.8.2
-        version: 2.8.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+        version: 2.8.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@chakra-ui/styled-system':
         specifier: ^2.9.2
         version: 2.9.2
@@ -43,22 +43,28 @@ importers:
         version: 6.0.0(@bufbuild/protobuf@1.10.0)
       '@penumbra-zone/ui':
         specifier: ^9.0.0
-        version: 9.0.0(tfyf7qkoqgs3rxm6e473o3th5y)
+        version: 9.1.1(anaage4fuv466ekrzf3iktl2xy)
       '@penumbra-zone/wasm':
         specifier: ^26.2.0
-        version: 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))
+        version: 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))
       '@radix-ui/react-icons':
         specifier: ^1.3.0
         version: 1.3.0(react@18.3.1)
       '@styled-icons/octicons':
         specifier: ^10.47.0
         version: 10.47.0(react@18.3.1)(styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))
+      '@tsconfig/strictest':
+        specifier: ^2.0.5
+        version: 2.0.5
+      '@tsconfig/vite-react':
+        specifier: ^3.0.2
+        version: 3.0.2
       '@vercel/analytics':
         specifier: ^1.3.1
-        version: 1.3.1(next@14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+        version: 1.3.1(next@14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@vercel/speed-insights':
         specifier: ^1.0.12
-        version: 1.0.12(next@14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+        version: 1.0.12(next@14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       bech32:
         specifier: ^2.0.0
         version: 2.0.0
@@ -80,6 +86,12 @@ importers:
       chartjs-plugin-zoom:
         specifier: ^2.0.1
         version: 2.0.1(chart.js@4.4.4)
+      configs:
+        specifier: https://github.com/prax-wallet/configs.git#main
+        version: prax-configs@https://codeload.github.com/prax-wallet/configs/tar.gz/28bb663aa5d042781e714288f28bf15a7075a990(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(jiti@1.21.6)(prettier@3.3.3)(tailwindcss@3.4.10)(typescript@5.6.2)
+      date-fns:
+        specifier: ^3.6.0
+        version: 3.6.0
       echarts:
         specifier: ^5.5.1
         version: 5.5.1
@@ -88,7 +100,7 @@ importers:
         version: 3.0.2(echarts@5.5.1)(react@18.3.1)
       framer-motion:
         specifier: ^11.3.31
-        version: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+        version: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       grpc-tools:
         specifier: ^1.12.4
         version: 1.12.4
@@ -100,7 +112,7 @@ importers:
         version: 4.17.21
       next:
         specifier: ^14.2.7
-        version: 14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+        version: 14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       pg:
         specifier: ^8.12.0
         version: 8.12.0
@@ -138,9 +150,21 @@ importers:
       '@babel/preset-typescript':
         specifier: ^7.24.7
         version: 7.24.7(@babel/core@7.25.2)
+      '@chakra-ui/react-types':
+        specifier: ^2.0.6
+        version: 2.0.6(react@18.3.1)
+      '@eslint/js':
+        specifier: ^9.10.0
+        version: 9.10.0
+      '@types/date-fns':
+        specifier: ^2.6.0
+        version: 2.6.0
       '@types/lodash':
         specifier: ^4.17.7
         version: 4.17.7
+      '@types/node':
+        specifier: ^22.5.4
+        version: 22.5.4
       '@types/pg':
         specifier: ^8.11.8
         version: 8.11.8
@@ -161,13 +185,22 @@ importers:
         version: 8.57.0
       eslint-config-next:
         specifier: 14.2.3
-        version: 14.2.3(eslint@8.57.0)(typescript@5.5.4)
+        version: 14.2.3(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)
+      eslint-plugin-react:
+        specifier: ^7.35.2
+        version: 7.35.2(eslint@8.57.0)
+      globals:
+        specifier: ^15.9.0
+        version: 15.9.0
       ts-loader:
         specifier: ^9.5.1
-        version: 9.5.1(typescript@5.5.4)(webpack@5.94.0)
+        version: 9.5.1(typescript@5.6.2)(webpack@5.94.0)
       typescript:
         specifier: ^5.5.4
-        version: 5.5.4
+        version: 5.6.2
+      typescript-eslint:
+        specifier: ^8.4.0
+        version: 8.5.0(eslint@8.57.0)(typescript@5.6.2)
 
 packages:
 
@@ -1053,6 +1086,11 @@ packages:
     peerDependencies:
       react: '>=18'
 
+  '@chakra-ui/react-types@2.0.6':
+    resolution: {integrity: sha512-aAq/nl//PneEfeaDb94zwfXor4OP/d5kc6dEXOZB2HJgCt3hu2+F/1u1QpPLPPTys5xexkQojuZQLnnD9lmQFw==}
+    peerDependencies:
+      react: '>=18'
+
   '@chakra-ui/react-types@2.0.7':
     resolution: {integrity: sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ==}
     peerDependencies:
@@ -1364,6 +1402,12 @@ packages:
   '@emotion/weak-memoize@0.4.0':
     resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
 
+  '@eslint-community/eslint-plugin-eslint-comments@4.4.0':
+    resolution: {integrity: sha512-yljsWl5Qv3IkIRmJ38h3NrHXFCm4EUl55M8doGTF6hvzvFF8kRpextgSrg2dwHev9lzBZyafCr9RelGIyQm6fw==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    peerDependencies:
+      eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
+
   '@eslint-community/eslint-utils@4.4.0':
     resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -1374,14 +1418,38 @@ packages:
     resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
 
+  '@eslint/compat@1.1.1':
+    resolution: {integrity: sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@eslint/config-array@0.18.0':
+    resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@eslint/eslintrc@2.1.4':
     resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
+  '@eslint/eslintrc@3.1.0':
+    resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@eslint/js@8.57.0':
     resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
+  '@eslint/js@9.10.0':
+    resolution: {integrity: sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@eslint/object-schema@2.1.4':
+    resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@eslint/plugin-kit@0.1.0':
+    resolution: {integrity: sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@floating-ui/core@1.6.7':
     resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==}
 
@@ -1415,6 +1483,10 @@ packages:
     resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
     deprecated: Use @eslint/object-schema instead
 
+  '@humanwhocodes/retry@0.3.0':
+    resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==}
+    engines: {node: '>=18.18'}
+
   '@img/sharp-darwin-arm64@0.33.5':
     resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
     engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
@@ -1629,62 +1701,62 @@ packages:
       '@types/react':
         optional: true
 
-  '@next/env@14.2.7':
-    resolution: {integrity: sha512-OTx9y6I3xE/eih+qtthppwLytmpJVPM5PPoJxChFsbjIEFXIayG0h/xLzefHGJviAa3Q5+Fd+9uYojKkHDKxoQ==}
+  '@next/env@14.2.9':
+    resolution: {integrity: sha512-hnDAoDPMii31V0ivibI8p6b023jOF1XblWTVjsDUoZKwnZlaBtJFZKDwFqi22R8r9i6W08dThUWU7Bsh2Rg8Ww==}
 
   '@next/eslint-plugin-next@14.2.3':
     resolution: {integrity: sha512-L3oDricIIjgj1AVnRdRor21gI7mShlSwU/1ZGHmqM3LzHhXXhdkrfeNY5zif25Bi5Dd7fiJHsbhoZCHfXYvlAw==}
 
-  '@next/swc-darwin-arm64@14.2.7':
-    resolution: {integrity: sha512-UhZGcOyI9LE/tZL3h9rs/2wMZaaJKwnpAyegUVDGZqwsla6hMfeSj9ssBWQS9yA4UXun3pPhrFLVnw5KXZs3vw==}
+  '@next/swc-darwin-arm64@14.2.9':
+    resolution: {integrity: sha512-/kfQifl3uLYi3DlwFlzCkgxe6fprJNLzzTUFknq3M5wGYicDIbdGlxUl6oHpVLJpBB/CBY3Y//gO6alz/K4NWA==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [darwin]
 
-  '@next/swc-darwin-x64@14.2.7':
-    resolution: {integrity: sha512-ys2cUgZYRc+CbyDeLAaAdZgS7N1Kpyy+wo0b/gAj+SeOeaj0Lw/q+G1hp+DuDiDAVyxLBCJXEY/AkhDmtihUTA==}
+  '@next/swc-darwin-x64@14.2.9':
+    resolution: {integrity: sha512-tK/RyhCmOCiXQ9IVdFrBbZOf4/1+0RSuJkebXU2uMEsusS51TjIJO4l8ZmEijH9gZa0pJClvmApRHi7JuBqsRw==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [darwin]
 
-  '@next/swc-linux-arm64-gnu@14.2.7':
-    resolution: {integrity: sha512-2xoWtE13sUJ3qrC1lwE/HjbDPm+kBQYFkkiVECJWctRASAHQ+NwjMzgrfqqMYHfMxFb5Wws3w9PqzZJqKFdWcQ==}
+  '@next/swc-linux-arm64-gnu@14.2.9':
+    resolution: {integrity: sha512-tS5eqwsp2nO7mzywRUuFYmefNZsUKM/mTG3exK2jIHv9TEVklE1SByB1KMhFkqlit1PxS9YK1tV8BOV90Wpbrw==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
 
-  '@next/swc-linux-arm64-musl@14.2.7':
-    resolution: {integrity: sha512-+zJ1gJdl35BSAGpkCbfyiY6iRTaPrt3KTl4SF/B1NyELkqqnrNX6cp4IjjjxKpd64/7enI0kf6b9O1Uf3cL0pw==}
+  '@next/swc-linux-arm64-musl@14.2.9':
+    resolution: {integrity: sha512-8svpeTFNAMTUMKQbEzE8qRAwl9o7mNBv7LR1bmSkQvo1oy4WrNyZbhWsldOiKrc4mZ5dfQkGYsI9T75mIFMfeA==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [linux]
 
-  '@next/swc-linux-x64-gnu@14.2.7':
-    resolution: {integrity: sha512-m6EBqrskeMUzykBrv0fDX/28lWIBGhMzOYaStp0ihkjzIYJiKUOzVYD1gULHc8XDf5EMSqoH/0/TRAgXqpQwmw==}
+  '@next/swc-linux-x64-gnu@14.2.9':
+    resolution: {integrity: sha512-0HNulLWpKTB7H5BhHCkEhcRAnWUHeAYCftrrGw3QC18+ZywTdAoPv/zEqKy/0adqt+ks4JDdlgSQ1lNKOKjo0A==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
 
-  '@next/swc-linux-x64-musl@14.2.7':
-    resolution: {integrity: sha512-gUu0viOMvMlzFRz1r1eQ7Ql4OE+hPOmA7smfZAhn8vC4+0swMZaZxa9CSIozTYavi+bJNDZ3tgiSdMjmMzRJlQ==}
+  '@next/swc-linux-x64-musl@14.2.9':
+    resolution: {integrity: sha512-hhVFViPHLAVUJRNtwwm609p9ozWajOmRvzOZzzKXgiVGwx/CALxlMUeh+M+e0Zj6orENhWLZeilOPHpptuENsA==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [linux]
 
-  '@next/swc-win32-arm64-msvc@14.2.7':
-    resolution: {integrity: sha512-PGbONHIVIuzWlYmLvuFKcj+8jXnLbx4WrlESYlVnEzDsa3+Q2hI1YHoXaSmbq0k4ZwZ7J6sWNV4UZfx1OeOlbQ==}
+  '@next/swc-win32-arm64-msvc@14.2.9':
+    resolution: {integrity: sha512-p/v6XlOdrk06xfN9z4evLNBqftVQUWiyduQczCwSj7hNh8fWTbzdVxsEiNOcajMXJbQiaX/ZzZdFgKVmmJnnGQ==}
     engines: {node: '>= 10'}
     cpu: [arm64]
     os: [win32]
 
-  '@next/swc-win32-ia32-msvc@14.2.7':
-    resolution: {integrity: sha512-BiSY5umlx9ed5RQDoHcdbuKTUkuFORDqzYKPHlLeS+STUWQKWziVOn3Ic41LuTBvqE0TRJPKpio9GSIblNR+0w==}
+  '@next/swc-win32-ia32-msvc@14.2.9':
+    resolution: {integrity: sha512-IcW9dynWDjMK/0M05E3zopbRen7v0/yEaMZbHFOSS1J/w+8YG3jKywOGZWNp/eCUVtUUXs0PW+7Lpz8uLu+KQA==}
     engines: {node: '>= 10'}
     cpu: [ia32]
     os: [win32]
 
-  '@next/swc-win32-x64-msvc@14.2.7':
-    resolution: {integrity: sha512-pxsI23gKWRt/SPHFkDEsP+w+Nd7gK37Hpv0ngc5HpWy2e7cKx9zR/+Q2ptAUqICNTecAaGWvmhway7pj/JLEWA==}
+  '@next/swc-win32-x64-msvc@14.2.9':
+    resolution: {integrity: sha512-gcbpoXyWZdVOBgNa5BRzynrL5UR1nb2ZT38yKgnphYU9UHjeecnylMHntrQiMg/QtONDcJPFC/PmsS47xIRYoA==}
     engines: {node: '>= 10'}
     cpu: [x64]
     os: [win32]
@@ -1713,8 +1785,8 @@ packages:
     peerDependencies:
       '@penumbra-zone/protobuf': 6.0.0
 
-  '@penumbra-zone/getters@16.0.0':
-    resolution: {integrity: sha512-c4saUCIooXKDIdl3UmXAtIspxkt/K1vZNyXRLwUyB0B0EfXj7qILlDbz2csOewU8SSKFIuzaBscIeJykOEHKXg==}
+  '@penumbra-zone/getters@17.0.0':
+    resolution: {integrity: sha512-f0o3te2ozm/T6w9Z8xaQlNkhY8dXZPy46+8+SD4bE+2vsO23876gIqK/826Lf59YKtMwi5NnB8H0787h3T5t+g==}
     peerDependencies:
       '@bufbuild/protobuf': ^1.10.0
       '@penumbra-zone/bech32m': 7.0.0
@@ -1724,30 +1796,30 @@ packages:
     resolution: {integrity: sha512-1K+/8bh53Kse4u/I1afUQuRrTnZhLLA6JWIV+mFiXX8An2J2CGIVDjp1mSJkUSzFjFDUzUX052kvYHCtZYK3QA==}
     hasBin: true
 
-  '@penumbra-zone/perspective@28.0.0':
-    resolution: {integrity: sha512-HfRR/8ap+/asSGwIFHHkScj9gnFmFQh6puGVhAeALCXa2lv/nMe9NIM1LFf1M+621NO5B5TWugXOKSl4yBcpzA==}
+  '@penumbra-zone/perspective@30.0.0':
+    resolution: {integrity: sha512-jgxWYCURzX5IosFCN70MSFWHbLo+3l0g83PFnDlvmswygDJdwObvOzV3rpSVnlVBXAQ9/ZKVAoA3Z6g7Bgr0mg==}
     peerDependencies:
       '@bufbuild/protobuf': ^1.10.0
       '@penumbra-zone/bech32m': 7.0.0
-      '@penumbra-zone/getters': 16.0.0
+      '@penumbra-zone/getters': 17.0.0
       '@penumbra-zone/protobuf': 6.0.0
-      '@penumbra-zone/wasm': 26.2.0
+      '@penumbra-zone/wasm': 28.0.0
 
   '@penumbra-zone/protobuf@6.0.0':
     resolution: {integrity: sha512-x+g2plwEnYwzB692oAIzA9yzqcbsJt1f1lYmPNJpWOqNA9wC3OPDOfzQa7rgP4v6+KNd5IbRfRNyGPd/6zxYNg==}
     peerDependencies:
       '@bufbuild/protobuf': ^1.10.0
 
-  '@penumbra-zone/types@21.0.0':
-    resolution: {integrity: sha512-ViEebo+S+NgMolu8la8/uxbh+pScVgzGJ82lqCt/bdimD+UGgIrw/b6tPamKXTAjS9eW2YEqT6UT+67alFEPpw==}
+  '@penumbra-zone/types@23.0.0':
+    resolution: {integrity: sha512-AaIK1A/T6mClpx12Uc5zOdAFzSHLOJS7HvB4A+n+Vo6rylcECz7JM4LV5XmkuWLe9dEW6fDir1XqiKdLQzGi0Q==}
     peerDependencies:
       '@bufbuild/protobuf': ^1.10.0
       '@penumbra-zone/bech32m': 7.0.0
-      '@penumbra-zone/getters': 16.0.0
+      '@penumbra-zone/getters': 17.0.0
       '@penumbra-zone/protobuf': 6.0.0
 
-  '@penumbra-zone/ui@9.0.0':
-    resolution: {integrity: sha512-luVUMsG9FMeSvt0gnDUdkcvaOEGfP3DTbtXBDwCltI7EGUzDoeFt6qCvPqmv8G2J83sjQv6eirhnwX6Li/aG1A==}
+  '@penumbra-zone/ui@9.1.1':
+    resolution: {integrity: sha512-ICy1MknA1Thp6zGeTc6MJOjLNolkHPRH+XUXhCCP+QMNKt9xAdvbw9rVq81MlXJaPGGf1p6nmzu03b99sv7esw==}
     peerDependencies:
       '@bufbuild/protobuf': ^1.10.0
       '@penumbra-zone/protobuf': 6.0.0
@@ -1770,6 +1842,10 @@ packages:
     resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
     engines: {node: '>=14'}
 
+  '@pkgr/core@0.1.1':
+    resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
+    engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+
   '@popperjs/core@2.11.8':
     resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
 
@@ -2505,8 +2581,8 @@ packages:
   '@radix-ui/rect@1.1.0':
     resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
 
-  '@remix-run/router@1.19.1':
-    resolution: {integrity: sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==}
+  '@remix-run/router@1.19.2':
+    resolution: {integrity: sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA==}
     engines: {node: '>=14.0.0'}
 
   '@rtsao/scc@1.1.0':
@@ -2515,6 +2591,9 @@ packages:
   '@rushstack/eslint-patch@1.10.4':
     resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==}
 
+  '@storybook/csf@0.0.1':
+    resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==}
+
   '@styled-icons/octicons@10.47.0':
     resolution: {integrity: sha512-JOqEbwbh23u/AdaINod8ZeVN5MEcOvkSeMTwGIPaPgz5PNuWRj/+1LpixmBeZjAr/WhB0pxZBBwA+e91BelQCA==}
     peerDependencies:
@@ -2542,6 +2621,12 @@ packages:
       react: ^17 || ^18
       react-dom: ^17 || ^18
 
+  '@tsconfig/strictest@2.0.5':
+    resolution: {integrity: sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==}
+
+  '@tsconfig/vite-react@3.0.2':
+    resolution: {integrity: sha512-AFynAtE1Un3Rko20Ghe2mVC/QWD4rStJ2PnyIZU2kzC4UyWpf1YhAEY87GojH/XPZCY8Mdt27gsYyy+6l6HV+w==}
+
   '@types/d3-array@3.0.3':
     resolution: {integrity: sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==}
 
@@ -2575,6 +2660,10 @@ packages:
   '@types/d3-time@3.0.0':
     resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==}
 
+  '@types/date-fns@2.6.0':
+    resolution: {integrity: sha512-9DSw2ZRzV0Tmpa6PHHJbMcZn79HHus+BBBohcOaDzkK/G3zMjDUDYjJIWBFLbkh+1+/IOS0A59BpQfdr37hASg==}
+    deprecated: This is a stub types definition for date-fns (https://github.com/date-fns/date-fns). date-fns provides its own type definitions, so you don't need @types/date-fns installed!
+
   '@types/estree@1.0.5':
     resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
 
@@ -2593,8 +2682,8 @@ packages:
   '@types/lodash@4.17.7':
     resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==}
 
-  '@types/node@22.5.2':
-    resolution: {integrity: sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==}
+  '@types/node@22.5.4':
+    resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==}
 
   '@types/parse-json@4.0.2':
     resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
@@ -2620,6 +2709,38 @@ packages:
   '@types/stylis@4.2.5':
     resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
 
+  '@typescript-eslint/eslint-plugin@7.18.0':
+    resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      '@typescript-eslint/parser': ^7.0.0
+      eslint: ^8.56.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/eslint-plugin@8.5.0':
+    resolution: {integrity: sha512-lHS5hvz33iUFQKuPFGheAB84LwcJ60G8vKnEhnfcK1l8kGVLro2SFYW6K0/tj8FUhRJ0VHyg1oAfg50QGbPPHw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
+      eslint: ^8.57.0 || ^9.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/parser@7.18.0':
+    resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      eslint: ^8.56.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
   '@typescript-eslint/parser@7.2.0':
     resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==}
     engines: {node: ^16.0.0 || >=18.0.0}
@@ -2630,14 +2751,68 @@ packages:
       typescript:
         optional: true
 
+  '@typescript-eslint/parser@8.5.0':
+    resolution: {integrity: sha512-gF77eNv0Xz2UJg/NbpWJ0kqAm35UMsvZf1GHj8D9MRFTj/V3tAciIWXfmPLsAAF/vUlpWPvUDyH1jjsr0cMVWw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/scope-manager@7.18.0':
+    resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+
   '@typescript-eslint/scope-manager@7.2.0':
     resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==}
     engines: {node: ^16.0.0 || >=18.0.0}
 
+  '@typescript-eslint/scope-manager@8.5.0':
+    resolution: {integrity: sha512-06JOQ9Qgj33yvBEx6tpC8ecP9o860rsR22hWMEd12WcTRrfaFgHr2RB/CA/B+7BMhHkXT4chg2MyboGdFGawYg==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@typescript-eslint/type-utils@7.18.0':
+    resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      eslint: ^8.56.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/type-utils@8.5.0':
+    resolution: {integrity: sha512-N1K8Ix+lUM+cIDhL2uekVn/ZD7TZW+9/rwz8DclQpcQ9rk4sIL5CAlBC0CugWKREmDjBzI/kQqU4wkg46jWLYA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/types@7.18.0':
+    resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+
   '@typescript-eslint/types@7.2.0':
     resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==}
     engines: {node: ^16.0.0 || >=18.0.0}
 
+  '@typescript-eslint/types@8.5.0':
+    resolution: {integrity: sha512-qjkormnQS5wF9pjSi6q60bKUHH44j2APxfh9TQRXK8wbYVeDYYdYJGIROL87LGZZ2gz3Rbmjc736qyL8deVtdw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+  '@typescript-eslint/typescript-estree@7.18.0':
+    resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
   '@typescript-eslint/typescript-estree@7.2.0':
     resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==}
     engines: {node: ^16.0.0 || >=18.0.0}
@@ -2647,10 +2822,39 @@ packages:
       typescript:
         optional: true
 
+  '@typescript-eslint/typescript-estree@8.5.0':
+    resolution: {integrity: sha512-vEG2Sf9P8BPQ+d0pxdfndw3xIXaoSjliG0/Ejk7UggByZPKXmJmw3GW5jV2gHNQNawBUyfahoSiCFVov0Ruf7Q==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  '@typescript-eslint/utils@7.18.0':
+    resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      eslint: ^8.56.0
+
+  '@typescript-eslint/utils@8.5.0':
+    resolution: {integrity: sha512-6yyGYVL0e+VzGYp60wvkBHiqDWOpT63pdMV2CVG4LVDd5uR6q1qQN/7LafBZtAtNIn/mqXjsSeS5ggv/P0iECw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      eslint: ^8.57.0 || ^9.0.0
+
+  '@typescript-eslint/visitor-keys@7.18.0':
+    resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+
   '@typescript-eslint/visitor-keys@7.2.0':
     resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==}
     engines: {node: ^16.0.0 || >=18.0.0}
 
+  '@typescript-eslint/visitor-keys@8.5.0':
+    resolution: {integrity: sha512-yTPqMnbAZJNy2Xq2XU8AdtOW9tJIr+UQb64aXB9f3B1498Zx9JorVgFJcZpEc9UBuCCrdzKID2RGAMkYcDtZOw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   '@ungap/structured-clone@1.2.0':
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
 
@@ -2873,8 +3077,8 @@ packages:
     resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
     engines: {node: '>=8'}
 
-  ansi-regex@6.0.1:
-    resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+  ansi-regex@6.1.0:
+    resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
     engines: {node: '>=12'}
 
   ansi-styles@3.2.1:
@@ -2968,8 +3172,9 @@ packages:
     resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==}
     engines: {node: '>=4'}
 
-  axobject-query@3.1.1:
-    resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==}
+  axobject-query@4.1.0:
+    resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+    engines: {node: '>= 0.4'}
 
   babel-loader@9.1.3:
     resolution: {integrity: sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==}
@@ -3050,8 +3255,8 @@ packages:
   camelize@1.0.1:
     resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
 
-  caniuse-lite@1.0.30001655:
-    resolution: {integrity: sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==}
+  caniuse-lite@1.0.30001660:
+    resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==}
 
   chalk@2.4.2:
     resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
@@ -3286,8 +3491,8 @@ packages:
       supports-color:
         optional: true
 
-  debug@4.3.6:
-    resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==}
+  debug@4.3.7:
+    resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
     engines: {node: '>=6.0'}
     peerDependencies:
       supports-color: '*'
@@ -3347,6 +3552,10 @@ packages:
   dom-helpers@5.2.1:
     resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
 
+  dotenv@16.0.3:
+    resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
+    engines: {node: '>=12'}
+
   eastasianwidth@0.2.0:
     resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
 
@@ -3359,8 +3568,8 @@ packages:
   echarts@5.5.1:
     resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
 
-  electron-to-chromium@1.5.13:
-    resolution: {integrity: sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==}
+  electron-to-chromium@1.5.18:
+    resolution: {integrity: sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==}
 
   emoji-regex@8.0.0:
     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -3433,6 +3642,12 @@ packages:
       typescript:
         optional: true
 
+  eslint-config-prettier@9.1.0:
+    resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==}
+    hasBin: true
+    peerDependencies:
+      eslint: '>=7.0.0'
+
   eslint-import-resolver-node@0.3.9:
     resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
 
@@ -3449,8 +3664,8 @@ packages:
       eslint-plugin-import-x:
         optional: true
 
-  eslint-module-utils@2.9.0:
-    resolution: {integrity: sha512-McVbYmwA3NEKwRQY5g4aWMdcZE5xZxV8i8l7CqJSrameuGSQJtSWaL/LxTEzSKKaCcOhlpDR8XEfYXWPrdo/ZQ==}
+  eslint-module-utils@2.11.0:
+    resolution: {integrity: sha512-gbBE5Hitek/oG6MUVj6sFuzEjA/ClzNflVrLovHi/JgLdC7fiN5gLAY1WIPW1a0V5I999MnsrvVrCOGmmVqDBQ==}
     engines: {node: '>=4'}
     peerDependencies:
       '@typescript-eslint/parser': '*'
@@ -3470,6 +3685,12 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
 
+  eslint-plugin-import-x@0.5.3:
+    resolution: {integrity: sha512-hJ/wkMcsLQXAZL3+txXIDpbW5cqwdm1rLTqV4VRY03aIbzE3zWE7rPZKW6Gzf7xyl1u3V1iYC6tOG77d9NF4GQ==}
+    engines: {node: '>=16'}
+    peerDependencies:
+      eslint: ^8.56.0 || ^9.0.0-0
+
   eslint-plugin-import@2.30.0:
     resolution: {integrity: sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==}
     engines: {node: '>=4'}
@@ -3480,11 +3701,25 @@ packages:
       '@typescript-eslint/parser':
         optional: true
 
-  eslint-plugin-jsx-a11y@6.9.0:
-    resolution: {integrity: sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==}
+  eslint-plugin-jsx-a11y@6.10.0:
+    resolution: {integrity: sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==}
     engines: {node: '>=4.0'}
     peerDependencies:
-      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+      eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9
+
+  eslint-plugin-prettier@5.2.1:
+    resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+    peerDependencies:
+      '@types/eslint': '>=8.0.0'
+      eslint: '>=8.0.0'
+      eslint-config-prettier: '*'
+      prettier: '>=3.0.0'
+    peerDependenciesMeta:
+      '@types/eslint':
+        optional: true
+      eslint-config-prettier:
+        optional: true
 
   eslint-plugin-react-hooks@4.6.2:
     resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==}
@@ -3492,12 +3727,53 @@ packages:
     peerDependencies:
       eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
 
-  eslint-plugin-react@7.35.1:
-    resolution: {integrity: sha512-B5ok2JgbaaWn/zXbKCGgKDNL2tsID3Pd/c/yvjcpsd9HQDwyYc/TQv3AZMmOvrJgCs3AnYNUHRCQEMMQAYJ7Yg==}
+  eslint-plugin-react-hooks@5.1.0-rc-c3cdbec0a7-20240708:
+    resolution: {integrity: sha512-Yj2ZS7MReTI9q+ibEeK2DEnWfP/Ovg/1jrK4K/WSPV+J62Wh3vyTOG5jmk5REdXOYbn+tZW4GcqAkmFO268msg==}
+    engines: {node: '>=10'}
+    peerDependencies:
+      eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
+
+  eslint-plugin-react-refresh@0.4.11:
+    resolution: {integrity: sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==}
+    peerDependencies:
+      eslint: '>=7'
+
+  eslint-plugin-react@7.35.2:
+    resolution: {integrity: sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==}
     engines: {node: '>=4'}
     peerDependencies:
       eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
 
+  eslint-plugin-storybook@0.9.0--canary.156.ed236ca.0:
+    resolution: {integrity: sha512-AOm5hbxT/0zp2dXPc3UH9WxUgvjjNXhWevb1i4DpAPMxxf9dGLmqIN3WlbsUSQ8CrQJnzDZbG1/DbKmjIzRLSg==}
+    engines: {node: '>= 18'}
+    peerDependencies:
+      eslint: '>=6'
+
+  eslint-plugin-tailwindcss@3.17.4:
+    resolution: {integrity: sha512-gJAEHmCq2XFfUP/+vwEfEJ9igrPeZFg+skeMtsxquSQdxba9XRk5bn0Bp9jxG1VV9/wwPKi1g3ZjItu6MIjhNg==}
+    engines: {node: '>=18.12.0'}
+    peerDependencies:
+      tailwindcss: ^3.4.0
+
+  eslint-plugin-turbo@2.1.1:
+    resolution: {integrity: sha512-E/34kdQd0n3RP18+e0DSV0f3YTSCOojUh1p4X0Xrho2PBYmJ3umSnNo9FhkZt6UDACl+nBQcYTFkRHMz76lJdw==}
+    peerDependencies:
+      eslint: '>6.6.0'
+
+  eslint-plugin-vitest@0.5.4:
+    resolution: {integrity: sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==}
+    engines: {node: ^18.0.0 || >= 20.0.0}
+    peerDependencies:
+      '@typescript-eslint/eslint-plugin': '*'
+      eslint: ^8.57.0 || ^9.0.0
+      vitest: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/eslint-plugin':
+        optional: true
+      vitest:
+        optional: true
+
   eslint-scope@5.1.1:
     resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
     engines: {node: '>=8.0.0'}
@@ -3506,15 +3782,37 @@ packages:
     resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
+  eslint-scope@8.0.2:
+    resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   eslint-visitor-keys@3.4.3:
     resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
+  eslint-visitor-keys@4.0.0:
+    resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   eslint@8.57.0:
     resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     hasBin: true
 
+  eslint@9.10.0:
+    resolution: {integrity: sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    hasBin: true
+    peerDependencies:
+      jiti: '*'
+    peerDependenciesMeta:
+      jiti:
+        optional: true
+
+  espree@10.1.0:
+    resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
   espree@9.6.1:
     resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3546,6 +3844,9 @@ packages:
   fast-deep-equal@3.1.3:
     resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
 
+  fast-diff@1.3.0:
+    resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+
   fast-glob@3.3.2:
     resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
     engines: {node: '>=8.6.0'}
@@ -3566,6 +3867,10 @@ packages:
     resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
     engines: {node: ^10.12.0 || >=12.0.0}
 
+  file-entry-cache@8.0.0:
+    resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+    engines: {node: '>=16.0.0'}
+
   fill-range@7.1.1:
     resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
     engines: {node: '>=8'}
@@ -3589,6 +3894,10 @@ packages:
     resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
     engines: {node: ^10.12.0 || >=12.0.0}
 
+  flat-cache@4.0.1:
+    resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+    engines: {node: '>=16'}
+
   flatted@3.3.1:
     resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
 
@@ -3603,8 +3912,8 @@ packages:
     resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
     engines: {node: '>=14'}
 
-  framer-motion@11.3.31:
-    resolution: {integrity: sha512-Xmxs08WBXnc2tNzNZbFSpquI33lvleJg4Y+hmZ+vFkn+laN9ZnR3gbZnNGKDtuz7c/x3u8dLg05OU3EhLobCsg==}
+  framer-motion@11.5.4:
+    resolution: {integrity: sha512-E+tb3/G6SO69POkdJT+3EpdMuhmtCh9EWuK4I1DnIC23L7tFPrl8vxP+LSovwaw6uUr73rUbpb4FgK011wbRJQ==}
     peerDependencies:
       '@emotion/is-prop-valid': '*'
       react: ^18.0.0
@@ -3702,6 +4011,14 @@ packages:
     resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
     engines: {node: '>=8'}
 
+  globals@14.0.0:
+    resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+    engines: {node: '>=18'}
+
+  globals@15.9.0:
+    resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==}
+    engines: {node: '>=18'}
+
   globalthis@1.0.4:
     resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
     engines: {node: '>= 0.4'}
@@ -3844,8 +4161,8 @@ packages:
     resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
     engines: {node: '>= 0.4'}
 
-  is-bun-module@1.1.0:
-    resolution: {integrity: sha512-4mTAVPlrXpaN3jtF0lsnPCMGnq4+qZjVIKq0HCpfcqf8OC1SM5oATCIAPM5V5FN05qp2NNnFndphmdZS9CV3hA==}
+  is-bun-module@1.2.1:
+    resolution: {integrity: sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==}
 
   is-callable@1.2.7:
     resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
@@ -4136,9 +4453,6 @@ packages:
     engines: {node: '>=10'}
     hasBin: true
 
-  ms@2.1.2:
-    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
-
   ms@2.1.3:
     resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
 
@@ -4160,8 +4474,8 @@ packages:
   neo-async@2.6.2:
     resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
 
-  next@14.2.7:
-    resolution: {integrity: sha512-4Qy2aK0LwH4eQiSvQWyKuC7JXE13bIopEQesWE0c/P3uuNRnZCQanI0vsrMLmUQJLAto+A+/8+sve2hd+BQuOQ==}
+  next@14.2.9:
+    resolution: {integrity: sha512-3CzBNo6BuJnRjcQvRw+irnU1WiuJNZEp+dkzkt91y4jeIDN/Emg95F+takSYiLpJ/HkxClVQRyqiTwYce5IVqw==}
     engines: {node: '>=18.17.0'}
     hasBin: true
     peerDependencies:
@@ -4417,6 +4731,10 @@ packages:
     resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
     engines: {node: ^10 || ^12 || >=14}
 
+  postcss@8.4.45:
+    resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==}
+    engines: {node: ^10 || ^12 || >=14}
+
   postgres-array@2.0.0:
     resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
     engines: {node: '>=4'}
@@ -4452,10 +4770,23 @@ packages:
   postgres-range@1.1.4:
     resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
 
+  prax-configs@https://codeload.github.com/prax-wallet/configs/tar.gz/28bb663aa5d042781e714288f28bf15a7075a990:
+    resolution: {tarball: https://codeload.github.com/prax-wallet/configs/tar.gz/28bb663aa5d042781e714288f28bf15a7075a990}
+    version: 1.0.0
+
   prelude-ls@1.2.1:
     resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
     engines: {node: '>= 0.8.0'}
 
+  prettier-linter-helpers@1.0.0:
+    resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
+    engines: {node: '>=6.0.0'}
+
+  prettier@3.3.3:
+    resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
+    engines: {node: '>=14'}
+    hasBin: true
+
   prop-types-exact@1.2.5:
     resolution: {integrity: sha512-wHDhA5TSSvU07gdzsdeT/FZg6zay94K4Y7swSK4YsRG3moWB0Qsp9g1Y5BBausP1HF8K4UeVe2Xt7ZFJByKp6A==}
     engines: {node: '>= 0.8'}
@@ -4534,8 +4865,8 @@ packages:
       '@types/react':
         optional: true
 
-  react-remove-scroll@2.5.10:
-    resolution: {integrity: sha512-m3zvBRANPBw3qxVVjEIPEQinkcwlFZ4qyomuWVpNJdv4c6MvHfXV0C3L9Jx5rr3HeBHKNRX+1jreB5QloDIJjA==}
+  react-remove-scroll@2.5.4:
+    resolution: {integrity: sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4544,8 +4875,8 @@ packages:
       '@types/react':
         optional: true
 
-  react-remove-scroll@2.5.4:
-    resolution: {integrity: sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==}
+  react-remove-scroll@2.5.5:
+    resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4554,8 +4885,8 @@ packages:
       '@types/react':
         optional: true
 
-  react-remove-scroll@2.5.5:
-    resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
+  react-remove-scroll@2.5.7:
+    resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4564,8 +4895,8 @@ packages:
       '@types/react':
         optional: true
 
-  react-remove-scroll@2.5.7:
-    resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==}
+  react-remove-scroll@2.6.0:
+    resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==}
     engines: {node: '>=10'}
     peerDependencies:
       '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -4574,15 +4905,15 @@ packages:
       '@types/react':
         optional: true
 
-  react-router-dom@6.26.1:
-    resolution: {integrity: sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw==}
+  react-router-dom@6.26.2:
+    resolution: {integrity: sha512-z7YkaEW0Dy35T3/QKPYB1LjMK2R1fxnHO8kWpUMTBdfVzZrWOiY9a7CtN8HqdWtDUWd5FY6Dl8HFsqVwH4uOtQ==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       react: '>=16.8'
       react-dom: '>=16.8'
 
-  react-router@6.26.1:
-    resolution: {integrity: sha512-kIwJveZNwp7teQRI5QmwWo39A5bXRyqpH0COKKmPnyD2vBvDwgFXSqDUYtt1h+FEyfnE8eXr7oe0MxRzVwCcvQ==}
+  react-router@6.26.2:
+    resolution: {integrity: sha512-tvN1iuT03kHgOFnLPfLJ8V95eijteveqdOSk+srqfePtQvqCExB8eHOYnlilbOcyJyKnYkr1vJvf7YqotAJu1A==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       react: '>=16.8'
@@ -4790,8 +5121,8 @@ packages:
       react: ^18.0.0
       react-dom: ^18.0.0
 
-  source-map-js@1.2.0:
-    resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
+  source-map-js@1.2.1:
+    resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
     engines: {node: '>=0.10.0'}
 
   source-map-support@0.5.21:
@@ -4813,6 +5144,9 @@ packages:
     resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
     engines: {node: '>= 10.x'}
 
+  stable-hash@0.0.4:
+    resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==}
+
   stop-iteration-iterator@1.0.0:
     resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==}
     engines: {node: '>= 0.4'}
@@ -4916,6 +5250,10 @@ packages:
     resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
     engines: {node: '>= 0.4'}
 
+  synckit@0.9.1:
+    resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==}
+    engines: {node: ^14.18.0 || >=16.0.0}
+
   tailwind-merge@2.5.2:
     resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==}
 
@@ -4948,8 +5286,8 @@ packages:
       uglify-js:
         optional: true
 
-  terser@5.31.6:
-    resolution: {integrity: sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==}
+  terser@5.32.0:
+    resolution: {integrity: sha512-v3Gtw3IzpBJ0ugkxEX8U0W6+TnPKRRCWGh1jC/iM/e3Ki5+qvO1L1EAZ56bZasc64aXHwRHNIQEzm6//i5cemQ==}
     engines: {node: '>=10'}
     hasBin: true
 
@@ -4989,6 +5327,10 @@ packages:
     peerDependencies:
       typescript: '>=4.2.0'
 
+  ts-dedent@2.2.0:
+    resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==}
+    engines: {node: '>=6.10'}
+
   ts-interface-checker@0.1.13:
     resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
 
@@ -5038,8 +5380,27 @@ packages:
     resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
     engines: {node: '>= 0.4'}
 
-  typescript@5.5.4:
-    resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==}
+  typescript-eslint@7.18.0:
+    resolution: {integrity: sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==}
+    engines: {node: ^18.18.0 || >=20.0.0}
+    peerDependencies:
+      eslint: ^8.56.0
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  typescript-eslint@8.5.0:
+    resolution: {integrity: sha512-uD+XxEoSIvqtm4KE97etm32Tn5MfaZWgWfMMREStLxR6JzvHkc2Tkj7zhTEK5XmtpTmKHNnG8Sot6qDfhHtR1Q==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    peerDependencies:
+      typescript: '*'
+    peerDependenciesMeta:
+      typescript:
+        optional: true
+
+  typescript@5.6.2:
+    resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
     engines: {node: '>=14.17'}
     hasBin: true
 
@@ -5193,8 +5554,8 @@ packages:
     resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
     engines: {node: '>= 6'}
 
-  yaml@2.5.0:
-    resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==}
+  yaml@2.5.1:
+    resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==}
     engines: {node: '>= 14'}
     hasBin: true
 
@@ -5264,7 +5625,7 @@ snapshots:
       '@babel/traverse': 7.25.6
       '@babel/types': 7.25.6
       convert-source-map: 2.0.0
-      debug: 4.3.6
+      debug: 4.3.7
       gensync: 1.0.0-beta.2
       json5: 2.2.3
       semver: 6.3.1
@@ -5322,7 +5683,7 @@ snapshots:
       '@babel/core': 7.25.2
       '@babel/helper-compilation-targets': 7.25.2
       '@babel/helper-plugin-utils': 7.24.8
-      debug: 4.3.6
+      debug: 4.3.7
       lodash.debounce: 4.0.8
       resolve: 1.22.8
     transitivePeerDependencies:
@@ -6067,7 +6428,7 @@ snapshots:
       '@babel/parser': 7.25.6
       '@babel/template': 7.25.0
       '@babel/types': 7.25.6
-      debug: 4.3.6
+      debug: 4.3.7
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
@@ -6080,7 +6441,7 @@ snapshots:
 
   '@bufbuild/protobuf@1.10.0': {}
 
-  '@chakra-ui/accordion@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/accordion@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/descendant': 3.1.0(react@18.3.1)
       '@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -6089,8 +6450,8 @@ snapshots:
       '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/transition': 2.1.0(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/transition': 2.1.0(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
   '@chakra-ui/alert@2.2.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)':
@@ -6294,7 +6655,7 @@ snapshots:
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
-  '@chakra-ui/menu@2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/menu@2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/clickable': 2.1.0(react@18.3.1)
       '@chakra-ui/descendant': 3.1.0(react@18.3.1)
@@ -6311,11 +6672,11 @@ snapshots:
       '@chakra-ui/react-use-update-effect': 2.1.0(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/transition': 2.1.0(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/transition': 2.1.0(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
-  '@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/focus-lock': 2.1.0(@types/react@18.3.5)(react@18.3.1)
@@ -6325,12 +6686,12 @@ snapshots:
       '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/transition': 2.1.0(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/transition': 2.1.0(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       aria-hidden: 1.2.4
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
-      react-remove-scroll: 2.5.10(@types/react@18.3.5)(react@18.3.1)
+      react-remove-scroll: 2.6.0(@types/react@18.3.5)(react@18.3.1)
     transitivePeerDependencies:
       - '@types/react'
 
@@ -6366,7 +6727,7 @@ snapshots:
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
-  '@chakra-ui/popover@2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/popover@2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/lazy-utils': 2.0.5
@@ -6380,7 +6741,7 @@ snapshots:
       '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
   '@chakra-ui/popper@3.1.0(react@18.3.1)':
@@ -6439,6 +6800,10 @@ snapshots:
       '@chakra-ui/react-use-safe-layout-effect': 2.1.0(react@18.3.1)
       react: 18.3.1
 
+  '@chakra-ui/react-types@2.0.6(react@18.3.1)':
+    dependencies:
+      react: 18.3.1
+
   '@chakra-ui/react-types@2.0.7(react@18.3.1)':
     dependencies:
       react: 18.3.1
@@ -6533,9 +6898,9 @@ snapshots:
       '@chakra-ui/utils': 2.0.15
       react: 18.3.1
 
-  '@chakra-ui/react@2.8.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/react@2.8.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
-      '@chakra-ui/accordion': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/accordion': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/alert': 2.2.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/avatar': 2.3.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/breadcrumb': 2.2.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -6556,11 +6921,11 @@ snapshots:
       '@chakra-ui/layout': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/live-region': 2.1.0(react@18.3.1)
       '@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(@types/react@18.3.5)(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@chakra-ui/number-input': 2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/pin-input': 2.1.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/popover': 2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/popover': 2.2.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/popper': 3.1.0(react@18.3.1)
       '@chakra-ui/portal': 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@chakra-ui/progress': 2.2.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -6575,7 +6940,7 @@ snapshots:
       '@chakra-ui/stat': 2.1.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/stepper': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/styled-system': 2.9.2
-      '@chakra-ui/switch': 2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/switch': 2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
       '@chakra-ui/table': 2.1.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/tabs': 3.0.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -6583,14 +6948,14 @@ snapshots:
       '@chakra-ui/textarea': 2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/theme': 3.3.1(@chakra-ui/styled-system@2.9.2)
       '@chakra-ui/theme-utils': 2.0.21
-      '@chakra-ui/toast': 7.0.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/tooltip': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@chakra-ui/transition': 2.1.0(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/toast': 7.0.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/tooltip': 2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      '@chakra-ui/transition': 2.1.0(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/utils': 2.0.15
       '@chakra-ui/visually-hidden': 2.2.0(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1)
       '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
     transitivePeerDependencies:
@@ -6661,12 +7026,12 @@ snapshots:
       csstype: 3.1.3
       lodash.mergewith: 4.6.2
 
-  '@chakra-ui/switch@2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/switch@2.1.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/checkbox': 2.3.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
   '@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)':
@@ -6738,7 +7103,7 @@ snapshots:
       '@chakra-ui/styled-system': 2.9.2
       '@chakra-ui/theme-tools': 2.1.2(@chakra-ui/styled-system@2.9.2)
 
-  '@chakra-ui/toast@7.0.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/toast@7.0.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/alert': 2.2.2(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
       '@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(react@18.3.1)
@@ -6750,11 +7115,11 @@ snapshots:
       '@chakra-ui/styled-system': 2.9.2
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
       '@chakra-ui/theme': 3.3.1(@chakra-ui/styled-system@2.9.2)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
 
-  '@chakra-ui/tooltip@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/tooltip@2.3.1(@chakra-ui/system@2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1))(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/dom-utils': 2.1.0
       '@chakra-ui/popper': 3.1.0(react@18.3.1)
@@ -6765,14 +7130,14 @@ snapshots:
       '@chakra-ui/react-use-merge-refs': 2.1.0(react@18.3.1)
       '@chakra-ui/shared-utils': 2.0.5
       '@chakra-ui/system': 2.6.2(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
 
-  '@chakra-ui/transition@2.1.0(framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@chakra-ui/transition@2.1.0(framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       '@chakra-ui/shared-utils': 2.0.5
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
   '@chakra-ui/utils@2.0.15':
@@ -6892,17 +7257,38 @@ snapshots:
 
   '@emotion/weak-memoize@0.4.0': {}
 
+  '@eslint-community/eslint-plugin-eslint-comments@4.4.0(eslint@9.10.0(jiti@1.21.6))':
+    dependencies:
+      escape-string-regexp: 4.0.0
+      eslint: 9.10.0(jiti@1.21.6)
+      ignore: 5.3.2
+
   '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
     dependencies:
       eslint: 8.57.0
       eslint-visitor-keys: 3.4.3
 
+  '@eslint-community/eslint-utils@4.4.0(eslint@9.10.0(jiti@1.21.6))':
+    dependencies:
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-visitor-keys: 3.4.3
+
   '@eslint-community/regexpp@4.11.0': {}
 
+  '@eslint/compat@1.1.1': {}
+
+  '@eslint/config-array@0.18.0':
+    dependencies:
+      '@eslint/object-schema': 2.1.4
+      debug: 4.3.7
+      minimatch: 3.1.2
+    transitivePeerDependencies:
+      - supports-color
+
   '@eslint/eslintrc@2.1.4':
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.6
+      debug: 4.3.7
       espree: 9.6.1
       globals: 13.24.0
       ignore: 5.3.2
@@ -6913,8 +7299,30 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
+  '@eslint/eslintrc@3.1.0':
+    dependencies:
+      ajv: 6.12.6
+      debug: 4.3.7
+      espree: 10.1.0
+      globals: 14.0.0
+      ignore: 5.3.2
+      import-fresh: 3.3.0
+      js-yaml: 4.1.0
+      minimatch: 3.1.2
+      strip-json-comments: 3.1.1
+    transitivePeerDependencies:
+      - supports-color
+
   '@eslint/js@8.57.0': {}
 
+  '@eslint/js@9.10.0': {}
+
+  '@eslint/object-schema@2.1.4': {}
+
+  '@eslint/plugin-kit@0.1.0':
+    dependencies:
+      levn: 0.4.1
+
   '@floating-ui/core@1.6.7':
     dependencies:
       '@floating-ui/utils': 0.2.7
@@ -6942,7 +7350,7 @@ snapshots:
   '@humanwhocodes/config-array@0.11.14':
     dependencies:
       '@humanwhocodes/object-schema': 2.0.3
-      debug: 4.3.6
+      debug: 4.3.7
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
@@ -6951,6 +7359,8 @@ snapshots:
 
   '@humanwhocodes/object-schema@2.0.3': {}
 
+  '@humanwhocodes/retry@0.3.0': {}
+
   '@img/sharp-darwin-arm64@0.33.5':
     optionalDependencies:
       '@img/sharp-libvips-darwin-arm64': 1.0.4
@@ -7149,37 +7559,37 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  '@next/env@14.2.7': {}
+  '@next/env@14.2.9': {}
 
   '@next/eslint-plugin-next@14.2.3':
     dependencies:
       glob: 10.3.10
 
-  '@next/swc-darwin-arm64@14.2.7':
+  '@next/swc-darwin-arm64@14.2.9':
     optional: true
 
-  '@next/swc-darwin-x64@14.2.7':
+  '@next/swc-darwin-x64@14.2.9':
     optional: true
 
-  '@next/swc-linux-arm64-gnu@14.2.7':
+  '@next/swc-linux-arm64-gnu@14.2.9':
     optional: true
 
-  '@next/swc-linux-arm64-musl@14.2.7':
+  '@next/swc-linux-arm64-musl@14.2.9':
     optional: true
 
-  '@next/swc-linux-x64-gnu@14.2.7':
+  '@next/swc-linux-x64-gnu@14.2.9':
     optional: true
 
-  '@next/swc-linux-x64-musl@14.2.7':
+  '@next/swc-linux-x64-musl@14.2.9':
     optional: true
 
-  '@next/swc-win32-arm64-msvc@14.2.7':
+  '@next/swc-win32-arm64-msvc@14.2.9':
     optional: true
 
-  '@next/swc-win32-ia32-msvc@14.2.7':
+  '@next/swc-win32-ia32-msvc@14.2.9':
     optional: true
 
-  '@next/swc-win32-x64-msvc@14.2.7':
+  '@next/swc-win32-x64-msvc@14.2.9':
     optional: true
 
   '@nodelib/fs.scandir@2.1.5':
@@ -7203,7 +7613,7 @@ snapshots:
       '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0)
       bech32: 2.0.0
 
-  '@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))':
+  '@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
       '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
@@ -7212,37 +7622,37 @@ snapshots:
   '@penumbra-zone/keys@4.2.1':
     optional: true
 
-  '@penumbra-zone/perspective@28.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))))':
+  '@penumbra-zone/perspective@30.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))))':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
       '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
-      '@penumbra-zone/getters': 16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
+      '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
       '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0)
-      '@penumbra-zone/wasm': 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))
+      '@penumbra-zone/wasm': 26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))
 
   '@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
 
-  '@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))':
+  '@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
       '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
-      '@penumbra-zone/getters': 16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
+      '@penumbra-zone/getters': 17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
       '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0)
       bignumber.js: 9.1.2
       idb: 8.0.0
       zod: 3.23.8
 
-  '@penumbra-zone/ui@9.0.0(tfyf7qkoqgs3rxm6e473o3th5y)':
+  '@penumbra-zone/ui@9.1.1(anaage4fuv466ekrzf3iktl2xy)':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
       '@emotion/react': 11.13.3(@types/react@18.3.5)(react@18.3.1)
       '@emotion/styled': 11.13.0(@emotion/react@11.13.3(@types/react@18.3.5)(react@18.3.1))(@types/react@18.3.5)(react@18.3.1)
       '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
-      '@penumbra-zone/perspective': 28.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))))
+      '@penumbra-zone/perspective': 30.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))))
       '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0)
-      '@penumbra-zone/types': 21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
+      '@penumbra-zone/types': 23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
       '@radix-ui/react-avatar': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@radix-ui/react-checkbox': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -7275,15 +7685,15 @@ snapshots:
       class-variance-authority: 0.7.0
       clsx: 2.1.1
       cmdk: 0.2.0(@types/react@18.3.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      framer-motion: 11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      framer-motion: 11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       humanize-duration: 3.32.1
       lucide-react: 0.378.0(react@18.3.1)
       murmurhash3js: 3.0.1
-      postcss: 8.4.38
+      postcss: 8.4.45
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
       react-loader-spinner: 6.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      react-router-dom: 6.26.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      react-router-dom: 6.26.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       sonner: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       styled-components: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       tailwind-merge: 2.5.2
@@ -7299,18 +7709,20 @@ snapshots:
       - immer
       - supports-color
 
-  '@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))':
+  '@penumbra-zone/wasm@26.2.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))(@penumbra-zone/types@23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))':
     dependencies:
       '@bufbuild/protobuf': 1.10.0
       '@penumbra-zone/bech32m': 7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
       '@penumbra-zone/protobuf': 6.0.0(@bufbuild/protobuf@1.10.0)
-      '@penumbra-zone/types': 21.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@16.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
+      '@penumbra-zone/types': 23.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/getters@17.0.0(@bufbuild/protobuf@1.10.0)(@penumbra-zone/bech32m@7.0.0(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0)))(@penumbra-zone/protobuf@6.0.0(@bufbuild/protobuf@1.10.0))
     optionalDependencies:
       '@penumbra-zone/keys': 4.2.1
 
   '@pkgjs/parseargs@0.11.0':
     optional: true
 
+  '@pkgr/core@0.1.1': {}
+
   '@popperjs/core@2.11.8': {}
 
   '@protobufjs/aspromise@1.1.2': {}
@@ -8088,12 +8500,16 @@ snapshots:
 
   '@radix-ui/rect@1.1.0': {}
 
-  '@remix-run/router@1.19.1': {}
+  '@remix-run/router@1.19.2': {}
 
   '@rtsao/scc@1.1.0': {}
 
   '@rushstack/eslint-patch@1.10.4': {}
 
+  '@storybook/csf@0.0.1':
+    dependencies:
+      lodash: 4.17.21
+
   '@styled-icons/octicons@10.47.0(react@18.3.1)(styled-components@6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1))':
     dependencies:
       '@babel/runtime': 7.25.6
@@ -8128,6 +8544,10 @@ snapshots:
       - '@types/react'
       - immer
 
+  '@tsconfig/strictest@2.0.5': {}
+
+  '@tsconfig/vite-react@3.0.2': {}
+
   '@types/d3-array@3.0.3': {}
 
   '@types/d3-color@3.1.0': {}
@@ -8158,6 +8578,10 @@ snapshots:
 
   '@types/d3-time@3.0.0': {}
 
+  '@types/date-fns@2.6.0':
+    dependencies:
+      date-fns: 3.6.0
+
   '@types/estree@1.0.5': {}
 
   '@types/geojson@7946.0.14': {}
@@ -8172,7 +8596,7 @@ snapshots:
 
   '@types/lodash@4.17.7': {}
 
-  '@types/node@22.5.2':
+  '@types/node@22.5.4':
     dependencies:
       undici-types: 6.19.8
 
@@ -8180,7 +8604,7 @@ snapshots:
 
   '@types/pg@8.11.8':
     dependencies:
-      '@types/node': 22.5.2
+      '@types/node': 22.5.4
       pg-protocol: 1.6.1
       pg-types: 4.0.2
 
@@ -8205,58 +8629,220 @@ snapshots:
 
   '@types/stylis@4.2.5': {}
 
-  '@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4)':
+  '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+    dependencies:
+      '@eslint-community/regexpp': 4.11.0
+      '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      '@typescript-eslint/scope-manager': 7.18.0
+      '@typescript-eslint/type-utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      '@typescript-eslint/visitor-keys': 7.18.0
+      eslint: 9.10.0(jiti@1.21.6)
+      graphemer: 1.4.0
+      ignore: 5.3.2
+      natural-compare: 1.4.0
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/eslint-plugin@8.5.0(@typescript-eslint/parser@8.5.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)':
+    dependencies:
+      '@eslint-community/regexpp': 4.11.0
+      '@typescript-eslint/parser': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+      '@typescript-eslint/scope-manager': 8.5.0
+      '@typescript-eslint/type-utils': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+      '@typescript-eslint/utils': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+      '@typescript-eslint/visitor-keys': 8.5.0
+      eslint: 8.57.0
+      graphemer: 1.4.0
+      ignore: 5.3.2
+      natural-compare: 1.4.0
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/scope-manager': 7.18.0
+      '@typescript-eslint/types': 7.18.0
+      '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+      '@typescript-eslint/visitor-keys': 7.18.0
+      debug: 4.3.7
+      eslint: 9.10.0(jiti@1.21.6)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2)':
     dependencies:
       '@typescript-eslint/scope-manager': 7.2.0
       '@typescript-eslint/types': 7.2.0
-      '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.5.4)
+      '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.6.2)
       '@typescript-eslint/visitor-keys': 7.2.0
-      debug: 4.3.6
+      debug: 4.3.7
       eslint: 8.57.0
     optionalDependencies:
-      typescript: 5.5.4
+      typescript: 5.6.2
     transitivePeerDependencies:
       - supports-color
 
+  '@typescript-eslint/parser@8.5.0(eslint@8.57.0)(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/scope-manager': 8.5.0
+      '@typescript-eslint/types': 8.5.0
+      '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
+      '@typescript-eslint/visitor-keys': 8.5.0
+      debug: 4.3.7
+      eslint: 8.57.0
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/scope-manager@7.18.0':
+    dependencies:
+      '@typescript-eslint/types': 7.18.0
+      '@typescript-eslint/visitor-keys': 7.18.0
+
   '@typescript-eslint/scope-manager@7.2.0':
     dependencies:
       '@typescript-eslint/types': 7.2.0
       '@typescript-eslint/visitor-keys': 7.2.0
 
+  '@typescript-eslint/scope-manager@8.5.0':
+    dependencies:
+      '@typescript-eslint/types': 8.5.0
+      '@typescript-eslint/visitor-keys': 8.5.0
+
+  '@typescript-eslint/type-utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      debug: 4.3.7
+      eslint: 9.10.0(jiti@1.21.6)
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/type-utils@8.5.0(eslint@8.57.0)(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
+      '@typescript-eslint/utils': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+      debug: 4.3.7
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+
+  '@typescript-eslint/types@7.18.0': {}
+
   '@typescript-eslint/types@7.2.0': {}
 
-  '@typescript-eslint/typescript-estree@7.2.0(typescript@5.5.4)':
+  '@typescript-eslint/types@8.5.0': {}
+
+  '@typescript-eslint/typescript-estree@7.18.0(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/types': 7.18.0
+      '@typescript-eslint/visitor-keys': 7.18.0
+      debug: 4.3.7
+      globby: 11.1.0
+      is-glob: 4.0.3
+      minimatch: 9.0.5
+      semver: 7.6.3
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/typescript-estree@7.2.0(typescript@5.6.2)':
     dependencies:
       '@typescript-eslint/types': 7.2.0
       '@typescript-eslint/visitor-keys': 7.2.0
-      debug: 4.3.6
+      debug: 4.3.7
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.3
       semver: 7.6.3
-      ts-api-utils: 1.3.0(typescript@5.5.4)
+      ts-api-utils: 1.3.0(typescript@5.6.2)
     optionalDependencies:
-      typescript: 5.5.4
+      typescript: 5.6.2
     transitivePeerDependencies:
       - supports-color
 
+  '@typescript-eslint/typescript-estree@8.5.0(typescript@5.6.2)':
+    dependencies:
+      '@typescript-eslint/types': 8.5.0
+      '@typescript-eslint/visitor-keys': 8.5.0
+      debug: 4.3.7
+      fast-glob: 3.3.2
+      is-glob: 4.0.3
+      minimatch: 9.0.5
+      semver: 7.6.3
+      ts-api-utils: 1.3.0(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  '@typescript-eslint/utils@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)':
+    dependencies:
+      '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
+      '@typescript-eslint/scope-manager': 7.18.0
+      '@typescript-eslint/types': 7.18.0
+      '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
+  '@typescript-eslint/utils@8.5.0(eslint@8.57.0)(typescript@5.6.2)':
+    dependencies:
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
+      '@typescript-eslint/scope-manager': 8.5.0
+      '@typescript-eslint/types': 8.5.0
+      '@typescript-eslint/typescript-estree': 8.5.0(typescript@5.6.2)
+      eslint: 8.57.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
+  '@typescript-eslint/visitor-keys@7.18.0':
+    dependencies:
+      '@typescript-eslint/types': 7.18.0
+      eslint-visitor-keys: 3.4.3
+
   '@typescript-eslint/visitor-keys@7.2.0':
     dependencies:
       '@typescript-eslint/types': 7.2.0
       eslint-visitor-keys: 3.4.3
 
+  '@typescript-eslint/visitor-keys@8.5.0':
+    dependencies:
+      '@typescript-eslint/types': 8.5.0
+      eslint-visitor-keys: 3.4.3
+
   '@ungap/structured-clone@1.2.0': {}
 
-  '@vercel/analytics@1.3.1(next@14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@vercel/analytics@1.3.1(next@14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     dependencies:
       server-only: 0.0.1
     optionalDependencies:
-      next: 14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      next: 14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
-  '@vercel/speed-insights@1.0.12(next@14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
+  '@vercel/speed-insights@1.0.12(next@14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)':
     optionalDependencies:
-      next: 14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+      next: 14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       react: 18.3.1
 
   '@visx/axis@3.10.1(react@18.3.1)':
@@ -8503,7 +9089,7 @@ snapshots:
 
   agent-base@6.0.2:
     dependencies:
-      debug: 4.3.6
+      debug: 4.3.7
     transitivePeerDependencies:
       - supports-color
 
@@ -8549,7 +9135,7 @@ snapshots:
 
   ansi-regex@5.0.1: {}
 
-  ansi-regex@6.0.1: {}
+  ansi-regex@6.1.0: {}
 
   ansi-styles@3.2.1:
     dependencies:
@@ -8670,9 +9256,7 @@ snapshots:
 
   axe-core@4.10.0: {}
 
-  axobject-query@3.1.1:
-    dependencies:
-      deep-equal: 2.2.3
+  axobject-query@4.1.0: {}
 
   babel-loader@9.1.3(@babel/core@7.25.2)(webpack@5.94.0):
     dependencies:
@@ -8736,8 +9320,8 @@ snapshots:
 
   browserslist@4.23.3:
     dependencies:
-      caniuse-lite: 1.0.30001655
-      electron-to-chromium: 1.5.13
+      caniuse-lite: 1.0.30001660
+      electron-to-chromium: 1.5.18
       node-releases: 2.0.18
       update-browserslist-db: 1.1.0(browserslist@4.23.3)
 
@@ -8761,7 +9345,7 @@ snapshots:
 
   camelize@1.0.1: {}
 
-  caniuse-lite@1.0.30001655: {}
+  caniuse-lite@1.0.30001660: {}
 
   chalk@2.4.2:
     dependencies:
@@ -8993,9 +9577,9 @@ snapshots:
     dependencies:
       ms: 2.1.3
 
-  debug@4.3.6:
+  debug@4.3.7:
     dependencies:
-      ms: 2.1.2
+      ms: 2.1.3
 
   deep-equal@2.2.3:
     dependencies:
@@ -9067,6 +9651,8 @@ snapshots:
       '@babel/runtime': 7.25.6
       csstype: 3.1.3
 
+  dotenv@16.0.3: {}
+
   eastasianwidth@0.2.0: {}
 
   echarts-for-react@3.0.2(echarts@5.5.1)(react@18.3.1):
@@ -9081,7 +9667,7 @@ snapshots:
       tslib: 2.3.0
       zrender: 5.6.0
 
-  electron-to-chromium@1.5.13: {}
+  electron-to-chromium@1.5.18: {}
 
   emoji-regex@8.0.0: {}
 
@@ -9208,25 +9794,29 @@ snapshots:
 
   escape-string-regexp@4.0.0: {}
 
-  eslint-config-next@14.2.3(eslint@8.57.0)(typescript@5.5.4):
+  eslint-config-next@14.2.3(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2):
     dependencies:
       '@next/eslint-plugin-next': 14.2.3
       '@rushstack/eslint-patch': 1.10.4
-      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.4)
+      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
-      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0)
-      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
-      eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0)
-      eslint-plugin-react: 7.35.1(eslint@8.57.0)
+      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0)
+      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0)
+      eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.0)
+      eslint-plugin-react: 7.35.2(eslint@8.57.0)
       eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
     optionalDependencies:
-      typescript: 5.5.4
+      typescript: 5.6.2
     transitivePeerDependencies:
       - eslint-import-resolver-webpack
       - eslint-plugin-import-x
       - supports-color
 
+  eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      eslint: 9.10.0(jiti@1.21.6)
+
   eslint-import-resolver-node@0.3.9:
     dependencies:
       debug: 3.2.7
@@ -9235,37 +9825,124 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0):
+  eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)):
     dependencies:
       '@nolyfill/is-core-module': 1.0.39
-      debug: 4.3.6
+      debug: 4.3.7
+      enhanced-resolve: 5.17.1
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))
+      fast-glob: 3.3.2
+      get-tsconfig: 4.8.0
+      is-bun-module: 1.2.1
+      is-glob: 4.0.3
+    optionalDependencies:
+      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)
+      eslint-plugin-import-x: 0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+    transitivePeerDependencies:
+      - '@typescript-eslint/parser'
+      - eslint-import-resolver-node
+      - eslint-import-resolver-webpack
+      - supports-color
+
+  eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0):
+    dependencies:
+      '@nolyfill/is-core-module': 1.0.39
+      debug: 4.3.7
       enhanced-resolve: 5.17.1
       eslint: 8.57.0
-      eslint-module-utils: 2.9.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
+      eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0)
       fast-glob: 3.3.2
       get-tsconfig: 4.8.0
-      is-bun-module: 1.1.0
+      is-bun-module: 1.2.1
       is-glob: 4.0.3
     optionalDependencies:
-      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
+      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)
+      eslint-plugin-import-x: 0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
     transitivePeerDependencies:
       - '@typescript-eslint/parser'
       - eslint-import-resolver-node
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-module-utils@2.9.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
+  eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      debug: 3.2.7
+    optionalDependencies:
+      '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-import-resolver-node: 0.3.9
+      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6))
+    transitivePeerDependencies:
+      - supports-color
+
+  eslint-module-utils@2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      debug: 3.2.7
+    optionalDependencies:
+      '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6))
+    transitivePeerDependencies:
+      - supports-color
+
+  eslint-module-utils@2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0):
     dependencies:
       debug: 3.2.7
     optionalDependencies:
-      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.4)
+      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
+      eslint: 8.57.0
+      eslint-import-resolver-node: 0.3.9
+      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0)
+    transitivePeerDependencies:
+      - supports-color
+
+  eslint-plugin-import-x@0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2):
+    dependencies:
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      debug: 4.3.7
+      doctrine: 3.0.0
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-import-resolver-node: 0.3.9
+      get-tsconfig: 4.8.0
+      is-glob: 4.0.3
+      minimatch: 9.0.5
+      semver: 7.6.3
+      stable-hash: 0.0.4
+      tslib: 2.7.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
+  eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0):
+    dependencies:
+      '@rtsao/scc': 1.1.0
+      array-includes: 3.1.8
+      array.prototype.findlastindex: 1.2.5
+      array.prototype.flat: 1.3.2
+      array.prototype.flatmap: 1.3.2
+      debug: 3.2.7
+      doctrine: 2.1.0
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
-      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0)
+      eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))
+      hasown: 2.0.2
+      is-core-module: 2.15.1
+      is-glob: 4.0.3
+      minimatch: 3.1.2
+      object.fromentries: 2.0.8
+      object.groupby: 1.0.3
+      object.values: 1.2.0
+      semver: 6.3.1
+      tsconfig-paths: 3.15.0
+    optionalDependencies:
+      '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
     transitivePeerDependencies:
+      - eslint-import-resolver-typescript
+      - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0):
+  eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0):
     dependencies:
       '@rtsao/scc': 1.1.0
       array-includes: 3.1.8
@@ -9276,7 +9953,7 @@ snapshots:
       doctrine: 2.1.0
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
-      eslint-module-utils: 2.9.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0)
+      eslint-module-utils: 2.11.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@9.10.0(jiti@1.21.6)))(eslint@8.57.0))(eslint@8.57.0)
       hasown: 2.0.2
       is-core-module: 2.15.1
       is-glob: 4.0.3
@@ -9287,20 +9964,20 @@ snapshots:
       semver: 6.3.1
       tsconfig-paths: 3.15.0
     optionalDependencies:
-      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.4)
+      '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.6.2)
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0):
+  eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.0):
     dependencies:
       aria-query: 5.1.3
       array-includes: 3.1.8
       array.prototype.flatmap: 1.3.2
       ast-types-flow: 0.0.8
       axe-core: 4.10.0
-      axobject-query: 3.1.1
+      axobject-query: 4.1.0
       damerau-levenshtein: 1.0.8
       emoji-regex: 9.2.2
       es-iterator-helpers: 1.0.19
@@ -9313,11 +9990,28 @@ snapshots:
       safe-regex-test: 1.0.3
       string.prototype.includes: 2.0.0
 
+  eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3):
+    dependencies:
+      eslint: 9.10.0(jiti@1.21.6)
+      prettier: 3.3.3
+      prettier-linter-helpers: 1.0.0
+      synckit: 0.9.1
+    optionalDependencies:
+      eslint-config-prettier: 9.1.0(eslint@9.10.0(jiti@1.21.6))
+
   eslint-plugin-react-hooks@4.6.2(eslint@8.57.0):
     dependencies:
       eslint: 8.57.0
 
-  eslint-plugin-react@7.35.1(eslint@8.57.0):
+  eslint-plugin-react-hooks@5.1.0-rc-c3cdbec0a7-20240708(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      eslint: 9.10.0(jiti@1.21.6)
+
+  eslint-plugin-react-refresh@0.4.11(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      eslint: 9.10.0(jiti@1.21.6)
+
+  eslint-plugin-react@7.35.2(eslint@8.57.0):
     dependencies:
       array-includes: 3.1.8
       array.prototype.findlast: 1.2.5
@@ -9339,6 +10033,57 @@ snapshots:
       string.prototype.matchall: 4.0.11
       string.prototype.repeat: 1.0.0
 
+  eslint-plugin-react@7.35.2(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      array-includes: 3.1.8
+      array.prototype.findlast: 1.2.5
+      array.prototype.flatmap: 1.3.2
+      array.prototype.tosorted: 1.1.4
+      doctrine: 2.1.0
+      es-iterator-helpers: 1.0.19
+      eslint: 9.10.0(jiti@1.21.6)
+      estraverse: 5.3.0
+      hasown: 2.0.2
+      jsx-ast-utils: 3.3.5
+      minimatch: 3.1.2
+      object.entries: 1.1.8
+      object.fromentries: 2.0.8
+      object.values: 1.2.0
+      prop-types: 15.8.1
+      resolve: 2.0.0-next.5
+      semver: 6.3.1
+      string.prototype.matchall: 4.0.11
+      string.prototype.repeat: 1.0.0
+
+  eslint-plugin-storybook@0.9.0--canary.156.ed236ca.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2):
+    dependencies:
+      '@storybook/csf': 0.0.1
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+      ts-dedent: 2.2.0
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
+  eslint-plugin-tailwindcss@3.17.4(tailwindcss@3.4.10):
+    dependencies:
+      fast-glob: 3.3.2
+      postcss: 8.4.45
+      tailwindcss: 3.4.10
+
+  eslint-plugin-turbo@2.1.1(eslint@9.10.0(jiti@1.21.6)):
+    dependencies:
+      dotenv: 16.0.3
+      eslint: 9.10.0(jiti@1.21.6)
+
+  eslint-plugin-vitest@0.5.4(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2):
+    dependencies:
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   eslint-scope@5.1.1:
     dependencies:
       esrecurse: 4.3.0
@@ -9349,8 +10094,15 @@ snapshots:
       esrecurse: 4.3.0
       estraverse: 5.3.0
 
+  eslint-scope@8.0.2:
+    dependencies:
+      esrecurse: 4.3.0
+      estraverse: 5.3.0
+
   eslint-visitor-keys@3.4.3: {}
 
+  eslint-visitor-keys@4.0.0: {}
+
   eslint@8.57.0:
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
@@ -9364,7 +10116,7 @@ snapshots:
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
-      debug: 4.3.6
+      debug: 4.3.7
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
@@ -9394,6 +10146,53 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
+  eslint@9.10.0(jiti@1.21.6):
+    dependencies:
+      '@eslint-community/eslint-utils': 4.4.0(eslint@9.10.0(jiti@1.21.6))
+      '@eslint-community/regexpp': 4.11.0
+      '@eslint/config-array': 0.18.0
+      '@eslint/eslintrc': 3.1.0
+      '@eslint/js': 9.10.0
+      '@eslint/plugin-kit': 0.1.0
+      '@humanwhocodes/module-importer': 1.0.1
+      '@humanwhocodes/retry': 0.3.0
+      '@nodelib/fs.walk': 1.2.8
+      ajv: 6.12.6
+      chalk: 4.1.2
+      cross-spawn: 7.0.3
+      debug: 4.3.7
+      escape-string-regexp: 4.0.0
+      eslint-scope: 8.0.2
+      eslint-visitor-keys: 4.0.0
+      espree: 10.1.0
+      esquery: 1.6.0
+      esutils: 2.0.3
+      fast-deep-equal: 3.1.3
+      file-entry-cache: 8.0.0
+      find-up: 5.0.0
+      glob-parent: 6.0.2
+      ignore: 5.3.2
+      imurmurhash: 0.1.4
+      is-glob: 4.0.3
+      is-path-inside: 3.0.3
+      json-stable-stringify-without-jsonify: 1.0.1
+      lodash.merge: 4.6.2
+      minimatch: 3.1.2
+      natural-compare: 1.4.0
+      optionator: 0.9.4
+      strip-ansi: 6.0.1
+      text-table: 0.2.0
+    optionalDependencies:
+      jiti: 1.21.6
+    transitivePeerDependencies:
+      - supports-color
+
+  espree@10.1.0:
+    dependencies:
+      acorn: 8.12.1
+      acorn-jsx: 5.3.2(acorn@8.12.1)
+      eslint-visitor-keys: 4.0.0
+
   espree@9.6.1:
     dependencies:
       acorn: 8.12.1
@@ -9418,6 +10217,8 @@ snapshots:
 
   fast-deep-equal@3.1.3: {}
 
+  fast-diff@1.3.0: {}
+
   fast-glob@3.3.2:
     dependencies:
       '@nodelib/fs.stat': 2.0.5
@@ -9440,6 +10241,10 @@ snapshots:
     dependencies:
       flat-cache: 3.2.0
 
+  file-entry-cache@8.0.0:
+    dependencies:
+      flat-cache: 4.0.1
+
   fill-range@7.1.1:
     dependencies:
       to-regex-range: 5.0.1
@@ -9467,6 +10272,11 @@ snapshots:
       keyv: 4.5.4
       rimraf: 3.0.2
 
+  flat-cache@4.0.1:
+    dependencies:
+      flatted: 3.3.1
+      keyv: 4.5.4
+
   flatted@3.3.1: {}
 
   focus-lock@1.3.5:
@@ -9482,7 +10292,7 @@ snapshots:
       cross-spawn: 7.0.3
       signal-exit: 4.1.0
 
-  framer-motion@11.3.31(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+  framer-motion@11.5.4(@emotion/is-prop-valid@1.3.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
     dependencies:
       tslib: 2.7.0
     optionalDependencies:
@@ -9592,6 +10402,10 @@ snapshots:
     dependencies:
       type-fest: 0.20.2
 
+  globals@14.0.0: {}
+
+  globals@15.9.0: {}
+
   globalthis@1.0.4:
     dependencies:
       define-properties: 1.2.1
@@ -9670,7 +10484,7 @@ snapshots:
   https-proxy-agent@5.0.1:
     dependencies:
       agent-base: 6.0.2
-      debug: 4.3.6
+      debug: 4.3.7
     transitivePeerDependencies:
       - supports-color
 
@@ -9737,7 +10551,7 @@ snapshots:
       call-bind: 1.0.7
       has-tostringtag: 1.0.2
 
-  is-bun-module@1.1.0:
+  is-bun-module@1.2.1:
     dependencies:
       semver: 7.6.3
 
@@ -9843,7 +10657,7 @@ snapshots:
 
   jest-worker@27.5.1:
     dependencies:
-      '@types/node': 22.5.2
+      '@types/node': 22.5.4
       merge-stream: 2.0.0
       supports-color: 8.1.1
 
@@ -9989,8 +10803,6 @@ snapshots:
 
   mkdirp@1.0.4: {}
 
-  ms@2.1.2: {}
-
   ms@2.1.3: {}
 
   murmurhash3js@3.0.1: {}
@@ -10007,27 +10819,27 @@ snapshots:
 
   neo-async@2.6.2: {}
 
-  next@14.2.7(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+  next@14.2.9(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
     dependencies:
-      '@next/env': 14.2.7
+      '@next/env': 14.2.9
       '@swc/helpers': 0.5.5
       busboy: 1.6.0
-      caniuse-lite: 1.0.30001655
+      caniuse-lite: 1.0.30001660
       graceful-fs: 4.2.11
       postcss: 8.4.31
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
       styled-jsx: 5.1.1(@babel/core@7.25.2)(react@18.3.1)
     optionalDependencies:
-      '@next/swc-darwin-arm64': 14.2.7
-      '@next/swc-darwin-x64': 14.2.7
-      '@next/swc-linux-arm64-gnu': 14.2.7
-      '@next/swc-linux-arm64-musl': 14.2.7
-      '@next/swc-linux-x64-gnu': 14.2.7
-      '@next/swc-linux-x64-musl': 14.2.7
-      '@next/swc-win32-arm64-msvc': 14.2.7
-      '@next/swc-win32-ia32-msvc': 14.2.7
-      '@next/swc-win32-x64-msvc': 14.2.7
+      '@next/swc-darwin-arm64': 14.2.9
+      '@next/swc-darwin-x64': 14.2.9
+      '@next/swc-linux-arm64-gnu': 14.2.9
+      '@next/swc-linux-arm64-musl': 14.2.9
+      '@next/swc-linux-x64-gnu': 14.2.9
+      '@next/swc-linux-x64-musl': 14.2.9
+      '@next/swc-win32-arm64-msvc': 14.2.9
+      '@next/swc-win32-ia32-msvc': 14.2.9
+      '@next/swc-win32-x64-msvc': 14.2.9
     transitivePeerDependencies:
       - '@babel/core'
       - babel-plugin-macros
@@ -10218,28 +11030,28 @@ snapshots:
 
   possible-typed-array-names@1.0.0: {}
 
-  postcss-import@15.1.0(postcss@8.4.38):
+  postcss-import@15.1.0(postcss@8.4.45):
     dependencies:
-      postcss: 8.4.38
+      postcss: 8.4.45
       postcss-value-parser: 4.2.0
       read-cache: 1.0.0
       resolve: 1.22.8
 
-  postcss-js@4.0.1(postcss@8.4.38):
+  postcss-js@4.0.1(postcss@8.4.45):
     dependencies:
       camelcase-css: 2.0.1
-      postcss: 8.4.38
+      postcss: 8.4.45
 
-  postcss-load-config@4.0.2(postcss@8.4.38):
+  postcss-load-config@4.0.2(postcss@8.4.45):
     dependencies:
       lilconfig: 3.1.2
-      yaml: 2.5.0
+      yaml: 2.5.1
     optionalDependencies:
-      postcss: 8.4.38
+      postcss: 8.4.45
 
-  postcss-nested@6.2.0(postcss@8.4.38):
+  postcss-nested@6.2.0(postcss@8.4.45):
     dependencies:
-      postcss: 8.4.38
+      postcss: 8.4.45
       postcss-selector-parser: 6.1.2
 
   postcss-selector-parser@6.1.2:
@@ -10253,13 +11065,19 @@ snapshots:
     dependencies:
       nanoid: 3.3.7
       picocolors: 1.1.0
-      source-map-js: 1.2.0
+      source-map-js: 1.2.1
 
   postcss@8.4.38:
     dependencies:
       nanoid: 3.3.7
       picocolors: 1.1.0
-      source-map-js: 1.2.0
+      source-map-js: 1.2.1
+
+  postcss@8.4.45:
+    dependencies:
+      nanoid: 3.3.7
+      picocolors: 1.1.0
+      source-map-js: 1.2.1
 
   postgres-array@2.0.0: {}
 
@@ -10283,8 +11101,46 @@ snapshots:
 
   postgres-range@1.1.4: {}
 
+  prax-configs@https://codeload.github.com/prax-wallet/configs/tar.gz/28bb663aa5d042781e714288f28bf15a7075a990(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(jiti@1.21.6)(prettier@3.3.3)(tailwindcss@3.4.10)(typescript@5.6.2):
+    dependencies:
+      '@eslint-community/eslint-plugin-eslint-comments': 4.4.0(eslint@9.10.0(jiti@1.21.6))
+      '@eslint/compat': 1.1.1
+      '@eslint/js': 9.10.0
+      eslint: 9.10.0(jiti@1.21.6)
+      eslint-config-prettier: 9.1.0(eslint@9.10.0(jiti@1.21.6))
+      eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import-x@0.5.3(eslint@8.57.0)(typescript@5.6.2))(eslint-plugin-import@2.30.0)(eslint@9.10.0(jiti@1.21.6))
+      eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)
+      eslint-plugin-import-x: 0.5.3(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.10.0(jiti@1.21.6)))(eslint@9.10.0(jiti@1.21.6))(prettier@3.3.3)
+      eslint-plugin-react: 7.35.2(eslint@9.10.0(jiti@1.21.6))
+      eslint-plugin-react-hooks: 5.1.0-rc-c3cdbec0a7-20240708(eslint@9.10.0(jiti@1.21.6))
+      eslint-plugin-react-refresh: 0.4.11(eslint@9.10.0(jiti@1.21.6))
+      eslint-plugin-storybook: 0.9.0--canary.156.ed236ca.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint-plugin-tailwindcss: 3.17.4(tailwindcss@3.4.10)
+      eslint-plugin-turbo: 2.1.1(eslint@9.10.0(jiti@1.21.6))
+      eslint-plugin-vitest: 0.5.4(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      typescript-eslint: 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+    transitivePeerDependencies:
+      - '@types/eslint'
+      - '@typescript-eslint/eslint-plugin'
+      - '@typescript-eslint/parser'
+      - eslint-import-resolver-node
+      - eslint-import-resolver-webpack
+      - jiti
+      - prettier
+      - supports-color
+      - tailwindcss
+      - typescript
+      - vitest
+
   prelude-ls@1.2.1: {}
 
+  prettier-linter-helpers@1.0.0:
+    dependencies:
+      fast-diff: 1.3.0
+
+  prettier@3.3.3: {}
+
   prop-types-exact@1.2.5:
     dependencies:
       call-bind: 1.0.7
@@ -10312,7 +11168,7 @@ snapshots:
       '@protobufjs/path': 1.1.2
       '@protobufjs/pool': 1.1.0
       '@protobufjs/utf8': 1.1.0
-      '@types/node': 22.5.2
+      '@types/node': 22.5.4
       long: 5.2.3
 
   punycode@2.3.1: {}
@@ -10382,7 +11238,7 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  react-remove-scroll@2.5.10(@types/react@18.3.5)(react@18.3.1):
+  react-remove-scroll@2.5.4(@types/react@18.3.5)(react@18.3.1):
     dependencies:
       react: 18.3.1
       react-remove-scroll-bar: 2.3.6(@types/react@18.3.5)(react@18.3.1)
@@ -10393,7 +11249,7 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  react-remove-scroll@2.5.4(@types/react@18.3.5)(react@18.3.1):
+  react-remove-scroll@2.5.5(@types/react@18.3.5)(react@18.3.1):
     dependencies:
       react: 18.3.1
       react-remove-scroll-bar: 2.3.6(@types/react@18.3.5)(react@18.3.1)
@@ -10404,7 +11260,7 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  react-remove-scroll@2.5.5(@types/react@18.3.5)(react@18.3.1):
+  react-remove-scroll@2.5.7(@types/react@18.3.5)(react@18.3.1):
     dependencies:
       react: 18.3.1
       react-remove-scroll-bar: 2.3.6(@types/react@18.3.5)(react@18.3.1)
@@ -10415,7 +11271,7 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  react-remove-scroll@2.5.7(@types/react@18.3.5)(react@18.3.1):
+  react-remove-scroll@2.6.0(@types/react@18.3.5)(react@18.3.1):
     dependencies:
       react: 18.3.1
       react-remove-scroll-bar: 2.3.6(@types/react@18.3.5)(react@18.3.1)
@@ -10426,16 +11282,16 @@ snapshots:
     optionalDependencies:
       '@types/react': 18.3.5
 
-  react-router-dom@6.26.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+  react-router-dom@6.26.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
     dependencies:
-      '@remix-run/router': 1.19.1
+      '@remix-run/router': 1.19.2
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
-      react-router: 6.26.1(react@18.3.1)
+      react-router: 6.26.2(react@18.3.1)
 
-  react-router@6.26.1(react@18.3.1):
+  react-router@6.26.2(react@18.3.1):
     dependencies:
-      '@remix-run/router': 1.19.1
+      '@remix-run/router': 1.19.2
       react: 18.3.1
 
   react-style-singleton@2.2.1(@types/react@18.3.5)(react@18.3.1):
@@ -10690,7 +11546,7 @@ snapshots:
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
 
-  source-map-js@1.2.0: {}
+  source-map-js@1.2.1: {}
 
   source-map-support@0.5.21:
     dependencies:
@@ -10705,6 +11561,8 @@ snapshots:
 
   split2@4.2.0: {}
 
+  stable-hash@0.0.4: {}
+
   stop-iteration-iterator@1.0.0:
     dependencies:
       internal-slot: 1.0.7
@@ -10777,7 +11635,7 @@ snapshots:
 
   strip-ansi@7.1.0:
     dependencies:
-      ansi-regex: 6.0.1
+      ansi-regex: 6.1.0
 
   strip-bom@3.0.0: {}
 
@@ -10832,6 +11690,11 @@ snapshots:
 
   supports-preserve-symlinks-flag@1.0.0: {}
 
+  synckit@0.9.1:
+    dependencies:
+      '@pkgr/core': 0.1.1
+      tslib: 2.7.0
+
   tailwind-merge@2.5.2: {}
 
   tailwindcss@3.4.10:
@@ -10850,11 +11713,11 @@ snapshots:
       normalize-path: 3.0.0
       object-hash: 3.0.0
       picocolors: 1.1.0
-      postcss: 8.4.38
-      postcss-import: 15.1.0(postcss@8.4.38)
-      postcss-js: 4.0.1(postcss@8.4.38)
-      postcss-load-config: 4.0.2(postcss@8.4.38)
-      postcss-nested: 6.2.0(postcss@8.4.38)
+      postcss: 8.4.45
+      postcss-import: 15.1.0(postcss@8.4.45)
+      postcss-js: 4.0.1(postcss@8.4.45)
+      postcss-load-config: 4.0.2(postcss@8.4.45)
+      postcss-nested: 6.2.0(postcss@8.4.45)
       postcss-selector-parser: 6.1.2
       resolve: 1.22.8
       sucrase: 3.35.0
@@ -10878,10 +11741,10 @@ snapshots:
       jest-worker: 27.5.1
       schema-utils: 3.3.0
       serialize-javascript: 6.0.2
-      terser: 5.31.6
+      terser: 5.32.0
       webpack: 5.94.0
 
-  terser@5.31.6:
+  terser@5.32.0:
     dependencies:
       '@jridgewell/source-map': 0.3.6
       acorn: 8.12.1
@@ -10912,20 +11775,22 @@ snapshots:
 
   tr46@0.0.3: {}
 
-  ts-api-utils@1.3.0(typescript@5.5.4):
+  ts-api-utils@1.3.0(typescript@5.6.2):
     dependencies:
-      typescript: 5.5.4
+      typescript: 5.6.2
+
+  ts-dedent@2.2.0: {}
 
   ts-interface-checker@0.1.13: {}
 
-  ts-loader@9.5.1(typescript@5.5.4)(webpack@5.94.0):
+  ts-loader@9.5.1(typescript@5.6.2)(webpack@5.94.0):
     dependencies:
       chalk: 4.1.2
       enhanced-resolve: 5.17.1
       micromatch: 4.0.8
       semver: 7.6.3
       source-map: 0.7.4
-      typescript: 5.5.4
+      typescript: 5.6.2
       webpack: 5.94.0
 
   tsconfig-paths@3.15.0:
@@ -10981,7 +11846,29 @@ snapshots:
       is-typed-array: 1.1.13
       possible-typed-array-names: 1.0.0
 
-  typescript@5.5.4: {}
+  typescript-eslint@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2):
+    dependencies:
+      '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2))(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      '@typescript-eslint/parser': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      '@typescript-eslint/utils': 7.18.0(eslint@9.10.0(jiti@1.21.6))(typescript@5.6.2)
+      eslint: 9.10.0(jiti@1.21.6)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - supports-color
+
+  typescript-eslint@8.5.0(eslint@8.57.0)(typescript@5.6.2):
+    dependencies:
+      '@typescript-eslint/eslint-plugin': 8.5.0(@typescript-eslint/parser@8.5.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2)
+      '@typescript-eslint/parser': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+      '@typescript-eslint/utils': 8.5.0(eslint@8.57.0)(typescript@5.6.2)
+    optionalDependencies:
+      typescript: 5.6.2
+    transitivePeerDependencies:
+      - eslint
+      - supports-color
+
+  typescript@5.6.2: {}
 
   ua-parser-js@1.0.38: {}
 
@@ -11157,7 +12044,7 @@ snapshots:
 
   yaml@1.10.2: {}
 
-  yaml@2.5.0: {}
+  yaml@2.5.1: {}
 
   yargs-parser@21.1.1: {}
 
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 00000000..5a368f49
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,3 @@
+import prettierConfig from 'configs/prettier';
+
+export default prettierConfig;
diff --git a/scripts/disable-lint-for-tmp-excludes.js b/scripts/disable-lint-for-tmp-excludes.js
new file mode 100644
index 00000000..4c6ad69a
--- /dev/null
+++ b/scripts/disable-lint-for-tmp-excludes.js
@@ -0,0 +1,28 @@
+import fs from 'fs';
+import tmpExcludes from './tmp-lint-excludes.js';
+
+// The ESLint comment to be added
+const eslintComment =
+  '// @ts-nocheck\n/* eslint-disable -- disabling this file as this was created before our strict rules */\n';
+
+tmpExcludes.forEach(filePath => {
+  // Read the file
+  fs.readFile(filePath, 'utf8', (err, data) => {
+    console.log('TCL: err', err);
+    console.log('TCL: data', data);
+    // Check if the first line is already the ESLint comment
+    const firstLine = data.split('\n')[0].trim();
+    if (firstLine === eslintComment.trim()) {
+      return;
+    }
+
+    // Prepend the ESLint comment
+    const updatedData = eslintComment + data;
+
+    // Write the updated file back to the filesystem
+    fs.writeFile(filePath, updatedData, 'utf8', () => {
+      // eslint-disable-next-line no-console -- log
+      console.log(`ESLint comment added to ${filePath}`);
+    });
+  });
+});
diff --git a/scripts/tmp-lint-excludes.js b/scripts/tmp-lint-excludes.js
new file mode 100644
index 00000000..60dd69d9
--- /dev/null
+++ b/scripts/tmp-lint-excludes.js
@@ -0,0 +1,67 @@
+/**
+ * We’ve setup strict linting rules, but we need to exclude the files that were made before that.
+ */
+
+export default [
+  'src/components/blockTimestamp.tsx',
+  'src/components/blocks/index.tsx',
+  'src/components/charts/buySellChart.tsx',
+  'src/components/charts/depthChart.tsx',
+  'src/components/charts/ohlcChart.tsx',
+  'src/components/copiedTx.tsx',
+  'src/components/executionHistory/blockDetails.tsx',
+  'src/components/executionHistory/blockSummary.tsx',
+  'src/components/layout.tsx',
+  'src/components/liquidityPositions/closedStatus.tsx',
+  'src/components/liquidityPositions/currentStatus.tsx',
+  'src/components/liquidityPositions/executionEvent.tsx',
+  'src/components/liquidityPositions/openStatus.tsx',
+  'src/components/liquidityPositions/timelinePosition.tsx',
+  'src/components/liquidityPositions/withdrawnStatus.tsx',
+  'src/components/lpAssetView.tsx',
+  'src/components/lpSearchBar.tsx',
+  'src/components/navbar.tsx',
+  // "src/components/pairSelector.tsx",
+  'src/components/swaps/index.tsx',
+  'src/components/util/loadingSpinner.tsx',
+  // "src/constants/configConstants.ts",
+  'src/pages/_app.tsx',
+  // 'src/pages/api/arbs/[...params].ts',
+  'src/pages/api/blockTimestamps/[...params].js',
+  'src/pages/api/blocks/[...params].js',
+  'src/pages/api/lp/[lp_nft_id]/position.ts',
+  'src/pages/api/lp/[lp_nft_id]/trades.js',
+  'src/pages/api/lp/[lp_nft_id].js',
+  'src/pages/api/lp/block/[...params].js',
+  'src/pages/api/lp/positionsByPrice/[...params].ts',
+  'src/pages/api/ohlc/[...params].ts',
+  'src/pages/api/shieldedPool/[token_inner].ts',
+  'src/pages/api/simulations/[...params].ts',
+  'src/pages/api/swaps/[...params].ts',
+  'src/pages/block/[block_height].tsx',
+  'src/pages/explorer/index.tsx',
+  'src/pages/index.tsx',
+  'src/pages/lp/[lp_nft_id].tsx',
+  'src/pages/lp/utils.tsx',
+  'src/pages/pair/[...params].tsx',
+  'src/pages/pair/index.tsx',
+  'src/pages/trade/[[...params]].tsx',
+  'src/pages/trades.tsx',
+  'src/utils/indexer/connector.tsx',
+  'src/utils/indexer/types/lps.tsx',
+  // "src/utils/math/base64.ts",
+  'src/utils/math/bech32.ts',
+  'src/utils/math/hex.ts',
+  'src/utils/math/hiLo.ts',
+  // "src/utils/math/validation.ts",
+  'src/utils/protos/services/app/shielded-pool.ts',
+  'src/utils/protos/services/dex/dex-query-service-client.ts',
+  'src/utils/protos/services/dex/simulated-trades.ts',
+  // 'src/utils/protos/services/utils.ts',
+  // 'src/utils/protos/types/DexQueryServiceClientInterface.ts',
+  'src/utils/protos/types/ShieldedPoolQuerier.ts',
+  'src/utils/protos/types/SimulationQuerier.ts',
+  // "src/utils/token/tokenFetch.tsx",
+  'src/utils/types/block.tsx',
+  // "src/utils/types/token.tsx",
+];
diff --git a/src/components/blockTimestamp.tsx b/src/components/blockTimestamp.tsx
index dab45f1b..89fe4e44 100644
--- a/src/components/blockTimestamp.tsx
+++ b/src/components/blockTimestamp.tsx
@@ -1,6 +1,7 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { FC } from "react";
-import { HStack } from "@chakra-ui/react";
-import { Text } from "@chakra-ui/react";
+import { HStack , Text } from "@chakra-ui/react";
 
 interface BlockTimestampProps {
   blockHeight: number;
diff --git a/src/components/blocks/index.tsx b/src/components/blocks/index.tsx
index 20547de8..346d98ec 100644
--- a/src/components/blocks/index.tsx
+++ b/src/components/blocks/index.tsx
@@ -1,4 +1,5 @@
 // copied from pages/trades.tsx
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 
 import {
   Text,
@@ -13,7 +14,7 @@ import { useEffect, useRef, useState } from "react";
 import { BlockSummary } from "@/components/executionHistory/blockSummary";
 import { BlockInfo, LiquidityPositionEvent } from "@/utils/indexer/types/lps";
 import { SwapExecutionWithBlockHeight } from "@/utils/protos/types/DexQueryServiceClientInterface";
-import { BlockInfoMap, BlockSummaryMap } from "@/utils/types/block";
+import { BlockInfoMap, BlockSummaryData, BlockSummaryMap } from "@/utils/types/block";
 
 export default function Blocks() {
   // Go back hardcoded N blocks
@@ -21,7 +22,6 @@ export default function Blocks() {
 
   const [isBlockRangeLoading, setIsBlockRangeLoading] = useState(true);
   const [isLoading, setIsLoading] = useState(true);
-  const [isLineLoading, setIsLineLoading] = useState(true);
 
   const [startingBlockHeight, setStartingBlockHeight] = useState(-1); // negative number meaning not set yet
   const [endingBlockHeight, setEndingBlockHeight] = useState(-1); // negative number meaning not set yet
@@ -32,46 +32,48 @@ export default function Blocks() {
 
   const currentStatusRef = useRef<HTMLDivElement>(null);
   const originalStatusRef = useRef<HTMLDivElement>(null);
-  const [lineHeight, setLineHeight] = useState(0);
-  const [lineTop, setLineTop] = useState(0);
+  const [, setLineHeight] = useState(0);
+  const [, setLineTop] = useState(0);
   const [error, setError] = useState<string | undefined>(undefined);
 
   // Get starting block number
   useEffect(() => {
     setIsBlockRangeLoading(true);
     if (endingBlockHeight <= 0 || startingBlockHeight <= 0) {
-      var blockInfoPromise: Promise<BlockInfo[]>;
+      let blockInfoPromise: Promise<BlockInfo[]>;
       if (userRequestedBlockEndHeight >= 1) {
         const startHeight = Math.max(
           userRequestedBlockEndHeight - NUMBER_BLOCKS_IN_TIMELINE + 1,
-          1
+          1,
         ); // Lowest block_height is 1
         blockInfoPromise = fetch(
-          `/api/blocks/${startHeight}/${userRequestedBlockEndHeight + 1}`
-        ).then((res) => res.json());
+          `/api/blocks/${startHeight}/${userRequestedBlockEndHeight + 1}`,
+        ).then((res) => res.json()) as Promise<BlockInfo[]>;
       } else {
         blockInfoPromise = fetch(
-          `/api/blocks/${NUMBER_BLOCKS_IN_TIMELINE}`
-        ).then((res) => res.json());
+          `/api/blocks/${NUMBER_BLOCKS_IN_TIMELINE}`,
+        ).then((res) => res.json()) as Promise<BlockInfo[]>;
       }
       Promise.all([blockInfoPromise])
         .then(([blockInfoResponse]) => {
-          const blockInfoList: BlockInfo[] = blockInfoResponse as BlockInfo[];
+          const blockInfoList: BlockInfo[] = blockInfoResponse;
           const blockInfoMap: BlockInfoMap = {};
-          blockInfoList.forEach((blockInfo: BlockInfo, i: number) => {
-            //console.log(blockInfo)
-            blockInfoMap[blockInfo["height"]] = blockInfo;
+          blockInfoList.forEach((blockInfo: BlockInfo) => {
+            // console.log(blockInfo)
+            blockInfoMap[blockInfo.height] = blockInfo;
           });
 
           if (blockInfoList.length === 0) {
             setIsLoading(false);
-            setError("No blocks found before: " + userRequestedBlockEndHeight);
+            setError(`No blocks found before: ${userRequestedBlockEndHeight}`);
+
+            // eslint-disable-next-line no-console -- logging for debugging
             console.log("No blocks found");
             return;
           } else {
-            setEndingBlockHeight(blockInfoList[0]["height"]);
+            setEndingBlockHeight((blockInfoList[0] as BlockInfo).height);
             setStartingBlockHeight(
-              blockInfoList[NUMBER_BLOCKS_IN_TIMELINE - 1]["height"]
+              (blockInfoList[NUMBER_BLOCKS_IN_TIMELINE - 1] as BlockInfo).height,
             );
             setBlockInfo(blockInfoMap);
             setError(undefined);
@@ -95,13 +97,13 @@ export default function Blocks() {
     setIsLoading(true);
     if (blockInfo && endingBlockHeight >= 1 && startingBlockHeight >= 1) {
       const liquidityPositionOpenClosePromise = fetch(
-        `/api/lp/block/${startingBlockHeight}/${endingBlockHeight + 1}`
+        `/api/lp/block/${startingBlockHeight}/${endingBlockHeight + 1}`,
       ).then((res) => res.json());
       const arbsPromise = fetch(
-        `/api/arbs/${startingBlockHeight}/${endingBlockHeight + 1}`
+        `/api/arbs/${startingBlockHeight}/${endingBlockHeight + 1}`,
       ).then((res) => res.json());
       const swapsPromise = fetch(
-        `/api/swaps/${startingBlockHeight}/${endingBlockHeight + 1}`
+        `/api/swaps/${startingBlockHeight}/${endingBlockHeight + 1}`,
       ).then((res) => res.json());
 
       Promise.all([
@@ -124,7 +126,7 @@ export default function Blocks() {
 
             // Initialize blocks
             const blockSummaryMap: BlockSummaryMap = {};
-            var i: number;
+            let i: number;
             for (i = startingBlockHeight; i <= endingBlockHeight; i++) {
               blockSummaryMap[i] = {
                 openPositionEvents: [],
@@ -132,46 +134,43 @@ export default function Blocks() {
                 withdrawPositionEvents: [],
                 swapExecutions: [],
                 arbExecutions: [],
-                createdAt: blockInfo[i]["created_at"],
+                createdAt: (blockInfo[i] as BlockInfo).created_at,
               };
             }
 
             positionData.forEach(
               (positionOpenCloseEvent: LiquidityPositionEvent) => {
-                if (positionOpenCloseEvent["type"].includes("PositionOpen")) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "openPositionEvents"
-                  ].push(positionOpenCloseEvent);
+                const blockSummary = blockSummaryMap[positionOpenCloseEvent.block_height] as BlockSummaryData;
+                if (positionOpenCloseEvent.type.includes("PositionOpen")) {
+                  blockSummary.openPositionEvents.push(positionOpenCloseEvent);
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionClose")
+                  positionOpenCloseEvent.type.includes("PositionClose")
                 ) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "closePositionEvents"
-                  ].push(positionOpenCloseEvent);
+                  blockSummary.closePositionEvents.push(positionOpenCloseEvent);
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionWithdraw")
+                  positionOpenCloseEvent.type.includes("PositionWithdraw")
                 ) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "withdrawPositionEvents"
-                  ].push(positionOpenCloseEvent);
+                  blockSummary.withdrawPositionEvents.push(positionOpenCloseEvent);
                 }
-              }
+              },
             );
 
             arbData.forEach((arb: SwapExecutionWithBlockHeight) => {
-              blockSummaryMap[arb.blockHeight]["arbExecutions"].push(
-                arb.swapExecution
+              const blockSummary = blockSummaryMap[arb.blockHeight] as BlockSummaryData;
+              blockSummary.arbExecutions.push(
+                arb.swapExecution,
               );
             });
 
             swapData.forEach((swap: SwapExecutionWithBlockHeight) => {
-              blockSummaryMap[swap.blockHeight]["swapExecutions"].push(
-                swap.swapExecution
+              const blockSummary = blockSummaryMap[swap.blockHeight] as BlockSummaryData;
+              blockSummary.swapExecutions.push(
+                swap.swapExecution,
               );
             });
 
             setBlockData(blockSummaryMap);
-          }
+          },
         )
         .catch((error) => {
           console.error("Error fetching block summary data:", error);
@@ -190,7 +189,6 @@ export default function Blocks() {
 
   // Draw vertical line
   useEffect(() => {
-    setIsLineLoading(true);
     if (currentStatusRef.current && originalStatusRef.current) {
       const firstBoxRect = currentStatusRef.current.getBoundingClientRect();
       const lastBoxRect = originalStatusRef.current.getBoundingClientRect();
@@ -200,8 +198,7 @@ export default function Blocks() {
       setLineHeight(newLineHeight - 50);
       setLineTop(firstBoxRect.bottom);
     }
-    setIsLineLoading(false);
-  });
+  }, []);
 
   const onSearch = (event: React.FormEvent<HTMLFormElement>) => {
     event.preventDefault();
@@ -230,8 +227,7 @@ export default function Blocks() {
       <Text>{error}</Text>
     </Box>
   ) : (
-    <>
-      <Box
+    <Box
         display="flex"
         flexDirection="column"
         alignItems="center"
@@ -266,11 +262,10 @@ export default function Blocks() {
             <BlockSummary
               key={index}
               blockHeight={endingBlockHeight - index}
-              blockSummary={blockData[endingBlockHeight - index]}
+              blockSummary={blockData[endingBlockHeight - index] as BlockSummaryData}
             />
           )
         )}
       </Box>
-    </>
   );
 }
diff --git a/src/components/charts/buySellChart.tsx b/src/components/charts/buySellChart.tsx
index 2cf7f949..11b50214 100644
--- a/src/components/charts/buySellChart.tsx
+++ b/src/components/charts/buySellChart.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { useRef, useEffect } from "react";
 import { Box, HStack, Spacer, Text, VStack } from "@chakra-ui/react";
 import { Position } from "@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb";
@@ -55,17 +57,17 @@ export default dynamic(
           );
 
           const p: BigNumber = fromBaseUnit(
-            BigInt(position!.phi!.component!.p!.lo || 0),
-            BigInt(position!.phi!.component!.p!.hi || 0),
+            BigInt(position.phi!.component!.p!.lo || 0),
+            BigInt(position.phi!.component!.p!.hi || 0),
             direction === 1 ? asset2Token.decimals : asset1Token.decimals
           );
           const q: BigNumber = fromBaseUnit(
-            BigInt(position!.phi!.component!.q!.lo || 0),
-            BigInt(position!.phi!.component!.q!.hi || 0),
+            BigInt(position.phi!.component!.q!.lo || 0),
+            BigInt(position.phi!.component!.q!.hi || 0),
             direction === 1 ? asset1Token.decimals : asset2Token.decimals
           );
 
-          let price = Number.parseFloat(
+          const price = Number.parseFloat(
             direction === 1 ? p.div(q).toFixed(6) : q.div(p).toFixed(6)
           );
 
@@ -80,17 +82,17 @@ export default dynamic(
           // Reconstruct a 'real' Position object from the JSON object as it is slightly different
           // somewhere up the stack. we need a real Position with toBinary to
           // enter wasm. this is sufficient for now.
-          //console.log("position", position)
+          // console.log("position", position)
           const protoPosition = Position.fromJson({
             phi: {
               component: {
                 p: {
-                  lo: String(position!.phi!.component!.p!.lo) || "0",
-                  hi: String(position!.phi!.component!.p!.hi) || "0",
+                  lo: String(position.phi!.component!.p!.lo) || "0",
+                  hi: String(position.phi!.component!.p!.hi) || "0",
                 },
                 q: {
-                  lo: String(position!.phi!.component!.q!.lo) || "0",
-                  hi: String(position!.phi!.component!.q!.hi) || "0",
+                  lo: String(position.phi!.component!.q!.lo) || "0",
+                  hi: String(position.phi!.component!.q!.hi) || "0",
                 },
                 fee: position.phi!.component!.fee as unknown as string,
               },
@@ -118,7 +120,7 @@ export default dynamic(
               },
             },
           });
-          //console.log("buy protoPosition", protoPosition)
+          // console.log("buy protoPosition", protoPosition)
           const positionId = computePositionId(protoPosition);
           // Convert inner byte array to bech32
           const innerStr = uint8ArrayToBase64(positionId.inner);
@@ -168,34 +170,34 @@ export default dynamic(
           );
 
           const p: BigNumber = fromBaseUnit(
-            BigInt(position!.phi!.component!.p!.lo || 0),
-            BigInt(position!.phi!.component!.p!.hi || 0),
+            BigInt(position.phi!.component!.p!.lo || 0),
+            BigInt(position.phi!.component!.p!.hi || 0),
             direction === 1 ? asset2Token.decimals : asset1Token.decimals
           );
           const q: BigNumber = fromBaseUnit(
-            BigInt(position!.phi!.component!.q!.lo || 0),
-            BigInt(position!.phi!.component!.q!.hi || 0),
+            BigInt(position.phi!.component!.q!.lo || 0),
+            BigInt(position.phi!.component!.q!.hi || 0),
             direction === 1 ? asset1Token.decimals : asset2Token.decimals
           );
 
-          let price = Number.parseFloat(
+          const price = Number.parseFloat(
             direction === 1 ? p.div(q).toFixed(6) : q.div(p).toFixed(6)
           );
 
           // Reconstruct a 'real' Position object from the JSON object as it is slightly different
           // somewhere up the stack. we need a real Position with toBinary to
           // enter wasm. this is sufficient for now.
-          //console.log("sell position", position);
+          // console.log("sell position", position);
           const protoPosition = Position.fromJson({
             phi: {
               component: {
                 p: {
-                  lo: String(position!.phi!.component!.p!.lo) || "0",
-                  hi: String(position!.phi!.component!.p!.hi) || "0",
+                  lo: String(position.phi!.component!.p!.lo) || "0",
+                  hi: String(position.phi!.component!.p!.hi) || "0",
                 },
                 q: {
-                  lo: String(position!.phi!.component!.q!.lo) || "0",
-                  hi: String(position!.phi!.component!.q!.hi) || "0",
+                  lo: String(position.phi!.component!.q!.lo) || "0",
+                  hi: String(position.phi!.component!.q!.hi) || "0",
                 },
                 fee: position.phi!.component!.fee as unknown as string,
               },
@@ -223,7 +225,7 @@ export default dynamic(
               },
             },
           });
-          //console.log("sell protoPosition", protoPosition);
+          // console.log("sell protoPosition", protoPosition);
           const positionId = computePositionId(protoPosition);
           // Convert inner byte array to bech32
           const innerStr = uint8ArrayToBase64(positionId.inner);
@@ -251,7 +253,7 @@ export default dynamic(
           return b.price - a.price;
         });
 
-      let midPointPrice: number = 0;
+      let midPointPrice = 0;
       if (
         cleaned_buy_side_positions.length > 0 &&
         cleaned_sell_side_positions.length > 0
diff --git a/src/components/charts/depthChart.tsx b/src/components/charts/depthChart.tsx
index abe6665f..b086ba24 100644
--- a/src/components/charts/depthChart.tsx
+++ b/src/components/charts/depthChart.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // src/components/charts/depthChart.tsx
 
 import React, { useRef, useEffect, useState } from "react";
@@ -37,9 +39,9 @@ const DepthChart = ({
 }: DepthChartProps) => {
   useEffect(() => {
     if (typeof window !== "undefined")
-      import("chartjs-plugin-zoom").then((plugin) => {
+      {import("chartjs-plugin-zoom").then((plugin) => {
         ChartJS.register(plugin.default);
-      });
+      });}
   }, []);
 
   const [isMouseOverChart, setIsMouseOverChart] = useState(false);
@@ -152,7 +154,7 @@ const DepthChart = ({
   // Function to update the chart's view to the current zoom level
   const updateZoomRange = () => {
     const chartInstance = chartRef.current;
-    if (!chartInstance) return;
+    if (!chartInstance) {return;}
 
     const midMarketPrice =
       (Math.min(...buySideData.map((d) => d.x)) +
@@ -313,7 +315,7 @@ const DepthChart = ({
     setMinXValue(midMarketPrice - range);
     setMaxXValue(midMarketPrice + range);
     setPadding(range * 0.0);
-    //setPadding((Math.max(...xVals) - Math.min(...xVals)) * 0.05);
+    // setPadding((Math.max(...xVals) - Math.min(...xVals)) * 0.05);
 
     const liquidityMax = Math.max(
       ...newRenderedSellSideData.map((p) => p.y),
@@ -410,7 +412,7 @@ const DepthChart = ({
   );
 
   function calculateMaxY(maxLiquidity: number) {
-    if (maxLiquidity < 10) return 10; // If less than 10, round up to 10
+    if (maxLiquidity < 10) {return 10;} // If less than 10, round up to 10
 
     // Round to the nearest upper number, eg for 1500, round to 2000, for 2000, round to 3000, for 10345 round to 11000, for 12790, round to 13000
     let roundedNumber = Math.ceil(maxLiquidity / 1000) * 1000;
@@ -467,7 +469,7 @@ const DepthChart = ({
     { leading: true, trailing: false }
   );
   function roundToNextBigNumber(number: number) {
-    if (number <= 10) return 10; // For numbers less than or equal to 10, round up to 10
+    if (number <= 10) {return 10;} // For numbers less than or equal to 10, round up to 10
 
     // Calculate the order of magnitude of the number
     const orderOfMagnitude = Math.floor(Math.log10(number));
@@ -533,7 +535,7 @@ const DepthChart = ({
       },
     },
     onHover: (event: ChartEvent, chartElement: any, chart: any) => {
-      if (!event.native) return;
+      if (!event.native) {return;}
 
       const nativeEvent = event.native as MouseEvent;
       // Convert the mouse's pixel position to the corresponding value on the chart's x-axis.
@@ -618,7 +620,7 @@ const DepthChart = ({
               position: "end",
               backgroundColor: "#6e6eb8",
               font: {
-                //family: "monospace"
+                // family: "monospace"
               },
             },
           },
@@ -638,8 +640,7 @@ const DepthChart = ({
   };
 
   return (
-    <>
-      <VStack height={["320px", "320px", "320px"]} width={["100%", "100%", "100%", "100%", "100%", "100%"]}>
+    <VStack height={["320px", "320px", "320px"]} width={["100%", "100%", "100%", "100%", "100%", "100%"]}>
         <div
           style={{ height: "320px", width: "100%" }}
           onMouseOver={handleMouseOverChart}
@@ -653,7 +654,7 @@ const DepthChart = ({
             colorScheme="purple"
             backgroundColor="var(--complimentary-background)"
             size={"sm"}
-            isDisabled={zoomIndex == 0 || disableMinusButton == true}
+            isDisabled={zoomIndex == 0 || disableMinusButton}
           >
             -
           </Button>
@@ -664,14 +665,13 @@ const DepthChart = ({
             backgroundColor="var(--complimentary-background)"
             size={"sm"}
             isDisabled={
-              zoomIndex == zoomLevels.length - 1 || disablePlusButton == true
+              zoomIndex == zoomLevels.length - 1 || disablePlusButton
             }
           >
             +
           </Button>
         </HStack>
       </VStack>
-    </>
   );
 };
 
diff --git a/src/components/charts/ohlcChart.tsx b/src/components/charts/ohlcChart.tsx
index 5d5f698a..d5f7e8db 100644
--- a/src/components/charts/ohlcChart.tsx
+++ b/src/components/charts/ohlcChart.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // src/components/charts/ohlcChart.tsx
 
 import React, { useEffect, useState } from "react";
@@ -17,9 +19,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
   const [isTimestampsLoading, setIsTimestampsLoading] = useState(true);
   const [ohlcData, setOHLCData] = useState([]); // [{open, high, low, close, directVolume, swapVolume, height}]
   const [originalOHLCData, setOriginalOHLCData] = useState([]); // [{open, high, low, close, directVolume, swapVolume, height}
-  const [blockToTimestamp, setBlockToTimestamp] = useState<{
-    [key: string]: string;
-  }>({}); // {height: timestamp}
+  const [blockToTimestamp, setBlockToTimestamp] = useState<Record<string, string>>({}); // {height: timestamp}
   const [error, setError] = useState<string | undefined>(undefined); // [error message]
   const [chartData, setChartData] = useState<
     [string, number, number, number, number][]
@@ -43,7 +43,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
       const startBlock = await fetch("/api/blocks/1")
         .then((res) => res.json())
         .then((data) => {
-          const currentBlock = data[0]['height']
+          const currentBlock = data[0].height
           console.log(currentBlock)
           const startBlock = currentBlock - Math.trunc(daysLookback * 24 * 60 * 60 / blockTimeSeconds);
           console.log("Start block: ", startBlock);
@@ -192,7 +192,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
     // Process the data and make a list of OHLC heights
     // format needed is '/api/blockTimestamps/range/{startHeight}/{endHeight}'
     const timestampsForHeights = fetch(
-      `/api/blockTimestamps/range/${originalOHLCData[0]["height"]}/${originalOHLCData[originalOHLCData.length - 1]["height"]}`
+      `/api/blockTimestamps/range/${originalOHLCData[0].height}/${originalOHLCData[originalOHLCData.length - 1].height}`
     ).then((res) => res.json());
 
     Promise.all([timestampsForHeights])
@@ -219,7 +219,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
         console.log("Timestamps: ", timestampsForHeightsResponse);
 
         // Convert to a dictionary with height as key and timestamp as value
-        const timestampMapping: { [key: string]: string } = {};
+        const timestampMapping: Record<string, string> = {};
         timestampsForHeightsResponse.forEach(
           (item: { height: string; created_at: string }) => {
             timestampMapping[item.height] = item.created_at;
@@ -258,13 +258,13 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
     // blockToTimestamp is a dictionary with height as key and timestamp as value
     const preparedData = ohlcData
       .map((ohlc) => {
-        const formattedDate = formatTimestamp(blockToTimestamp[ohlc["height"]]);
+        const formattedDate = formatTimestamp(blockToTimestamp[ohlc.height]);
         if (!formattedDate) {
           console.error(
-            `Invalid timestamp for height ${ohlc["height"]}: ${blockToTimestamp[ohlc["height"]]
+            `Invalid timestamp for height ${ohlc.height}: ${blockToTimestamp[ohlc.height]
             }`
           );
-          setError("Missing timestamp for height " + ohlc["height"]);
+          setError("Missing timestamp for height " + ohlc.height);
           return null;
         }
 
@@ -272,15 +272,15 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
           10 ** Math.abs(asset2Token.decimals - asset1Token.decimals);
         return [
           formattedDate,
-          ((ohlc["open"] as number) / decimalCorrection).toFixed(6),
-          ((ohlc["close"] as number) / decimalCorrection).toFixed(6),
-          ((ohlc["low"] as number) / decimalCorrection).toFixed(6),
-          ((ohlc["high"] as number) / decimalCorrection).toFixed(6),
+          ((ohlc.open as number) / decimalCorrection).toFixed(6),
+          ((ohlc.close as number) / decimalCorrection).toFixed(6),
+          ((ohlc.low as number) / decimalCorrection).toFixed(6),
+          ((ohlc.high as number) / decimalCorrection).toFixed(6),
           // Volume
           // Divide volume by decimals of the quote token depending on the direction of the canldestick data
           (
-            (((ohlc["swapVolume"] as number) +
-              ohlc["directVolume"]) as number) /
+            (((ohlc.swapVolume as number) +
+              ohlc.directVolume)) /
             10 ** asset1Token.decimals
           ).toFixed(2),
         ];
@@ -299,7 +299,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
     const volumePreparedData = preparedData.map((item) => [
       item[0],
       item[5],
-    ]) as [string, number][];
+    ]);
 
     setChartData(
       preparedData.map((item) => [item[0], item[1], item[2], item[3], item[4]])
@@ -327,17 +327,17 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
 
     const batchOHLCData = (batch: any[], intervalStart: Date) => {
       const aggregatedOHLC: any = {
-        open: batch[0]["open"],
-        high: Math.max(...batch.map((ohlc) => ohlc["high"])),
-        low: Math.min(...batch.map((ohlc) => ohlc["low"])),
-        close: batch[batch.length - 1]["close"],
-        directVolume: batch.reduce((acc, ohlc) => acc + ohlc["directVolume"], 0),
-        swapVolume: batch.reduce((acc, ohlc) => acc + ohlc["swapVolume"], 0),
-        height: batch[0]["height"],
+        open: batch[0].open,
+        high: Math.max(...batch.map((ohlc) => ohlc.high)),
+        low: Math.min(...batch.map((ohlc) => ohlc.low)),
+        close: batch[batch.length - 1].close,
+        directVolume: batch.reduce((acc, ohlc) => acc + ohlc.directVolume, 0),
+        swapVolume: batch.reduce((acc, ohlc) => acc + ohlc.swapVolume, 0),
+        height: batch[0].height,
       };
 
       // Add the interval start time to blockToTimestamp
-      blockToTimestamp[aggregatedOHLC["height"]] = intervalStart.toISOString();
+      blockToTimestamp[aggregatedOHLC.height] = intervalStart.toISOString();
 
       return aggregatedOHLC;
     };
@@ -388,7 +388,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
       let currentIntervalStart: Date | null = null;
 
       originalOHLCData.forEach((ohlc, index) => {
-        const timestamp = new Date(blockToTimestamp[ohlc["height"]]);
+        const timestamp = new Date(blockToTimestamp[ohlc.height]);
         const intervalStart = getIntervalStart(timestamp.toISOString());
 
         if (currentIntervalStart === null) {
@@ -408,7 +408,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
             currentIntervalStart = new Date(currentIntervalStart.getTime() + timeAggregateSeconds * 1000);
             if (currentIntervalStart < intervalStart) {
               const previousOHLC = aggregatedData[aggregatedData.length - 1];
-              const placeholderOHLC = createPlaceholderOHLC(currentIntervalStart, previousOHLC["close"]);
+              const placeholderOHLC = createPlaceholderOHLC(currentIntervalStart, previousOHLC.close);
               aggregatedData.push(placeholderOHLC);
             }
           }
@@ -583,7 +583,7 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
         },
         fillerColor: "rgba(255, 255, 255, 0.2)", // Slightly brighter fill color
         borderColor: "rgba(255, 255, 255, 0.2)", // Light grey border
-        //handleIcon:"M8.2,13.4c0,0.6-0.4,1-1,1H1.8c-0.6,0-1-0.4-1-1v-6.8c0-0.6,0.4-1,1-1h5.4c0.6,0,1,0.4,1,1V13.4z", // Handle icon
+        // handleIcon:"M8.2,13.4c0,0.6-0.4,1-1,1H1.8c-0.6,0-1-0.4-1-1v-6.8c0-0.6,0.4-1,1-1h5.4c0.6,0,1,0.4,1,1V13.4z", // Handle icon
         handleSize: "100%", // Size of the handle
         handleStyle: {
           color: "rgba(255, 255, 255, 0.6)", // Light grey handle
@@ -609,11 +609,10 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
           justifyContent="center"
           alignItems="center"
         >
-          <Text>{`${error}`}</Text>
+          <Text>{error}</Text>
         </VStack>
       ) : (
-        <>
-          <VStack flex={1} height="100%" width="100%" position="relative">
+        <VStack flex={1} height="100%" width="100%" position="relative">
             <ButtonGroup
               size="xs"
               isAttached
@@ -675,7 +674,6 @@ const OHLCChart = ({ asset1Token, asset2Token }: OHLCChartProps) => {
               style={{ height: "400px", width: "100%" }}
             />
           </VStack>
-        </>
       )}
     </VStack>
   );
diff --git a/src/components/copiedTx.tsx b/src/components/copiedTx.tsx
index 3d8e3112..de7116f5 100644
--- a/src/components/copiedTx.tsx
+++ b/src/components/copiedTx.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { FC, useState } from "react";
 import { CopyIcon } from "@radix-ui/react-icons";
 import { HStack } from "@chakra-ui/react";
diff --git a/src/components/executionHistory/blockDetails.tsx b/src/components/executionHistory/blockDetails.tsx
index d6c99e89..d7dab9a3 100644
--- a/src/components/executionHistory/blockDetails.tsx
+++ b/src/components/executionHistory/blockDetails.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { BlockSummaryData } from "@/utils/types/block";
 import { VStack, Text } from "@chakra-ui/react";
 
@@ -7,8 +9,7 @@ export interface BlockDetailsProps {
 
 export const BlockDetails = ({ blockSummary }: BlockDetailsProps) => {
   return (
-    <>
-      <VStack align="flex-start" spacing={2}>
+    <VStack align="flex-start" spacing={2}>
         <Text fontSize="medium" fontStyle="monospace">
           {"Positions Opened: "}
           {blockSummary.openPositionEvents.length}
@@ -30,6 +31,5 @@ export const BlockDetails = ({ blockSummary }: BlockDetailsProps) => {
           {blockSummary.arbExecutions.length}
         </Text>
       </VStack>
-    </>
   );
 }
\ No newline at end of file
diff --git a/src/components/executionHistory/blockSummary.tsx b/src/components/executionHistory/blockSummary.tsx
index 8217c84b..198a19ec 100644
--- a/src/components/executionHistory/blockSummary.tsx
+++ b/src/components/executionHistory/blockSummary.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { Box, HStack, Flex, Text } from "@chakra-ui/react";
 import BlockTimestampView from "../blockTimestamp";
 import { BlockDetails } from "./blockDetails";
@@ -30,4 +32,4 @@ export const BlockSummary = ({ blockHeight, blockSummary }: BlockSummaryProps) =
       <BlockDetails blockSummary={blockSummary} />
     </Flex>
   );
-};
\ No newline at end of file
+};
diff --git a/src/components/layout.tsx b/src/components/layout.tsx
index e3d41a2b..8a42c76f 100644
--- a/src/components/layout.tsx
+++ b/src/components/layout.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // components/Layout.js
 
 import Head from "next/head";
diff --git a/src/components/liquidityPositions/closedStatus.tsx b/src/components/liquidityPositions/closedStatus.tsx
index e7a5e8ff..8df8d1fb 100644
--- a/src/components/liquidityPositions/closedStatus.tsx
+++ b/src/components/liquidityPositions/closedStatus.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React from "react";
 import {
   VStack,
@@ -14,8 +16,7 @@ interface ClosedPositionStatusProps {
 
 const ClosedPositionStatus = ({ nftId, lp_event }: ClosedPositionStatusProps) => {
   return (
-    <>
-      <VStack align={"left"} spacing={2}>
+    <VStack align={"left"} spacing={2}>
         <Text fontSize={"large"} fontWeight={"bold"} paddingBottom=".2em">
           Position Closed
         </Text>
@@ -30,7 +31,6 @@ const ClosedPositionStatus = ({ nftId, lp_event }: ClosedPositionStatusProps) =>
           />
         </HStack>
       </VStack>
-    </>
   );
 };
 
diff --git a/src/components/liquidityPositions/currentStatus.tsx b/src/components/liquidityPositions/currentStatus.tsx
index 17321912..7306af73 100644
--- a/src/components/liquidityPositions/currentStatus.tsx
+++ b/src/components/liquidityPositions/currentStatus.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { useEffect, useState } from "react";
 import { VStack, Text, Badge, HStack, Image, Avatar } from "@chakra-ui/react";
 import {
@@ -30,7 +32,7 @@ const CurrentLPStatus = ({ nftId, position }: CurrentLPStatusProps) => {
   // First process position to human readable pieces
 
   // Get status
-  const status = (position.state as PositionState).state.toString();
+  const status = (position.state!).state.toString();
 
   // https://buf.build/penumbra-zone/penumbra/docs/main:penumbra.core.component.dex.v1#penumbra.core.component.dex.v1.PositionState.PositionStateEnum
   let statusText = "";
@@ -56,10 +58,10 @@ const CurrentLPStatus = ({ nftId, position }: CurrentLPStatusProps) => {
   }
 
   // Get fee tier
-  const feeTier = Number(position!.phi!.component!.fee);
+  const feeTier = Number(position.phi!.component!.fee);
 
-  const asset1 = position!.phi!.pair!.asset1;
-  const asset2 = position!.phi!.pair!.asset2;
+  const asset1 = position.phi!.pair!.asset1;
+  const asset2 = position.phi!.pair!.asset2;
 
   // States for tokens
   const [asset1Token, setAsset1Token] = useState<Token>({
@@ -82,10 +84,10 @@ const CurrentLPStatus = ({ nftId, position }: CurrentLPStatusProps) => {
     // Function to fetch tokens asynchronously
     const fetchTokens = async () => {
       try {
-        const asset1 = position!.phi!.pair!.asset1;
-        const asset2 = position!.phi!.pair!.asset2;
+        const asset1 = position.phi!.pair!.asset1;
+        const asset2 = position.phi!.pair!.asset2;
 
-        if (asset1 && asset1.inner) {
+        if (asset1?.inner) {
           const fetchedAsset1Token = fetchTokenAsset(asset1.inner);
           if (!fetchedAsset1Token) {
             setAssetError("Asset 1 token not found");
@@ -94,7 +96,7 @@ const CurrentLPStatus = ({ nftId, position }: CurrentLPStatusProps) => {
           setAsset1Token(fetchedAsset1Token);
         }
 
-        if (asset2 && asset2.inner) {
+        if (asset2?.inner) {
           const fetchedAsset2Token = fetchTokenAsset(asset2.inner);
           if (!fetchedAsset2Token) {
             setAssetError("Asset 2 token not found");
@@ -115,25 +117,25 @@ const CurrentLPStatus = ({ nftId, position }: CurrentLPStatusProps) => {
   }
 
   const reserves1 = fromBaseUnit(
-    BigInt(position!.reserves!.r1?.lo || 0),
-    BigInt(position!.reserves!.r1?.hi || 0),
+    BigInt(position.reserves!.r1?.lo || 0),
+    BigInt(position.reserves!.r1?.hi || 0),
     asset1Token.decimals
   );
 
   const reserves2 = fromBaseUnit(
-    BigInt(position!.reserves!.r2?.lo || 0),
-    BigInt(position!.reserves!.r2?.hi || 0),
+    BigInt(position.reserves!.r2?.lo || 0),
+    BigInt(position.reserves!.r2?.hi || 0),
     asset2Token.decimals
   );
 
   const p: BigNumber = fromBaseUnit(
-    BigInt(position!.phi!.component!.p!.lo || 0),
-    BigInt(position!.phi!.component!.p!.hi || 0),
+    BigInt(position.phi!.component!.p!.lo || 0),
+    BigInt(position.phi!.component!.p!.hi || 0),
     asset2Token.decimals
   );
   const q: BigNumber = fromBaseUnit(
-    BigInt(position!.phi!.component!.q!.lo || 0),
-    BigInt(position!.phi!.component!.q!.hi || 0),
+    BigInt(position.phi!.component!.q!.lo || 0),
+    BigInt(position.phi!.component!.q!.hi || 0),
     asset1Token.decimals
   );
 
diff --git a/src/components/liquidityPositions/executionEvent.tsx b/src/components/liquidityPositions/executionEvent.tsx
index 40d2c582..849ba3b1 100644
--- a/src/components/liquidityPositions/executionEvent.tsx
+++ b/src/components/liquidityPositions/executionEvent.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { useEffect, useState } from "react";
 import {
   Box,
diff --git a/src/components/liquidityPositions/openStatus.tsx b/src/components/liquidityPositions/openStatus.tsx
index ba327dea..28d3eabd 100644
--- a/src/components/liquidityPositions/openStatus.tsx
+++ b/src/components/liquidityPositions/openStatus.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { useEffect, useState } from "react";
 import {
   Box,
@@ -27,8 +29,7 @@ interface OpenPositionStatusProps {
 
 const OpenPositionStatus = ({ nftId, lp_event }: OpenPositionStatusProps) => {
   return (
-    <>
-      <VStack align={"left"} spacing={2}>
+    <VStack align={"left"} spacing={2}>
         <Text fontSize={"large"} fontWeight={"bold"} paddingBottom=".2em">
           Position Opened
         </Text>
@@ -44,7 +45,6 @@ const OpenPositionStatus = ({ nftId, lp_event }: OpenPositionStatusProps) => {
         </HStack>
         <LPAssetView sectionTitle={"Initial Reserves"} lp_event={lp_event} />
       </VStack>
-    </>
   );
 };
 
diff --git a/src/components/liquidityPositions/timelinePosition.tsx b/src/components/liquidityPositions/timelinePosition.tsx
index ce869055..321a4496 100644
--- a/src/components/liquidityPositions/timelinePosition.tsx
+++ b/src/components/liquidityPositions/timelinePosition.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React from "react";
 import { Box, HStack, Text, VStack } from "@chakra-ui/react";
 import { LiquidityPositionEvent } from "@/utils/indexer/types/lps";
@@ -16,10 +18,9 @@ export const POSITION_CLOSE_EVENT = "EventQueuePositionClose";
 export const POSITION_WITHDRAW_EVENT = "EventPositionWithdraw";
 
 const TimelinePosition = ({ nftId, lp_event }: TimelinePositionProps) => {
-  //console.log(lp_event);
+  // console.log(lp_event);
   return (
-    <>
-      <HStack
+    <HStack
         spacing={{ base: "1em", md: "2em" }}
         alignItems={{ base: "flex-start", md: "center" }}
         flexDirection={{ base: "column", md: "row" }}
@@ -42,7 +43,6 @@ const TimelinePosition = ({ nftId, lp_event }: TimelinePositionProps) => {
           <BlockTimestampView blockHeight={lp_event.block_height} timestamp={lp_event.created_at} />
         </VStack>
       </HStack>
-    </>
   );
 };
 
diff --git a/src/components/liquidityPositions/withdrawnStatus.tsx b/src/components/liquidityPositions/withdrawnStatus.tsx
index 8fdd7c1a..68da90af 100644
--- a/src/components/liquidityPositions/withdrawnStatus.tsx
+++ b/src/components/liquidityPositions/withdrawnStatus.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React from "react";
 import {
   VStack,
@@ -18,8 +20,7 @@ const WithdrawnPositionStatus = ({
   lp_event,
 }: WithdrawnPositionStatusProps) => {
   return (
-    <>
-      <VStack align={"left"} spacing={2}>
+    <VStack align={"left"} spacing={2}>
         <Text fontSize={"large"} fontWeight={"bold"} paddingBottom=".2em">
           Position Withdrawn
         </Text>
@@ -35,7 +36,6 @@ const WithdrawnPositionStatus = ({
         </HStack>
         <LPAssetView sectionTitle={"Reserves Withdrawn"} lp_event={lp_event}/>
       </VStack>
-    </>
   );
 };
 
diff --git a/src/components/lpAssetView.tsx b/src/components/lpAssetView.tsx
index 2ae65c3c..4ffc0455 100644
--- a/src/components/lpAssetView.tsx
+++ b/src/components/lpAssetView.tsx
@@ -1,7 +1,8 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { FC, useEffect, useState } from "react";
 import { CopyIcon } from "@radix-ui/react-icons";
-import { Avatar, HStack, VStack } from "@chakra-ui/react";
-import { Text } from "@chakra-ui/react";
+import { Avatar, HStack, VStack , Text } from "@chakra-ui/react";
 import {
   LiquidityPositionEvent,
   PositionExecutionEvent,
@@ -72,7 +73,7 @@ const LPAssetView: FC<LPAssetViewProps> = ({ sectionTitle, lp_event }) => {
 
         if (asset2) {
           const fetchedAsset2Token = fetchTokenAsset(asset2)
-          //const fetchedAsset2Token = await fetchToken(asset2);
+          // const fetchedAsset2Token = await fetchToken(asset2);
           if (!fetchedAsset2Token) {
             setAssetError("Asset 2 token not found");
             throw new Error("Asset 2 token not found");
@@ -128,8 +129,7 @@ const LPAssetView: FC<LPAssetViewProps> = ({ sectionTitle, lp_event }) => {
   }, [lp_event, asset1Token, asset2Token]);
 
   return (
-    <>
-      <VStack align={"left"} spacing={2} paddingTop={".5em"}>
+    <VStack align={"left"} spacing={2} paddingTop={".5em"}>
         <Text fontSize={"medium"} fontStyle={"oblique"}>
           {sectionTitle}{" "}
         </Text>
@@ -163,7 +163,6 @@ const LPAssetView: FC<LPAssetViewProps> = ({ sectionTitle, lp_event }) => {
           </HStack>
         </HStack>
       </VStack>
-    </>
   );
 };
 
diff --git a/src/components/lpSearchBar.tsx b/src/components/lpSearchBar.tsx
index e0ece1b3..30bb8ee5 100644
--- a/src/components/lpSearchBar.tsx
+++ b/src/components/lpSearchBar.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // components/lpSearchBar.tsx
 
 import React, { useState } from "react";
diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
index bc3af84e..57a42c4f 100644
--- a/src/components/navbar.tsx
+++ b/src/components/navbar.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // components/navbar.tsx
 
 import Image from "next/image";
diff --git a/src/components/pairSelector.tsx b/src/components/pairSelector.tsx
index 3f6b4abe..fe0c9f14 100644
--- a/src/components/pairSelector.tsx
+++ b/src/components/pairSelector.tsx
@@ -1,17 +1,17 @@
-import { useEffect, useState } from "react";
-import { Box, Text, Flex } from "@chakra-ui/react";
-import { fetchAllTokenAssets } from "@/utils/token/tokenFetch";
-import OutsideClickHandler from "react-outside-click-handler";
-import { Token } from "@/utils/types/token";
+import { useEffect, useState } from 'react';
+import { Box, Text, Flex } from '@chakra-ui/react';
+import { fetchAllTokenAssets } from '@/utils/token/tokenFetch';
+import OutsideClickHandler from 'react-outside-click-handler';
+import { Token } from '@/utils/types/token';
 
-const orderedAssets = ["UM", "USDC"];
+const orderedAssets = ['UM', 'USDC'];
 
 export default function PairSelector({
   show,
   setShow,
   onSelect,
 }: {
-  show: Boolean;
+  show: boolean;
   setShow: (show: boolean) => void;
   onSelect: (assets: [Token, Token]) => void;
 }) {
@@ -20,9 +20,7 @@ export default function PairSelector({
 
   useEffect(() => {
     const tokenAssets = fetchAllTokenAssets();
-    setTokenAssets(
-      Object.fromEntries(tokenAssets.map((asset) => [asset.symbol, asset]))
-    );
+    setTokenAssets(Object.fromEntries(tokenAssets.map(asset => [asset.symbol, asset])));
   }, []);
 
   useEffect(() => {
@@ -34,56 +32,61 @@ export default function PairSelector({
       onSelect(selectedAssets as [Token, Token]);
       setShow(false);
     }
-  }, [selectedAssets]);
+  }, [selectedAssets, onSelect, setShow]);
 
   return (
     <OutsideClickHandler onOutsideClick={() => setShow(false)}>
       <Box
-        display={show ? "block" : "none"}
-        position="absolute"
-        top="100%"
-        left="0"
+        display={show ? 'block' : 'none'}
+        position='absolute'
+        top='100%'
+        left='0'
         width={360}
         zIndex={1000}
         p={2}
-        border="1px solid rgba(255, 255, 255, 0.1)"
+        border='1px solid rgba(255, 255, 255, 0.1)'
         borderRadius={10}
-        background="var(--charcoal)"
+        background='var(--charcoal)'
         maxHeight={300}
-        overflow="scroll"
-        textAlign="left"
+        overflow='scroll'
+        textAlign='left'
       >
         <Text fontSize={15} fontWeight={600} py={2} px={4} mb={2}>
-          {!selectedAssets.length ? "Select Base Asset" : "Select Quote Asset"}
+          {!selectedAssets.length ? 'Select Base Asset' : 'Select Quote Asset'}
         </Text>
         {[
-          ...orderedAssets.map((symbol) => tokenAssets[symbol]),
+          ...orderedAssets.map(symbol => tokenAssets[symbol]),
           ...Object.values(tokenAssets)
-            .filter((asset) => !orderedAssets.includes(asset.symbol))
+            .filter(asset => !orderedAssets.includes(asset.symbol))
             .sort((a, b) => {
               return a.symbol.localeCompare(b.symbol);
             }),
         ]
-          .filter((asset) => asset && !selectedAssets.includes(asset))
-          .map((asset) => (
-            <Flex
-              key={asset.symbol}
-              as="button"
-              width="100%"
-              py={2}
-              px={4}
-              borderRadius={10}
-              _hover={{ background: "var(--body-background)" }}
-              onClick={() => setSelectedAssets([...selectedAssets, asset])}
-            >
-              <Text fontSize={14} fontWeight={600} mr={2}>
-                {asset.symbol}
-              </Text>
-              <Text fontSize={14} opacity="0.75">
-                {asset.display}
-              </Text>
-            </Flex>
-          ))}
+          .filter(asset => asset && !selectedAssets.includes(asset))
+          .map(asset => {
+            if (!asset) {
+              return null;
+            }
+            return (
+              <Flex
+                key={asset.symbol}
+                as='button'
+                width='100%'
+                py={2}
+                px={4}
+                borderRadius={10}
+                _hover={{ background: 'var(--body-background)' }}
+                onClick={() => setSelectedAssets([...selectedAssets, asset])}
+              >
+                <Text fontSize={14} fontWeight={600} mr={2}>
+                  {asset.symbol}
+                </Text>
+                <Text fontSize={14} opacity='0.75'>
+                  {asset.display}
+                </Text>
+              </Flex>
+            );
+          })}
       </Box>
     </OutsideClickHandler>
   );
diff --git a/src/components/swaps/index.tsx b/src/components/swaps/index.tsx
index 2b3bced9..105d221c 100644
--- a/src/components/swaps/index.tsx
+++ b/src/components/swaps/index.tsx
@@ -1,8 +1,9 @@
 // copied from pages/index
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 
 import { useEffect, useState } from "react";
 import { Price, Trace, TraceType } from "../../pages/block/[block_height]";
-import { Box, Heading, HStack, Link, Stack, VStack } from "@chakra-ui/react";
+import { Box, Link, Stack, VStack } from "@chakra-ui/react";
 import {
   SwapExecution,
   SwapExecution_Trace,
@@ -27,11 +28,11 @@ export default function Swaps() {
   const [isLoading, setIsLoading] = useState(true);
 
   useEffect(() => {
-    let fetchData = async () => {
+    const fetchData = async () => {
       const blockHeight = await fetch("/api/blocks/1")
         .then((res) => res.json())
         .then((data) => {
-          return data[0]["height"];
+          return data[0].height;
         })
         .catch((err) => {
           console.error(err);
@@ -42,7 +43,7 @@ export default function Swaps() {
 
       let swaps = [];
       let blockRange = 10;
-      let maxBlocks = 100000;
+      const maxBlocks = 100000;
 
       while (blockRange <= maxBlocks && swaps.length == 0) {
         console.log(
diff --git a/src/components/util/loadingSpinner.tsx b/src/components/util/loadingSpinner.tsx
index e009d5e9..44f96ffe 100644
--- a/src/components/util/loadingSpinner.tsx
+++ b/src/components/util/loadingSpinner.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { Center, VStack, Spinner, Text } from "@chakra-ui/react";
 
 export const LoadingSpinner = () => {
diff --git a/src/constants/configConstants.ts b/src/constants/configConstants.ts
index fc165028..f131f3ed 100644
--- a/src/constants/configConstants.ts
+++ b/src/constants/configConstants.ts
@@ -3,10 +3,10 @@ export interface ConstantsConfig {
   chainId: string;
 }
 
-const defaultChainId = "penumbra-1"
-const defaultCuiolaUrl = "https://cuiloa.testnet.penumbra.zone"
+const defaultChainId = "penumbra-1";
+const defaultCuiolaUrl = "https://cuiloa.testnet.penumbra.zone";
 
 export const Constants: ConstantsConfig = {
-  cuiloaUrl: process.env.NEXT_PUBLIC_CUILOA_URL ? process.env.NEXT_PUBLIC_CUILOA_URL : defaultCuiolaUrl,
-  chainId: process.env.NEXT_PUBLIC_CHAIN_ID ? process.env.NEXT_PUBLIC_CHAIN_ID : defaultChainId,
+  cuiloaUrl: process.env["NEXT_PUBLIC_CUILOA_URL"] ?? defaultCuiolaUrl,
+  chainId: process.env["NEXT_PUBLIC_CHAIN_ID"] ?? defaultChainId,
 };
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 77c1d2f2..7637681e 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import type { AppProps } from "next/app";
 import React from "react";
 import "@/global.css";
diff --git a/src/pages/api/arbs/[...params].ts b/src/pages/api/arbs/[...params].ts
index abad9d04..77f27a89 100644
--- a/src/pages/api/arbs/[...params].ts
+++ b/src/pages/api/arbs/[...params].ts
@@ -1,39 +1,36 @@
 // pages/api/arbs/[...params].ts
 
-import { DexQueryServiceClient } from "@/utils/protos/services/dex/dex-query-service-client";
-import { SwapExecutionWithBlockHeight } from "@/utils/protos/types/DexQueryServiceClientInterface";
-import { NextApiRequest, NextApiResponse } from "next";
+import { DexQueryServiceClient } from '@/utils/protos/services/dex/dex-query-service-client';
+import { NextApiRequest, NextApiResponse } from 'next';
 
-const grpcEndpoint = process.env.PENUMBRA_GRPC_ENDPOINT!
+const grpcEndpoint = process.env['PENUMBRA_GRPC_ENDPOINT'];
 if (!grpcEndpoint) {
-    throw new Error("PENUMBRA_GRPC_ENDPOINT is not set")
+  throw new Error('PENUMBRA_GRPC_ENDPOINT is not set');
 }
 
 export default async function arbsByBlockRange(req: NextApiRequest, res: NextApiResponse) {
-    const params = req.query.params as string[];
+  const params = req.query['params'] as string[];
 
-    const startHeight = params[0] || null;
-    const endHeight = params[1] || null;
+  const startHeight = params[0] ?? null;
+  const endHeight = params[1] ?? null;
 
-    try {
-        if (!startHeight || !endHeight) {
-            return res.status(400).json({ error: "Invalid query parameters" });
-        }
-        // TODO: validate StartHeight/EndHeight are numbers
-        const dex_querier = new DexQueryServiceClient({
-            grpcEndpoint: grpcEndpoint,
-        });
+  try {
+    if (!startHeight || !endHeight) {
+      res.status(400).json({ error: 'Invalid query parameters' });
+      return;
+    }
+    // TODO: validate StartHeight/EndHeight are numbers
+    const dex_querier = new DexQueryServiceClient({
+      grpcEndpoint: grpcEndpoint ?? '',
+    });
 
-        const data = await dex_querier.arbExecutions(
-            parseInt(startHeight),
-            parseInt(endHeight)
-        );
+    const data = await dex_querier.arbExecutions(parseInt(startHeight), parseInt(endHeight));
 
-        res.status(200).json(data as SwapExecutionWithBlockHeight[]);
-    } catch (error) {
-        console.error("Error getting liquidty positions by price grpc data:", error);
-        res.status(500).json({
-            error: `Error getting liquidty positions by price grpc data: ${error}`,
-        });
-    }
+    res.status(200).json(data ?? null);
+  } catch (error) {
+    console.error('Error getting liquidty positions by price grpc data:', error);
+    res.status(500).json({
+      error: `Error getting liquidty positions by price grpc data: ${error as string}`,
+    });
+  }
 }
diff --git a/src/pages/api/blockTimestamps/[...params].js b/src/pages/api/blockTimestamps/[...params].js
index 4388875f..94d9948d 100644
--- a/src/pages/api/blockTimestamps/[...params].js
+++ b/src/pages/api/blockTimestamps/[...params].js
@@ -1,23 +1,25 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/blockTimestamps/[...params].js
 
 import { IndexerQuerier } from "../../../utils/indexer/connector";
 
-const indexerEndpoint = process.env.PENUMBRA_INDEXER_ENDPOINT
+const indexerEndpoint = process.env.PENUMBRA_INDEXER_ENDPOINT;
 if (!indexerEndpoint) {
-    throw new Error("PENUMBRA_INDEXER_ENDPOINT is not set")
+  throw new Error("PENUMBRA_INDEXER_ENDPOINT is not set");
 }
 
 export default async function blockTimestampsFetchHandler(req, res) {
   const indexerQuerier = new IndexerQuerier(indexerEndpoint);
 
   // if the first param is 'range' then we are fetching a range of blocks
-  
+
   // Params will be an arbitrarily long list of block heights
   const params = req.query.params;
   let blocks = [];
 
-  if (params[0] == "range") {
-    if (params.length != 3 || isNaN(params[1]) || isNaN(params[2])) {
+  if (params[0] === "range") {
+    if (params.length !== 3 || isNaN(params[1]) || isNaN(params[2])) {
       res.status(400).json({ error: "Invalid block height range" });
       return;
     }
@@ -25,7 +27,7 @@ export default async function blockTimestampsFetchHandler(req, res) {
     // define blocks as inclusive range between the two block heights
     const start = parseInt(params[1]);
     const end = parseInt(params[2]);
-    blocks = Array.from({length: end - start + 1}, (_, i) => start + i);
+    blocks = Array.from({ length: end - start + 1 }, (_, i) => start + i);
   } else {
     for (const param of params) {
       if (isNaN(param)) {
diff --git a/src/pages/api/blocks/[...params].js b/src/pages/api/blocks/[...params].js
index 734a5c06..ccc7cc9c 100644
--- a/src/pages/api/blocks/[...params].js
+++ b/src/pages/api/blocks/[...params].js
@@ -1,30 +1,34 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/blocks/[...params].js
 
 import { IndexerQuerier } from "../../../utils/indexer/connector";
 
-const grpcEndpoint = process.env.PENUMBRA_GRPC_ENDPOINT
+const grpcEndpoint = process.env.PENUMBRA_GRPC_ENDPOINT;
 if (!grpcEndpoint) {
-    throw new Error("PENUMBRA_GRPC_ENDPOINT is not set")
+  throw new Error("PENUMBRA_GRPC_ENDPOINT is not set");
 }
 
-const indexerEndpoint = process.env.PENUMBRA_INDEXER_ENDPOINT
+const indexerEndpoint = process.env.PENUMBRA_INDEXER_ENDPOINT;
 if (!indexerEndpoint) {
-    throw new Error("PENUMBRA_INDEXER_ENDPOINT is not set")
+  throw new Error("PENUMBRA_INDEXER_ENDPOINT is not set");
 }
 
 export default async function blockInfoFetchHandler(req, res) {
-  
   const indexerQuerier = new IndexerQuerier(indexerEndpoint);
   try {
     if (req.query.params.length === 1) {
-        const n = req.query.params[0];
-        const data = await indexerQuerier.fetchMostRecentNBlocks(parseInt(n));
-        res.status(200).json(data);
-    }  else {
-        const startHeight = req.query.params[0];
-        const endHeight = req.query.params[1];
-        const data = await indexerQuerier.fetchBlocksWithinRange(parseInt(startHeight), parseInt(endHeight))
-        res.status(200).json(data);
+      const n = req.query.params[0];
+      const data = await indexerQuerier.fetchMostRecentNBlocks(parseInt(n));
+      res.status(200).json(data);
+    } else {
+      const startHeight = req.query.params[0];
+      const endHeight = req.query.params[1];
+      const data = await indexerQuerier.fetchBlocksWithinRange(
+        parseInt(startHeight),
+        parseInt(endHeight),
+      );
+      res.status(200).json(data);
     }
   } catch (error) {
     console.error("Error fetching block data:", error);
diff --git a/src/pages/api/lp/[lp_nft_id].js b/src/pages/api/lp/[lp_nft_id].js
index c00c971d..1869519a 100644
--- a/src/pages/api/lp/[lp_nft_id].js
+++ b/src/pages/api/lp/[lp_nft_id].js
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/lp/[lp_nft_id].js
 import { IndexerQuerier } from "../../../utils/indexer/connector";
 
diff --git a/src/pages/api/lp/[lp_nft_id]/position.ts b/src/pages/api/lp/[lp_nft_id]/position.ts
index c79399b5..af2f8bdd 100644
--- a/src/pages/api/lp/[lp_nft_id]/position.ts
+++ b/src/pages/api/lp/[lp_nft_id]/position.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/lp/[lp_nft_id]/position.ts
 import { DexQueryServiceClient } from "../../../../utils/protos/services/dex/dex-query-service-client";
 import {
@@ -24,7 +26,7 @@ export default async function liquidityPositionDataHandler(req: any, res: any) {
 
     const data = await lp_querier.liquidityPositionById(positionId);
 
-    res.status(200).json(data as Position);
+    res.status(200).json(data!);
   } catch (error) {
     console.error("Error fetching liquidity position grpc data:", error);
     res
diff --git a/src/pages/api/lp/[lp_nft_id]/trades.js b/src/pages/api/lp/[lp_nft_id]/trades.js
index e75c1a57..b48a4ccd 100644
--- a/src/pages/api/lp/[lp_nft_id]/trades.js
+++ b/src/pages/api/lp/[lp_nft_id]/trades.js
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/lp/[lp_nft_id]/trades.js
 import { IndexerQuerier } from "../../../../utils/indexer/connector";
 
diff --git a/src/pages/api/lp/block/[...params].js b/src/pages/api/lp/block/[...params].js
index 0ff947e0..6f78ba6a 100644
--- a/src/pages/api/lp/block/[...params].js
+++ b/src/pages/api/lp/block/[...params].js
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/lp/positionsByBlockHeight/[...params].js
 import { IndexerQuerier } from "../../../../utils/indexer/connector";
 
diff --git a/src/pages/api/lp/positionsByPrice/[...params].ts b/src/pages/api/lp/positionsByPrice/[...params].ts
index fea0ea66..d41a85b2 100644
--- a/src/pages/api/lp/positionsByPrice/[...params].ts
+++ b/src/pages/api/lp/positionsByPrice/[...params].ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/lp/positionsByPrice/[...params].ts
 import { NextApiRequest, NextApiResponse } from "next";
 import { DexQueryServiceClient } from "@/utils/protos/services/dex/dex-query-service-client";
@@ -25,7 +27,7 @@ export default async function positionsByPriceHandler(
 
   try {
     if (!token1 || !token2 || !limit) {
-      return res.status(400).json({ error: "Invalid query parameters" });
+      res.status(400).json({ error: "Invalid query parameters" }); return;
     }
 
     // Get token 1 & 2
@@ -38,9 +40,9 @@ export default async function positionsByPriceHandler(
     );
 
     if (!asset1Token || !asset2Token) {
-      return res
+      res
         .status(400)
-        .json({ error: "Could not find requested token in registry" });
+        .json({ error: "Could not find requested token in registry" }); return;
     }
 
     const lp_querier = new DexQueryServiceClient({
diff --git a/src/pages/api/ohlc/[...params].ts b/src/pages/api/ohlc/[...params].ts
index 55f71090..3fbcfe7e 100644
--- a/src/pages/api/ohlc/[...params].ts
+++ b/src/pages/api/ohlc/[...params].ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/ohlc/[...params].ts
 
 import { DexQueryServiceClient } from "@/utils/protos/services/dex/dex-query-service-client";
@@ -29,12 +31,12 @@ export default async function candleStickData(
   try {
     const tokenAssets = fetchAllTokenAssets();
     if (!startHeight || !tokenIn || !tokenOut || !limit) {
-      return res.status(400).json({ error: "Invalid query parameters" });
+      res.status(400).json({ error: "Invalid query parameters" }); return;
     }
 
     // Set a HARD limit to prevent abuse
     if (parseInt(limit) > 10000) {
-      return res.status(400).json({ error: "Limit exceeded" });
+      res.status(400).json({ error: "Limit exceeded" }); return;
     }
 
     const dex_querier = new DexQueryServiceClient({
@@ -48,9 +50,9 @@ export default async function candleStickData(
       (x) => x.display.toLowerCase() === tokenOut.toLowerCase()
     )?.inner;
     if (!tokenInInner || !tokenOutInner) {
-      return res.status(400).json({
+      res.status(400).json({
         error: `Invalid token pair, a token was not found: ${tokenIn} ${tokenOut}`,
-      });
+      }); return;
     }
 
     const tradingPair = new DirectedTradingPair();
diff --git a/src/pages/api/shieldedPool/[token_inner].ts b/src/pages/api/shieldedPool/[token_inner].ts
index a3a2601c..f278a074 100644
--- a/src/pages/api/shieldedPool/[token_inner].ts
+++ b/src/pages/api/shieldedPool/[token_inner].ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/shieldedPool/[token_inner].ts
 import { ShieldedPoolQuerier } from "../../../utils/protos/services/app/shielded-pool";
 import { base64ToUint8Array } from "../../../utils/math/base64";
@@ -27,7 +29,7 @@ export default async function assetMetadataHandler(req: any, res: any) {
 
     const data = await pool_querier.assetMetadata(positionId);
 
-    res.status(200).json(data as Metadata);
+    res.status(200).json(data!);
   } catch (error) {
     console.error("Error fetching asset metadata grpc data:", error);
     res
diff --git a/src/pages/api/simulations/[...params].ts b/src/pages/api/simulations/[...params].ts
index 1a96d6fd..d8967f80 100644
--- a/src/pages/api/simulations/[...params].ts
+++ b/src/pages/api/simulations/[...params].ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/simulations/[...params].ts
 import { SimulationQuerier } from "@/utils/protos/services/dex/simulated-trades";
 import { base64ToUint8Array } from "../../../utils/math/base64";
@@ -31,7 +33,7 @@ export default async function simulationHandler(
 
   try {
     if (!token1 || !token2 || !amountIn) {
-      return res.status(400).json({ error: "Invalid query parameters" });
+      res.status(400).json({ error: "Invalid query parameters" }); return;
     }
 
     if (String(singleHop).toLocaleLowerCase() === "singlehop") {
@@ -48,9 +50,9 @@ export default async function simulationHandler(
     );
 
     if (!asset1Token || !asset2Token) {
-      return res
+      res
         .status(400)
-        .json({ error: "Could not find requested token in registry" });
+        .json({ error: "Could not find requested token in registry" }); return;
     }
     const sim_querier = new SimulationQuerier({
       grpcEndpoint: grpcEndpoint,
@@ -112,7 +114,7 @@ export default async function simulationHandler(
       // If the error message contains 'there are no orders to fulfill this swap', return an empty array
       if (errorMessage.includes("there are no orders to fulfill this swap")) {
         console.log("No orders to fulfill swap");
-        return res.status(200).json({ traces: [] });
+        res.status(200).json({ traces: [] }); return;
       }
     }
 
diff --git a/src/pages/api/swaps/[...params].ts b/src/pages/api/swaps/[...params].ts
index a2a62aa8..f696a2b1 100644
--- a/src/pages/api/swaps/[...params].ts
+++ b/src/pages/api/swaps/[...params].ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/api/swaps/[...params].ts
 
 import { DexQueryServiceClient } from "@/utils/protos/services/dex/dex-query-service-client";
@@ -18,7 +20,7 @@ export default async function swapsByBlockRange(req: NextApiRequest, res: NextAp
 
     try {
         if (!startHeight || !endHeight) {
-            return res.status(400).json({ error: "Invalid query parameters" });
+            res.status(400).json({ error: "Invalid query parameters" }); return;
         }
         // TODO: validate StartHeight/EndHeight are numbers
         const dex_querier = new DexQueryServiceClient({
diff --git a/src/pages/block/[block_height].tsx b/src/pages/block/[block_height].tsx
index 9cb873b8..ce911fc2 100644
--- a/src/pages/block/[block_height].tsx
+++ b/src/pages/block/[block_height].tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import Layout from "@/components/layout";
 import { useRouter } from "next/router";
 import {
@@ -53,13 +55,13 @@ export const Price = ({
       const inputDisplayDenomExponent = firstValueMetadata.decimals ?? 0;
       const outputDisplayDenomExponent = lastValueMetadata.decimals ?? 0;
       const formattedInputAmount = fromBaseUnit(
-        BigInt(inputValue.amount?.lo ?? 0),
-        BigInt(inputValue.amount?.hi ?? 0),
+        BigInt(inputValue.amount.lo ?? 0),
+        BigInt(inputValue.amount.hi ?? 0),
         inputDisplayDenomExponent
       ).toFixed(6);
       const formattedOutputAmount = fromBaseUnit(
-        BigInt(outputValue.amount?.lo ?? 0),
-        BigInt(outputValue.amount?.hi ?? 0),
+        BigInt(outputValue.amount.lo ?? 0),
+        BigInt(outputValue.amount.hi ?? 0),
         outputDisplayDenomExponent
       ).toFixed(6);
       const outputToInputRatio = new BigNumber(formattedOutputAmount)
@@ -73,7 +75,7 @@ export const Price = ({
     }
   }
 
-  if (!price) return null;
+  if (!price) {return null;}
   return <span className="text-xs text-muted-foreground">{price}</span>;
 };
 
@@ -340,19 +342,19 @@ export default function Block() {
             arbsResponse,
             swapsResponse,
           ]) => {
-            const blockInfoList: BlockInfo[] = blockInfoResponse as BlockInfo[];
+            const blockInfoList: BlockInfo[] = blockInfoResponse;
             const positionData: LiquidityPositionEvent[] =
-              liquidityPositionOpenCloseResponse as LiquidityPositionEvent[];
+              liquidityPositionOpenCloseResponse;
             const otherPositionData: LiquidityPositionEvent[] =
-              liquidityPositionOtherResponse as LiquidityPositionEvent[];
+              liquidityPositionOtherResponse;
             const arbData: SwapExecutionWithBlockHeight[] =
-              arbsResponse as SwapExecutionWithBlockHeight[];
+              arbsResponse;
             const swapData: SwapExecutionWithBlockHeight[] =
-              swapsResponse as SwapExecutionWithBlockHeight[];
+              swapsResponse;
 
             if (blockInfoList.length === 0) {
-              //setError(`No data for block ${block_height} found`);
-              //setIsLoading(false);
+              // setError(`No data for block ${block_height} found`);
+              // setIsLoading(false);
               console.log(`No data for block ${block_height} found`);
               blockInfoList.push({
                 height: height,
@@ -368,24 +370,24 @@ export default function Block() {
               otherPositionEvents: [],
               swapExecutions: [],
               arbExecutions: [],
-              createdAt: blockInfoList[0]["created_at"],
+              createdAt: blockInfoList[0].created_at,
             };
             positionData.forEach(
               (positionOpenCloseEvent: LiquidityPositionEvent) => {
-                if (positionOpenCloseEvent["type"].includes("PositionOpen")) {
-                  detailedBlockSummaryData["openPositionEvents"].push(
+                if (positionOpenCloseEvent.type.includes("PositionOpen")) {
+                  detailedBlockSummaryData.openPositionEvents.push(
                     positionOpenCloseEvent
                   );
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionClose")
+                  positionOpenCloseEvent.type.includes("PositionClose")
                 ) {
-                  detailedBlockSummaryData["closePositionEvents"].push(
+                  detailedBlockSummaryData.closePositionEvents.push(
                     positionOpenCloseEvent
                   );
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionWithdraw")
+                  positionOpenCloseEvent.type.includes("PositionWithdraw")
                 ) {
-                  detailedBlockSummaryData["withdrawPositionEvents"].push(
+                  detailedBlockSummaryData.withdrawPositionEvents.push(
                     positionOpenCloseEvent
                   );
                 }
@@ -393,16 +395,16 @@ export default function Block() {
             );
             otherPositionData.forEach(
               (positionEvent: LiquidityPositionEvent) => {
-                detailedBlockSummaryData["otherPositionEvents"].push(
+                detailedBlockSummaryData.otherPositionEvents.push(
                   positionEvent
                 );
               }
             );
             arbData.forEach((arb: SwapExecutionWithBlockHeight) => {
-              detailedBlockSummaryData["arbExecutions"].push(arb.swapExecution);
+              detailedBlockSummaryData.arbExecutions.push(arb.swapExecution);
             });
             swapData.forEach((swap: SwapExecutionWithBlockHeight) => {
-              detailedBlockSummaryData["swapExecutions"].push(
+              detailedBlockSummaryData.swapExecutions.push(
                 swap.swapExecution
               );
             });
@@ -577,8 +579,7 @@ export default function Block() {
               >
                 {blockData!.swapExecutions.map(
                   (swapExecution: SwapExecution) => (
-                    <>
-                      <Box overflowX="auto" width="100%">
+                    <Box overflowX="auto" width="100%">
                         <VStack
                           spacing={2}
                           align="left"
@@ -601,7 +602,6 @@ export default function Block() {
                           )}
                         </VStack>
                       </Box>
-                    </>
                   )
                 )}
               </VStack>
diff --git a/src/pages/explorer/index.tsx b/src/pages/explorer/index.tsx
index e208d173..d0267e35 100644
--- a/src/pages/explorer/index.tsx
+++ b/src/pages/explorer/index.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { Box, Flex, Text } from "@chakra-ui/react";
 import Layout from "../../components/layout";
 import { LPSearchBar } from "../../components/lpSearchBar";
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 29eb4d99..f4e83465 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 export default function Home() {
   return null;
 }
@@ -5,7 +6,7 @@ export default function Home() {
 export async function getServerSideProps() {
   return {
     redirect: {
-      destination: "/trade",
+      destination: '/trade',
     },
   };
 }
diff --git a/src/pages/lp/[lp_nft_id].tsx b/src/pages/lp/[lp_nft_id].tsx
index 6662e41b..7beb5ff6 100644
--- a/src/pages/lp/[lp_nft_id].tsx
+++ b/src/pages/lp/[lp_nft_id].tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/lp/[lp_nft_id].js
 
 import React, { useEffect, useRef, useState } from "react";
@@ -126,7 +128,7 @@ export default function LP() {
     // if showAllTradeEvents, dont do anything, however if its false, remove all but the first and last n trade events
     if (!showAllTradeEvents) {
       // Find the first and last trade events
-      //! In theory they always have to be sandwiched between LP events
+      // ! In theory they always have to be sandwiched between LP events
       let firstTradeIndex = allEvents.findIndex(
         (event) => "lpevent_attributes" in event
       );
diff --git a/src/pages/lp/utils.tsx b/src/pages/lp/utils.tsx
index 4594c4b9..92b6699b 100644
--- a/src/pages/lp/utils.tsx
+++ b/src/pages/lp/utils.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/lp/utils.tsx
 
 import React, { useState } from "react";
diff --git a/src/pages/pair/[...params].tsx b/src/pages/pair/[...params].tsx
index d6a804a3..e3b3966d 100644
--- a/src/pages/pair/[...params].tsx
+++ b/src/pages/pair/[...params].tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/tradingPairs/index.tsx
 
 import React, { useEffect, useRef, useState } from "react";
@@ -330,14 +332,14 @@ export default function TradingPairs() {
     console.log(asset2Token);
 
     // Set single and multi hop depth chart data
-    simulatedMultiHopAsset1SellData!.traces.forEach((trace) => {
+    simulatedMultiHopAsset1SellData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(trace.value.length - 1);
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset1Token.decimals);
       const outputValue =
         Number(
@@ -347,7 +349,7 @@ export default function TradingPairs() {
       const price: number = outputValue / inputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedMultiHopAsset1SellData!.traces[0]) {
+      if (trace === simulatedMultiHopAsset1SellData.traces[0]) {
         console.log("Best Asset1 Sell Price for multi hop", price);
         setBestAsset1SellPriceMultiHop(Number(price));
         bestAsset1SellPriceMultiHop = price;
@@ -376,14 +378,14 @@ export default function TradingPairs() {
     });
 
     // Similar logic for single hop
-    simulatedSingleHopAsset1SellData!.traces.forEach((trace) => {
+    simulatedSingleHopAsset1SellData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(1); // If this isnt 1 then something is wrong
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset1Token.decimals);
       const outputValue =
         Number(
@@ -393,7 +395,7 @@ export default function TradingPairs() {
       const price: number = outputValue / inputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedSingleHopAsset1SellData!.traces[0]) {
+      if (trace === simulatedSingleHopAsset1SellData.traces[0]) {
         console.log("Best Asset1 Sell Price for single hop", price);
         setBestAsset1SellPriceSingleHop(Number(price));
         bestAsset1SellPriceSingleHop = price;
@@ -421,7 +423,7 @@ export default function TradingPairs() {
     });
 
     // Do it all again for the buy side :)
-    //! Maybe theres a way to refactor this to be more concise
+    // ! Maybe theres a way to refactor this to be more concise
     let bestAsset1BuyPriceMultiHop: number | undefined;
     let bestAsset1BuyPriceSingleHop: number | undefined;
 
@@ -430,14 +432,14 @@ export default function TradingPairs() {
     setDepthChartSingleHopAsset1BuyPoints([]);
 
     // Set single and multi hop depth chart data
-    simulatedMultiHopAsset1BuyData!.traces.forEach((trace) => {
+    simulatedMultiHopAsset1BuyData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(trace.value.length - 1);
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset2Token.decimals);
       const outputValue =
         Number(
@@ -448,7 +450,7 @@ export default function TradingPairs() {
       const price: number = inputValue / outputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedMultiHopAsset1BuyData!.traces[0]) {
+      if (trace === simulatedMultiHopAsset1BuyData.traces[0]) {
         console.log("Best Asset1 Buy Price for multi hop", price);
         setBestAsset1BuyPriceMultiHop(Number(price));
         bestAsset1BuyPriceMultiHop = price;
@@ -477,14 +479,14 @@ export default function TradingPairs() {
     });
 
     // Similar logic for single hop
-    simulatedSingleHopAsset1BuyData!.traces.forEach((trace) => {
+    simulatedSingleHopAsset1BuyData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(1); // If this isnt 1 then something is wrong
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset2Token.decimals);
       const outputValue =
         Number(
@@ -495,7 +497,7 @@ export default function TradingPairs() {
       const price: number = inputValue / outputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedSingleHopAsset1BuyData!.traces[0]) {
+      if (trace === simulatedSingleHopAsset1BuyData.traces[0]) {
         console.log("Best Asset1 Buy Price for single hop", price);
         setBestAsset1BuyPriceSingleHop(Number(price));
         bestAsset1BuyPriceSingleHop = price;
diff --git a/src/pages/pair/index.tsx b/src/pages/pair/index.tsx
index aa74a7e6..eb24ea43 100644
--- a/src/pages/pair/index.tsx
+++ b/src/pages/pair/index.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/pairs.tsx
 
 import { useState, useEffect } from 'react';
@@ -43,8 +45,7 @@ export default function Pairs() {
             {isLoading ? (
               <LoadingSpinner />
             ) : 
-            <>
-                <VStack height={'100%'} width={'100%'}>
+            <VStack height={'100%'} width={'100%'}>
                     <HStack justifyContent={'space-evenly'} width={'100%'} paddingTop={'5%'}>
                         <Box borderColor="gray.200">
                             <VStack>
@@ -67,7 +68,6 @@ export default function Pairs() {
                         </form>
                     </Box>
                 </VStack>
-            </>
             }
         </Layout>
     )
diff --git a/src/pages/trade/[[...params]].tsx b/src/pages/trade/[[...params]].tsx
index 44e99a8b..2b481128 100644
--- a/src/pages/trade/[[...params]].tsx
+++ b/src/pages/trade/[[...params]].tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import React, { useEffect, useRef, useState } from "react";
 import { useRouter } from "next/router";
 import Layout from "../../components/layout";
@@ -329,14 +331,14 @@ export default function TradingPairs() {
     console.log(asset2Token);
 
     // Set single and multi hop depth chart data
-    simulatedMultiHopAsset1SellData!.traces.forEach((trace) => {
+    simulatedMultiHopAsset1SellData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(trace.value.length - 1);
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset1Token.decimals);
       const outputValue =
         Number(
@@ -346,7 +348,7 @@ export default function TradingPairs() {
       const price: number = outputValue / inputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedMultiHopAsset1SellData!.traces[0]) {
+      if (trace === simulatedMultiHopAsset1SellData.traces[0]) {
         console.log("Best Asset1 Sell Price for multi hop", price);
         setBestAsset1SellPriceMultiHop(Number(price));
         bestAsset1SellPriceMultiHop = price;
@@ -375,14 +377,14 @@ export default function TradingPairs() {
     });
 
     // Similar logic for single hop
-    simulatedSingleHopAsset1SellData!.traces.forEach((trace) => {
+    simulatedSingleHopAsset1SellData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(1); // If this isnt 1 then something is wrong
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset1Token.decimals);
       const outputValue =
         Number(
@@ -392,7 +394,7 @@ export default function TradingPairs() {
       const price: number = outputValue / inputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedSingleHopAsset1SellData!.traces[0]) {
+      if (trace === simulatedSingleHopAsset1SellData.traces[0]) {
         console.log("Best Asset1 Sell Price for single hop", price);
         setBestAsset1SellPriceSingleHop(Number(price));
         bestAsset1SellPriceSingleHop = price;
@@ -420,7 +422,7 @@ export default function TradingPairs() {
     });
 
     // Do it all again for the buy side :)
-    //! Maybe theres a way to refactor this to be more concise
+    // ! Maybe theres a way to refactor this to be more concise
     let bestAsset1BuyPriceMultiHop: number | undefined;
     let bestAsset1BuyPriceSingleHop: number | undefined;
 
@@ -429,14 +431,14 @@ export default function TradingPairs() {
     setDepthChartSingleHopAsset1BuyPoints([]);
 
     // Set single and multi hop depth chart data
-    simulatedMultiHopAsset1BuyData!.traces.forEach((trace) => {
+    simulatedMultiHopAsset1BuyData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(trace.value.length - 1);
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset2Token.decimals);
       const outputValue =
         Number(
@@ -447,7 +449,7 @@ export default function TradingPairs() {
       const price: number = inputValue / outputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedMultiHopAsset1BuyData!.traces[0]) {
+      if (trace === simulatedMultiHopAsset1BuyData.traces[0]) {
         console.log("Best Asset1 Buy Price for multi hop", price);
         setBestAsset1BuyPriceMultiHop(Number(price));
         bestAsset1BuyPriceMultiHop = price;
@@ -476,14 +478,14 @@ export default function TradingPairs() {
     });
 
     // Similar logic for single hop
-    simulatedSingleHopAsset1BuyData!.traces.forEach((trace) => {
+    simulatedSingleHopAsset1BuyData.traces.forEach((trace) => {
       // First item is the input, last item is the output
       const input = trace.value.at(0);
       const output = trace.value.at(1); // If this isnt 1 then something is wrong
 
       const inputValue =
         Number(
-          joinLoHi(BigInt(input!.amount!.lo!), BigInt(input!.amount!.hi))
+          joinLoHi(BigInt(input!.amount!.lo), BigInt(input!.amount!.hi))
         ) / Number(10 ** asset2Token.decimals);
       const outputValue =
         Number(
@@ -494,7 +496,7 @@ export default function TradingPairs() {
       const price: number = inputValue / outputValue;
 
       // First trace will have best price, so set only on first iteration
-      if (trace === simulatedSingleHopAsset1BuyData!.traces[0]) {
+      if (trace === simulatedSingleHopAsset1BuyData.traces[0]) {
         console.log("Best Asset1 Buy Price for single hop", price);
         setBestAsset1BuyPriceSingleHop(Number(price));
         bestAsset1BuyPriceSingleHop = price;
diff --git a/src/pages/trades.tsx b/src/pages/trades.tsx
index c58edd81..8f3304c1 100644
--- a/src/pages/trades.tsx
+++ b/src/pages/trades.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // pages/trades.tsx
 
 import {
@@ -43,7 +45,7 @@ export default function Trades() {
   useEffect(() => {
     setIsBlockRangeLoading(true);
     if (endingBlockHeight <= 0 || startingBlockHeight <= 0) {
-      var blockInfoPromise: Promise<BlockInfo[]>;
+      let blockInfoPromise: Promise<BlockInfo[]>;
       if (userRequestedBlockEndHeight >= 1) {
         const startHeight = Math.max(
           userRequestedBlockEndHeight - NUMBER_BLOCKS_IN_TIMELINE + 1,
@@ -59,11 +61,11 @@ export default function Trades() {
       }
       Promise.all([blockInfoPromise])
         .then(([blockInfoResponse]) => {
-          const blockInfoList: BlockInfo[] = blockInfoResponse as BlockInfo[];
+          const blockInfoList: BlockInfo[] = blockInfoResponse;
           const blockInfoMap: BlockInfoMap = {};
           blockInfoList.forEach((blockInfo: BlockInfo, i: number) => {
-            //console.log(blockInfo)
-            blockInfoMap[blockInfo["height"]] = blockInfo;
+            // console.log(blockInfo)
+            blockInfoMap[blockInfo.height] = blockInfo;
           });
 
           if (blockInfoList.length === 0) {
@@ -72,9 +74,9 @@ export default function Trades() {
             console.log("No blocks found");
             return;
           } else {
-            setEndingBlockHeight(blockInfoList[0]["height"]);
+            setEndingBlockHeight(blockInfoList[0].height);
             setStartingBlockHeight(
-              blockInfoList[NUMBER_BLOCKS_IN_TIMELINE - 1]["height"]
+              blockInfoList[NUMBER_BLOCKS_IN_TIMELINE - 1].height
             );
             setBlockInfo(blockInfoMap);
             setError(undefined);
@@ -127,7 +129,7 @@ export default function Trades() {
 
             // Initialize blocks
             const blockSummaryMap: BlockSummaryMap = {};
-            var i: number;
+            let i: number;
             for (i = startingBlockHeight; i <= endingBlockHeight; i++) {
               blockSummaryMap[i] = {
                 openPositionEvents: [],
@@ -135,40 +137,34 @@ export default function Trades() {
                 withdrawPositionEvents: [],
                 swapExecutions: [],
                 arbExecutions: [],
-                createdAt: blockInfo[i]["created_at"],
+                createdAt: blockInfo[i].created_at,
               };
             }
 
             positionData.forEach(
               (positionOpenCloseEvent: LiquidityPositionEvent) => {
-                if (positionOpenCloseEvent["type"].includes("PositionOpen")) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "openPositionEvents"
-                  ].push(positionOpenCloseEvent);
+                if (positionOpenCloseEvent.type.includes("PositionOpen")) {
+                  blockSummaryMap[positionOpenCloseEvent.block_height].openPositionEvents.push(positionOpenCloseEvent);
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionClose")
+                  positionOpenCloseEvent.type.includes("PositionClose")
                 ) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "closePositionEvents"
-                  ].push(positionOpenCloseEvent);
+                  blockSummaryMap[positionOpenCloseEvent.block_height].closePositionEvents.push(positionOpenCloseEvent);
                 } else if (
-                  positionOpenCloseEvent["type"].includes("PositionWithdraw")
+                  positionOpenCloseEvent.type.includes("PositionWithdraw")
                 ) {
-                  blockSummaryMap[positionOpenCloseEvent["block_height"]][
-                    "withdrawPositionEvents"
-                  ].push(positionOpenCloseEvent);
+                  blockSummaryMap[positionOpenCloseEvent.block_height].withdrawPositionEvents.push(positionOpenCloseEvent);
                 }
               }
             );
 
             arbData.forEach((arb: SwapExecutionWithBlockHeight) => {
-              blockSummaryMap[arb.blockHeight]["arbExecutions"].push(
+              blockSummaryMap[arb.blockHeight].arbExecutions.push(
                 arb.swapExecution
               );
             });
 
             swapData.forEach((swap: SwapExecutionWithBlockHeight) => {
-              blockSummaryMap[swap.blockHeight]["swapExecutions"].push(
+              blockSummaryMap[swap.blockHeight].swapExecutions.push(
                 swap.swapExecution
               );
             });
@@ -273,8 +269,7 @@ export default function Trades() {
                 {Array.from(
                   Array(endingBlockHeight - startingBlockHeight + 1)
                 ).map((_, index: number) => (
-                  <>
-                    <VStack
+                  <VStack
                       key={index}
                       align={"flex-start"}
                       paddingTop={index === 0 ? "0" : "3em"}
@@ -291,7 +286,6 @@ export default function Trades() {
                         />
                       </VStack>
                     </VStack>
-                  </>
                 ))}
               </VStack>
             </VStack>
diff --git a/src/utils/indexer/connector.tsx b/src/utils/indexer/connector.tsx
index efcb5e4e..e7b86274 100644
--- a/src/utils/indexer/connector.tsx
+++ b/src/utils/indexer/connector.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { Pool } from "pg";
 import { BlockInfo, LiquidityPositionEvent } from "./types/lps";
 import { bech32ToInner } from "../math/bech32";
@@ -49,7 +51,7 @@ export class IndexerQuerier {
       return value.map((item) => this.recursivelyParseJSON(item));
     } else if (typeof value === "object" && value !== null) {
       // If it's an object, apply recursively to each value
-      const parsedObject: { [key: string]: any } = {};
+      const parsedObject: Record<string, any> = {};
       Object.keys(value).forEach((key) => {
         parsedObject[key] = this.recursivelyParseJSON(value[key]);
       });
@@ -165,7 +167,7 @@ export class IndexerQuerier {
   `;
 
     // Use parameterized query to prevent SQL injection
-    //const res = await this.query(queryText);
+    // const res = await this.query(queryText);
     const res = await this.query(queryText, [`${startHeight}`, `${endHeight}`]);
     return res;
   }
diff --git a/src/utils/indexer/types/lps.tsx b/src/utils/indexer/types/lps.tsx
index 9672b9dc..fd72f33e 100644
--- a/src/utils/indexer/types/lps.tsx
+++ b/src/utils/indexer/types/lps.tsx
@@ -1,6 +1,8 @@
-export type LiquidityPositionEvent = {
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
+export interface LiquidityPositionEvent {
   block_height: number;
-  event_id: number; //! Needed for sorting
+  event_id: number; // ! Needed for sorting
   block_id: number;
   tx_id: number;
   type: string;
@@ -29,11 +31,11 @@ export type LiquidityPositionEvent = {
       };
     };
   };
-};
+}
 
-export type PositionExecutionEvent = {
+export interface PositionExecutionEvent {
   block_height: number;
-  event_id: number; //! Needed for sorting
+  event_id: number; // ! Needed for sorting
   block_id: number;
   tx_id: number;
   type: string;
@@ -62,9 +64,9 @@ export type PositionExecutionEvent = {
       };
     };
   };
-};
+}
 
 export interface BlockInfo {
   height: number,
   created_at: string,
-}
\ No newline at end of file
+}
diff --git a/src/utils/math/base64.ts b/src/utils/math/base64.ts
index 7d1e74f0..ecf4917e 100644
--- a/src/utils/math/base64.ts
+++ b/src/utils/math/base64.ts
@@ -10,7 +10,7 @@ export const Base64StringSchema = z.string().refine(
   },
   {
     message: "Invalid base64 string",
-  }
+  },
 );
 
 export type Base64Str = z.infer<typeof Base64StringSchema>;
@@ -20,7 +20,7 @@ export const InnerBase64Schema = z.object({ inner: Base64StringSchema });
 export const base64ToUint8Array = (base64: string): Uint8Array => {
   const validated = validateSchema(Base64StringSchema, base64);
   const binString = atob(validated);
-  return Uint8Array.from(binString, (byte) => byte.codePointAt(0)!);
+  return Uint8Array.from(binString, (byte) => byte.codePointAt(0) ?? 0);
 };
 
 export const uint8ArrayToBase64 = (byteArray: Uint8Array): string => {
diff --git a/src/utils/math/bech32.ts b/src/utils/math/bech32.ts
index 98193df0..54e7890b 100644
--- a/src/utils/math/bech32.ts
+++ b/src/utils/math/bech32.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { bech32m } from "bech32";
 import { uint8ArrayToBase64, base64ToUint8Array } from "./base64";
 
diff --git a/src/utils/math/hex.ts b/src/utils/math/hex.ts
index 3018b21a..77425e66 100644
--- a/src/utils/math/hex.ts
+++ b/src/utils/math/hex.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { Base64StringSchema } from "./base64";
 import { validateSchema } from "./validation";
 
@@ -21,10 +23,10 @@ export const base64ToHex = (base64: string): string => {
  * @see https://stackoverflow.com/a/41797377/974981
  */
 export const hexToBase64 = (hex: string): string => {
-  if (!hex) return "";
+  if (!hex) {return "";}
 
   const hexPairs = hex.match(/[0-9A-Fa-f]{2}/g);
-  if (!hexPairs) throw new Error("Invalid hexadecimal input");
+  if (!hexPairs) {throw new Error("Invalid hexadecimal input");}
 
   const binaryString = hexPairs
     .map((a) => String.fromCharCode(parseInt(a, 16)))
@@ -51,7 +53,7 @@ export const hexToUint8Array = (hexString: string): Uint8Array => {
     throw new Error(`Invalid hexadecimal string: ${hexString}`);
   }
 
-  if (!hexString) return new Uint8Array();
+  if (!hexString) {return new Uint8Array();}
 
   // Split the string into pairs of characters
   const hexPairs = hexString.match(/.{1,2}/g)!;
diff --git a/src/utils/math/hiLo.ts b/src/utils/math/hiLo.ts
index 738e82e6..f96272bf 100644
--- a/src/utils/math/hiLo.ts
+++ b/src/utils/math/hiLo.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 // https://github.com/penumbra-zone/web/blob/main/packages/types/src/lo-hi.ts
 
 import BigNumber from "bignumber.js";
diff --git a/src/utils/protos/services/app/shielded-pool.ts b/src/utils/protos/services/app/shielded-pool.ts
index 1ff211fe..caf42891 100644
--- a/src/utils/protos/services/app/shielded-pool.ts
+++ b/src/utils/protos/services/app/shielded-pool.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { PromiseClient } from "@connectrpc/connect";
 import { createClient } from "../utils";
 import { ShieldedPoolService } from "@penumbra-zone/protobuf";
@@ -16,7 +18,7 @@ export class ShieldedPoolQuerier implements ShieldedPoolQuerierInterface {
 
   async assetMetadata(assetId: AssetId): Promise<Metadata | undefined> {
     const res = await this.client.assetMetadataById({ assetId });
-    //console.info(res)
+    // console.info(res)
     return res.denomMetadata;
   }
 }
diff --git a/src/utils/protos/services/dex/dex-query-service-client.ts b/src/utils/protos/services/dex/dex-query-service-client.ts
index a7fbcee2..9711ddfc 100644
--- a/src/utils/protos/services/dex/dex-query-service-client.ts
+++ b/src/utils/protos/services/dex/dex-query-service-client.ts
@@ -1,18 +1,20 @@
-import { PromiseClient } from "@connectrpc/connect";
-import { createClient } from "../utils";
-import { DexService } from "@penumbra-zone/protobuf";
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
+import { PromiseClient } from '@connectrpc/connect';
+import { createClient } from '../utils';
+import { DexService } from '@penumbra-zone/protobuf';
 import {
   PositionId,
   Position,
   DirectedTradingPair,
   SwapExecution,
   CandlestickData,
-} from "@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb";
+} from '@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb';
 import {
   DexQueryServiceClientInterface,
   SwapExecutionWithBlockHeight,
-} from "../../types/DexQueryServiceClientInterface";
-import { Readable } from "stream";
+} from '../../types/DexQueryServiceClientInterface';
+import { Readable } from 'stream';
 
 export class DexQueryServiceClient implements DexQueryServiceClientInterface {
   private readonly client: PromiseClient<typeof DexService>;
@@ -21,17 +23,15 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
     this.client = createClient(grpcEndpoint, DexService);
   }
 
-  async liquidityPositionById(
-    positionId: PositionId
-  ): Promise<Position | undefined> {
-    //console.log('liquidityPositionById', positionId)
+  async liquidityPositionById(positionId: PositionId): Promise<Position | undefined> {
+    // console.log('liquidityPositionById', positionId)
     const res = await this.client.liquidityPositionById({ positionId });
     return res.data;
   }
 
   async liquidityPositionsByPrice(
     tradingPair: DirectedTradingPair,
-    limit: number
+    limit: number,
   ): Promise<Position[] | undefined> {
     const res = await this.client.liquidityPositionsByPrice({
       tradingPair,
@@ -39,9 +39,9 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
     });
 
     if (!res[Symbol.asyncIterator]) {
-      console.error("Received:", res);
+      console.error('Received:', res);
       throw new Error(
-        "Received an unexpected response type from the server, expected an async iterable."
+        'Received an unexpected response type from the server, expected an async iterable.',
       );
     }
 
@@ -55,7 +55,7 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
 
   async arbExecutions(
     startHeight: number,
-    endHeight: number
+    endHeight: number,
   ): Promise<SwapExecutionWithBlockHeight[] | undefined> {
     const res = await this.client.arbExecutions({
       startHeight: BigInt(startHeight),
@@ -63,16 +63,16 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
     });
 
     if (!res[Symbol.asyncIterator]) {
-      console.error("Received:", res);
+      console.error('Received:', res);
       throw new Error(
-        "Received an unexpected response type from the server, expected an async iterable."
+        'Received an unexpected response type from the server, expected an async iterable.',
       );
     }
 
     const arbs: SwapExecutionWithBlockHeight[] = [];
     for await (const arb of res as Readable) {
       const swapExecution: SwapExecution = arb.swapExecution;
-      const blockHeight: number = Number(arb.height);
+      const blockHeight = Number(arb.height);
       arbs.push({ swapExecution, blockHeight });
     }
     return arbs;
@@ -80,7 +80,7 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
 
   async swapExecutions(
     startHeight: number,
-    endHeight: number
+    endHeight: number,
   ): Promise<SwapExecutionWithBlockHeight[] | undefined> {
     const res = await this.client.swapExecutions({
       startHeight: BigInt(startHeight),
@@ -88,16 +88,16 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
     });
 
     if (!res[Symbol.asyncIterator]) {
-      console.error("Received:", res);
+      console.error('Received:', res);
       throw new Error(
-        "Received an unexpected response type from the server, expected an async iterable."
+        'Received an unexpected response type from the server, expected an async iterable.',
       );
     }
 
     const swaps: SwapExecutionWithBlockHeight[] = [];
     for await (const swap of res as Readable) {
       const swapExecution: SwapExecution = swap.swapExecution;
-      const blockHeight: number = Number(swap.height);
+      const blockHeight = Number(swap.height);
       swaps.push({ swapExecution, blockHeight });
     }
     return swaps;
@@ -106,7 +106,7 @@ export class DexQueryServiceClient implements DexQueryServiceClientInterface {
   async candlestickData(
     pair: DirectedTradingPair,
     startHeight: number,
-    limit: number
+    limit: number,
   ): Promise<CandlestickData[] | undefined> {
     const res = await this.client.candlestickData({
       pair,
diff --git a/src/utils/protos/services/dex/simulated-trades.ts b/src/utils/protos/services/dex/simulated-trades.ts
index 4cfe8a98..3c410f09 100644
--- a/src/utils/protos/services/dex/simulated-trades.ts
+++ b/src/utils/protos/services/dex/simulated-trades.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { PromiseClient } from "@connectrpc/connect";
 import { createClient } from "../utils";
 import { SimulationService } from "@penumbra-zone/protobuf";
diff --git a/src/utils/protos/types/ShieldedPoolQuerier.ts b/src/utils/protos/types/ShieldedPoolQuerier.ts
index 6c8ae1fd..5fd6b30b 100644
--- a/src/utils/protos/types/ShieldedPoolQuerier.ts
+++ b/src/utils/protos/types/ShieldedPoolQuerier.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import {
   AssetId,
   Metadata,
diff --git a/src/utils/protos/types/SimulationQuerier.ts b/src/utils/protos/types/SimulationQuerier.ts
index 02856904..18170247 100644
--- a/src/utils/protos/types/SimulationQuerier.ts
+++ b/src/utils/protos/types/SimulationQuerier.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import {
   SimulateTradeRequest,
   SwapExecution,
diff --git a/src/utils/token/tokenFetch.tsx b/src/utils/token/tokenFetch.tsx
index 72fe9893..98df7f7b 100644
--- a/src/utils/token/tokenFetch.tsx
+++ b/src/utils/token/tokenFetch.tsx
@@ -1,13 +1,9 @@
-import {
-  uint8ArrayToBase64,
-  base64ToUint8Array,
-} from "../../utils/math/base64";
+import { uint8ArrayToBase64, base64ToUint8Array } from "../math/base64";
 import { Constants } from "../../constants/configConstants";
 import {
   AssetId,
   AssetImage,
   DenomUnit,
-  Metadata,
 } from "@penumbra-zone/protobuf/penumbra/core/asset/v1/asset_pb";
 import { ChainRegistryClient, Registry } from "@penumbra-labs/registry";
 import { Token } from "../types/token";
@@ -29,9 +25,9 @@ export const fetchAllTokenAssets = (): Token[] => {
       const displayParts = x.display.split("/");
       tokens.push({
         decimals: decimalsFromDenomUnits(x.denomUnits),
-        display: displayParts[displayParts.length - 1],
+        display: displayParts[displayParts.length - 1] ?? "",
         symbol: x.symbol,
-        inner: uint8ArrayToBase64(x.penumbraAssetId?.inner),
+        inner: uint8ArrayToBase64(x.penumbraAssetId.inner),
         imagePath: imagePathFromAssetImages(x.images),
       });
     }
@@ -40,7 +36,7 @@ export const fetchAllTokenAssets = (): Token[] => {
 };
 
 export const fetchTokenAsset = (
-  tokenId: Uint8Array | string
+  tokenId: Uint8Array | string,
 ): Token | undefined => {
   const assetId: AssetId = new AssetId();
   assetId.inner =
@@ -51,7 +47,7 @@ export const fetchTokenAsset = (
   const displayParts = tokenMetadata.display.split("/");
   return {
     decimals: decimalsFromDenomUnits(tokenMetadata.denomUnits),
-    display: displayParts[displayParts.length - 1],
+    display: displayParts[displayParts.length - 1] ?? "",
     symbol: tokenMetadata.symbol,
     inner: typeof tokenId !== "string" ? uint8ArrayToBase64(tokenId) : tokenId,
     imagePath: imagePathFromAssetImages(tokenMetadata.images),
@@ -59,10 +55,10 @@ export const fetchTokenAsset = (
 };
 
 export const imagePathFromAssetImages = (
-  assetImages: AssetImage[]
+  assetImages: AssetImage[],
 ): string | undefined => {
   // Take first png/svg from first AssetImage
-  var imagePath: string | undefined = undefined;
+  let imagePath: string | undefined = undefined;
   assetImages.forEach((x) => {
     if (x.png.length > 0) {
       imagePath = x.png;
@@ -75,7 +71,7 @@ export const imagePathFromAssetImages = (
 
 export const decimalsFromDenomUnits = (denomUnits: DenomUnit[]): number => {
   // Search denomUnits for highest exponent
-  var decimals = 0;
+  let decimals = 0;
   denomUnits.forEach((x) => {
     if (x.exponent >= decimals) {
       decimals = x.exponent;
diff --git a/src/utils/types/block.tsx b/src/utils/types/block.tsx
index d1ade3e0..345cc24c 100644
--- a/src/utils/types/block.tsx
+++ b/src/utils/types/block.tsx
@@ -1,3 +1,5 @@
+// @ts-nocheck
+/* eslint-disable -- disabling this file as this was created before our strict rules */
 import { SwapExecution } from "@penumbra-zone/protobuf/penumbra/core/component/dex/v1/dex_pb";
 import { BlockInfo, LiquidityPositionEvent } from "../indexer/types/lps";
 
@@ -20,10 +22,6 @@ export interface BlockDetailedSummaryData {
   createdAt: string;
 }
 
-export interface BlockInfoMap {
-  [key: number]: BlockInfo;
-}
+export type BlockInfoMap = Record<number, BlockInfo>;
 
-export interface BlockSummaryMap {
-  [key: number]: BlockSummaryData;
-}
+export type BlockSummaryMap = Record<number, BlockSummaryData>;
diff --git a/src/utils/types/token.tsx b/src/utils/types/token.tsx
index 1fcabbd8..88f3f225 100644
--- a/src/utils/types/token.tsx
+++ b/src/utils/types/token.tsx
@@ -1,8 +1,7 @@
-
 export interface Token {
-    decimals: number;
-    display: string;
-    symbol: string;
-    inner: string;
-    imagePath?: string;
-}
\ No newline at end of file
+  decimals: number;
+  display: string;
+  symbol: string;
+  inner: string;
+  imagePath?: string;
+}
diff --git a/tsconfig.json b/tsconfig.json
index d10e8655..6ba43ba1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,27 +1,35 @@
 {
   "compilerOptions": {
-    "jsx": "preserve",
+    "composite": true,
+    "exactOptionalPropertyTypes": false,
+    "lib": [
+      "ESNext",
+      "DOM",
+      "DOM.Iterable",
+      "DOM.AsyncIterable"
+    ],
+    "noEmit": true,
     "target": "ESNext",
-    "lib": ["dom", "dom.iterable", "esnext"],
-    "allowJs": true,
     "skipLibCheck": true,
-    "strict": true,
-    "noEmit": true,
-    "esModuleInterop": true,
-    "module": "esnext",
-    "moduleResolution": "bundler",
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "incremental": true,
     "plugins": [
       {
         "name": "next"
       }
     ],
     "paths": {
-      "@/*": ["./src/*", "./styles/*"]
-    }
+      "@/*": [
+        "./src/*",
+        "./styles/*"
+      ]
+    },
+    "allowJs": true,
+    "incremental": true,
+    "jsx": "preserve"
   },
+  "extends": [
+    "@tsconfig/strictest/tsconfig.json",
+    "@tsconfig/vite-react/tsconfig.json"
+  ],
   "include": [
     "next-env.d.ts",
     "**/*.ts",
@@ -29,5 +37,7 @@
     ".next/types/**/*.ts",
     "styles/styles.d.ts"
   ],
-  "exclude": ["node_modules"]
-}
+  "exclude": [
+    "node_modules"
+  ]
+}
\ No newline at end of file