From a14bc6dd4be0eb27bbd523398dbda2f36873ab2e Mon Sep 17 00:00:00 2001 From: Yoshihiro OKUMURA Date: Fri, 11 Sep 2026 21:25:39 +0900 Subject: [PATCH] feat: migrate from Create React App to Vite react-scripts 4 on React 17 no longer builds on a current toolchain. Move to Vite 8 with React 19 and TypeScript 7, and take the same shape the other two converted sites settled on. - react-router-dom v5 -> react-router v8: Switch/Redirect become Routes/Navigate, and withRouter and RouteComponentProps give way to useParams, useLocation and useNavigate - swap the unmaintained dependencies: axios -> ky, react-html-parser -> @orrisroot/react-html-parser, react-ga -> react-ga4, react-helmet -> @dr.pogodin/react-helmet, react-image-lightbox -> yet-another-react-lightbox, moment -> date-fns, and a local HashLink in place of react-router-hash-link - drop react-app-polyfill, the jest setup and xregexp - replace ESLint with Biome, and match the other sites' tsconfigs - serve the dumped JSON from static-contents/modules/ at runtime instead of compiling it into the bundle, and mount that directory with sirv in both the dev and preview servers - lazy-load NewArticleAlert: at 342 kB of static bibliography it is the largest file in the app and only ever renders on the top page, which cuts the entry chunk from 580 kB to 200 kB - restate the theme sizes the modules/ move and border-box need, and keep the browser's own font on form controls - set the GA4 measurement ID replacing the shut-down UA property - write down the deployment procedure --- .gitignore | 52 +- .ncurc.js | 6 + README.md | 183 +- biome.json | 39 + public/index.html => index.html | 11 +- package-lock.json | 2110 +++ package.json | 99 +- public/.htaccess | 5 +- public/manifest.json | 26 +- src/App.css | 2 +- src/App.test.tsx | 9 - src/App.tsx | 25 +- src/common/AppRoot.tsx | 109 +- src/common/CenterColumn.tsx | 47 +- src/common/Footer.tsx | 28 +- src/common/Header.tsx | 103 +- src/common/LeftColumn.tsx | 5 +- src/common/MainContent.tsx | 55 +- src/common/XoopsPathRedirect.tsx | 50 +- src/common/assets/theme/style.css | 17 +- src/common/assets/xoops.css | 79 +- src/common/blocks/MainMenu.tsx | 25 +- src/common/blocks/SelectLang.tsx | 39 +- src/common/lib/HashLink.tsx | 53 + src/common/lib/LangFlag.tsx | 25 +- src/common/lib/LinkImage.tsx | 27 +- src/common/lib/Loading.module.css | 27 + src/common/lib/Loading.tsx | 17 +- src/common/lib/NoticeSiteHasBeenArchived.tsx | 10 +- src/common/lib/PageNotFound.tsx | 72 +- src/common/lib/UserRankStarImage.tsx | 14 +- src/common/lib/XoopsCode.tsx | 148 +- src/config.ts | 11 +- src/credits/Credits.tsx | 23 +- src/credits/CreditsAboutUs.tsx | 7 +- src/credits/CreditsPage.tsx | 36 +- src/credits/CreditsXoopsPathRedirect.tsx | 73 +- src/credits/block/CreditsMenu.tsx | 21 +- src/credits/lib/CreditsUtils.ts | 30 +- .../blocks/CerebellarPlatformCommittee.tsx | 42 +- .../blocks/CerebrationOfDrItosNewBook.tsx | 12 +- src/custom/blocks/NewArticleAlert.tsx | 14091 +++++++++++----- src/custom/blocks/Welcome.tsx | 34 +- src/d3forum/D3Forum.tsx | 31 +- src/d3forum/D3ForumCategory.tsx | 79 +- src/d3forum/D3ForumForum.tsx | 264 +- src/d3forum/D3ForumPost.tsx | 149 +- src/d3forum/D3ForumTop.tsx | 94 +- src/d3forum/D3ForumTopic.tsx | 197 +- src/d3forum/D3ForumXoopsPathRedirect.tsx | 100 +- src/d3forum/assets/d3forum_common.css | 62 +- src/d3forum/assets/d3forum_main.css | 8 +- src/d3forum/lib/CategoryJump.tsx | 64 +- src/d3forum/lib/D3ForumUtils.ts | 76 +- src/d3forum/lib/ForumJump.tsx | 46 +- src/d3forum/lib/Post.tsx | 96 +- src/d3forum/lib/PostIcon.tsx | 18 +- src/d3forum/lib/PostsTree.tsx | 41 +- src/database/Database.tsx | 44 +- src/database/DatabaseAdvancedSearch.tsx | 67 +- src/database/DatabaseDetailItem.tsx | 123 +- .../DatabaseSearchByAdvancedKeyword.tsx | 71 +- src/database/DatabaseSearchByIndexId.tsx | 123 +- src/database/DatabaseSearchByItemType.tsx | 92 +- src/database/DatabaseSearchByKeyword.tsx | 79 +- src/database/DatabaseTop.module.css | 2 +- src/database/DatabaseTop.tsx | 15 +- src/database/DatabaseXoopsPathRedirect.tsx | 64 +- src/database/blocks/IndexTree.module.css | 12 +- src/database/blocks/IndexTree.tsx | 185 +- src/database/blocks/Rankings.module.css | 2 +- src/database/blocks/Rankings.tsx | 97 +- src/database/blocks/RecentContents.module.css | 2 +- src/database/blocks/RecentContents.tsx | 37 +- src/database/blocks/Search.tsx | 135 +- .../item-type/binder/BinderAdvancedSearch.tsx | 16 +- .../item-type/binder/BinderDetail.tsx | 51 +- src/database/item-type/binder/BinderList.tsx | 11 +- src/database/item-type/binder/BinderTop.tsx | 5 +- .../item-type/book/BookAdvancedSearch.tsx | 36 +- src/database/item-type/book/BookDetail.tsx | 65 +- src/database/item-type/book/BookList.tsx | 15 +- src/database/item-type/book/BookTop.tsx | 5 +- src/database/item-type/book/index.tsx | 6 +- .../conference/ConferenceAdvancedSearch.tsx | 39 +- .../item-type/conference/ConferenceDetail.tsx | 61 +- .../item-type/conference/ConferenceList.tsx | 24 +- .../item-type/conference/ConferenceTop.tsx | 7 +- .../item-type/conference/ConferenceUtil.tsx | 41 +- src/database/item-type/conference/index.tsx | 8 +- .../item-type/data/DataAdvancedSearch.tsx | 48 +- src/database/item-type/data/DataDetail.tsx | 107 +- src/database/item-type/data/DataList.tsx | 17 +- src/database/item-type/data/DataTop.tsx | 10 +- src/database/item-type/data/DataUtil.tsx | 17 +- src/database/item-type/data/index.tsx | 8 +- .../item-type/files/FilesAdvancedSearch.tsx | 37 +- src/database/item-type/files/FilesDetail.tsx | 49 +- src/database/item-type/files/FilesList.tsx | 16 +- src/database/item-type/files/FilesTop.tsx | 5 +- src/database/item-type/files/FilesUtil.tsx | 6 +- src/database/item-type/files/index.tsx | 8 +- src/database/item-type/index.tsx | 36 +- .../item-type/lib/AdvancedSearchBase.tsx | 122 +- src/database/item-type/lib/DetailBase.tsx | 19 +- src/database/item-type/lib/ListBase.tsx | 21 +- src/database/item-type/lib/TopBase.tsx | 20 +- src/database/item-type/lib/field/Author.tsx | 19 +- .../item-type/lib/field/ChangeLog.tsx | 23 +- .../item-type/lib/field/Contributer.tsx | 11 +- .../item-type/lib/field/CreativeCommons.tsx | 43 +- src/database/item-type/lib/field/DateTime.tsx | 17 +- .../item-type/lib/field/Description.tsx | 9 +- .../lib/field/FileDownloadButton.module.css | 10 +- .../lib/field/FileDownloadButton.tsx | 33 +- src/database/item-type/lib/field/FileSize.tsx | 9 +- .../item-type/lib/field/FreeKeyword.tsx | 9 +- src/database/item-type/lib/field/ItemFile.tsx | 49 +- .../item-type/lib/field/ItemIndex.tsx | 25 +- src/database/item-type/lib/field/Language.tsx | 13 +- .../field/LicenseAgreementDialog.module.css | 2 +- .../lib/field/LicenseAgreementDialog.tsx | 207 +- .../item-type/lib/field/Preview.module.css | 2 +- src/database/item-type/lib/field/Preview.tsx | 122 +- .../item-type/lib/field/PublicationDate.tsx | 9 +- src/database/item-type/lib/field/Readme.tsx | 7 +- .../item-type/lib/field/RelatedTo.tsx | 24 +- src/database/item-type/lib/field/Rights.tsx | 7 +- .../item-type/lib/field/SimPFLinkIcon.tsx | 7 +- src/database/item-type/lib/field/index.tsx | 4 +- .../item-type/memo/MemoAdvancedSearch.tsx | 18 +- src/database/item-type/memo/MemoDetail.tsx | 49 +- src/database/item-type/memo/MemoList.tsx | 11 +- src/database/item-type/memo/MemoTop.tsx | 3 +- src/database/item-type/memo/index.tsx | 8 +- .../item-type/model/ModelAdvancedSearch.tsx | 37 +- src/database/item-type/model/ModelDetail.tsx | 95 +- src/database/item-type/model/ModelList.tsx | 17 +- src/database/item-type/model/ModelTop.tsx | 7 +- src/database/item-type/model/ModelUtil.tsx | 17 +- src/database/item-type/model/index.tsx | 8 +- .../item-type/paper/PaperAdvancedSearch.tsx | 36 +- src/database/item-type/paper/PaperDetail.tsx | 46 +- src/database/item-type/paper/PaperList.tsx | 34 +- src/database/item-type/paper/PaperTop.tsx | 5 +- src/database/item-type/paper/PaperUtil.tsx | 17 +- src/database/item-type/paper/index.tsx | 8 +- .../PresentationAdvancedSearch.tsx | 49 +- .../presentation/PresentationDetail.tsx | 102 +- .../presentation/PresentationList.tsx | 20 +- .../presentation/PresentationTop.tsx | 5 +- .../presentation/PresentationUtil.tsx | 17 +- src/database/item-type/presentation/index.tsx | 8 +- .../simulator/SimulatorAdvancedSearch.tsx | 41 +- .../item-type/simulator/SimulatorDetail.tsx | 107 +- .../item-type/simulator/SimulatorList.tsx | 17 +- .../item-type/simulator/SimulatorTop.tsx | 7 +- .../item-type/simulator/SimulatorUtil.tsx | 17 +- src/database/item-type/simulator/index.tsx | 8 +- .../stimulus/StimulusAdvancedSearch.tsx | 41 +- .../item-type/stimulus/StimulusDetail.tsx | 105 +- .../item-type/stimulus/StimulusList.tsx | 17 +- .../item-type/stimulus/StimulusTop.tsx | 10 +- .../item-type/stimulus/StimulusUtil.tsx | 17 +- src/database/item-type/stimulus/index.tsx | 8 +- .../item-type/tool/ToolAdvancedSearch.tsx | 46 +- src/database/item-type/tool/ToolDetail.tsx | 95 +- src/database/item-type/tool/ToolList.tsx | 13 +- src/database/item-type/tool/ToolTop.tsx | 7 +- src/database/item-type/tool/ToolUtil.tsx | 17 +- src/database/item-type/tool/index.tsx | 8 +- .../item-type/url/UrlAdvancedSearch.tsx | 18 +- src/database/item-type/url/UrlDetail.tsx | 60 +- src/database/item-type/url/UrlList.tsx | 18 +- src/database/item-type/url/UrlTop.tsx | 5 +- src/database/item-type/url/UrlUtil.tsx | 13 +- src/database/item-type/url/index.tsx | 6 +- src/database/lib/AdvancedSearchQuery.ts | 35 +- src/database/lib/DatabaseListIndex.tsx | 21 +- src/database/lib/DatabaseListItem.module.css | 2 +- src/database/lib/DatabaseListItem.tsx | 336 +- src/database/lib/IndexUtil.ts | 34 +- src/database/lib/ItemUtil.ts | 395 +- src/functions.ts | 62 +- src/index.css | 2 +- src/index.tsx | 15 - src/main.tsx | 38 + src/normalize-overrides.css | 30 + src/pico/Pico.tsx | 78 +- src/pico/PicoCategory.tsx | 45 +- src/pico/PicoContent.tsx | 32 +- src/pico/PicoIndex.tsx | 10 +- src/pico/PicoMenu.tsx | 53 +- src/pico/PicoXoopsPathRedirect.tsx | 36 +- src/pico/assets/pico_main.css | 2 +- src/pico/lib/PicoUtils.ts | 38 +- src/react-app-env.d.ts | 1 - src/serviceWorker.ts | 143 - src/siteData.ts | 86 + tsconfig.app.json | 29 + tsconfig.json | 26 +- tsconfig.node.json | 25 + vite.config.ts | 62 + yarn.lock | 11685 ------------- 204 files changed, 17118 insertions(+), 19490 deletions(-) create mode 100644 .ncurc.js create mode 100644 biome.json rename public/index.html => index.html (70%) create mode 100644 package-lock.json delete mode 100644 src/App.test.tsx create mode 100644 src/common/lib/HashLink.tsx create mode 100644 src/common/lib/Loading.module.css delete mode 100644 src/index.tsx create mode 100644 src/main.tsx create mode 100644 src/normalize-overrides.css delete mode 100644 src/react-app-env.d.ts delete mode 100644 src/serviceWorker.ts create mode 100644 src/siteData.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts delete mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 63d0404..785a308 100644 --- a/.gitignore +++ b/.gitignore @@ -1,35 +1,25 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local -.eslintcache - +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* +lerna-debug.log* -# database contents -/dl-limit-items.csv -/public/database/items.json -/public/database/file -/public/documents/images -/public/documents/*.json -/src/database/assets/*.json -/src/credits/assets/*.json -/src/d3forum/assets/*.json -/src/pico/assets/*.json +node_modules +dist +dist-ssr +coverage +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.ncurc.js b/.ncurc.js new file mode 100644 index 0000000..c7b5d41 --- /dev/null +++ b/.ncurc.js @@ -0,0 +1,6 @@ +// Keep @types/node on the 24.x line to match the deployment target. Its +// "latest" dist-tag points at the 22.x line, so the default target would +// report no updates at all instead of offering 24.x patches. +export default { + target: (name) => (name === '@types/node' ? 'minor' : 'latest'), +}; diff --git a/README.md b/README.md index 897dc83..26d1d1c 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,177 @@ -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +# Cerebellar Platform -## Available Scripts +Static front-end for the archived [Cerebellar Platform](http://cerebellum.neuroinf.jp/) site, +built with [Vite](https://vite.dev/), React and TypeScript. -In the project directory, you can run: +## Requirements -### `npm start` +- Node.js 20.19+ / 22.12+ (Vite 8) +- npm -Runs the app in the development mode.
-Open [http://localhost:3000](http://localhost:3000) to view it in the browser. +## Setup -The page will reload if you make edits.
-You will also see any lint errors in the console. +```sh +npm install +``` -### `npm test` +## Site data -Launches the test runner in the interactive watch mode.
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. +The pages are rendered from JSON dumped out of the original XooNIps/XOOPS +installation by [xoops-static-exporter](https://git.ni.riken.jp/niu/xoops-static-exporter) +(`sites/cerebellum.neuroinf.jp/`). -### `npm run build` +All of it lives in `static-contents/`, which sits next to the repository rather +than inside it: -Builds the app for production to the `build` folder.
-It correctly bundles React in production mode and optimizes the build for the best performance. +``` +cerebellum.neuroinf.jp/ +├── cerebellum.neuroinf.jp/ this repository +└── static-contents/ + ├── modules/ one directory per source XOOPS module + │ ├── credits/ credits.json + │ ├── documents/ config.json, .json, images/ + │ ├── forum/ d3forum.json + │ └── xoonips/ tree.json, items.json, file/, ... + └── rss.xml +``` -The build is minified and the filenames include the hashes.
-Your app is ready to be deployed! +Each pico module keeps its own `config.json` — the index of its categories and +pages — next to the page bodies it describes, and each d3forum module its own +`d3forum.json`. -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. +The dev and preview servers mount that directory at the site root. It is +deliberately kept out of `dist/`: it runs to gigabytes, and the web server maps +it in directly. It is generated content and is not tracked in git. -### `npm run eject` +## Scripts -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** +| Command | Description | +| --- | --- | +| `npm run dev` | Start the dev server on http://localhost:5173 | +| `npm run build` | Type-check and build into `dist/` | +| `npm run preview` | Serve the production build on http://localhost:4173 | +| `npm run lint` | Lint with [Biome](https://biomejs.dev/) | +| `npm run format` | Format with Biome | +| `npm run check` | Lint, format and organize imports, applying the safe fixes | -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. +`@types/node` is pinned to the major that matches the Node runtime in use (24); +`.ncurc.js` keeps `npm-check-updates` from bumping it past that. -Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. +There is currently no test suite. -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. +## Deployment -## Learn More +Build locally and copy the result up; the server does not need a toolchain. -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). +### 1. Build and check -To learn React, check out the [React documentation](https://reactjs.org/). +```sh +npm ci +npm run check # biome, writes fixes +npm run build # runs tsc -b, then vite build +npm run preview # localhost:4173 , serves dist/ + static-contents/ +``` + +`dist/` is a few MB. `static-contents/` is never part of it — the dev and +preview servers mount it, and in production the web server maps it in. + +### 2. Send up the site data + +About 150 MB, almost all of it under `modules/xoonips/file/`. The server mirrors +the local layout: `static-contents/` sits next to the document root. Run this +from the directory that holds both the repository and `static-contents/`: + +``` +/data/www/cerebellum.neuroinf.jp/ +├── html/ document root +└── static-contents/ +``` + +```sh +rsync -a --delete static-contents/ \ + user@server:/data/www/cerebellum.neuroinf.jp/static-contents/ +``` + +### 3. Push the build + +```sh +rsync -a --delete dist/ user@server:/data/www/cerebellum.neuroinf.jp/html/ +``` + +`--delete` clears out the previous build, and with it the data symlinks from +step 4 — that is deliberate, they are recreated right after. Anything left over +from an older deployment goes too. + +### 4. Link the site data into the document root + +```sh +cd /data/www/cerebellum.neuroinf.jp/html +ln -s ../static-contents/* . +``` + +That links every top-level entry of `static-contents/` — currently `modules/` +and `rss.xml`: + +``` +/data/www/cerebellum.neuroinf.jp/html/ +├── index.html from dist/ +├── assets/ from dist/ +├── .htaccess from dist/ +├── modules -> ../static-contents/modules +└── rss.xml -> ../static-contents/rss.xml +``` + +The glob keeps the two in step, which matters because `rss.xml` sits beside +`modules/` rather than inside it: linking `modules` alone leaves `/rss.xml` +returning 404, a break that `npm run preview` cannot reproduce because it mounts +the whole directory. It also picks up anything added to `static-contents/` +later. Note that it skips dotfiles, of which there are none today. + +The links are relative, so the whole tree can be moved without rewriting them. + +Run steps 3 and 4 back to back. In between, `/modules/...` and `/rss.xml` are +404 because step 3 removed the links; that is why plain `ln -s` works here +without `-f`, and why a stale or wrong link repairs itself on the next deploy. + +Apache needs `Options FollowSymLinks`, `AllowOverride All` and +`Require all granted` on the document root, and `Options FollowSymLinks` with +`Require all granted` on `static-contents/`. + +Use symlinks rather than `Alias`. An `Alias /modules ...` maps the URL outside +the document root, so `.htaccess` no longer applies to it and every legacy +`/modules/xoonips/*.php` URL stops reaching the SPA redirect handler. With +symlinks the normal precedence still holds: real files are served directly and +everything else falls through to `index.html`. + +### 5. Check the deployed site + +```sh +curl -I https://cerebellum.neuroinf.jp/rss.xml # 200 +curl -I https://cerebellum.neuroinf.jp/database/file/1.png # 301 +curl -I https://cerebellum.neuroinf.jp/modules/xoonips/tree.json # 200 +``` + +Then load `/`, an item page, `/forum` and `/documents/` in a browser and +confirm the images resolve. + +### Upgrading from v1.0.0 + +v1.0.0 bundled most of the data into the JavaScript and served the rest from +`database/` and `documents/` at the site root; it all moved under `modules/`. +Nothing extra is needed: `--delete` in step 2 clears the old data layout, and +`--delete` in step 3 removes the v1.0.0 symlinks from the document root along +with the old build. + +Run steps 2 to 4 back to back: in between, the live v1.0.0 build points at paths +that no longer exist. + +The v1.0.0 download links stay alive. `.htaccess` sends `/database/file/...` to +`/modules/xoonips/file/...` with a 301. The links inside `rss.xml` are legacy +XOOPS URLs (`/modules/xoonips/detail.php?item_id=`), unaffected by the move and +resolved by the SPA as before. + +## Google Analytics + +`GOOGLE_ANALYTICS_TRACKING_ID` in `src/config.ts` carries the GA4 measurement +ID that replaced the Universal Analytics property shut down in 2023. Emptying +it disables tracking. diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..4c09d74 --- /dev/null +++ b/biome.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.5.13/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "includes": ["**", "!**/dist", "!src/common/assets", "!src/d3forum/assets"] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 120 + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "jsxQuoteStyle": "double", + "semicolons": "always", + "trailingCommas": "es5", + "arrowParentheses": "always" + } + }, + "linter": { + "enabled": true, + "rules": { + "preset": "recommended" + } + }, + "assist": { + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/public/index.html b/index.html similarity index 70% rename from public/index.html rename to index.html index d2960d0..17229b3 100644 --- a/public/index.html +++ b/index.html @@ -1,19 +1,20 @@ - + - - + + - + - + Cerebellar Platform - Official Site
+ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..998a8c6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2110 @@ +{ + "name": "cerebellum", + "version": "2.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cerebellum", + "version": "2.0.0", + "dependencies": { + "@dr.pogodin/react-helmet": "^3.2.3", + "@orrisroot/react-html-parser": "^3.0.1", + "async-lock": "^1.4.1", + "date-fns": "^4.4.0", + "ky": "^2.1.0", + "lokijs": "^1.5.12", + "modern-normalize": "^3.0.1", + "rc-tree": "^5.13.1", + "react": "^19.3.0", + "react-cookie": "^8.1.2", + "react-dom": "^19.3.0", + "react-ga4": "^3.0.1", + "react-overlays": "^5.2.1", + "react-router": "^8.3.1", + "yet-another-react-lightbox": "^3.32.2" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.13", + "@types/async-lock": "^1.4.2", + "@types/lokijs": "^1.5.14", + "@types/node": "^24.13.4", + "@types/react": "^19.3.0", + "@types/react-dom": "^19.3.0", + "@vitejs/plugin-react": "^6.1.1", + "sirv": "^3.0.2", + "typescript": "~7.0.2", + "vite": "^8.3.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.13.tgz", + "integrity": "sha512-+SEC/mFk1a+5mvUANZgbZTaiZXs1nj4iMhL/PHiqDT5TPUEPFIlliEtkKKZB4N862yylHC3UI+/Sj2I0HJEqhA==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.5.13", + "@biomejs/cli-darwin-x64": "2.5.13", + "@biomejs/cli-linux-arm64": "2.5.13", + "@biomejs/cli-linux-arm64-musl": "2.5.13", + "@biomejs/cli-linux-x64": "2.5.13", + "@biomejs/cli-linux-x64-musl": "2.5.13", + "@biomejs/cli-win32-arm64": "2.5.13", + "@biomejs/cli-win32-x64": "2.5.13" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.13.tgz", + "integrity": "sha512-nYSuDJ6zgVqZUkAkJkvhXxsF2PYIrUk/g638K4voCXz7foI9f7b6C2/7+oAihsHQlivZNMUrm/y8ywlcHQtZOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.13.tgz", + "integrity": "sha512-KVy1ceEDuJ3AzFxjT9kkxbVy+UANw1pjEMUS6lvKfxjJ+fmkRvc7sQn1Xo6ETgseEI7wUQoV03KSga3XfE8YRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.13.tgz", + "integrity": "sha512-VlNMtoxOqs0dUR6drxxHr18SNUvI7xxAuHZlH4s/dstYSf3g6RaqVgo8JRnhcOhKz9afWrvtJTboNG1JuYlIDQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.13.tgz", + "integrity": "sha512-CH32xpep3dNS5EVJpAHlYchkBYznxyVZQrx0b6YYYlPL9u9ZeD2NtqiK/6s64+HFS2a7hGnryLlqqZAOh8ax5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.13.tgz", + "integrity": "sha512-Fi6gIxbUaJ3ZCIXeG3ggIBPF76O2DjDN67WrPX/ODRv54GeXPm2gbEPC96Yb0yrJoiH0Eax1JLx1Pi0XbsNFZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.13.tgz", + "integrity": "sha512-F3pmwl+VHoUuVJN/tbNLKeLt0SVK3EIyN1jXlMcNyQGYRQQTVqXF+GgkP0/CjGXFN87e/mv0sBfUnWqWza5PKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.13.tgz", + "integrity": "sha512-+WD13qshXrr0Icv4BfsAdzm8Fs3TL+nZ59zEQxsYNd8lcgZJ0A5+OrlwsL1PipVCmWeRpxgIPD6DAcEd7smkCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.5.13", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.13.tgz", + "integrity": "sha512-VOofU/nW761XWzUeUNE8zzYNyPrxuMuNFMizL0qz7J75yeV8N7WFheUlk1/K6dOkaFpH9wJ+lDKlwjAbw0346w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@dr.pogodin/react-helmet": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@dr.pogodin/react-helmet/-/react-helmet-3.2.3.tgz", + "integrity": "sha512-tnSmLKyK4Jan4iGpTKMrlss33hAR8u7WAV5LojGGNlgh1+J87S5ssNOeBAEnmFh40ztaZdX3Jc+qy+0F3wHIiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "react": "19" + } + }, + "node_modules/@orrisroot/react-html-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@orrisroot/react-html-parser/-/react-html-parser-3.0.1.tgz", + "integrity": "sha512-sld7HvPrO61juvgrpw8hpO8CFPd9qmEwlq8XO9r/DlcIMgddNVa7Mytf2NZAcMjZz+PZSPtcsIVAZOoGdICIRw==", + "license": "MIT", + "dependencies": { + "htmlparser2": "^12.0.0" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.149.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.149.0.tgz", + "integrity": "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.8.tgz", + "integrity": "sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.8.tgz", + "integrity": "sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.8.tgz", + "integrity": "sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.8.tgz", + "integrity": "sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.8.tgz", + "integrity": "sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.8.tgz", + "integrity": "sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.8.tgz", + "integrity": "sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.8.tgz", + "integrity": "sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.8.tgz", + "integrity": "sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.8.tgz", + "integrity": "sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.8.tgz", + "integrity": "sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.8.tgz", + "integrity": "sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.8.tgz", + "integrity": "sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.8.tgz", + "integrity": "sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.8.tgz", + "integrity": "sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/async-lock": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.4.2.tgz", + "integrity": "sha512-HlZ6Dcr205BmNhwkdXqrg2vkFMN2PluI7Lgr8In3B3wE5PiQHhjRqtW/lGdVU9gw+sM0JcIDx2AN+cW8oSWIcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/lokijs": { + "version": "1.5.14", + "resolved": "https://registry.npmjs.org/@types/lokijs/-/lokijs-1.5.14.tgz", + "integrity": "sha512-4Fic47BX3Qxr8pd12KT6/T1XWU8dOlJBIp1jGoMbaDbiEvdv50rAii+B3z1b/J2pvMywcVP+DBPGP5/lgLOKGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.13.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.4.tgz", + "integrity": "sha512-YJ7EqCstVTzIr0fMr7qul/977en+pQHrfmuKIo6Zr9i75Be21dr3MovcfvGtyvi2HAUrRerWps5sMO9I7WaxDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@types/warning": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.4.tgz", + "integrity": "sha512-CqN8MnISMwQbLJXO3doBAV4Yw9hx9/Pyr2rZ78+NfaCnhyRA/nKrpyk6E7mKw17ZOaQdLpK9GiUjrqLzBlN3sg==", + "license": "MIT" + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.1.tgz", + "integrity": "sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.145.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", + "license": "MIT" + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.4.0.tgz", + "integrity": "sha512-+1UMbeh68lH1SegH83CGWwpb6OHHbpSgr3+s5Eww5M4CAgswBpoWS0AjTOfEJ33HiYKz1hdj/KTFprzXHmq/6w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-3.1.1.tgz", + "integrity": "sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==", + "license": "MIT", + "dependencies": { + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0", + "entities": "^8.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-3.0.0.tgz", + "integrity": "sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/domhandler": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-6.0.1.tgz", + "integrity": "sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^3.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-4.0.2.tgz", + "integrity": "sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^3.0.0", + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/entities": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.1.0.tgz", + "integrity": "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-12.0.0.tgz", + "integrity": "sha512-Tz7u1i95/g2x2jz81+x0FBVhBhY5aRTvD3tXXdFaljuNdzDLJ8UGNRrTcj2cgQvAg3iW/h77Fz15nLW0L0CrZw==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^3.0.0", + "domhandler": "^6.0.0", + "domutils": "^4.0.2", + "entities": "^8.0.0" + }, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/ky": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ky/-/ky-2.1.0.tgz", + "integrity": "sha512-nIKwelw+7qVqKOlX4Eht6GXfEXlDHcdIjyLWV3s119kYt5s+70ayTnYS+0fRNmtgGRRAfqdeWQbh8YizqkS0ng==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lokijs": { + "version": "1.5.12", + "resolved": "https://registry.npmjs.org/lokijs/-/lokijs-1.5.12.tgz", + "integrity": "sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/modern-normalize": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-3.0.1.tgz", + "integrity": "sha512-VqlMdYi59Uch6fnUPxnpijWUQe+TW6zeWCvyr6Mb7JibheHzSuAAoJi2c71ZwIaWKpECpGpYHoaaBp6rBRr+/g==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/rc-motion": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.5.tgz", + "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.44.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz", + "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.44.1", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.13.1.tgz", + "integrity": "sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-util": { + "version": "5.44.4", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz", + "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-virtual-list": { + "version": "3.19.2", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.19.2.tgz", + "integrity": "sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-cookie": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-8.1.2.tgz", + "integrity": "sha512-S45Z1y1dHyYfLEI4bFKQICuP+SwJqTPWbdc2ZpE6aQSdjSVJAjUDfwTPq8B7BWieIsgyyEWMb/QOrudtwJMjXA==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.7", + "hoist-non-react-statics": "^3.3.2", + "universal-cookie": "^8.0.0" + }, + "peerDependencies": { + "react": ">= 16.3.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/react-ga4": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-ga4/-/react-ga4-3.0.1.tgz", + "integrity": "sha512-GyCc01bSheWXjzGDyHsXMOqk/SP5Cf/JrcJTg4hcpKx4eeSwaJKpJUc+ipF4ffLTZkmabmf3ZGBv4OKHTXNXyA==", + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", + "license": "MIT" + }, + "node_modules/react-overlays": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.2.1.tgz", + "integrity": "sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.8", + "@popperjs/core": "^2.11.6", + "@restart/hooks": "^0.4.7", + "@types/warning": "^3.0.0", + "dom-helpers": "^5.2.0", + "prop-types": "^15.7.2", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, + "node_modules/react-router": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-8.3.1.tgz", + "integrity": "sha512-TEOpiO2g0TJHEOJeRVv4amUFun9v1npCKszvcquNvzETUtJ8udV86ah5eFoHT7g26bsBvT6EiIhqulR8eDF++A==", + "license": "MIT", + "dependencies": { + "cookie-es": "^3.1.1" + }, + "engines": { + "node": ">=22.22.0" + }, + "peerDependencies": { + "react": ">=19.2.7", + "react-dom": ">=19.2.7" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.8.tgz", + "integrity": "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.149.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.8", + "@rolldown/binding-android-arm64": "1.2.8", + "@rolldown/binding-darwin-arm64": "1.2.8", + "@rolldown/binding-darwin-x64": "1.2.8", + "@rolldown/binding-freebsd-x64": "1.2.8", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.8", + "@rolldown/binding-linux-arm64-gnu": "1.2.8", + "@rolldown/binding-linux-arm64-musl": "1.2.8", + "@rolldown/binding-linux-ppc64-gnu": "1.2.8", + "@rolldown/binding-linux-s390x-gnu": "1.2.8", + "@rolldown/binding-linux-x64-gnu": "1.2.8", + "@rolldown/binding-linux-x64-musl": "1.2.8", + "@rolldown/binding-openharmony-arm64": "1.2.8", + "@rolldown/binding-win32-arm64-msvc": "1.2.8", + "@rolldown/binding-win32-x64-msvc": "1.2.8" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/universal-cookie": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-8.1.2.tgz", + "integrity": "sha512-kcKzTGNsxVytujrYOvQbvh//QyFrA53HrzCGyzh6i9ujCww5gfPrLK0tG+jJD40SIIldiEjBNPPSR8fBMS21GA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.1.1" + } + }, + "node_modules/vite": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz", + "integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.6", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/yet-another-react-lightbox": { + "version": "3.32.2", + "resolved": "https://registry.npmjs.org/yet-another-react-lightbox/-/yet-another-react-lightbox-3.32.2.tgz", + "integrity": "sha512-F4HtHQfUNpvkj+AmECgWM4XRdCqMY5gXpKgOUx39+T+FyxLe8II4SK/pwMyYj2X54KH9lFSQeHYY1/GfYf3SdA==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/igordanchenko" + }, + "peerDependencies": { + "@types/react": "^16 || ^17 || ^18 || ^19", + "@types/react-dom": "^16 || ^17 || ^18 || ^19", + "react": "^16.8.0 || ^17 || ^18 || ^19", + "react-dom": "^16.8.0 || ^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + } + } +} diff --git a/package.json b/package.json index 533a0b3..6bc0e80 100644 --- a/package.json +++ b/package.json @@ -1,60 +1,43 @@ { - "name": "cerebellum", - "version": "1.0.0", - "private": true, - "dependencies": { - "@types/async-lock": "^1.1.1", - "@types/jest": "26.0.23", - "@types/lokijs": "^1.5.4", - "@types/node": "15.6.1", - "@types/react": "17.0.8", - "@types/react-dom": "17.0.5", - "@types/react-helmet": "^6.1.1", - "@types/react-html-parser": "^2.0.1", - "@types/react-router-dom": "^5.1.7", - "@types/react-router-hash-link": "^2.4.0", - "async-lock": "^1.3.0", - "axios": "^0.21.1", - "lokijs": "^1.5.12", - "moment": "^2.29.1", - "rc-tree": "^4.1.5", - "react": "^17.0.2", - "react-app-polyfill": "^2.0.0", - "react-cookie": "^4.0.3", - "react-dom": "^17.0.2", - "react-ga": "^3.3.0", - "react-helmet": "^6.1.0", - "react-html-parser": "^2.0.2", - "react-image-lightbox": "^5.1.1", - "react-overlays": "^5.0.1", - "react-router-dom": "^5.2.0", - "react-router-hash-link": "^2.4.3", - "react-scripts": "4.0.3", - "react-spinner-material": "^1.1.3", - "typescript": "4.3.2", - "xregexp": "^5.0.2" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" - }, - "eslintConfig": { - "extends": "react-app" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all", - "ie 11" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version", - "ie 11" - ] - } + "name": "cerebellum", + "version": "2.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview", + "lint": "biome lint", + "format": "biome format --write", + "check": "biome check --write" + }, + "dependencies": { + "@dr.pogodin/react-helmet": "^3.2.3", + "@orrisroot/react-html-parser": "^3.0.1", + "async-lock": "^1.4.1", + "date-fns": "^4.4.0", + "ky": "^2.1.0", + "lokijs": "^1.5.12", + "modern-normalize": "^3.0.1", + "rc-tree": "^5.13.1", + "react": "^19.3.0", + "react-cookie": "^8.1.2", + "react-dom": "^19.3.0", + "react-ga4": "^3.0.1", + "react-overlays": "^5.2.1", + "react-router": "^8.3.1", + "yet-another-react-lightbox": "^3.32.2" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.13", + "@types/async-lock": "^1.4.2", + "@types/lokijs": "^1.5.14", + "@types/node": "^24.13.4", + "@types/react": "^19.3.0", + "@types/react-dom": "^19.3.0", + "@vitejs/plugin-react": "^6.1.1", + "sirv": "^3.0.2", + "typescript": "~7.0.2", + "vite": "^8.3.0" + } } diff --git a/public/.htaccess b/public/.htaccess index 68eecbf..d782ad6 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -2,7 +2,10 @@ RewriteEngine on RewriteBase / RewriteCond %{QUERY_STRING} (^|&)file_id=([0-9]+)($|&) -RewriteRule ^modules/xoonips/download.php /database/file/%2? [R=301,L] +RewriteRule ^modules/xoonips/download.php /modules/xoonips/file/%2? [R=301,L] + +# File downloads moved under /modules/xoonips/ ; keep the v1.0.0 links alive. +RewriteRule ^database/file/(.*)$ /modules/xoonips/file/$1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d [OR] diff --git a/public/manifest.json b/public/manifest.json index 30002e8..aa12b13 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,15 +1,15 @@ { - "short_name": "Cerebellar Platform", - "name": "Cerebellar Platform", - "icons": [ - { - "src": "favicon.ico", - "sizes": "32x32 16x16", - "type": "image/x-icon" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" + "short_name": "Cerebellar Platform", + "name": "Cerebellar Platform", + "icons": [ + { + "src": "favicon.ico", + "sizes": "32x32 16x16", + "type": "image/x-icon" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" } diff --git a/src/App.css b/src/App.css index 46f0a08..19353d4 100644 --- a/src/App.css +++ b/src/App.css @@ -1 +1 @@ -@import url('./common/assets/theme/style.css'); \ No newline at end of file +@import url("./common/assets/theme/style.css"); diff --git a/src/App.test.tsx b/src/App.test.tsx deleted file mode 100644 index a754b20..0000000 --- a/src/App.test.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; - -it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/src/App.tsx b/src/App.tsx index 822f033..0afc045 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,20 +1,17 @@ -import React, { Component } from 'react'; -import { BrowserRouter } from 'react-router-dom'; +import { HelmetProvider } from '@dr.pogodin/react-helmet'; import { CookiesProvider } from 'react-cookie'; +import { BrowserRouter } from 'react-router'; import AppRoot from './common/AppRoot'; import './App.css'; -class App extends Component { - - render() { - return ( - - - - - - ); - } -} +const App = () => ( + + + + + + + +); export default App; diff --git a/src/common/AppRoot.tsx b/src/common/AppRoot.tsx index 9250ff5..d16a980 100644 --- a/src/common/AppRoot.tsx +++ b/src/common/AppRoot.tsx @@ -1,83 +1,62 @@ -import React, { Component } from 'react'; -import { ReactCookieProps, withCookies } from 'react-cookie'; -import ReactGA from 'react-ga'; -import { Helmet } from 'react-helmet'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; -import Config, { MultiLang } from '../config'; +import { Helmet } from '@dr.pogodin/react-helmet'; +import { useEffect, useRef } from 'react'; +import { useCookies } from 'react-cookie'; +import ReactGA from 'react-ga4'; +import { useLocation } from 'react-router'; +import Config, { type MultiLang } from '../config'; import Functions from '../functions'; import CenterColumn from './CenterColumn'; import Header from './Header'; import LeftColumn from './LeftColumn'; +const isAnalyticsEnabled = Config.GOOGLE_ANALYTICS_TRACKING_ID !== ''; -interface Props extends RouteComponentProps, ReactCookieProps { } -interface State { - lang: MultiLang; +if (isAnalyticsEnabled) { + ReactGA.initialize(Config.GOOGLE_ANALYTICS_TRACKING_ID); } -class AppRoot extends Component { +const toMultiLang = (value: unknown): MultiLang | null => (value === 'en' || value === 'ja' ? value : null); - constructor(props: Props) { - super(props); - this.state = { lang: 'en' }; - if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') { - ReactGA.initialize(Config.GOOGLE_ANALYTICS_TRACKING_ID); - } - } +const AppRoot = () => { + const location = useLocation(); + const [cookies, setCookie] = useCookies(['ml_lang']); + const previousLocation = useRef(null); - static getDerivedStateFromProps(nextProps: Props, prevState: State) { - const params = new URLSearchParams(nextProps.location.search); - const param_lang = params.get('ml_lang'); - const cookie_lang = typeof nextProps.cookies !== 'undefined' ? nextProps.cookies.get('ml_lang') : null; - let lang = param_lang || (typeof cookie_lang === 'string' ? cookie_lang : null) || prevState.lang; - if (lang !== 'en' && lang !== 'ja') { - lang = 'en'; - } - if (cookie_lang !== lang) { - if (typeof nextProps.cookies !== 'undefined') { - nextProps.cookies.set('ml_lang', lang, { path: '/' }); - } - } - if (prevState.lang !== lang) { - return { lang }; - } - return null; - } + const paramLang = toMultiLang(new URLSearchParams(location.search).get('ml_lang')); + const cookieLang = toMultiLang(cookies.ml_lang); + const lang: MultiLang = paramLang ?? cookieLang ?? 'en'; - componentDidMount() { - const { pathname } = this.props.location; - if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') { - ReactGA.set({ page: pathname }); - ReactGA.pageview(pathname); + useEffect(() => { + if (cookies.ml_lang !== lang) { + setCookie('ml_lang', lang, { path: '/' }); } - } + }, [cookies.ml_lang, lang, setCookie]); - componentDidUpdate(prevProps: Props) { - const { pathname, search } = this.props.location; - if (Config.GOOGLE_ANALYTICS_TRACKING_ID !== '') { - ReactGA.set({ page: pathname }); - ReactGA.pageview(pathname); + useEffect(() => { + if (isAnalyticsEnabled) { + ReactGA.send({ hitType: 'pageview', page: location.pathname + location.search }); } - if (pathname !== prevProps.location.pathname || search !== prevProps.location.search) { + const current = location.pathname + location.search; + if (previousLocation.current !== null && previousLocation.current !== current) { window.scrollTo(0, 0); } - } + previousLocation.current = current; + }, [location.pathname, location.search]); - render() { - const { lang } = this.state; - return ( - <> - - {Functions.siteTitle(lang)} - {Functions.siteSlogan(lang)} - -
-
- - -
- - ); - } -} + return ( + <> + + + {Functions.siteTitle(lang)} - {Functions.siteSlogan(lang)} + + +
+
+ + +
+ + ); +}; -export default withCookies(withRouter(AppRoot)); +export default AppRoot; diff --git a/src/common/CenterColumn.tsx b/src/common/CenterColumn.tsx index d1e9b51..6c7bb02 100644 --- a/src/common/CenterColumn.tsx +++ b/src/common/CenterColumn.tsx @@ -1,16 +1,21 @@ -import React from 'react'; -import { Route, Switch } from 'react-router-dom'; -import { MultiLang } from '../config'; +import { lazy, Suspense } from 'react'; +import { useLocation } from 'react-router'; +import type { MultiLang } from '../config'; import CerebellarPlatformCommittee from '../custom/blocks/CerebellarPlatformCommittee'; import CerebrationOfDrItosNewBook from '../custom/blocks/CerebrationOfDrItosNewBook'; -import NewArticleAlert from '../custom/blocks/NewArticleAlert'; +import Loading from './lib/Loading'; + +// A standing bibliography, and by far the largest source file in the app. It +// only ever appears on the top page, so keep it out of the entry chunk. +const NewArticleAlert = lazy(() => import('../custom/blocks/NewArticleAlert')); + +import Welcome from '../custom/blocks/Welcome'; import Rankings from '../database/blocks/Rankings'; import RecentContents from '../database/blocks/RecentContents'; import DatabaseTop from '../database/DatabaseTop'; import Functions from '../functions'; import Footer from './Footer'; import MainContent from './MainContent'; -import Welcome from '../custom/blocks/Welcome'; interface Props { lang: MultiLang; @@ -21,7 +26,7 @@ const CenterBlocks = (props: Props) => { return (
-
+
Welcome to Cerebellar Platform
@@ -30,23 +35,27 @@ const CenterBlocks = (props: Props) => {
Cerebration of Dr. Ito's New Book
- +
Cerebellar Platfrom Committee
- +
New article alert
- + }> + +
-
{Functions.mlang('[en]Item Types[/en][ja]アイテムタイプ一覧[/ja]', lang)}
+
+ {Functions.mlang('[en]Item Types[/en][ja]アイテムタイプ一覧[/ja]', lang)} +
@@ -63,32 +72,32 @@ const CenterBlocks = (props: Props) => {
-
{Functions.mlang('[en]Recent Contents[/en][ja]新着コンテンツ[/ja]', lang)}
+
+ {Functions.mlang('[en]Recent Contents[/en][ja]新着コンテンツ[/ja]', lang)} +
-
); -} +}; const CenterColumn = (props: Props) => { const { lang } = props; + const { pathname } = useLocation(); return (
- - } /> - + {pathname === '/' && }
@@ -96,6 +105,6 @@ const CenterColumn = (props: Props) => {
); -} +}; -export default CenterColumn; \ No newline at end of file +export default CenterColumn; diff --git a/src/common/Footer.tsx b/src/common/Footer.tsx index cff3566..0118bdc 100644 --- a/src/common/Footer.tsx +++ b/src/common/Footer.tsx @@ -1,8 +1,7 @@ -import React from 'react'; -import { MultiLang } from '../config'; +import type { MultiLang } from '../config'; import Functions from '../functions'; -import bannerCBS from './assets/theme/images/banner-riken-cbs.png'; import bannerRIKEN from './assets/theme/images/banner-riken.png'; +import bannerCBS from './assets/theme/images/banner-riken-cbs.png'; import bannerXooNIps from './assets/theme/images/banner-xoonips.png'; import LinkImage from './lib/LinkImage'; @@ -15,13 +14,28 @@ const Footer = (props: Props) => { return (
- - - + + +
Copyright (C) 2018 Neuroinformatics Unit, RIKEN Center for Brain Science
); -} +}; export default Footer; diff --git a/src/common/Header.tsx b/src/common/Header.tsx index 0ac26aa..80a4b8b 100644 --- a/src/common/Header.tsx +++ b/src/common/Header.tsx @@ -1,69 +1,64 @@ -import React, { ChangeEvent, Component, FormEvent } from 'react'; -import { Link, RouteComponentProps, withRouter } from 'react-router-dom'; -import Config, { MultiLang } from '../config'; +import { type ChangeEvent, type FormEvent, useState } from 'react'; +import { Link, useNavigate } from 'react-router'; +import Config, { type MultiLang } from '../config'; import ItemUtil from '../database/lib/ItemUtil'; import Functions from '../functions'; -interface Props extends RouteComponentProps { +interface Props { lang: MultiLang; } -interface State { - keyword: string; -} +const Header = (props: Props) => { + const { lang } = props; + const navigate = useNavigate(); + const [keyword, setKeyword] = useState(''); -class Header extends Component { + const handleChangeKeyword = (event: ChangeEvent) => { + setKeyword(event.target.value); + }; - constructor(props: Props) { - super(props); - this.handleChangeKeyword = this.handleChangeKeyword.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.state = { keyword: '' }; - } - - handleChangeKeyword(event: ChangeEvent) { - const keyword = event.target.value; - this.setState({ keyword }); - } - - handleSubmit(event: FormEvent) { + const handleSubmit = (event: FormEvent) => { event.preventDefault(); - const keyword = this.state.keyword.trim(); - if (keyword !== '') { - const url = ItemUtil.getSearchByKeywordUrl('all', this.state.keyword); - this.props.history.push(url); + if (keyword.trim() !== '') { + void navigate(ItemUtil.getSearchByKeywordUrl('all', keyword)); } - } + }; - render() { - const { lang } = this.props; - const title = Functions.mlang(Config.SITE_TITLE, lang); - return ( -