From 6b395e5735969fd14b55317e445043ab38a52b8e Mon Sep 17 00:00:00 2001 From: syntaxbullet Date: Tue, 16 Jun 2026 13:02:47 +0200 Subject: [PATCH] chore: migrate to payload / nextjs --- .editorconfig | 10 + .env.example | 17 + .gitignore | 26 +- .npmrc | 2 + .pi/auth.json | 9 + .pi/settings.json | 6 + .pi/skills/cms-migration/SKILL.md | 149 + .../reference/PAYLOAD-FIELD-REFERENCE.md | 1252 ++ .pi/skills/payload/README.md | 57 + .pi/skills/payload/SKILL.md | 409 + .../reference/ACCESS-CONTROL-ADVANCED.md | 704 + .../payload/reference/ACCESS-CONTROL.md | 697 + .pi/skills/payload/reference/ADAPTERS.md | 326 + .pi/skills/payload/reference/ADVANCED.md | 386 + .pi/skills/payload/reference/COLLECTIONS.md | 303 + .pi/skills/payload/reference/ENDPOINTS.md | 634 + .../payload/reference/FIELD-TYPE-GUARDS.md | 553 + .pi/skills/payload/reference/FIELDS.md | 744 + .pi/skills/payload/reference/HOOKS.md | 186 + .../payload/reference/PLUGIN-DEVELOPMENT.md | 1436 ++ .pi/skills/payload/reference/QUERIES.md | 274 + .pi/trust.json | 3 + .prettierignore | 14 + .prettierrc.json | 6 + .vscode/extensions.json | 3 + .vscode/launch.json | 24 + .vscode/settings.json | 41 + Dockerfile | 71 + README.md | 303 + bun.lock | 457 - components.json | 17 + docker-compose.yml | 31 + eslint.config.mjs | 38 + index.html | 14 - next-sitemap.config.cjs | 20 + next.config.ts | 54 + package-lock.json | 13690 +++++++++++++++- package.json | 110 +- playwright.config.ts | 41 + postcss.config.js | 7 + public/favicon.ico | Bin 0 -> 15086 bytes public/favicon.svg | 23 + public/website-template-OG.webp | Bin 0 -> 101500 bytes redirects.ts | 18 + src/App.tsx | 75 - src/Footer/Component.tsx | 32 + src/Footer/RowLabel.tsx | 13 + src/Footer/config.ts | 32 + src/Footer/hooks/revalidateFooter.ts | 13 + src/Header/Component.client.tsx | 42 + src/Header/Component.tsx | 9 + src/Header/Nav/index.tsx | 25 + src/Header/RowLabel.tsx | 13 + src/Header/config.ts | 32 + src/Header/hooks/revalidateHeader.ts | 13 + src/access/anyone.ts | 3 + src/access/authenticated.ts | 9 + src/access/authenticatedOrPublished.ts | 13 + .../(sitemaps)/pages-sitemap.xml/route.ts | 68 + .../(sitemaps)/posts-sitemap.xml/route.ts | 55 + src/app/(frontend)/[[...slug]]/page.tsx | 12 + src/app/(frontend)/globals.css | 124 + src/app/(frontend)/layout.tsx | 21 + src/app/(frontend)/next/exit-preview/route.ts | 7 + src/app/(frontend)/next/preview/route.ts | 59 + src/app/(frontend)/next/seed/route.ts | 31 + src/app/(frontend)/not-found.tsx | 18 + .../admin/[[...segments]]/not-found.tsx | 24 + .../(payload)/admin/[[...segments]]/page.tsx | 24 + src/app/(payload)/admin/importMap.js | 80 + src/app/(payload)/api/[...slug]/route.ts | 20 + .../(payload)/api/graphql-playground/route.ts | 7 + src/app/(payload)/api/graphql/route.ts | 8 + src/app/(payload)/custom.scss | 0 src/app/(payload)/layout.tsx | 31 + src/blocks/ArchiveBlock/Component.tsx | 65 + src/blocks/ArchiveBlock/config.ts | 94 + src/blocks/Banner/Component.tsx | 26 + src/blocks/Banner/config.ts | 37 + src/blocks/CallToAction/Component.tsx | 23 + src/blocks/CallToAction/config.ts | 42 + src/blocks/Code/Component.client.tsx | 33 + src/blocks/Code/Component.tsx | 21 + src/blocks/Code/CopyButton.tsx | 33 + src/blocks/Code/config.ts | 33 + src/blocks/Content/Component.tsx | 43 + src/blocks/Content/config.ts | 79 + src/blocks/Form/Checkbox/index.tsx | 45 + src/blocks/Form/Component.tsx | 163 + src/blocks/Form/Country/index.tsx | 65 + src/blocks/Form/Country/options.ts | 982 ++ src/blocks/Form/Email/index.tsx | 38 + src/blocks/Form/Error/index.tsx | 15 + src/blocks/Form/Message/index.tsx | 13 + src/blocks/Form/Number/index.tsx | 36 + src/blocks/Form/Select/index.tsx | 63 + src/blocks/Form/State/index.tsx | 64 + src/blocks/Form/State/options.ts | 52 + src/blocks/Form/Text/index.tsx | 32 + src/blocks/Form/Textarea/index.tsx | 40 + src/blocks/Form/Width/index.tsx | 13 + src/blocks/Form/config.ts | 51 + src/blocks/Form/fields.tsx | 21 + src/blocks/MediaBlock/Component.tsx | 67 + src/blocks/MediaBlock/config.ts | 14 + src/blocks/RelatedPosts/Component.tsx | 32 + src/blocks/RenderBlocks.tsx | 51 + src/collections/Categories.ts | 28 + src/collections/Media.ts | 81 + src/collections/Pages/hooks/revalidatePage.ts | 43 + src/collections/Pages/index.ts | 136 + .../Posts/hooks/populateAuthors.ts | 37 + src/collections/Posts/hooks/revalidatePost.ts | 44 + src/collections/Posts/index.ts | 233 + src/collections/Users/index.ts | 26 + src/components/AdminBar/index.scss | 7 + src/components/AdminBar/index.tsx | 89 + .../BeforeDashboard/SeedButton/index.scss | 12 + .../BeforeDashboard/SeedButton/index.tsx | 88 + src/components/BeforeDashboard/index.scss | 24 + src/components/BeforeDashboard/index.tsx | 69 + src/components/BeforeLogin/index.tsx | 14 + src/components/Card/index.tsx | 80 + src/components/CollectionArchive/index.tsx | 32 + src/components/Link/index.tsx | 66 + src/components/LivePreviewListener/index.tsx | 10 + src/components/Logo/Logo.tsx | 29 + src/components/Media/ImageMedia/index.tsx | 105 + src/components/Media/VideoMedia/index.tsx | 46 + src/components/Media/index.tsx | 25 + src/components/Media/types.ts | 22 + src/components/PageRange/index.tsx | 57 + src/components/Pagination/index.tsx | 101 + src/components/PayloadRedirects/index.tsx | 48 + src/components/RichText/index.tsx | 81 + src/components/ui/button.tsx | 63 +- src/components/ui/card.tsx | 71 +- src/components/ui/checkbox.tsx | 29 + src/components/ui/input.tsx | 39 +- src/components/ui/label.tsx | 33 +- src/components/ui/pagination.tsx | 92 + src/components/ui/select.tsx | 166 + src/components/ui/textarea.tsx | 36 +- src/cssVariables.js | 12 + src/endpoints/seed/contact-form.ts | 111 + src/endpoints/seed/contact-page.ts | 56 + src/endpoints/seed/home-static.ts | 88 + src/endpoints/seed/home.ts | 675 + src/endpoints/seed/image-1.ts | 67 + src/endpoints/seed/image-2.ts | 67 + src/endpoints/seed/image-hero-1.ts | 5 + src/endpoints/seed/image-hero1.webp | Bin 0 -> 771366 bytes src/endpoints/seed/image-post1.webp | Bin 0 -> 117606 bytes src/endpoints/seed/image-post2.webp | Bin 0 -> 168786 bytes src/endpoints/seed/image-post3.webp | Bin 0 -> 112146 bytes src/endpoints/seed/index.ts | 298 + src/endpoints/seed/post-1.ts | 315 + src/endpoints/seed/post-2.ts | 232 + src/endpoints/seed/post-3.ts | 268 + src/environment.d.ts | 14 + src/fields/defaultLexical.ts | 47 + src/fields/link.ts | 139 + src/fields/linkGroup.ts | 28 + src/heros/HighImpact/index.tsx | 46 + src/heros/LowImpact/index.tsx | 25 + src/heros/MediumImpact/index.tsx | 46 + src/heros/PostHero/index.tsx | 73 + src/heros/RenderHero.tsx | 25 + src/heros/config.ts | 72 + src/hooks/populatePublishedAt.ts | 15 + src/hooks/revalidateRedirects.ts | 11 + src/main.tsx | 13 - src/payload-types.ts | 1817 ++ src/payload.config.ts | 92 + src/plugins/index.ts | 92 + src/providers/HeaderTheme/index.tsx | 33 + src/providers/Theme/InitTheme/index.tsx | 50 + src/providers/Theme/ThemeSelector/index.tsx | 51 + src/providers/Theme/ThemeSelector/types.ts | 5 + src/providers/Theme/index.tsx | 57 + src/providers/Theme/shared.ts | 17 + src/providers/Theme/types.ts | 10 + src/providers/index.tsx | 14 + src/search/Component.tsx | 41 + src/search/beforeSync.ts | 60 + src/search/fieldOverrides.ts | 61 + src/spa/NextApp.tsx | 78 + src/{ => spa}/components/LoginGate.tsx | 0 .../components/TestimonialsSection.tsx | 4 +- .../components/WegZurAuszeichnungSection.tsx | 4 +- .../components/editor/LayoutEditor.tsx | 6 +- .../components/forms/BewerbungsForm.tsx | 2 +- .../components/forms/KontaktForm.tsx | 2 +- .../components/forms/SponsoringForm.tsx | 2 +- src/{ => spa}/components/layout/Layout.tsx | 12 +- .../components/layout/ScrollToTop.tsx | 2 +- .../membership/MembershipWizard.tsx | 2 +- src/{ => spa}/components/ui/LoadingScreen.tsx | 0 src/{ => spa}/components/ui/badge.tsx | 2 +- src/spa/components/ui/button.tsx | 61 + src/spa/components/ui/card.tsx | 92 + src/{ => spa}/components/ui/carousel.tsx | 4 +- src/spa/components/ui/input.tsx | 23 + src/spa/components/ui/label.tsx | 20 + .../components/ui/munich-skyline-bg.tsx | 0 .../components/ui/partner-ticker.tsx | 0 .../components/ui/process-timeline.tsx | 2 +- src/spa/components/ui/textarea.tsx | 22 + src/{ => spa}/data/blog.ts | 0 src/{ => spa}/data/events.ts | 0 src/{ => spa}/data/winners.ts | 0 src/{ => spa}/hooks/useIsMobile.ts | 0 src/{ => spa}/index.css | 0 src/{ => spa}/lib/utils.ts | 0 src/{ => spa}/pages/About.tsx | 14 +- src/{ => spa}/pages/BlogDetail.tsx | 6 +- src/{ => spa}/pages/Contact.tsx | 4 +- src/{ => spa}/pages/Datenschutz.tsx | 4 +- src/{ => spa}/pages/EventDetail.tsx | 6 +- src/{ => spa}/pages/FormularUpload.tsx | 4 +- src/{ => spa}/pages/Home.tsx | 22 +- src/{ => spa}/pages/Impressum.tsx | 4 +- src/{ => spa}/pages/MitgliedWerden.tsx | 8 +- src/{ => spa}/pages/Netzwerk.tsx | 8 +- src/{ => spa}/pages/Participation.tsx | 10 +- src/{ => spa}/pages/Preistraeger.tsx | 8 +- src/{ => spa}/pages/PreistraegerDetail.tsx | 6 +- src/{ => spa}/pages/Press.tsx | 6 +- src/spa/router.tsx | 56 + src/utilities/canUseDOM.ts | 1 + src/utilities/deepMerge.ts | 35 + src/utilities/formatAuthors.ts | 24 + src/utilities/formatDateTime.ts | 20 + src/utilities/generateMeta.ts | 49 + src/utilities/generatePreviewPath.ts | 31 + src/utilities/getDocument.ts | 31 + src/utilities/getGlobals.ts | 26 + src/utilities/getMeUser.ts | 43 + src/utilities/getMediaUrl.ts | 19 + src/utilities/getRedirects.ts | 26 + src/utilities/getURL.ts | 26 + src/utilities/mergeOpenGraph.ts | 22 + src/utilities/toKebabCase.ts | 5 + src/utilities/ui.ts | 12 + src/utilities/useClickableCard.ts | 108 + src/utilities/useDebounce.ts | 17 + tailwind.config.mjs | 48 + test.env | 1 + tests/e2e/admin.e2e.spec.ts | 41 + tests/e2e/frontend.e2e.spec.ts | 17 + tests/helpers/login.ts | 31 + tests/helpers/seedUser.ts | 46 + tests/int/api.int.spec.ts | 20 + tsconfig.json | 52 + vite.config.js | 20 - vitest.config.mts | 12 + vitest.setup.ts | 4 + 257 files changed, 33616 insertions(+), 1451 deletions(-) create mode 100644 .editorconfig create mode 100644 .env.example create mode 100644 .npmrc create mode 100644 .pi/auth.json create mode 100644 .pi/settings.json create mode 100644 .pi/skills/cms-migration/SKILL.md create mode 100644 .pi/skills/cms-migration/reference/PAYLOAD-FIELD-REFERENCE.md create mode 100644 .pi/skills/payload/README.md create mode 100644 .pi/skills/payload/SKILL.md create mode 100644 .pi/skills/payload/reference/ACCESS-CONTROL-ADVANCED.md create mode 100644 .pi/skills/payload/reference/ACCESS-CONTROL.md create mode 100644 .pi/skills/payload/reference/ADAPTERS.md create mode 100644 .pi/skills/payload/reference/ADVANCED.md create mode 100644 .pi/skills/payload/reference/COLLECTIONS.md create mode 100644 .pi/skills/payload/reference/ENDPOINTS.md create mode 100644 .pi/skills/payload/reference/FIELD-TYPE-GUARDS.md create mode 100644 .pi/skills/payload/reference/FIELDS.md create mode 100644 .pi/skills/payload/reference/HOOKS.md create mode 100644 .pi/skills/payload/reference/PLUGIN-DEVELOPMENT.md create mode 100644 .pi/skills/payload/reference/QUERIES.md create mode 100644 .pi/trust.json create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 Dockerfile create mode 100644 README.md delete mode 100644 bun.lock create mode 100644 components.json create mode 100644 docker-compose.yml create mode 100644 eslint.config.mjs delete mode 100644 index.html create mode 100644 next-sitemap.config.cjs create mode 100644 next.config.ts create mode 100644 playwright.config.ts create mode 100644 postcss.config.js create mode 100644 public/favicon.ico create mode 100644 public/favicon.svg create mode 100644 public/website-template-OG.webp create mode 100644 redirects.ts delete mode 100644 src/App.tsx create mode 100644 src/Footer/Component.tsx create mode 100644 src/Footer/RowLabel.tsx create mode 100644 src/Footer/config.ts create mode 100644 src/Footer/hooks/revalidateFooter.ts create mode 100644 src/Header/Component.client.tsx create mode 100644 src/Header/Component.tsx create mode 100644 src/Header/Nav/index.tsx create mode 100644 src/Header/RowLabel.tsx create mode 100644 src/Header/config.ts create mode 100644 src/Header/hooks/revalidateHeader.ts create mode 100644 src/access/anyone.ts create mode 100644 src/access/authenticated.ts create mode 100644 src/access/authenticatedOrPublished.ts create mode 100644 src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts create mode 100644 src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts create mode 100644 src/app/(frontend)/[[...slug]]/page.tsx create mode 100644 src/app/(frontend)/globals.css create mode 100644 src/app/(frontend)/layout.tsx create mode 100644 src/app/(frontend)/next/exit-preview/route.ts create mode 100644 src/app/(frontend)/next/preview/route.ts create mode 100644 src/app/(frontend)/next/seed/route.ts create mode 100644 src/app/(frontend)/not-found.tsx create mode 100644 src/app/(payload)/admin/[[...segments]]/not-found.tsx create mode 100644 src/app/(payload)/admin/[[...segments]]/page.tsx create mode 100644 src/app/(payload)/admin/importMap.js create mode 100644 src/app/(payload)/api/[...slug]/route.ts create mode 100644 src/app/(payload)/api/graphql-playground/route.ts create mode 100644 src/app/(payload)/api/graphql/route.ts create mode 100644 src/app/(payload)/custom.scss create mode 100644 src/app/(payload)/layout.tsx create mode 100644 src/blocks/ArchiveBlock/Component.tsx create mode 100644 src/blocks/ArchiveBlock/config.ts create mode 100644 src/blocks/Banner/Component.tsx create mode 100644 src/blocks/Banner/config.ts create mode 100644 src/blocks/CallToAction/Component.tsx create mode 100644 src/blocks/CallToAction/config.ts create mode 100644 src/blocks/Code/Component.client.tsx create mode 100644 src/blocks/Code/Component.tsx create mode 100644 src/blocks/Code/CopyButton.tsx create mode 100644 src/blocks/Code/config.ts create mode 100644 src/blocks/Content/Component.tsx create mode 100644 src/blocks/Content/config.ts create mode 100644 src/blocks/Form/Checkbox/index.tsx create mode 100644 src/blocks/Form/Component.tsx create mode 100644 src/blocks/Form/Country/index.tsx create mode 100644 src/blocks/Form/Country/options.ts create mode 100644 src/blocks/Form/Email/index.tsx create mode 100644 src/blocks/Form/Error/index.tsx create mode 100644 src/blocks/Form/Message/index.tsx create mode 100644 src/blocks/Form/Number/index.tsx create mode 100644 src/blocks/Form/Select/index.tsx create mode 100644 src/blocks/Form/State/index.tsx create mode 100644 src/blocks/Form/State/options.ts create mode 100644 src/blocks/Form/Text/index.tsx create mode 100644 src/blocks/Form/Textarea/index.tsx create mode 100644 src/blocks/Form/Width/index.tsx create mode 100644 src/blocks/Form/config.ts create mode 100644 src/blocks/Form/fields.tsx create mode 100644 src/blocks/MediaBlock/Component.tsx create mode 100644 src/blocks/MediaBlock/config.ts create mode 100644 src/blocks/RelatedPosts/Component.tsx create mode 100644 src/blocks/RenderBlocks.tsx create mode 100644 src/collections/Categories.ts create mode 100644 src/collections/Media.ts create mode 100644 src/collections/Pages/hooks/revalidatePage.ts create mode 100644 src/collections/Pages/index.ts create mode 100644 src/collections/Posts/hooks/populateAuthors.ts create mode 100644 src/collections/Posts/hooks/revalidatePost.ts create mode 100644 src/collections/Posts/index.ts create mode 100644 src/collections/Users/index.ts create mode 100644 src/components/AdminBar/index.scss create mode 100644 src/components/AdminBar/index.tsx create mode 100644 src/components/BeforeDashboard/SeedButton/index.scss create mode 100644 src/components/BeforeDashboard/SeedButton/index.tsx create mode 100644 src/components/BeforeDashboard/index.scss create mode 100644 src/components/BeforeDashboard/index.tsx create mode 100644 src/components/BeforeLogin/index.tsx create mode 100644 src/components/Card/index.tsx create mode 100644 src/components/CollectionArchive/index.tsx create mode 100644 src/components/Link/index.tsx create mode 100644 src/components/LivePreviewListener/index.tsx create mode 100644 src/components/Logo/Logo.tsx create mode 100644 src/components/Media/ImageMedia/index.tsx create mode 100644 src/components/Media/VideoMedia/index.tsx create mode 100644 src/components/Media/index.tsx create mode 100644 src/components/Media/types.ts create mode 100644 src/components/PageRange/index.tsx create mode 100644 src/components/Pagination/index.tsx create mode 100644 src/components/PayloadRedirects/index.tsx create mode 100644 src/components/RichText/index.tsx create mode 100644 src/components/ui/checkbox.tsx create mode 100644 src/components/ui/pagination.tsx create mode 100644 src/components/ui/select.tsx create mode 100644 src/cssVariables.js create mode 100644 src/endpoints/seed/contact-form.ts create mode 100644 src/endpoints/seed/contact-page.ts create mode 100644 src/endpoints/seed/home-static.ts create mode 100644 src/endpoints/seed/home.ts create mode 100644 src/endpoints/seed/image-1.ts create mode 100644 src/endpoints/seed/image-2.ts create mode 100644 src/endpoints/seed/image-hero-1.ts create mode 100644 src/endpoints/seed/image-hero1.webp create mode 100644 src/endpoints/seed/image-post1.webp create mode 100644 src/endpoints/seed/image-post2.webp create mode 100644 src/endpoints/seed/image-post3.webp create mode 100644 src/endpoints/seed/index.ts create mode 100644 src/endpoints/seed/post-1.ts create mode 100644 src/endpoints/seed/post-2.ts create mode 100644 src/endpoints/seed/post-3.ts create mode 100644 src/environment.d.ts create mode 100644 src/fields/defaultLexical.ts create mode 100644 src/fields/link.ts create mode 100644 src/fields/linkGroup.ts create mode 100644 src/heros/HighImpact/index.tsx create mode 100644 src/heros/LowImpact/index.tsx create mode 100644 src/heros/MediumImpact/index.tsx create mode 100644 src/heros/PostHero/index.tsx create mode 100644 src/heros/RenderHero.tsx create mode 100644 src/heros/config.ts create mode 100644 src/hooks/populatePublishedAt.ts create mode 100644 src/hooks/revalidateRedirects.ts delete mode 100644 src/main.tsx create mode 100644 src/payload-types.ts create mode 100644 src/payload.config.ts create mode 100644 src/plugins/index.ts create mode 100644 src/providers/HeaderTheme/index.tsx create mode 100644 src/providers/Theme/InitTheme/index.tsx create mode 100644 src/providers/Theme/ThemeSelector/index.tsx create mode 100644 src/providers/Theme/ThemeSelector/types.ts create mode 100644 src/providers/Theme/index.tsx create mode 100644 src/providers/Theme/shared.ts create mode 100644 src/providers/Theme/types.ts create mode 100644 src/providers/index.tsx create mode 100644 src/search/Component.tsx create mode 100644 src/search/beforeSync.ts create mode 100644 src/search/fieldOverrides.ts create mode 100644 src/spa/NextApp.tsx rename src/{ => spa}/components/LoginGate.tsx (100%) rename src/{ => spa}/components/TestimonialsSection.tsx (98%) rename src/{ => spa}/components/WegZurAuszeichnungSection.tsx (99%) rename src/{ => spa}/components/editor/LayoutEditor.tsx (99%) rename src/{ => spa}/components/forms/BewerbungsForm.tsx (99%) rename src/{ => spa}/components/forms/KontaktForm.tsx (99%) rename src/{ => spa}/components/forms/SponsoringForm.tsx (99%) rename src/{ => spa}/components/layout/Layout.tsx (99%) rename src/{ => spa}/components/layout/ScrollToTop.tsx (80%) rename src/{ => spa}/components/membership/MembershipWizard.tsx (99%) rename src/{ => spa}/components/ui/LoadingScreen.tsx (100%) rename src/{ => spa}/components/ui/badge.tsx (97%) create mode 100644 src/spa/components/ui/button.tsx create mode 100644 src/spa/components/ui/card.tsx rename src/{ => spa}/components/ui/carousel.tsx (98%) create mode 100644 src/spa/components/ui/input.tsx create mode 100644 src/spa/components/ui/label.tsx rename src/{ => spa}/components/ui/munich-skyline-bg.tsx (100%) rename src/{ => spa}/components/ui/partner-ticker.tsx (100%) rename src/{ => spa}/components/ui/process-timeline.tsx (98%) create mode 100644 src/spa/components/ui/textarea.tsx rename src/{ => spa}/data/blog.ts (100%) rename src/{ => spa}/data/events.ts (100%) rename src/{ => spa}/data/winners.ts (100%) rename src/{ => spa}/hooks/useIsMobile.ts (100%) rename src/{ => spa}/index.css (100%) rename src/{ => spa}/lib/utils.ts (100%) rename src/{ => spa}/pages/About.tsx (98%) rename src/{ => spa}/pages/BlogDetail.tsx (98%) rename src/{ => spa}/pages/Contact.tsx (99%) rename src/{ => spa}/pages/Datenschutz.tsx (99%) rename src/{ => spa}/pages/EventDetail.tsx (98%) rename src/{ => spa}/pages/FormularUpload.tsx (99%) rename src/{ => spa}/pages/Home.tsx (98%) rename src/{ => spa}/pages/Impressum.tsx (99%) rename src/{ => spa}/pages/MitgliedWerden.tsx (99%) rename src/{ => spa}/pages/Netzwerk.tsx (99%) rename src/{ => spa}/pages/Participation.tsx (99%) rename src/{ => spa}/pages/Preistraeger.tsx (98%) rename src/{ => spa}/pages/PreistraegerDetail.tsx (98%) rename src/{ => spa}/pages/Press.tsx (99%) create mode 100644 src/spa/router.tsx create mode 100644 src/utilities/canUseDOM.ts create mode 100644 src/utilities/deepMerge.ts create mode 100644 src/utilities/formatAuthors.ts create mode 100644 src/utilities/formatDateTime.ts create mode 100644 src/utilities/generateMeta.ts create mode 100644 src/utilities/generatePreviewPath.ts create mode 100644 src/utilities/getDocument.ts create mode 100644 src/utilities/getGlobals.ts create mode 100644 src/utilities/getMeUser.ts create mode 100644 src/utilities/getMediaUrl.ts create mode 100644 src/utilities/getRedirects.ts create mode 100644 src/utilities/getURL.ts create mode 100644 src/utilities/mergeOpenGraph.ts create mode 100644 src/utilities/toKebabCase.ts create mode 100644 src/utilities/ui.ts create mode 100644 src/utilities/useClickableCard.ts create mode 100644 src/utilities/useDebounce.ts create mode 100644 tailwind.config.mjs create mode 100644 test.env create mode 100644 tests/e2e/admin.e2e.spec.ts create mode 100644 tests/e2e/frontend.e2e.spec.ts create mode 100644 tests/helpers/login.ts create mode 100644 tests/helpers/seedUser.ts create mode 100644 tests/int/api.int.spec.ts create mode 100644 tsconfig.json delete mode 100644 vite.config.js create mode 100644 vitest.config.mts create mode 100644 vitest.setup.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d8e085a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf +max_line_length = null diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..57bee94 --- /dev/null +++ b/.env.example @@ -0,0 +1,17 @@ +# Database connection string +DATABASE_URL=mongodb://127.0.0.1/your-database-name + +# Or use a PG connection string +#DATABASE_URL=postgresql://127.0.0.1:5432/your-database-name + +# Used to encrypt JWT tokens +PAYLOAD_SECRET=YOUR_SECRET_HERE + +# Used to configure CORS, format links and more. No trailing slash +NEXT_PUBLIC_SERVER_URL=http://localhost:3000 + +# Secret used to authenticate cron jobs +CRON_SECRET=YOUR_CRON_SECRET_HERE + +# Used to validate preview requests +PREVIEW_SECRET=YOUR_SECRET_HERE diff --git a/.gitignore b/.gitignore index 5ec01c2..7ad09c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,22 @@ -node_modules/ -dist/ -public/extracted_logos/ -*.timestamp-*.mjs +build +dist / media +node_modules .DS_Store -.pi +.env +.next +next-env.d.ts +.vercel + +# Payload default media upload directory +public/media/ + +public/robots.txt +public/sitemap*.xml + + +# Playwright +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5ff455c --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +legacy-peer-deps=true +enable-pre-post-scripts=true diff --git a/.pi/auth.json b/.pi/auth.json new file mode 100644 index 0000000..3261ba2 --- /dev/null +++ b/.pi/auth.json @@ -0,0 +1,9 @@ +{ + "openai-codex": { + "type": "oauth", + "access": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5MzQ0ZTY1LWJiYzktNDRkMS1hOWQwLWY5NTdiMDc5YmQwZSIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MSJdLCJjbGllbnRfaWQiOiJhcHBfRU1vYW1FRVo3M2YwQ2tYYVhwN2hyYW5uIiwiZXhwIjoxNzgyMTE3MzgxLCJodHRwczovL2FwaS5vcGVuYWkuY29tL2F1dGgiOnsiY2hhdGdwdF9hY2NvdW50X2lkIjoiMDJjZDFlOGMtMzViZi00ODkxLTgyYTktOTkyY2RiZTFkNTZlIiwiY2hhdGdwdF9hY2NvdW50X3VzZXJfaWQiOiJ1c2VyLXFqNHVwSVJ1b25sTEdPTUZYRVNUOXNxOF9fMDJjZDFlOGMtMzViZi00ODkxLTgyYTktOTkyY2RiZTFkNTZlIiwiY2hhdGdwdF9jb21wdXRlX3Jlc2lkZW5jeSI6Im5vX2NvbnN0cmFpbnQiLCJjaGF0Z3B0X3BsYW5fdHlwZSI6InByb2xpdGUiLCJjaGF0Z3B0X3VzZXJfaWQiOiJ1c2VyLXFqNHVwSVJ1b25sTEdPTUZYRVNUOXNxOCIsImxvY2FsaG9zdCI6dHJ1ZSwidXNlcl9pZCI6InVzZXItcWo0dXBJUnVvbmxMR09NRlhFU1Q5c3E4In0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vcHJvZmlsZSI6eyJlbWFpbCI6Iml2aXNjcmlwdHNAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWV9LCJpYXQiOjE3ODEyNTMzODAsImlzcyI6Imh0dHBzOi8vYXV0aC5vcGVuYWkuY29tIiwianRpIjoiNmUzNmQ1ZDEtZTVmYi00YWMwLWI2ZjQtYTgyZmU3M2JhNGNmIiwibmJmIjoxNzgxMjUzMzgwLCJwd2RfYXV0aF90aW1lIjoxNzgxMjUzMzc5ODA0LCJzY3AiOlsib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIiwib2ZmbGluZV9hY2Nlc3MiXSwic2Vzc2lvbl9pZCI6ImF1dGhzZXNzXzdtUkllRWpicHk0OHJDOGJVRVlIM2hqOCIsInNsIjp0cnVlLCJzdWIiOiJnb29nbGUtb2F1dGgyfDExNTU5MjY0ODIxMjU4MzQ5NzgzMCJ9.ZVEDhcFG8jbJdwIMJcNdBwZQtLFXfqFHscHUReBan0VeDyrwdNi5PWPaRX_IinmthoNML5iCVOf9chpIYXh3OTsuI2V3r-5Cb8sMm7I54xm6oDPo_DQ5NEZPFBxRAyGlM0iI2rlb6rrc_Rqhn34UyvLrFSK8xJyQ94GR4P5RmYYGS8kMP0gghY4Eg8nKw_uTJ1c4DSpYOzSYbM3ocdp7J9pKt-oOosLLv4TdLsO6fu0gY8TGnDJ8WkpgmHSTsCYWG32fzRKq3gJzEhXkTQB72nuNYpbjFhWRYxAU4Wc2Lu6cfo-ulqa_CXCV6j_5gd9G-yCfQC2S5McgL6lT4XRE955mL5FPXlmu0A__IKDn1qbd0PqAX5XyO9vP7yp2kUFZO0a4QqEpsfoWLM_TjAf8dgD8_IlClDDRxlSMBl_ex6xPre208ion_WvJXv68tCxQnAQKrdEUoqRkD3gawvXjo7_GpJZqzldJS7Nb_s7ZVJrwfumu7Vg8NHUHfKSOdIJv36jtDhqxcklYEhpsqsIDFkiJttGr2aYmJioztISkc5KaVQBhnnRTmcrH1ui2mB4KHcjldv_u9ArdOX09WWxo2h-uDcyKFXThsGyNS-fT9_acFGlH1iL5gG5EvokxT_v_FeysufrrOy_NGHeGEMhvoJYqpvQtyYIJ7wD_fOwjD3E", + "refresh": "rt.1.AAA-V8eXajSoeYFAkKuxM-B3FbeINU-bE9c0FFX_V3rl628PMBaM23IGydwbMqKRX6MuO5HeD8AevAyaOevN5e2LRj3hX0DKPjXzy0BMY0CjgY11fBZIewkNH5e11c3c-L9M7-jooIDcHvzOo_AmG1YQa2JpExX5lYRiL230GuAlTFZOg7vyZlyu3jixjdF1ZRslY7sbIOljJitITbXyf-0s0dmElZaHrMK8NKDPGWoTUgo9qYrx1XRNGazpNcOStkoCAsk-M9XZXcskUJGbuAwJFyC04MLLPE6Be80-6FY8pmWYiFCFiR4OM-ctu4AWXDQ", + "expires": 1782117380801, + "accountId": "02cd1e8c-35bf-4891-82a9-992cdbe1d56e" + } +} \ No newline at end of file diff --git a/.pi/settings.json b/.pi/settings.json new file mode 100644 index 0000000..b2c1bd1 --- /dev/null +++ b/.pi/settings.json @@ -0,0 +1,6 @@ +{ + "lastChangelogVersion": "0.79.1", + "defaultProvider": "openai-codex", + "defaultModel": "gpt-5.5", + "defaultThinkingLevel": "medium" +} \ No newline at end of file diff --git a/.pi/skills/cms-migration/SKILL.md b/.pi/skills/cms-migration/SKILL.md new file mode 100644 index 0000000..3b3693f --- /dev/null +++ b/.pi/skills/cms-migration/SKILL.md @@ -0,0 +1,149 @@ +--- +name: cms-migration +description: Use when user wants to migrate content from another CMS (WordPress, Contentful, Strapi, Sanity, Webflow, etc.) to Payload CMS +--- + +# CMS Migration to Payload + +Interactive workflow to design Payload collections from source CMS data. Config-first approach: establish the data structure through conversation before any data import. + +## Workflow + +``` +Start + ↓ +Ask for data sample + ↓ +Analyze data shape + ↓ +Propose collection config + ↓ +User reviews ──────────────┐ + │ │ + ├─ changes needed ───→ Adjust config ──→ (back to User reviews) + │ + └─ looks good ───→ Config confirmed + ↓ + More collections? ──────┐ + │ │ + ├─ yes ──→ (back to Ask for data sample) + │ + └─ no ───→ All collections confirmed + ↓ + Discuss migration approach + ↓ + Done +``` + +## Phase 1: Data Analysis + +When user provides data (JSON, CSV, or describes their schema): + +1. **Identify field types** - text, number, date, relationships, media, rich text +2. **Spot patterns** - IDs, timestamps, nested objects, arrays +3. **Note relationships** - foreign keys, embedded refs, linked content types +4. **Flag ambiguities** - fields that could be multiple types, unclear purposes + +## Phase 2: Propose Collection Config + +Present a Payload collection config based on analysis: + +```typescript +// Example output format +export const Posts: CollectionConfig = { + slug: 'posts', + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'content', type: 'richText' }, + { name: 'author', type: 'relationship', relationTo: 'users' }, + // ... + ], +} +``` + +Explain your reasoning for each field choice. When something could go multiple ways (group vs JSON, text vs textarea, select vs relationship), ask rather than assume. + +## Phase 3: Iterate with User + +Work through uncertainties: required fields, hasMany relationships, rich text vs HTML, custom timestamps vs built-in. Continue until the user confirms the config. + +## Phase 4: Additional Collections + +After each confirmation, ask: + +> "Are there other content types we should create collections for?" + +If yes, loop back to Phase 1 with new data sample. + +Common related collections to prompt for: +- Media/uploads +- Users/authors +- Categories/tags +- Settings (global) + +## Phase 5: Migration Approach + +Only after ALL collections are confirmed, discuss data import: + +1. **Order matters** - which collections have no dependencies? Migrate those first +2. **Relationship mapping** - how to resolve source IDs to Payload IDs +3. **Media handling** - download/re-upload vs external URLs +4. **Rich text** - HTML conversion needs or keep raw + +Offer to generate a seed script or walk through manual import. + +## Things to Clarify + +Throughout the process, watch for these: + +- **ID references** - are they relationships to other collections? +- **Image/file URLs** - upload fields or keep as external URLs? +- **Nested objects** - group, array, or blocks? +- **Localization** - any fields need per-locale values? +- **Access control** - who can read/write this collection? +- **Related content types** - categories, tags, authors that need their own collections? + +## Critical: Select vs Relationship + +**This is the most common migration mistake.** Data that looks static often needs to be dynamic. + +When you see repeated string values (categories, tags, types, statuses): + +```json +{ "category": "Technology" } +{ "category": "News" } +{ "category": "Technology" } +``` + +**Don't assume it's a select field.** Ask: + +> "I see `category` has values like 'Technology', 'News'. Should this be: +> - A **select field** with fixed options (values won't change) +> - A **relationship** to a Categories collection (users can add/edit/remove categories later)" + +**Default to relationship** for anything that looks like: +- Categories, tags, topics, labels +- Authors, assignees, reviewers +- Statuses beyond simple draft/published +- Types that might expand over time + +**Use select only for:** +- Truly fixed enums (yes/no, draft/published/archived) +- Options defined by business logic, not content (payment status, priority levels) +- Values that would break functionality if changed (role types with code dependencies) + +If creating a relationship, remember to add the related collection (Categories, Tags, etc.) to the migration plan. + +## Reference Documentation + +- **[PAYLOAD-FIELD-REFERENCE.md](reference/PAYLOAD-FIELD-REFERENCE.md)** - Complete Payload field type schemas with examples + +## Common Pitfalls + +| Issue | How to Handle | +|-------|---------------| +| User provides partial data | Ask for more samples, especially edge cases | +| Unclear relationships | Ask user to describe how content types connect | +| Rich text ambiguity | Clarify: Lexical editor, Slate, or store raw HTML | +| Missing media collection | Always confirm upload collection exists before referencing | +| Overly complex nested data | Consider flattening or using blocks instead of deep groups | diff --git a/.pi/skills/cms-migration/reference/PAYLOAD-FIELD-REFERENCE.md b/.pi/skills/cms-migration/reference/PAYLOAD-FIELD-REFERENCE.md new file mode 100644 index 0000000..d80ce6c --- /dev/null +++ b/.pi/skills/cms-migration/reference/PAYLOAD-FIELD-REFERENCE.md @@ -0,0 +1,1252 @@ +# Payload CMS Field Reference for AI-Assisted Migration + +This document helps AI assistants analyze source CMS data and generate appropriate Payload collection configurations. When given sample data from a source CMS, use this reference to determine the correct Payload field types. + +## How to Use This Document + +1. Analyze the source data structure (JSON, API response, or database schema) +2. For each field, determine the data type and pattern +3. Match to the appropriate Payload field type below +4. Generate a Payload collection config + +--- + +## Field Type Schemas + +Every field shares these **base properties**: + +```typescript +type BaseField = { + name: string // Required. Field identifier (camelCase) + label?: string // Admin UI label. Defaults to name + required?: boolean // Validation. Default: false + unique?: boolean // Database unique constraint + index?: boolean // Database index for faster queries + localized?: boolean // Enable per-locale values + hidden?: boolean // Hide from admin UI + saveToJWT?: boolean // Include in auth JWT + defaultValue?: unknown // Default when creating new docs + validate?: Function // Custom validation function + access?: { // Field-level access control + create?: Function + read?: Function + update?: Function + } + hooks?: { // Field lifecycle hooks + beforeValidate?: Function[] + beforeChange?: Function[] + afterChange?: Function[] + afterRead?: Function[] + } + admin?: { + condition?: Function // Conditionally show/hide field + description?: string // Help text below field + position?: 'sidebar' // Move to sidebar in admin + width?: string // CSS width (e.g., '50%') + style?: CSSProperties // Inline styles + className?: string // CSS class + readOnly?: boolean // Disable editing + disabled?: boolean // Disable field entirely + hidden?: boolean // Hide in admin + components?: { // Custom React components + Field?: Component + Cell?: Component + Filter?: Component + } + } +} +``` + +--- + +## Field Types + +### text + +Single-line text input. + +**Full schema:** +```typescript +type TextField = BaseField & { + type: 'text' + minLength?: number // Minimum character count + maxLength?: number // Maximum character count + hasMany?: boolean // Allow multiple values (array of strings) + minRows?: number // Min items when hasMany: true + maxRows?: number // Max items when hasMany: true + admin?: BaseField['admin'] & { + placeholder?: string // Placeholder text + autoComplete?: string // HTML autocomplete attribute + rtl?: boolean // Right-to-left text + } +} +``` + +**Use when:** +- Short strings (titles, names, slugs, URLs) +- Data is typically < 200 characters +- No line breaks expected + +**Source patterns:** +```json +{ "title": "Hello World" } +{ "slug": "hello-world" } +{ "url": "https://example.com" } +{ "sku": "PROD-12345" } +``` + +**Payload config examples:** +```typescript +{ name: 'title', type: 'text', required: true } +{ name: 'slug', type: 'text', unique: true, index: true } +{ name: 'tags', type: 'text', hasMany: true, maxRows: 10 } +{ name: 'sku', type: 'text', minLength: 5, maxLength: 20 } +``` + +--- + +### textarea + +Multi-line text without formatting. + +**Full schema:** +```typescript +type TextareaField = BaseField & { + type: 'textarea' + minLength?: number // Minimum character count + maxLength?: number // Maximum character count + admin?: BaseField['admin'] & { + placeholder?: string // Placeholder text + rows?: number // Visible rows (height) + rtl?: boolean // Right-to-left text + } +} +``` + +**Use when:** +- Longer text content without HTML/rich formatting +- Descriptions, excerpts, plain summaries +- Data contains line breaks but no markup + +**Source patterns:** +```json +{ "description": "A longer description\nthat spans multiple lines" } +{ "excerpt": "Brief summary of the content..." } +{ "bio": "Author biography text here" } +``` + +**Payload config examples:** +```typescript +{ name: 'description', type: 'textarea' } +{ name: 'excerpt', type: 'textarea', maxLength: 500 } +{ name: 'bio', type: 'textarea', admin: { rows: 6 } } +``` + +--- + +### richText + +Rich text editor (Lexical by default, or Slate). + +**Full schema:** +```typescript +type RichTextField = BaseField & { + type: 'richText' + editor?: LexicalEditorConfig // Lexical editor configuration + // Lexical-specific options (via editor config): + // - features: Enable/disable toolbar features + // - lexical: Raw Lexical configuration + admin?: BaseField['admin'] & { + hideGutter?: boolean // Hide left gutter + elements?: string[] // Deprecated (Slate). Use editor.features + leaves?: string[] // Deprecated (Slate). Use editor.features + } +} +``` + +**Use when:** +- HTML content from WYSIWYG editors +- Markdown content (will need conversion) +- Content with formatting (bold, italic, links, headings) +- Content blocks from Contentful, Sanity, etc. + +**Source patterns:** +```json +{ "content": "

Hello world

" } +{ "body": "# Heading\n\nParagraph with **bold**" } +{ "content": { "nodeType": "document", "content": [...] } } +``` + +**Payload config examples:** +```typescript +{ name: 'content', type: 'richText' } +{ name: 'body', type: 'richText', required: true } +``` + +**Migration notes:** +- WordPress `content.rendered` can be imported as HTML +- Contentful Rich Text requires conversion to Lexical format +- Markdown should be converted to HTML first, or use Lexical markdown plugin +- Data stored as Lexical JSON, not HTML + +--- + +### number + +Numeric values (integers or decimals). + +**Full schema:** +```typescript +type NumberField = BaseField & { + type: 'number' + min?: number // Minimum value + max?: number // Maximum value + hasMany?: boolean // Allow multiple values (array of numbers) + minRows?: number // Min items when hasMany: true + maxRows?: number // Max items when hasMany: true + admin?: BaseField['admin'] & { + placeholder?: string // Placeholder text + autoComplete?: string // HTML autocomplete attribute + step?: number // Increment step (e.g., 0.01 for currency) + } +} +``` + +**Use when:** +- Prices, quantities, counts +- Ratings, scores +- Any numeric data + +**Source patterns:** +```json +{ "price": 29.99 } +{ "quantity": 5 } +{ "rating": 4.5 } +{ "views": 1000 } +``` + +**Payload config examples:** +```typescript +{ name: 'price', type: 'number', min: 0, admin: { step: 0.01 } } +{ name: 'quantity', type: 'number', min: 0, max: 1000 } +{ name: 'rating', type: 'number', min: 0, max: 5 } +{ name: 'scores', type: 'number', hasMany: true } +``` + +--- + +### email + +Email address field with built-in validation. + +**Full schema:** +```typescript +type EmailField = BaseField & { + type: 'email' + minLength?: number // Minimum character count + maxLength?: number // Maximum character count + admin?: BaseField['admin'] & { + placeholder?: string // Placeholder text + autoComplete?: string // HTML autocomplete attribute + } +} +``` + +**Use when:** +- Field contains email addresses +- Field name suggests email (email, contactEmail, etc.) + +**Source patterns:** +```json +{ "email": "user@example.com" } +{ "contactEmail": "support@company.com" } +``` + +**Payload config examples:** +```typescript +{ name: 'email', type: 'email', required: true } +{ name: 'contactEmail', type: 'email', admin: { placeholder: 'you@example.com' } } +``` + +--- + +### date + +Date/datetime picker. + +**Full schema:** +```typescript +type DateField = BaseField & { + type: 'date' + admin?: BaseField['admin'] & { + placeholder?: string // Placeholder text + date?: { + displayFormat?: string // Display format (e.g., 'MMM d, yyyy') + pickerAppearance?: 'dayOnly' | 'dayAndTime' | 'monthOnly' | 'timeOnly' + minDate?: Date // Earliest selectable date + maxDate?: Date // Latest selectable date + } + } +} +``` + +**Use when:** +- ISO date strings +- Timestamps +- Any date/time values + +**Source patterns:** +```json +{ "publishedAt": "2024-01-15T10:30:00Z" } +{ "createdAt": "2024-01-15" } +{ "eventDate": 1705312200000 } +``` + +**Payload config examples:** +```typescript +{ name: 'publishedAt', type: 'date' } +{ name: 'eventDate', type: 'date', admin: { date: { pickerAppearance: 'dayAndTime' } } } +{ name: 'birthDate', type: 'date', admin: { date: { pickerAppearance: 'dayOnly' } } } +``` + +**Migration notes:** +- Payload stores dates as ISO strings +- Unix timestamps should be converted: `new Date(timestamp).toISOString()` + +--- + +### checkbox + +Boolean true/false toggle. + +**Full schema:** +```typescript +type CheckboxField = BaseField & { + type: 'checkbox' + defaultValue?: boolean // Default checked state + admin?: BaseField['admin'] // No additional checkbox-specific admin options +} +``` + +**Use when:** +- Boolean values +- Yes/no flags +- Feature toggles + +**Source patterns:** +```json +{ "featured": true } +{ "isPublished": false } +{ "allowComments": true } +``` + +**Payload config examples:** +```typescript +{ name: 'featured', type: 'checkbox', defaultValue: false } +{ name: 'isPublished', type: 'checkbox' } +{ name: 'allowComments', type: 'checkbox', defaultValue: true } +``` + +--- + +### select + +Dropdown with predefined options. + +**Full schema:** +```typescript +type SelectField = BaseField & { + type: 'select' + options: Array< // Required. List of options + | string // Simple: just the value (label = value) + | { label: string; value: string } // Full: separate label and value + > + hasMany?: boolean // Allow multiple selections + defaultValue?: string | string[] // Default selected value(s) + admin?: BaseField['admin'] & { + isClearable?: boolean // Allow clearing selection + isSortable?: boolean // Allow drag-to-reorder when hasMany + } +} +``` + +**Use when:** +- Enum values +- Status fields +- Category/type with fixed options +- Field has limited set of valid values + +**Source patterns:** +```json +{ "status": "published" } +{ "priority": "high" } +{ "type": "article" } +{ "tags": ["featured", "trending"] } +``` + +**Payload config examples:** +```typescript +// Simple options (value = label) +{ name: 'priority', type: 'select', options: ['low', 'medium', 'high'] } + +// Full options +{ + name: 'status', + type: 'select', + options: [ + { label: 'Draft', value: 'draft' }, + { label: 'Published', value: 'published' }, + { label: 'Archived', value: 'archived' }, + ], + defaultValue: 'draft', +} + +// Multiple selection +{ + name: 'tags', + type: 'select', + hasMany: true, + options: [ + { label: 'Featured', value: 'featured' }, + { label: 'Trending', value: 'trending' }, + { label: 'New', value: 'new' }, + ], +} +``` + +**Detecting options from data:** +If you see the same field with different values across records, collect unique values to build options: +```json +// Record 1: { "status": "draft" } +// Record 2: { "status": "published" } +// Record 3: { "status": "published" } +// options: draft, published +``` + +--- + +### radio + +Radio button group (single selection, always visible). + +**Full schema:** +```typescript +type RadioField = BaseField & { + type: 'radio' + options: Array< // Required. List of options + | string // Simple: just the value + | { label: string; value: string } // Full: separate label and value + > + defaultValue?: string // Default selected value + admin?: BaseField['admin'] & { + layout?: 'horizontal' | 'vertical' // Button arrangement + } +} +``` + +**Use when:** +- Same as select, but fewer options (2-4) +- User should see all options at once + +**Payload config examples:** +```typescript +{ + name: 'size', + type: 'radio', + options: [ + { label: 'Small', value: 'sm' }, + { label: 'Medium', value: 'md' }, + { label: 'Large', value: 'lg' }, + ], + defaultValue: 'md', +} + +{ + name: 'alignment', + type: 'radio', + options: ['left', 'center', 'right'], + admin: { layout: 'horizontal' }, +} +``` + +--- + +### relationship + +Reference to another document. + +**Full schema:** +```typescript +type RelationshipField = BaseField & { + type: 'relationship' + relationTo: string | string[] // Required. Target collection slug(s) + hasMany?: boolean // Allow multiple selections + minRows?: number // Min items when hasMany: true + maxRows?: number // Max items when hasMany: true + filterOptions?: // Limit selectable documents + | Where // Static where query + | ((args: FilterOptionsProps) => Where | boolean) // Dynamic filter + admin?: BaseField['admin'] & { + isSortable?: boolean // Allow drag-to-reorder when hasMany + allowCreate?: boolean // Allow creating new docs from field (default: true) + allowEdit?: boolean // Allow editing related doc inline + } +} + +// When relationTo is an array (polymorphic), stored value shape is: +// { relationTo: 'collectionSlug', value: 'documentId' } + +// When relationTo is a string, stored value is just the ID: +// 'documentId' +``` + +**Use when:** +- Foreign key / ID reference to another collection +- Nested object that should be a separate document +- Author, category, tag references + +**Source patterns:** +```json +// ID reference +{ "author": 123 } +{ "authorId": "user_abc123" } + +// Object with ID +{ "author": { "id": 123, "name": "John" } } + +// Contentful link +{ "author": { "sys": { "id": "abc123", "linkType": "Entry" } } } + +// Array of references +{ "categories": [1, 2, 3] } +{ "tags": [{ "id": 1 }, { "id": 2 }] } +``` + +**Payload config examples:** +```typescript +// Single relationship +{ name: 'author', type: 'relationship', relationTo: 'users' } + +// Multiple relationships (hasMany) +{ name: 'categories', type: 'relationship', relationTo: 'categories', hasMany: true } + +// Polymorphic (multiple collection types) +{ + name: 'relatedContent', + type: 'relationship', + relationTo: ['posts', 'pages', 'products'], + hasMany: true, +} + +// With filter (only show published posts) +{ + name: 'featuredPost', + type: 'relationship', + relationTo: 'posts', + filterOptions: { + status: { equals: 'published' }, + }, +} +``` + +--- + +### upload + +File/media upload field. References a document in an upload-enabled collection. + +**Full schema:** +```typescript +type UploadField = BaseField & { + type: 'upload' + relationTo: string // Required. Upload collection slug (e.g., 'media') + hasMany?: boolean // Allow multiple files + minRows?: number // Min items when hasMany: true + maxRows?: number // Max items when hasMany: true + filterOptions?: // Limit selectable files + | Where + | ((args: FilterOptionsProps) => Where | boolean) + admin?: BaseField['admin'] & { + isSortable?: boolean // Allow drag-to-reorder when hasMany + } +} + +// Stored value is the upload document ID (or array of IDs when hasMany) +``` + +**Use when:** +- Image URLs or references +- File attachments +- Media library references + +**Source patterns:** +```json +// URL reference +{ "featuredImage": "https://example.com/image.jpg" } + +// WordPress media ID +{ "featured_media": 456 } + +// Object with URL +{ "image": { "url": "https://...", "alt": "Description" } } + +// Contentful asset +{ "image": { "sys": { "linkType": "Asset" }, "fields": { "file": { "url": "//images.ctfassets.net/..." } } } } + +// Multiple images +{ "gallery": ["https://...", "https://..."] } +``` + +**Payload config examples:** +```typescript +{ name: 'featuredImage', type: 'upload', relationTo: 'media' } +{ name: 'gallery', type: 'upload', relationTo: 'media', hasMany: true, maxRows: 10 } +{ name: 'document', type: 'upload', relationTo: 'documents' } +``` + +**Migration notes:** +- Download remote images and upload to Payload +- Store the new Payload media ID in the field +- Preserve alt text as a separate field on the media collection or via a group + +--- + +### array + +Repeatable group of fields. + +**Full schema:** +```typescript +type ArrayField = BaseField & { + type: 'array' + fields: Field[] // Required. Sub-fields for each row + minRows?: number // Minimum number of rows + maxRows?: number // Maximum number of rows + labels?: { // Custom row labels + singular?: string + plural?: string + } + admin?: BaseField['admin'] & { + initCollapsed?: boolean // Start rows collapsed + isSortable?: boolean // Allow drag-to-reorder (default: true) + components?: { + RowLabel?: Component // Custom row label component + } + } + // Each row automatically gets an 'id' field +} + +// Stored as array of objects: +// [{ id: 'abc', field1: 'value', field2: 'value' }, ...] +``` + +**Use when:** +- Array of objects with consistent structure +- Repeater fields (ACF, etc.) +- List of items with multiple properties each + +**Source patterns:** +```json +{ + "socialLinks": [ + { "platform": "twitter", "url": "https://twitter.com/..." }, + { "platform": "github", "url": "https://github.com/..." } + ] +} + +{ + "features": [ + { "title": "Feature 1", "description": "..." }, + { "title": "Feature 2", "description": "..." } + ] +} +``` + +**Payload config examples:** +```typescript +{ + name: 'socialLinks', + type: 'array', + labels: { singular: 'Link', plural: 'Links' }, + minRows: 1, + maxRows: 5, + fields: [ + { + name: 'platform', + type: 'select', + options: ['twitter', 'github', 'linkedin'], + required: true, + }, + { name: 'url', type: 'text', required: true }, + ], +} + +{ + name: 'features', + type: 'array', + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'description', type: 'textarea' }, + { name: 'icon', type: 'upload', relationTo: 'media' }, + ], +} +``` + +--- + +### group + +Nested object (non-repeating). + +**Full schema:** +```typescript +type GroupField = BaseField & { + type: 'group' + fields: Field[] // Required. Sub-fields + admin?: BaseField['admin'] & { + hideGutter?: boolean // Remove left border/gutter + } +} + +// Stored as nested object: +// { field1: 'value', field2: 'value' } +``` + +**Use when:** +- Nested object that's always singular +- Organizational grouping of related fields +- SEO metadata, address blocks, etc. + +**Source patterns:** +```json +{ + "seo": { + "title": "Page Title", + "description": "Meta description", + "keywords": ["a", "b"] + } +} + +{ + "address": { + "street": "123 Main St", + "city": "Springfield", + "zip": "12345" + } +} +``` + +**Payload config examples:** +```typescript +{ + name: 'seo', + type: 'group', + label: 'SEO Settings', + fields: [ + { name: 'title', type: 'text', maxLength: 60 }, + { name: 'description', type: 'textarea', maxLength: 160 }, + { name: 'keywords', type: 'text', hasMany: true }, + ], +} + +{ + name: 'address', + type: 'group', + fields: [ + { name: 'street', type: 'text' }, + { name: 'city', type: 'text' }, + { name: 'state', type: 'text' }, + { name: 'zip', type: 'text' }, + { name: 'country', type: 'select', options: ['US', 'CA', 'UK'] }, + ], +} +``` + +--- + +### blocks + +Flexible content / page builder blocks. + +**Full schema:** +```typescript +type BlocksField = BaseField & { + type: 'blocks' + blocks: Block[] // Required. Available block types + minRows?: number // Minimum number of blocks + maxRows?: number // Maximum number of blocks + admin?: BaseField['admin'] & { + initCollapsed?: boolean // Start blocks collapsed + isSortable?: boolean // Allow drag-to-reorder (default: true) + } +} + +type Block = { + slug: string // Required. Unique block identifier + labels?: { // Custom labels + singular?: string + plural?: string + } + fields: Field[] // Required. Fields in this block + imageURL?: string // Preview image URL + imageAltText?: string // Alt text for preview + admin?: { + components?: { + Label?: Component // Custom block label + } + } +} + +// Stored as array with blockType identifier: +// [ +// { id: 'abc', blockType: 'hero', title: 'Welcome' }, +// { id: 'def', blockType: 'textBlock', content: {...} } +// ] +``` + +**Use when:** +- Dynamic content zones +- Page builder layouts +- ACF Flexible Content +- Contentful/Sanity block content + +**Source patterns:** +```json +{ + "layout": [ + { "type": "hero", "title": "Welcome", "image": "..." }, + { "type": "textBlock", "content": "

...

" }, + { "type": "gallery", "images": [...] } + ] +} +``` + +**Payload config examples:** +```typescript +{ + name: 'layout', + type: 'blocks', + minRows: 1, + blocks: [ + { + slug: 'hero', + labels: { singular: 'Hero Section', plural: 'Hero Sections' }, + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'subtitle', type: 'text' }, + { name: 'image', type: 'upload', relationTo: 'media' }, + { + name: 'cta', + type: 'group', + fields: [ + { name: 'label', type: 'text' }, + { name: 'url', type: 'text' }, + ], + }, + ], + }, + { + slug: 'textBlock', + labels: { singular: 'Text Block', plural: 'Text Blocks' }, + fields: [ + { name: 'content', type: 'richText', required: true }, + ], + }, + { + slug: 'gallery', + fields: [ + { name: 'images', type: 'upload', relationTo: 'media', hasMany: true }, + { name: 'columns', type: 'select', options: ['2', '3', '4'] }, + ], + }, + ], +} +``` + +**Migration notes:** +- Map source block `type` field to Payload `blockType` +- Each block type needs its own field definitions + +--- + +### json + +Arbitrary JSON data. + +**Full schema:** +```typescript +type JSONField = BaseField & { + type: 'json' + jsonSchema?: JSONSchema // Optional JSON Schema for validation + admin?: BaseField['admin'] & { + editorOptions?: object // Monaco editor options + } +} + +// Stored as-is (any valid JSON) +``` + +**Use when:** +- Unstructured or highly variable data +- Third-party API responses to store +- Data that doesn't fit other types +- Temporary/flexible storage during migration + +**Source patterns:** +```json +{ "metadata": { "arbitrary": "data", "nested": { "values": true } } } +{ "apiResponse": { ... } } +{ "config": { "settings": [...] } } +``` + +**Payload config examples:** +```typescript +{ name: 'metadata', type: 'json' } + +// With JSON Schema validation +{ + name: 'settings', + type: 'json', + jsonSchema: { + type: 'object', + properties: { + theme: { type: 'string' }, + notifications: { type: 'boolean' }, + }, + }, +} +``` + +**Migration notes:** +- Use as fallback when data structure is unknown or highly variable +- Consider converting to proper fields later for better querying + +--- + +### point + +Geographic coordinates (longitude, latitude). + +**Full schema:** +```typescript +type PointField = BaseField & { + type: 'point' + admin?: BaseField['admin'] // No additional point-specific admin options +} + +// Stored as GeoJSON Point: +// [longitude, latitude] // Note: longitude first! +// e.g., [-74.0060, 40.7128] for New York City +``` + +**Use when:** +- Latitude/longitude pairs +- Map locations +- Geolocation data + +**Source patterns:** +```json +{ "location": { "lat": 40.7128, "lng": -74.0060 } } +{ "coordinates": [40.7128, -74.0060] } +{ "geo": { "latitude": 40.7128, "longitude": -74.0060 } } +``` + +**Payload config examples:** +```typescript +{ name: 'location', type: 'point' } +{ name: 'coordinates', type: 'point', required: true } +``` + +**Migration notes:** +- Payload uses GeoJSON format: `[longitude, latitude]` +- Many sources use `[latitude, longitude]` - swap if needed! +- Convert from `{ lat, lng }` objects to `[lng, lat]` array + +--- + +### row (Layout) + +Horizontal layout for placing fields side-by-side. + +**Full schema:** +```typescript +type RowField = { + type: 'row' + fields: Field[] // Required. Fields to display in row + admin?: { + condition?: Function // Conditionally show/hide + } +} +// No name required - purely layout +``` + +**Payload config example:** +```typescript +{ + type: 'row', + fields: [ + { name: 'firstName', type: 'text', admin: { width: '50%' } }, + { name: 'lastName', type: 'text', admin: { width: '50%' } }, + ], +} +``` + +--- + +### collapsible (Layout) + +Collapsible section for grouping fields. + +**Full schema:** +```typescript +type CollapsibleField = { + type: 'collapsible' + label: string | Function // Required. Section header + fields: Field[] // Required. Fields inside + admin?: { + initCollapsed?: boolean // Start collapsed (default: false) + condition?: Function + } +} +// No name required - purely layout +``` + +**Payload config example:** +```typescript +{ + type: 'collapsible', + label: 'Advanced Settings', + admin: { initCollapsed: true }, + fields: [ + { name: 'customCSS', type: 'textarea' }, + { name: 'customJS', type: 'textarea' }, + ], +} +``` + +--- + +### tabs (Layout) + +Tabbed interface for organizing fields. + +**Full schema:** +```typescript +type TabsField = { + type: 'tabs' + tabs: Tab[] // Required. Array of tabs + admin?: { + condition?: Function + } +} + +type Tab = { + label: string // Required. Tab label + name?: string // If set, fields are nested under this key + fields: Field[] // Required. Fields in this tab + description?: string // Help text for tab +} +// No name on parent - tabs are layout only (unless tab has name) +``` + +**Payload config example:** +```typescript +{ + type: 'tabs', + tabs: [ + { + label: 'Content', + fields: [ + { name: 'title', type: 'text' }, + { name: 'body', type: 'richText' }, + ], + }, + { + label: 'SEO', + name: 'seo', // Fields nested under 'seo' key + fields: [ + { name: 'title', type: 'text' }, + { name: 'description', type: 'textarea' }, + ], + }, + ], +} +``` + +--- + +### ui (Custom Component) + +Render custom React component without storing data. + +**Full schema:** +```typescript +type UIField = { + type: 'ui' + name: string // Required (for key, not storage) + admin: { + components: { + Field: Component // Required. React component to render + Cell?: Component // List view component + } + condition?: Function + } +} +// Does NOT store data - purely visual +``` + +--- + +## Collection-Level Configuration + +### Basic Collection + +```typescript +const posts: CollectionConfig = { + slug: 'posts', + labels: { + singular: 'Post', + plural: 'Posts', + }, + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'slug', type: 'text', unique: true }, + { name: 'content', type: 'richText' }, + { name: 'author', type: 'relationship', relationTo: 'users' }, + { name: 'publishedAt', type: 'date' }, + ], +} +``` + +### Upload Collection + +```typescript +const media: CollectionConfig = { + slug: 'media', + labels: { + singular: 'Media', + plural: 'Media', + }, + upload: { + staticDir: 'media', // Directory for files (relative to project) + staticURL: '/media', // URL path prefix + mimeTypes: ['image/*', 'application/pdf'], // Allowed types + filesRequiredOnCreate: true, // Require file on create (default: true) + + // Image-specific options: + imageSizes: [ // Auto-generate resized versions + { name: 'thumbnail', width: 300, height: 300, position: 'centre' }, + { name: 'card', width: 768, height: 1024, position: 'centre' }, + { name: 'tablet', width: 1024 }, // Height auto + ], + adminThumbnail: 'thumbnail', // Size to show in admin + focalPoint: true, // Enable focal point selection + crop: true, // Enable cropping + + // Storage adapter (optional - defaults to local): + // adapter: s3Adapter({ ... }) + }, + fields: [ + { name: 'alt', type: 'text', required: true }, + { name: 'caption', type: 'textarea' }, + ], +} +``` + +**Upload document auto-fields:** +When you create an upload collection, Payload automatically adds these fields: +- `filename` - Original filename +- `mimeType` - File MIME type +- `filesize` - Size in bytes +- `width` - Image width (images only) +- `height` - Image height (images only) +- `url` - Public URL to file +- `thumbnailURL` - URL to thumbnail (if imageSizes configured) +- `sizes` - Object with all generated size URLs + +### Auth Collection + +```typescript +const users: CollectionConfig = { + slug: 'users', + auth: true, + fields: [ + { name: 'name', type: 'text' }, + { name: 'role', type: 'select', options: ['admin', 'editor', 'user'] }, + ], +} +``` + +--- + +## Common Migration Patterns + +### WordPress to Payload + +| WordPress | Payload | +|-----------|---------| +| `post_title` | `text` (title) | +| `post_content` | `richText` (HTML) | +| `post_excerpt` | `textarea` | +| `post_status` | `select` (draft/published) | +| `post_author` | `relationship` to users | +| `featured_media` | `upload` to media | +| `post_date` | `date` | +| ACF Repeater | `array` | +| ACF Group | `group` | +| ACF Flexible Content | `blocks` | + +### Contentful to Payload + +| Contentful | Payload | +|------------|---------| +| Short Text | `text` | +| Long Text | `textarea` | +| Rich Text | `richText` (needs conversion) | +| Number | `number` | +| Date | `date` | +| Boolean | `checkbox` | +| Media | `upload` | +| Reference | `relationship` | +| Array of References | `relationship` (hasMany) | + +### Strapi to Payload + +| Strapi | Payload | +|--------|---------| +| string | `text` | +| text | `textarea` | +| richtext/blocks | `richText` | +| integer/float/decimal | `number` | +| boolean | `checkbox` | +| date/datetime | `date` | +| enumeration | `select` | +| media | `upload` | +| relation | `relationship` | +| component | `group` or `array` | +| dynamiczone | `blocks` | + +--- + +## AI Instructions + +When analyzing source data to generate Payload config: + +1. **Identify collections** - Each distinct content type becomes a collection +2. **Detect relationships** - ID references between types become `relationship` fields +3. **Infer field types** - Use the patterns above to match data to Payload types +4. **Preserve structure** - Nested objects become `group`, arrays of objects become `array` +5. **Flag unknowns** - If data doesn't match patterns, suggest `json` as fallback and add a warning +6. **Generate valid TypeScript** - Output should be copy-paste ready + +**Output format:** +```typescript +import type { CollectionConfig } from 'payload' + +export const collectionName: CollectionConfig = { + slug: 'collection-name', + fields: [ + // fields here + ], +} +``` diff --git a/.pi/skills/payload/README.md b/.pi/skills/payload/README.md new file mode 100644 index 0000000..d6d9510 --- /dev/null +++ b/.pi/skills/payload/README.md @@ -0,0 +1,57 @@ +# Payload Skill for AI Coding Agents + +Agent skill providing comprehensive guidance for Payload development with TypeScript patterns, field configurations, hooks, access control, and API examples. + +## What's Included + +The `payload` skill provides expert guidance on: + +- **Collections**: Auth, uploads, drafts, live preview configurations +- **Fields**: All field types including relationships, arrays, blocks, joins, virtual fields +- **Hooks**: beforeChange, afterChange, beforeValidate, field hooks +- **Access Control**: Collection, field, and global access patterns including RBAC and multi-tenant +- **Queries**: Local API, REST, and GraphQL with complex operators +- **Database Adapters**: MongoDB, Postgres, SQLite configurations and transactions +- **Advanced Features**: Jobs queue, custom endpoints, localization, plugins + +## Usage + +Once installed, the Agent will automatically invoke the skill when you're working on Payload CMS projects. The skill activates when you: + +- Edit `payload.config.ts` files +- Work with collection or global configurations +- Ask about Payload-specific patterns +- Need guidance on fields, hooks, or access control + +You can also explicitly invoke it: + +``` +@payload how do I implement row-level access control? +``` + +## Documentation Structure + +``` +skills/payload/ +├── SKILL.md # Main skill file with quick reference +└── reference/ + ├── FIELDS.md # All field types and configurations + ├── COLLECTIONS.md # Collection patterns + ├── HOOKS.md # Hook patterns and examples + ├── ACCESS-CONTROL.md # Basic access control + ├── ACCESS-CONTROL-ADVANCED.md # Advanced access patterns + ├── QUERIES.md # Query patterns and APIs + ├── ADAPTERS.md # Database and storage adapters + └── ADVANCED.md # Jobs, endpoints, localization +``` + +## Resources + +- [Payload Documentation](https://payloadcms.com/docs) +- [GitHub Repository](https://github.com/payloadcms/payload) +- [Examples](https://github.com/payloadcms/payload/tree/main/examples) +- [Templates](https://github.com/payloadcms/payload/tree/main/templates) + +## License + +MIT diff --git a/.pi/skills/payload/SKILL.md b/.pi/skills/payload/SKILL.md new file mode 100644 index 0000000..5abccb4 --- /dev/null +++ b/.pi/skills/payload/SKILL.md @@ -0,0 +1,409 @@ +--- +name: payload +description: Use when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior. +--- + +# Payload Application Development + +Payload is a Next.js native CMS with TypeScript-first architecture, providing admin panel, database management, REST/GraphQL APIs, authentication, and file storage. + +## Quick Reference + +| Task | Solution | Details | +| ------------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Auto-generate slugs | `slugField()` | [FIELDS.md#slug-field-helper](reference/FIELDS.md#slug-field-helper) | +| Restrict content by user | Access control with query | [ACCESS-CONTROL.md#row-level-security-with-complex-queries](reference/ACCESS-CONTROL.md#row-level-security-with-complex-queries) | +| Local API user ops | `user` + `overrideAccess: false` | [QUERIES.md#access-control-in-local-api](reference/QUERIES.md#access-control-in-local-api) | +| Draft/publish workflow | `versions: { drafts: true }` | [COLLECTIONS.md#versioning--drafts](reference/COLLECTIONS.md#versioning--drafts) | +| Computed fields | `virtual: true` with afterRead | [FIELDS.md#virtual-fields](reference/FIELDS.md#virtual-fields) | +| Conditional fields | `admin.condition` | [FIELDS.md#conditional-fields](reference/FIELDS.md#conditional-fields) | +| Custom field validation | `validate` function | [FIELDS.md#text-field](reference/FIELDS.md#text-field) | +| Filter relationship list | `filterOptions` on field | [FIELDS.md#relationship](reference/FIELDS.md#relationship) | +| Select specific fields | `select` parameter | [QUERIES.md#local-api](reference/QUERIES.md#local-api) | +| Auto-set author/dates | beforeChange hook | [HOOKS.md#collection-hooks](reference/HOOKS.md#collection-hooks) | +| Prevent hook loops | `req.context` check | [HOOKS.md#hook-context](reference/HOOKS.md#hook-context) | +| Cascading deletes | beforeDelete hook | [HOOKS.md#collection-hooks](reference/HOOKS.md#collection-hooks) | +| Geospatial queries | `point` field with `near`/`within` | [FIELDS.md#point-geolocation](reference/FIELDS.md#point-geolocation) | +| Reverse relationships | `join` field type | [FIELDS.md#join-fields](reference/FIELDS.md#join-fields) | +| Next.js revalidation | Context control in afterChange | [HOOKS.md#nextjs-revalidation-with-context-control](reference/HOOKS.md#nextjs-revalidation-with-context-control) | +| Query by relationship | Nested property syntax | [QUERIES.md#nested-properties](reference/QUERIES.md#nested-properties) | +| Complex queries | AND/OR logic | [QUERIES.md#andor-logic](reference/QUERIES.md#andor-logic) | +| Transactions | Pass `req` to operations | [ADAPTERS.md#threading-req-through-operations](reference/ADAPTERS.md#threading-req-through-operations) | +| Background jobs | Jobs queue with tasks | [ADVANCED.md#jobs-queue](reference/ADVANCED.md#jobs-queue) | +| Custom API routes | Collection custom endpoints | [ADVANCED.md#custom-endpoints](reference/ADVANCED.md#custom-endpoints) | +| Cloud storage | Storage adapter plugins | [ADAPTERS.md#storage-adapters](reference/ADAPTERS.md#storage-adapters) | +| Multi-language | `localization` config + `localized: true` | [ADVANCED.md#localization](reference/ADVANCED.md#localization) | +| Create plugin | `(options) => (config) => Config` | [PLUGIN-DEVELOPMENT.md#plugin-architecture](reference/PLUGIN-DEVELOPMENT.md#plugin-architecture) | +| Plugin package setup | Package structure with SWC | [PLUGIN-DEVELOPMENT.md#plugin-package-structure](reference/PLUGIN-DEVELOPMENT.md#plugin-package-structure) | +| Add fields to collection | Map collections, spread fields | [PLUGIN-DEVELOPMENT.md#adding-fields-to-collections](reference/PLUGIN-DEVELOPMENT.md#adding-fields-to-collections) | +| Plugin hooks | Preserve existing hooks in array | [PLUGIN-DEVELOPMENT.md#adding-hooks](reference/PLUGIN-DEVELOPMENT.md#adding-hooks) | +| Check field type | Type guard functions | [FIELD-TYPE-GUARDS.md](reference/FIELD-TYPE-GUARDS.md) | + +## Quick Start + +```bash +npx create-payload-app@latest my-app +cd my-app +pnpm dev +``` + +### Minimal Config + +```ts +import { buildConfig } from 'payload' +import { mongooseAdapter } from '@payloadcms/db-mongodb' +import { lexicalEditor } from '@payloadcms/richtext-lexical' +import path from 'path' +import { fileURLToPath } from 'url' + +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + +export default buildConfig({ + admin: { + user: 'users', + importMap: { + baseDir: path.resolve(dirname), + }, + }, + collections: [Users, Media], + editor: lexicalEditor(), + secret: process.env.PAYLOAD_SECRET, + typescript: { + outputFile: path.resolve(dirname, 'payload-types.ts'), + }, + db: mongooseAdapter({ + url: process.env.DATABASE_URL, + }), +}) +``` + +## Essential Patterns + +### Basic Collection + +```ts +import type { CollectionConfig } from 'payload' + +export const Posts: CollectionConfig = { + slug: 'posts', + admin: { + useAsTitle: 'title', + defaultColumns: ['title', 'author', 'status', 'createdAt'], + }, + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'slug', type: 'text', unique: true, index: true }, + { name: 'content', type: 'richText' }, + { name: 'author', type: 'relationship', relationTo: 'users' }, + ], + timestamps: true, +} +``` + +For more collection patterns (auth, upload, drafts, live preview), see [COLLECTIONS.md](reference/COLLECTIONS.md). + +### Common Fields + +```ts +// Text field +{ name: 'title', type: 'text', required: true } + +// Relationship +{ name: 'author', type: 'relationship', relationTo: 'users', required: true } + +// Rich text +{ name: 'content', type: 'richText', required: true } + +// Select +{ name: 'status', type: 'select', options: ['draft', 'published'], defaultValue: 'draft' } + +// Upload +{ name: 'image', type: 'upload', relationTo: 'media' } +``` + +For all field types (array, blocks, point, join, virtual, conditional, etc.), see [FIELDS.md](reference/FIELDS.md). + +### Hook Example + +```ts +export const Posts: CollectionConfig = { + slug: 'posts', + hooks: { + beforeChange: [ + async ({ data, operation }) => { + if (operation === 'create') { + data.slug = slugify(data.title) + } + return data + }, + ], + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +For all hook patterns, see [HOOKS.md](reference/HOOKS.md). For access control, see [ACCESS-CONTROL.md](reference/ACCESS-CONTROL.md). + +### Access Control with Type Safety + +```ts +import type { Access } from 'payload' +import type { User } from '@/payload-types' + +// Type-safe access control +export const adminOnly: Access = ({ req }) => { + const user = req.user as User + return user?.roles?.includes('admin') || false +} + +// Row-level access control +export const ownPostsOnly: Access = ({ req }) => { + const user = req.user as User + if (!user) return false + if (user.roles?.includes('admin')) return true + + return { + author: { equals: user.id }, + } +} +``` + +### Query Example + +```ts +// Local API +const posts = await payload.find({ + collection: 'posts', + where: { + status: { equals: 'published' }, + 'author.name': { contains: 'john' }, + }, + depth: 2, + limit: 10, + sort: '-createdAt', +}) + +// Query with populated relationships +const post = await payload.findByID({ + collection: 'posts', + id: '123', + depth: 2, // Populates relationships (default is 2) +}) +// Returns: { author: { id: "user123", name: "John" } } + +// Without depth, relationships return IDs only +const post = await payload.findByID({ + collection: 'posts', + id: '123', + depth: 0, +}) +// Returns: { author: "user123" } +``` + +For all query operators and REST/GraphQL examples, see [QUERIES.md](reference/QUERIES.md). + +### Getting Payload Instance + +```ts +// In API routes (Next.js) +import { getPayload } from 'payload' +import config from '@payload-config' + +export async function GET() { + const payload = await getPayload({ config }) + + const posts = await payload.find({ + collection: 'posts', + }) + + return Response.json(posts) +} + +// In Server Components +import { getPayload } from 'payload' +import config from '@payload-config' + +export default async function Page() { + const payload = await getPayload({ config }) + const { docs } = await payload.find({ collection: 'posts' }) + + return
{docs.map(post =>

{post.title}

)}
+} +``` + +### Logger Usage + +```ts +// ✅ Valid: single string +payload.logger.error('Something went wrong') + +// ✅ Valid: object with msg and err +payload.logger.error({ msg: 'Failed to process', err: error }) + +// ❌ Invalid: don't pass error as second argument +payload.logger.error('Failed to process', error) + +// ❌ Invalid: use `err` not `error`, use `msg` not `message` +payload.logger.error({ message: 'Failed', error: error }) +``` + +## Security Pitfalls + +### 1. Local API Access Control (CRITICAL) + +**By default, Local API operations bypass ALL access control**, even when passing a user. + +```ts +// ❌ SECURITY BUG: Passes user but ignores their permissions +await payload.find({ + collection: 'posts', + user: someUser, // Access control is BYPASSED! +}) + +// ✅ SECURE: Actually enforces the user's permissions +await payload.find({ + collection: 'posts', + user: someUser, + overrideAccess: false, // REQUIRED for access control +}) +``` + +**When to use each:** + +- `overrideAccess: true` (default) - Server-side operations you trust (cron jobs, system tasks) +- `overrideAccess: false` - When operating on behalf of a user (API routes, webhooks) + +See [QUERIES.md#access-control-in-local-api](reference/QUERIES.md#access-control-in-local-api). + +### 2. Transaction Failures in Hooks + +**Nested operations in hooks without `req` break transaction atomicity.** + +```ts +// ❌ DATA CORRUPTION RISK: Separate transaction +hooks: { + afterChange: [ + async ({ doc, req }) => { + await req.payload.create({ + collection: 'audit-log', + data: { docId: doc.id }, + // Missing req - runs in separate transaction! + }) + }, + ] +} + +// ✅ ATOMIC: Same transaction +hooks: { + afterChange: [ + async ({ doc, req }) => { + await req.payload.create({ + collection: 'audit-log', + data: { docId: doc.id }, + req, // Maintains atomicity + }) + }, + ] +} +``` + +See [ADAPTERS.md#threading-req-through-operations](reference/ADAPTERS.md#threading-req-through-operations). + +### 3. Infinite Hook Loops + +**Hooks triggering operations that trigger the same hooks create infinite loops.** + +```ts +// ❌ INFINITE LOOP +hooks: { + afterChange: [ + async ({ doc, req }) => { + await req.payload.update({ + collection: 'posts', + id: doc.id, + data: { views: doc.views + 1 }, + req, + }) // Triggers afterChange again! + }, + ] +} + +// ✅ SAFE: Use context flag +hooks: { + afterChange: [ + async ({ doc, req, context }) => { + if (context.skipHooks) return + + await req.payload.update({ + collection: 'posts', + id: doc.id, + data: { views: doc.views + 1 }, + context: { skipHooks: true }, + req, + }) + }, + ] +} +``` + +See [HOOKS.md#context](reference/HOOKS.md#context). + +## Project Structure + +```txt +src/ +├── app/ +│ ├── (frontend)/ +│ │ └── page.tsx +│ └── (payload)/ +│ └── admin/[[...segments]]/page.tsx +├── collections/ +│ ├── Posts.ts +│ ├── Media.ts +│ └── Users.ts +├── globals/ +│ └── Header.ts +├── components/ +│ └── CustomField.tsx +├── hooks/ +│ └── slugify.ts +└── payload.config.ts +``` + +## Type Generation + +```ts +// payload.config.ts +export default buildConfig({ + typescript: { + outputFile: path.resolve(dirname, 'payload-types.ts'), + }, + // ... +}) + +// Usage +import type { Post, User } from '@/payload-types' +``` + +## Reference Documentation + +- **[FIELDS.md](reference/FIELDS.md)** - All field types, validation, admin options +- **[FIELD-TYPE-GUARDS.md](reference/FIELD-TYPE-GUARDS.md)** - Type guards for runtime field type checking and narrowing +- **[COLLECTIONS.md](reference/COLLECTIONS.md)** - Collection configs, auth, upload, drafts, live preview +- **[HOOKS.md](reference/HOOKS.md)** - Collection hooks, field hooks, context patterns +- **[ACCESS-CONTROL.md](reference/ACCESS-CONTROL.md)** - Collection, field, global access control, RBAC, multi-tenant +- **[ACCESS-CONTROL-ADVANCED.md](reference/ACCESS-CONTROL-ADVANCED.md)** - Context-aware, time-based, subscription-based access, factory functions, templates +- **[QUERIES.md](reference/QUERIES.md)** - Query operators, Local/REST/GraphQL APIs +- **[ENDPOINTS.md](reference/ENDPOINTS.md)** - Custom API endpoints: authentication, helpers, request/response patterns +- **[ADAPTERS.md](reference/ADAPTERS.md)** - Database, storage, email adapters, transactions +- **[ADVANCED.md](reference/ADVANCED.md)** - Authentication, jobs, endpoints, components, plugins, localization +- **[PLUGIN-DEVELOPMENT.md](reference/PLUGIN-DEVELOPMENT.md)** - Plugin architecture, monorepo structure, patterns, best practices + +## Resources + +- llms-full.txt: +- Docs: +- GitHub: +- Examples: +- Templates: diff --git a/.pi/skills/payload/reference/ACCESS-CONTROL-ADVANCED.md b/.pi/skills/payload/reference/ACCESS-CONTROL-ADVANCED.md new file mode 100644 index 0000000..ad164f2 --- /dev/null +++ b/.pi/skills/payload/reference/ACCESS-CONTROL-ADVANCED.md @@ -0,0 +1,704 @@ +# Payload Access Control - Advanced Patterns + +Advanced access control patterns including context-aware access, time-based restrictions, factory functions, and production templates. + +## Context-Aware Access Patterns + +### Locale-Specific Access + +Control access based on user locale for internationalized content. + +```ts +import type { Access } from 'payload' + +export const localeSpecificAccess: Access = ({ req: { user, locale } }) => { + // Authenticated users can access all locales + if (user) return true + + // Public users can only access English content + if (locale === 'en') return true + + return false +} + +// Usage in collection +export const Posts: CollectionConfig = { + slug: 'posts', + access: { + read: localeSpecificAccess, + }, + fields: [{ name: 'title', type: 'text', localized: true }], +} +``` + +**Source**: `docs/access-control/overview.mdx` (req.locale argument) + +### Device-Specific Access + +Restrict access based on device type or user agent. + +```ts +import type { Access } from 'payload' + +export const mobileOnlyAccess: Access = ({ req: { headers } }) => { + const userAgent = headers?.get('user-agent') || '' + return /mobile|android|iphone/i.test(userAgent) +} + +export const desktopOnlyAccess: Access = ({ req: { headers } }) => { + const userAgent = headers?.get('user-agent') || '' + return !/mobile|android|iphone/i.test(userAgent) +} + +// Usage +export const MobileContent: CollectionConfig = { + slug: 'mobile-content', + access: { + read: mobileOnlyAccess, + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +**Source**: Synthesized (headers pattern) + +### IP-Based Access + +Restrict access from specific IP addresses (requires middleware/proxy headers). + +```ts +import type { Access } from 'payload' + +export const restrictedIpAccess = (allowedIps: string[]): Access => { + return ({ req: { headers } }) => { + const ip = headers?.get('x-forwarded-for') || headers?.get('x-real-ip') + return allowedIps.includes(ip || '') + } +} + +// Usage +const internalIps = ['192.168.1.0/24', '10.0.0.5'] + +export const InternalDocs: CollectionConfig = { + slug: 'internal-docs', + access: { + read: restrictedIpAccess(internalIps), + }, + fields: [{ name: 'content', type: 'richText' }], +} +``` + +**Note**: Requires your server to pass IP address via headers (common with proxies/load balancers). + +**Source**: Synthesized (headers pattern) + +## Time-Based Access Patterns + +### Today's Records Only + +```ts +import type { Access } from 'payload' + +export const todayOnlyAccess: Access = ({ req: { user } }) => { + if (!user) return false + + const now = new Date() + const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()) + const endOfDay = new Date(startOfDay.getTime() + 24 * 60 * 60 * 1000) + + return { + createdAt: { + greater_than_equal: startOfDay.toISOString(), + less_than: endOfDay.toISOString(), + }, + } +} +``` + +**Source**: `test/access-control/config.ts` (query constraint patterns) + +### Recent Records (Last N Days) + +```ts +import type { Access } from 'payload' + +export const recentRecordsAccess = (days: number): Access => { + return ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + const cutoff = new Date() + cutoff.setDate(cutoff.getDate() - days) + + return { + createdAt: { + greater_than_equal: cutoff.toISOString(), + }, + } + } +} + +// Usage: Users see only last 30 days, admins see all +export const Logs: CollectionConfig = { + slug: 'logs', + access: { + read: recentRecordsAccess(30), + }, + fields: [{ name: 'message', type: 'text' }], +} +``` + +### Scheduled Content (Publish Date Range) + +```ts +import type { Access } from 'payload' + +export const scheduledContentAccess: Access = ({ req: { user } }) => { + // Editors see all content + if (user?.roles?.includes('admin') || user?.roles?.includes('editor')) { + return true + } + + const now = new Date().toISOString() + + // Public sees only content within publish window + return { + and: [ + { publishDate: { less_than_equal: now } }, + { + or: [{ unpublishDate: { exists: false } }, { unpublishDate: { greater_than: now } }], + }, + ], + } +} +``` + +**Source**: Synthesized (query constraint + date patterns) + +## Subscription-Based Access + +### Active Subscription Required + +```ts +import type { Access } from 'payload' + +export const activeSubscriptionAccess: Access = async ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + try { + const subscription = await req.payload.findByID({ + collection: 'subscriptions', + id: user.subscriptionId, + }) + + return subscription?.status === 'active' + } catch { + return false + } +} + +// Usage +export const PremiumContent: CollectionConfig = { + slug: 'premium-content', + access: { + read: activeSubscriptionAccess, + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +### Subscription Tier-Based Access + +```ts +import type { Access } from 'payload' + +export const tierBasedAccess = (requiredTier: string): Access => { + const tierHierarchy = ['free', 'basic', 'pro', 'enterprise'] + + return async ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + try { + const subscription = await req.payload.findByID({ + collection: 'subscriptions', + id: user.subscriptionId, + }) + + if (subscription?.status !== 'active') return false + + const userTierIndex = tierHierarchy.indexOf(subscription.tier) + const requiredTierIndex = tierHierarchy.indexOf(requiredTier) + + return userTierIndex >= requiredTierIndex + } catch { + return false + } + } +} + +// Usage +export const EnterpriseFeatures: CollectionConfig = { + slug: 'enterprise-features', + access: { + read: tierBasedAccess('enterprise'), + }, + fields: [{ name: 'feature', type: 'text' }], +} +``` + +**Source**: Synthesized (async + cross-collection pattern) + +## Factory Functions + +Reusable functions that generate access control configurations. + +### createRoleBasedAccess + +Generate access control for specific roles. + +```ts +import type { Access } from 'payload' + +export function createRoleBasedAccess(roles: string[]): Access { + return ({ req: { user } }) => { + if (!user) return false + return roles.some((role) => user.roles?.includes(role)) + } +} + +// Usage +const adminOrEditor = createRoleBasedAccess(['admin', 'editor']) +const moderatorAccess = createRoleBasedAccess(['admin', 'moderator']) + +export const Posts: CollectionConfig = { + slug: 'posts', + access: { + create: adminOrEditor, + update: adminOrEditor, + delete: moderatorAccess, + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +**Source**: `test/access-control/config.ts` + +### createOrgScopedAccess + +Generate organization-scoped access with optional admin bypass. + +```ts +import type { Access } from 'payload' + +export function createOrgScopedAccess(allowAdmin = true): Access { + return ({ req: { user } }) => { + if (!user) return false + if (allowAdmin && user.roles?.includes('admin')) return true + + return { + organizationId: { in: user.organizationIds || [] }, + } + } +} + +// Usage +const orgScoped = createOrgScopedAccess() // Admins bypass +const strictOrgScoped = createOrgScopedAccess(false) // Admins also scoped + +export const Projects: CollectionConfig = { + slug: 'projects', + access: { + read: orgScoped, + update: orgScoped, + delete: strictOrgScoped, + }, + fields: [ + { name: 'title', type: 'text' }, + { name: 'organizationId', type: 'text', required: true }, + ], +} +``` + +**Source**: `test/access-control/config.ts` + +### createTeamBasedAccess + +Generate team-scoped access with configurable field name. + +```ts +import type { Access } from 'payload' + +export function createTeamBasedAccess(teamField = 'teamId'): Access { + return ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + return { + [teamField]: { in: user.teamIds || [] }, + } + } +} + +// Usage with custom field name +const projectTeamAccess = createTeamBasedAccess('projectTeam') + +export const Tasks: CollectionConfig = { + slug: 'tasks', + access: { + read: projectTeamAccess, + update: projectTeamAccess, + }, + fields: [ + { name: 'title', type: 'text' }, + { name: 'projectTeam', type: 'text', required: true }, + ], +} +``` + +**Source**: Synthesized (org pattern variation) + +### createTimeLimitedAccess + +Generate access limited to records within specified days. + +```ts +import type { Access } from 'payload' + +export function createTimeLimitedAccess(daysAccess: number): Access { + return ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + const cutoff = new Date() + cutoff.setDate(cutoff.getDate() - daysAccess) + + return { + createdAt: { + greater_than_equal: cutoff.toISOString(), + }, + } + } +} + +// Usage: Users see 90 days, admins see all +export const ActivityLogs: CollectionConfig = { + slug: 'activity-logs', + access: { + read: createTimeLimitedAccess(90), + }, + fields: [{ name: 'action', type: 'text' }], +} +``` + +**Source**: Synthesized (time + query pattern) + +## Configuration Templates + +Complete collection configurations for common scenarios. + +### Basic Authenticated Collection + +```ts +import type { CollectionConfig } from 'payload' + +export const BasicCollection: CollectionConfig = { + slug: 'basic-collection', + access: { + create: ({ req: { user } }) => Boolean(user), + read: ({ req: { user } }) => Boolean(user), + update: ({ req: { user } }) => Boolean(user), + delete: ({ req: { user } }) => Boolean(user), + }, + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'content', type: 'richText' }, + ], +} +``` + +**Source**: `docs/access-control/collections.mdx` + +### Public + Authenticated Collection + +```ts +import type { CollectionConfig } from 'payload' + +export const PublicAuthCollection: CollectionConfig = { + slug: 'posts', + access: { + // Only admins/editors can create + create: ({ req: { user } }) => { + return user?.roles?.some((role) => ['admin', 'editor'].includes(role)) || false + }, + + // Authenticated users see all, public sees only published + read: ({ req: { user } }) => { + if (user) return true + return { _status: { equals: 'published' } } + }, + + // Only admins/editors can update + update: ({ req: { user } }) => { + return user?.roles?.some((role) => ['admin', 'editor'].includes(role)) || false + }, + + // Only admins can delete + delete: ({ req: { user } }) => { + return user?.roles?.includes('admin') || false + }, + }, + versions: { + drafts: true, + }, + fields: [ + { name: 'title', type: 'text', required: true }, + { name: 'content', type: 'richText', required: true }, + { name: 'author', type: 'relationship', relationTo: 'users' }, + ], +} +``` + +**Source**: `templates/website/src/collections/Posts/index.ts` + +### Multi-User/Self-Service Collection + +```ts +import type { CollectionConfig } from 'payload' + +export const SelfServiceCollection: CollectionConfig = { + slug: 'users', + auth: true, + access: { + // Admins can create users + create: ({ req: { user } }) => user?.roles?.includes('admin') || false, + + // Anyone can read user profiles + read: () => true, + + // Users can update self, admins can update anyone + update: ({ req: { user }, id }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + return user.id === id + }, + + // Only admins can delete + delete: ({ req: { user } }) => user?.roles?.includes('admin') || false, + }, + fields: [ + { name: 'name', type: 'text', required: true }, + { name: 'email', type: 'email', required: true }, + { + name: 'roles', + type: 'select', + hasMany: true, + options: ['admin', 'editor', 'user'], + access: { + // Only admins can read/update roles + read: ({ req: { user } }) => user?.roles?.includes('admin') || false, + update: ({ req: { user } }) => user?.roles?.includes('admin') || false, + }, + }, + ], +} +``` + +**Source**: `templates/website/src/collections/Users/index.ts` + +## Debugging Tips + +### Log Access Check Execution + +```ts +export const debugAccess: Access = ({ req: { user }, id }) => { + console.log('Access check:', { + userId: user?.id, + userRoles: user?.roles, + docId: id, + timestamp: new Date().toISOString(), + }) + return true +} +``` + +### Verify Arguments Availability + +```ts +export const checkArgsAccess: Access = (args) => { + console.log('Available arguments:', { + hasReq: 'req' in args, + hasUser: args.req?.user ? 'yes' : 'no', + hasId: args.id ? 'provided' : 'undefined', + hasData: args.data ? 'provided' : 'undefined', + }) + return true +} +``` + +### Measure Async Operation Timing + +```ts +export const timedAsyncAccess: Access = async ({ req }) => { + const start = Date.now() + + const result = await fetch('https://auth-service.example.com/validate', { + headers: { userId: req.user?.id }, + }) + + console.log(`Access check took ${Date.now() - start}ms`) + + return result.ok +} +``` + +### Test Access Without User + +```ts +// In test/development +const testAccess = await payload.find({ + collection: 'posts', + overrideAccess: false, // Enforce access control + user: undefined, // Simulate no user +}) + +console.log('Public access result:', testAccess.docs.length) +``` + +**Source**: Synthesized (debugging best practices) + +## Performance Considerations + +### Async Operations Impact + +```ts +// ❌ Slow: Multiple sequential async calls +export const slowAccess: Access = async ({ req: { user } }) => { + const org = await req.payload.findByID({ collection: 'orgs', id: user.orgId }) + const team = await req.payload.findByID({ collection: 'teams', id: user.teamId }) + const subscription = await req.payload.findByID({ collection: 'subs', id: user.subId }) + + return org.active && team.active && subscription.active +} + +// ✅ Fast: Use query constraints or cache in context +export const fastAccess: Access = ({ req: { user, context } }) => { + // Cache expensive lookups + if (!context.orgStatus) { + context.orgStatus = checkOrgStatus(user.orgId) + } + + return context.orgStatus +} +``` + +### Query Constraint Optimization + +```ts +// ❌ Avoid: Non-indexed fields in constraints +export const slowQuery: Access = () => ({ + 'metadata.internalCode': { equals: 'ABC123' }, // Slow if not indexed +}) + +// ✅ Better: Use indexed fields +export const fastQuery: Access = () => ({ + status: { equals: 'active' }, // Indexed field + organizationId: { in: ['org1', 'org2'] }, // Indexed field +}) +``` + +### Field Access on Large Arrays + +```ts +// ❌ Slow: Complex access on array fields +const arrayField: ArrayField = { + name: 'items', + type: 'array', + fields: [ + { + name: 'secretData', + type: 'text', + access: { + read: async ({ req }) => { + // Async call runs for EVERY array item + const result = await expensiveCheck() + return result + }, + }, + }, + ], +} + +// ✅ Fast: Simple checks or cache result +const optimizedArrayField: ArrayField = { + name: 'items', + type: 'array', + fields: [ + { + name: 'secretData', + type: 'text', + access: { + read: ({ req: { user }, context }) => { + // Cache once, reuse for all items + if (context.canReadSecret === undefined) { + context.canReadSecret = user?.roles?.includes('admin') + } + return context.canReadSecret + }, + }, + }, + ], +} +``` + +### Avoid N+1 Queries + +```ts +// ❌ N+1 Problem: Query per access check +export const n1Access: Access = async ({ req, id }) => { + // Runs for EACH document in list + const doc = await req.payload.findByID({ collection: 'docs', id }) + return doc.isPublic +} + +// ✅ Better: Use query constraint to filter at DB level +export const efficientAccess: Access = () => { + return { isPublic: { equals: true } } +} +``` + +**Performance Best Practices:** + +1. **Minimize Async Operations**: Use query constraints over async lookups when possible +2. **Cache Expensive Checks**: Store results in `req.context` for reuse +3. **Index Query Fields**: Ensure fields in query constraints are indexed +4. **Avoid Complex Logic in Array Fields**: Simple boolean checks preferred +5. **Use Query Constraints**: Let database filter rather than loading all records + +**Source**: Synthesized (operational best practices) + +## Enhanced Best Practices + +Comprehensive security and implementation guidelines: + +1. **Default Deny**: Start with restrictive access, gradually add permissions +2. **Type Guards**: Use TypeScript for user type safety and better IDE support +3. **Validate Data**: Never trust frontend-provided IDs or data +4. **Async for Critical Checks**: Use async operations for important security decisions +5. **Consistent Logic**: Apply same rules at field and collection levels +6. **Test Edge Cases**: Test with no user, wrong user, admin user scenarios +7. **Monitor Access**: Log failed access attempts for security review +8. **Regular Audit**: Review access rules quarterly or after major changes +9. **Cache Wisely**: Use `req.context` for expensive operations +10. **Document Intent**: Add comments explaining complex access rules +11. **Avoid Secrets in Client**: Never expose sensitive logic to client-side +12. **Rate Limit External Calls**: Protect against DoS on external validation services +13. **Handle Errors Gracefully**: Access functions should return `false` on error, not throw +14. **Use Environment Vars**: Store configuration (IPs, API keys) in env vars +15. **Test Local API**: Remember to set `overrideAccess: false` when testing +16. **Consider Performance**: Measure impact of async operations on login time +17. **Version Control**: Track access control changes in git history +18. **Principle of Least Privilege**: Grant minimum access required for functionality + +**Sources**: `docs/access-control/*.mdx`, synthesized best practices diff --git a/.pi/skills/payload/reference/ACCESS-CONTROL.md b/.pi/skills/payload/reference/ACCESS-CONTROL.md new file mode 100644 index 0000000..39571f5 --- /dev/null +++ b/.pi/skills/payload/reference/ACCESS-CONTROL.md @@ -0,0 +1,697 @@ +# Payload Access Control Reference + +Complete reference for access control patterns across collections, fields, and globals. + +## At a Glance + +| Feature | Scope | Returns | Use Case | +| --------------------- | --------------------------------------------------------- | ---------------------- | ---------------------------------- | +| **Collection Access** | create, read, update, delete, admin, unlock, readVersions | boolean \| Where query | Document-level permissions | +| **Field Access** | create, read, update | boolean only | Field-level visibility/editability | +| **Global Access** | read, update, readVersions | boolean \| Where query | Global document permissions | + +## Three Layers of Access Control + +Payload provides three distinct access control layers: + +1. **Collection-Level**: Controls operations on entire documents (create, read, update, delete, admin, unlock, readVersions) +2. **Field-Level**: Controls access to individual fields (create, read, update) +3. **Global-Level**: Controls access to global documents (read, update, readVersions) + +## Return Value Types + +Access control functions can return: + +- **Boolean**: `true` (allow) or `false` (deny) +- **Query Constraint**: `Where` object for row-level security (collection-level only) + +Field-level access does NOT support query constraints - only boolean returns. + +## Operation Decision Tree + +```txt +User makes request + │ + ├─ Collection access check + │ ├─ Returns false? → Deny entire operation + │ ├─ Returns true? → Continue + │ └─ Returns Where? → Apply query constraint + │ + ├─ Field access check (if applicable) + │ ├─ Returns false? → Field omitted from result + │ └─ Returns true? → Include field + │ + └─ Operation completed +``` + +## Collection Access Control + +### Basic Patterns + +```ts +import type { CollectionConfig, Access } from 'payload' + +export const Posts: CollectionConfig = { + slug: 'posts', + access: { + // Boolean: Only authenticated users can create + create: ({ req: { user } }) => Boolean(user), + + // Query constraint: Public sees published, users see all + read: ({ req: { user } }) => { + if (user) return true + return { status: { equals: 'published' } } + }, + + // User-specific: Admins or document owner + update: ({ req: { user }, id }) => { + if (user?.roles?.includes('admin')) return true + return { author: { equals: user?.id } } + }, + + // Async: Check related data + delete: async ({ req, id }) => { + const hasComments = await req.payload.count({ + collection: 'comments', + where: { post: { equals: id } }, + }) + return hasComments === 0 + }, + + // Admin panel visibility + admin: ({ req: { user } }) => { + return user?.roles?.includes('admin') || user?.roles?.includes('editor') + }, + }, + fields: [ + { name: 'title', type: 'text' }, + { name: 'status', type: 'select', options: ['draft', 'published'] }, + { name: 'author', type: 'relationship', relationTo: 'users' }, + ], +} +``` + +### Role-Based Access Control (RBAC) Pattern + +Payload does NOT provide a roles system by default. The following is a commonly accepted pattern for implementing role-based access control in auth collections: + +```ts +import type { CollectionConfig } from 'payload' + +export const Users: CollectionConfig = { + slug: 'users', + auth: true, + fields: [ + { name: 'name', type: 'text', required: true }, + { name: 'email', type: 'email', required: true }, + { + name: 'roles', + type: 'select', + hasMany: true, + options: ['admin', 'editor', 'user'], + defaultValue: ['user'], + required: true, + // Save roles to JWT for access control without database lookups + saveToJWT: true, + access: { + // Only admins can update roles + update: ({ req: { user } }) => user?.roles?.includes('admin'), + }, + }, + ], +} +``` + +**Important Notes:** + +1. **Not Built-In**: Payload does not provide a roles system out of the box. You must add a `roles` field to your auth collection. +2. **Save to JWT**: Use `saveToJWT: true` to include roles in the JWT token, enabling role checks without database queries. +3. **Default Value**: Set a `defaultValue` to automatically assign new users a default role. +4. **Access Control**: Restrict who can modify roles (typically only admins). +5. **Role Options**: Define your own role hierarchy based on your application needs. + +**Using Roles in Access Control:** + +```ts +import type { Access } from 'payload' + +// Check for specific role +export const adminOnly: Access = ({ req: { user } }) => { + return user?.roles?.includes('admin') +} + +// Check for multiple roles +export const adminOrEditor: Access = ({ req: { user } }) => { + return Boolean(user?.roles?.some((role) => ['admin', 'editor'].includes(role))) +} + +// Role hierarchy check +export const hasMinimumRole: Access = ({ req: { user } }, minRole: string) => { + const roleHierarchy = ['user', 'editor', 'admin'] + const userHighestRole = Math.max(...(user?.roles?.map((r) => roleHierarchy.indexOf(r)) || [-1])) + const requiredRoleIndex = roleHierarchy.indexOf(minRole) + + return userHighestRole >= requiredRoleIndex +} +``` + +### Reusable Access Functions + +```ts +import type { Access } from 'payload' + +// Anyone (public) +export const anyone: Access = () => true + +// Authenticated only +export const authenticated: Access = ({ req: { user } }) => Boolean(user) + +// Authenticated or published content +export const authenticatedOrPublished: Access = ({ req: { user } }) => { + if (user) return true + return { _status: { equals: 'published' } } +} + +// Admin only +export const admins: Access = ({ req: { user } }) => { + return user?.roles?.includes('admin') +} + +// Admin or editor +export const adminsOrEditors: Access = ({ req: { user } }) => { + return Boolean(user?.roles?.some((role) => ['admin', 'editor'].includes(role))) +} + +// Self or admin +export const adminsOrSelf: Access = ({ req: { user } }) => { + if (user?.roles?.includes('admin')) return true + return { id: { equals: user?.id } } +} + +// Usage +export const Posts: CollectionConfig = { + slug: 'posts', + access: { + create: authenticated, + read: authenticatedOrPublished, + update: adminsOrEditors, + delete: admins, + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +### Row-Level Security with Complex Queries + +```ts +import type { Access } from 'payload' + +// Organization-scoped access +export const organizationScoped: Access = ({ req: { user } }) => { + if (user?.roles?.includes('admin')) return true + + // Users see only their organization's data + return { + organization: { + equals: user?.organization, + }, + } +} + +// Multiple conditions with AND +export const complexAccess: Access = ({ req: { user } }) => { + return { + and: [ + { status: { equals: 'published' } }, + { 'author.isActive': { equals: true } }, + { + or: [{ visibility: { equals: 'public' } }, { author: { equals: user?.id } }], + }, + ], + } +} + +// Team-based access +export const teamMemberAccess: Access = ({ req: { user } }) => { + if (!user) return false + if (user.roles?.includes('admin')) return true + + return { + 'team.members': { + contains: user.id, + }, + } +} +``` + +### Header-Based Access (API Keys) + +```ts +import type { Access } from 'payload' + +export const apiKeyAccess: Access = ({ req }) => { + const apiKey = req.headers.get('x-api-key') + + if (!apiKey) return false + + // Validate against stored keys + return apiKey === process.env.VALID_API_KEY +} + +// Bearer token validation +export const bearerTokenAccess: Access = async ({ req }) => { + const auth = req.headers.get('authorization') + + if (!auth?.startsWith('Bearer ')) return false + + const token = auth.slice(7) + const isValid = await validateToken(token) + + return isValid +} +``` + +## Field Access Control + +Field access does NOT support query constraints - only boolean returns. + +### Basic Field Access + +```ts +import type { NumberField, FieldAccess } from 'payload' + +const salaryReadAccess: FieldAccess = ({ req: { user }, doc }) => { + // Self can read own salary + if (user?.id === doc?.id) return true + // Admin can read all salaries + return user?.roles?.includes('admin') +} + +const salaryUpdateAccess: FieldAccess = ({ req: { user } }) => { + // Only admins can update salary + return user?.roles?.includes('admin') +} + +const salaryField: NumberField = { + name: 'salary', + type: 'number', + access: { + read: salaryReadAccess, + update: salaryUpdateAccess, + }, +} +``` + +### Sibling Data Access + +```ts +import type { ArrayField, FieldAccess } from 'payload' + +const contentReadAccess: FieldAccess = ({ req: { user }, siblingData }) => { + // Authenticated users see all + if (user) return true + // Public sees only if marked public + return siblingData?.isPublic === true +} + +const arrayField: ArrayField = { + name: 'sections', + type: 'array', + fields: [ + { + name: 'isPublic', + type: 'checkbox', + defaultValue: false, + }, + { + name: 'content', + type: 'text', + access: { + read: contentReadAccess, + }, + }, + ], +} +``` + +### Nested Field Access + +```ts +import type { GroupField, FieldAccess } from 'payload' + +const internalOnlyAccess: FieldAccess = ({ req: { user } }) => { + return user?.roles?.includes('admin') || user?.roles?.includes('internal') +} + +const groupField: GroupField = { + name: 'internalMetadata', + type: 'group', + access: { + read: internalOnlyAccess, + update: internalOnlyAccess, + }, + fields: [ + { name: 'internalNotes', type: 'textarea' }, + { name: 'priority', type: 'select', options: ['low', 'medium', 'high'] }, + ], +} +``` + +### Hiding Admin Fields + +```ts +import type { CollectionConfig } from 'payload' + +export const Users: CollectionConfig = { + slug: 'users', + auth: true, + fields: [ + { name: 'name', type: 'text', required: true }, + { name: 'email', type: 'email', required: true }, + { + name: 'roles', + type: 'select', + hasMany: true, + options: ['admin', 'editor', 'user'], + access: { + // Hide from UI, but still saved/queried + read: ({ req: { user } }) => user?.roles?.includes('admin'), + // Only admins can update roles + update: ({ req: { user } }) => user?.roles?.includes('admin'), + }, + }, + ], +} +``` + +## Global Access Control + +```ts +import type { GlobalConfig, Access } from 'payload' + +const adminOnly: Access = ({ req: { user } }) => { + return user?.roles?.includes('admin') +} + +export const SiteSettings: GlobalConfig = { + slug: 'site-settings', + access: { + read: () => true, // Anyone can read settings + update: adminOnly, // Only admins can update + readVersions: adminOnly, // Only admins can see version history + }, + fields: [ + { name: 'siteName', type: 'text' }, + { name: 'maintenanceMode', type: 'checkbox' }, + ], +} +``` + +## Multi-Tenant Access Control + +```ts +import type { Access, CollectionConfig } from 'payload' + +// Add tenant field to user type +interface User { + id: string + tenantId: string + roles?: string[] +} + +// Tenant-scoped access +const tenantAccess: Access = ({ req: { user } }) => { + // No user = no access + if (!user) return false + + // Super admin sees all + if (user.roles?.includes('super-admin')) return true + + // Users see only their tenant's data + return { + tenant: { + equals: (user as User).tenantId, + }, + } +} + +export const Posts: CollectionConfig = { + slug: 'posts', + access: { + create: tenantAccess, + read: tenantAccess, + update: tenantAccess, + delete: tenantAccess, + }, + fields: [ + { name: 'title', type: 'text' }, + { + name: 'tenant', + type: 'text', + required: true, + access: { + // Tenant field hidden from non-admins + update: ({ req: { user } }) => user?.roles?.includes('super-admin'), + }, + hooks: { + // Auto-set tenant on create + beforeChange: [ + ({ req, operation, value }) => { + if (operation === 'create' && !value) { + return (req.user as User)?.tenantId + } + return value + }, + ], + }, + }, + ], +} +``` + +## Auth Collection Patterns + +### Self or Admin Pattern + +```ts +import type { CollectionConfig } from 'payload' + +export const Users: CollectionConfig = { + slug: 'users', + auth: true, + access: { + // Anyone can read user profiles + read: () => true, + + // Users can update themselves, admins can update anyone + update: ({ req: { user }, id }) => { + if (user?.roles?.includes('admin')) return true + return user?.id === id + }, + + // Only admins can delete + delete: ({ req: { user } }) => user?.roles?.includes('admin'), + }, + fields: [ + { name: 'name', type: 'text' }, + { name: 'email', type: 'email' }, + ], +} +``` + +### Restrict Self-Updates + +```ts +import type { CollectionConfig, FieldAccess } from 'payload' + +const preventSelfRoleChange: FieldAccess = ({ req: { user }, id }) => { + // Admins can change anyone's roles + if (user?.roles?.includes('admin')) return true + // Users cannot change their own roles + if (user?.id === id) return false + return false +} + +export const Users: CollectionConfig = { + slug: 'users', + auth: true, + fields: [ + { + name: 'roles', + type: 'select', + hasMany: true, + options: ['admin', 'editor', 'user'], + access: { + update: preventSelfRoleChange, + }, + }, + ], +} +``` + +## Cross-Collection Validation + +```ts +import type { Access } from 'payload' + +// Check if user is a project member before allowing access +export const projectMemberAccess: Access = async ({ req, id }) => { + const { user, payload } = req + + if (!user) return false + if (user.roles?.includes('admin')) return true + + // Check if document exists and user is member + const project = await payload.findByID({ + collection: 'projects', + id: id as string, + depth: 0, + }) + + return project.members?.includes(user.id) +} + +// Prevent deletion if document has dependencies +export const preventDeleteWithDependencies: Access = async ({ req, id }) => { + const { payload } = req + + const dependencyCount = await payload.count({ + collection: 'related-items', + where: { + parent: { equals: id }, + }, + }) + + return dependencyCount === 0 +} +``` + +## Access Control Function Arguments + +### Collection Create + +```ts +create: ({ req, data }) => boolean | Where + +// req: PayloadRequest +// - req.user: Authenticated user (if any) +// - req.payload: Payload instance for queries +// - req.headers: Request headers +// - req.locale: Current locale +// data: The data being created +``` + +### Collection Read + +```ts +read: ({ req, id }) => boolean | Where + +// req: PayloadRequest +// id: Document ID being read +// - undefined during Access Operation (login check) +// - string when reading specific document +``` + +### Collection Update + +```ts +update: ({ req, id, data }) => boolean | Where + +// req: PayloadRequest +// id: Document ID being updated +// data: New values being applied +``` + +### Collection Delete + +```ts +delete: ({ req, id }) => boolean | Where + +// req: PayloadRequest +// id: Document ID being deleted +``` + +### Field Create + +```ts +access: { + create: ({ req, data, siblingData }) => boolean +} + +// req: PayloadRequest +// data: Full document data +// siblingData: Adjacent field values at same level +``` + +### Field Read + +```ts +access: { + read: ({ req, id, doc, siblingData }) => boolean +} + +// req: PayloadRequest +// id: Document ID +// doc: Full document +// siblingData: Adjacent field values +``` + +### Field Update + +```ts +access: { + update: ({ req, id, data, doc, siblingData }) => boolean +} + +// req: PayloadRequest +// id: Document ID +// data: New values +// doc: Current document +// siblingData: Adjacent field values +``` + +## Important Notes + +1. **Local API Default**: Access control is **skipped by default** in Local API (`overrideAccess: true`). When passing a `user` parameter, you almost always want to set `overrideAccess: false` to respect that user's permissions: + + ```ts + // ❌ WRONG: Passes user but bypasses access control (default behavior) + await payload.find({ + collection: 'posts', + user: someUser, // User is ignored for access control! + }) + + // ✅ CORRECT: Respects the user's permissions + await payload.find({ + collection: 'posts', + user: someUser, + overrideAccess: false, // Required to enforce access control + }) + ``` + + **Why this matters**: If you pass `user` without `overrideAccess: false`, the operation runs with admin privileges regardless of the user's actual permissions. This is a common security mistake. + +2. **Field Access Limitations**: Field-level access does NOT support query constraints - only boolean returns. + +3. **Admin Panel Visibility**: The `admin` access control determines if a collection appears in the admin panel for a user. + +4. **Access Before Hooks**: Access control executes BEFORE hooks run, so hooks cannot modify access behavior. + +5. **Query Constraints**: Only collection-level `read` access supports query constraints. All other operations and field-level access require boolean returns. + +## Best Practices + +1. **Reusable Functions**: Create named access functions for common patterns +2. **Fail Secure**: Default to `false` for sensitive operations +3. **Cache Checks**: Use `req.context` to cache expensive validation +4. **Type Safety**: Type your user object for better IDE support +5. **Test Thoroughly**: Write tests for complex access control logic +6. **Document Intent**: Add comments explaining access rules +7. **Audit Logs**: Track access control decisions for security review +8. **Performance**: Avoid N+1 queries in access functions +9. **Error Handling**: Access functions should not throw - return `false` instead +10. **Tenant Hooks**: Auto-set tenant fields in `beforeChange` hooks + +## Advanced Patterns + +For advanced access control patterns including context-aware access, time-based restrictions, subscription-based access, factory functions, configuration templates, debugging tips, and performance optimization, see [ACCESS-CONTROL-ADVANCED.md](ACCESS-CONTROL-ADVANCED.md). diff --git a/.pi/skills/payload/reference/ADAPTERS.md b/.pi/skills/payload/reference/ADAPTERS.md new file mode 100644 index 0000000..64d0f10 --- /dev/null +++ b/.pi/skills/payload/reference/ADAPTERS.md @@ -0,0 +1,326 @@ +# Payload Adapters Reference + +Complete reference for database, storage, and email adapters. + +## Database Adapters + +### MongoDB + +```ts +import { mongooseAdapter } from '@payloadcms/db-mongodb' + +export default buildConfig({ + db: mongooseAdapter({ + url: process.env.DATABASE_URL, + }), +}) +``` + +### Postgres + +```ts +import { postgresAdapter } from '@payloadcms/db-postgres' + +export default buildConfig({ + db: postgresAdapter({ + pool: { + connectionString: process.env.DATABASE_URL, + }, + push: false, // Don't auto-push schema changes + migrationDir: './migrations', + }), +}) +``` + +### SQLite + +```ts +import { sqliteAdapter } from '@payloadcms/db-sqlite' + +export default buildConfig({ + db: sqliteAdapter({ + client: { + url: 'file:./payload.db', + }, + transactionOptions: {}, // Enable transactions (disabled by default) + }), +}) +``` + +## Transactions + +Payload automatically uses transactions for all-or-nothing database operations. Pass `req` to include operations in the same transaction. + +```ts +import type { CollectionAfterChangeHook } from 'payload' + +const afterChange: CollectionAfterChangeHook = async ({ req, doc }) => { + // This will be part of the same transaction + await req.payload.create({ + req, // Pass req to use same transaction + collection: 'audit-log', + data: { action: 'created', docId: doc.id }, + }) +} + +// Manual transaction control +const transactionID = await payload.db.beginTransaction() +try { + await payload.create({ + collection: 'orders', + data: orderData, + req: { transactionID }, + }) + await payload.update({ + collection: 'inventory', + id: itemId, + data: { stock: newStock }, + req: { transactionID }, + }) + await payload.db.commitTransaction(transactionID) +} catch (error) { + await payload.db.rollbackTransaction(transactionID) + throw error +} +``` + +**Note**: MongoDB requires replicaset for transactions. SQLite requires `transactionOptions: {}` to enable. + +### Threading req Through Operations + +**Critical**: When performing nested operations in hooks, always pass `req` to maintain transaction context. Failing to do so breaks atomicity and can cause partial updates. + +```ts +import type { CollectionAfterChangeHook } from 'payload' + +// ✅ CORRECT: Thread req through nested operations +const resaveChildren: CollectionAfterChangeHook = async ({ collection, doc, req }) => { + // Find children - pass req + const children = await req.payload.find({ + collection: 'children', + where: { parent: { equals: doc.id } }, + req, // Maintains transaction context + }) + + // Update each child - pass req + for (const child of children.docs) { + await req.payload.update({ + id: child.id, + collection: 'children', + data: { updatedField: 'value' }, + req, // Same transaction as parent operation + }) + } +} + +// ❌ WRONG: Missing req breaks transaction +const brokenHook: CollectionAfterChangeHook = async ({ collection, doc, req }) => { + const children = await req.payload.find({ + collection: 'children', + where: { parent: { equals: doc.id } }, + // Missing req - separate transaction or no transaction + }) + + for (const child of children.docs) { + await req.payload.update({ + id: child.id, + collection: 'children', + data: { updatedField: 'value' }, + // Missing req - if parent operation fails, these updates persist + }) + } +} +``` + +**Why This Matters:** + +- **MongoDB (with replica sets)**: Creates atomic session across operations +- **PostgreSQL**: All operations use same Drizzle transaction +- **SQLite (with transactions enabled)**: Ensures rollback on errors +- **Without req**: Each operation runs independently, breaking atomicity + +**When req is Required:** + +- All mutating operations in hooks (create, update, delete) +- Operations that must succeed/fail together +- When using MongoDB replica sets or Postgres +- Any operation that relies on `req.context` or `req.user` + +**When req is Optional:** + +- Read-only lookups independent of current transaction +- Operations with `disableTransaction: true` +- Administrative operations with `overrideAccess: true` + +## Storage Adapters + +Available storage adapters: + +- **@payloadcms/storage-s3** - AWS S3 +- **@payloadcms/storage-azure** - Azure Blob Storage +- **@payloadcms/storage-gcs** - Google Cloud Storage +- **@payloadcms/storage-r2** - Cloudflare R2 +- **@payloadcms/storage-vercel-blob** - Vercel Blob +- **@payloadcms/storage-uploadthing** - Uploadthing + +### AWS S3 + +```ts +import { s3Storage } from '@payloadcms/storage-s3' + +export default buildConfig({ + plugins: [ + s3Storage({ + collections: { + media: true, + }, + bucket: process.env.S3_BUCKET, + config: { + credentials: { + accessKeyId: process.env.S3_ACCESS_KEY_ID, + secretAccessKey: process.env.S3_SECRET_ACCESS_KEY, + }, + region: process.env.S3_REGION, + }, + }), + ], +}) +``` + +### Azure Blob Storage + +```ts +import { azureStorage } from '@payloadcms/storage-azure' + +export default buildConfig({ + plugins: [ + azureStorage({ + collections: { + media: true, + }, + connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING, + containerName: process.env.AZURE_STORAGE_CONTAINER_NAME, + }), + ], +}) +``` + +### Google Cloud Storage + +```ts +import { gcsStorage } from '@payloadcms/storage-gcs' + +export default buildConfig({ + plugins: [ + gcsStorage({ + collections: { + media: true, + }, + bucket: process.env.GCS_BUCKET, + options: { + projectId: process.env.GCS_PROJECT_ID, + credentials: JSON.parse(process.env.GCS_CREDENTIALS), + }, + }), + ], +}) +``` + +### Cloudflare R2 + +```ts +import { r2Storage } from '@payloadcms/storage-r2' + +export default buildConfig({ + plugins: [ + r2Storage({ + collections: { + media: true, + }, + bucket: process.env.R2_BUCKET, + config: { + credentials: { + accessKeyId: process.env.R2_ACCESS_KEY_ID, + secretAccessKey: process.env.R2_SECRET_ACCESS_KEY, + }, + region: 'auto', + endpoint: process.env.R2_ENDPOINT, + }, + }), + ], +}) +``` + +### Vercel Blob + +```ts +import { vercelBlobStorage } from '@payloadcms/storage-vercel-blob' + +export default buildConfig({ + plugins: [ + vercelBlobStorage({ + collections: { + media: true, + }, + token: process.env.BLOB_READ_WRITE_TOKEN, + }), + ], +}) +``` + +### Uploadthing + +```ts +import { uploadthingStorage } from '@payloadcms/storage-uploadthing' + +export default buildConfig({ + plugins: [ + uploadthingStorage({ + collections: { + media: true, + }, + options: { + token: process.env.UPLOADTHING_TOKEN, + acl: 'public-read', + }, + }), + ], +}) +``` + +## Email Adapters + +### Nodemailer (SMTP) + +```ts +import { nodemailerAdapter } from '@payloadcms/email-nodemailer' + +export default buildConfig({ + email: nodemailerAdapter({ + defaultFromAddress: 'noreply@example.com', + defaultFromName: 'My App', + transportOptions: { + host: process.env.SMTP_HOST, + port: 587, + auth: { + user: process.env.SMTP_USER, + pass: process.env.SMTP_PASS, + }, + }, + }), +}) +``` + +### Resend + +```ts +import { resendAdapter } from '@payloadcms/email-resend' + +export default buildConfig({ + email: resendAdapter({ + defaultFromAddress: 'noreply@example.com', + defaultFromName: 'My App', + apiKey: process.env.RESEND_API_KEY, + }), +}) +``` diff --git a/.pi/skills/payload/reference/ADVANCED.md b/.pi/skills/payload/reference/ADVANCED.md new file mode 100644 index 0000000..ce5e359 --- /dev/null +++ b/.pi/skills/payload/reference/ADVANCED.md @@ -0,0 +1,386 @@ +# Payload Advanced Features + +Complete reference for authentication, jobs, custom endpoints, components, plugins, and localization. + +## Authentication + +### Login + +```ts +// REST API +const response = await fetch('/api/users/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + email: 'user@example.com', + password: 'password', + }), +}) + +// Local API +const result = await payload.login({ + collection: 'users', + data: { + email: 'user@example.com', + password: 'password', + }, +}) +``` + +### Forgot Password + +```ts +await payload.forgotPassword({ + collection: 'users', + data: { + email: 'user@example.com', + }, +}) +``` + +### Custom Strategy + +```ts +import type { CollectionConfig, Strategy } from 'payload' + +const customStrategy: Strategy = { + name: 'custom', + authenticate: async ({ payload, headers }) => { + const token = headers.get('authorization')?.split(' ')[1] + if (!token) return { user: null } + + const user = await verifyToken(token) + return { user } + }, +} + +export const Users: CollectionConfig = { + slug: 'users', + auth: { + strategies: [customStrategy], + }, + fields: [], +} +``` + +### API Keys + +```ts +import type { CollectionConfig } from 'payload' + +export const APIKeys: CollectionConfig = { + slug: 'api-keys', + auth: { + disableLocalStrategy: true, + useAPIKey: true, + }, + fields: [], +} +``` + +## Jobs Queue + +Offload long-running or scheduled tasks to background workers. + +### Tasks + +```ts +import { buildConfig } from 'payload' +import type { TaskConfig } from 'payload' + +export default buildConfig({ + jobs: { + tasks: [ + { + slug: 'sendWelcomeEmail', + inputSchema: [ + { name: 'userEmail', type: 'text', required: true }, + { name: 'userName', type: 'text', required: true }, + ], + outputSchema: [{ name: 'emailSent', type: 'checkbox', required: true }], + retries: 2, // Retry up to 2 times on failure + handler: async ({ input, req }) => { + await sendEmail({ + to: input.userEmail, + subject: `Welcome ${input.userName}`, + }) + return { output: { emailSent: true } } + }, + } as TaskConfig<'sendWelcomeEmail'>, + ], + }, +}) +``` + +### Queueing Jobs + +```ts +// In a hook or endpoint +await req.payload.jobs.queue({ + task: 'sendWelcomeEmail', + input: { + userEmail: 'user@example.com', + userName: 'John', + }, + waitUntil: new Date('2024-12-31'), // Optional: schedule for future +}) +``` + +### Workflows + +Multi-step jobs that run in sequence: + +```ts +{ + slug: 'onboardUser', + inputSchema: [{ name: 'userId', type: 'text' }], + handler: async ({ job, req }) => { + const results = await job.runInlineTask({ + task: async ({ input }) => { + // Step 1: Send welcome email + await sendEmail(input.userId) + return { output: { emailSent: true } } + }, + }) + + await job.runInlineTask({ + task: async () => { + // Step 2: Create onboarding tasks + await createTasks() + return { output: { tasksCreated: true } } + }, + }) + }, +} +``` + +## Custom Endpoints + +Add custom REST API routes to collections, globals, or root config. See [ENDPOINTS.md](ENDPOINTS.md) for detailed patterns, authentication, helpers, and real-world examples. + +### Root Endpoints + +```ts +import { buildConfig } from 'payload' +import type { Endpoint } from 'payload' + +const helloEndpoint: Endpoint = { + path: '/hello', + method: 'get', + handler: () => { + return Response.json({ message: 'Hello!' }) + }, +} + +const greetEndpoint: Endpoint = { + path: '/greet/:name', + method: 'get', + handler: (req) => { + return Response.json({ + message: `Hello ${req.routeParams.name}!`, + }) + }, +} + +export default buildConfig({ + endpoints: [helloEndpoint, greetEndpoint], + collections: [], + secret: process.env.PAYLOAD_SECRET || '', +}) +``` + +### Collection Endpoints + +```ts +import type { CollectionConfig, Endpoint } from 'payload' + +const featuredEndpoint: Endpoint = { + path: '/featured', + method: 'get', + handler: async (req) => { + const posts = await req.payload.find({ + collection: 'posts', + where: { featured: { equals: true } }, + }) + return Response.json(posts) + }, +} + +export const Posts: CollectionConfig = { + slug: 'posts', + endpoints: [featuredEndpoint], + fields: [ + { name: 'title', type: 'text' }, + { name: 'featured', type: 'checkbox' }, + ], +} +``` + +## Custom Components + +### Field Component (Client) + +```tsx +'use client' +import { useField } from '@payloadcms/ui' +import type { TextFieldClientComponent } from 'payload' + +export const CustomField: TextFieldClientComponent = () => { + const { value, setValue } = useField() + + return setValue(e.target.value)} /> +} +``` + +### Custom View + +```tsx +'use client' +import { DefaultTemplate } from '@payloadcms/next/templates' + +export const CustomView = () => { + return ( + +

Custom Dashboard

+ {/* Your content */} +
+ ) +} +``` + +### Admin Config + +```ts +import { buildConfig } from 'payload' + +export default buildConfig({ + admin: { + components: { + beforeDashboard: ['/components/BeforeDashboard'], + beforeLogin: ['/components/BeforeLogin'], + views: { + custom: { + Component: '/views/Custom', + path: '/custom', + }, + }, + }, + }, + collections: [], + secret: process.env.PAYLOAD_SECRET || '', +}) +``` + +## Plugins + +### Available Plugins + +- **@payloadcms/plugin-seo** - SEO fields with meta title/description, Open Graph, preview generation +- **@payloadcms/plugin-redirects** - Manage URL redirects (301/302) for Next.js apps +- **@payloadcms/plugin-nested-docs** - Hierarchical document structures with breadcrumbs +- **@payloadcms/plugin-form-builder** - Dynamic form builder with submissions and validation +- **@payloadcms/plugin-search** - Full-text search integration (Algolia support) +- **@payloadcms/plugin-stripe** - Stripe payments, subscriptions, webhooks +- **@payloadcms/plugin-ecommerce** - Complete ecommerce solution (products, variants, carts, orders) +- **@payloadcms/plugin-import-export** - Import/export data via CSV +- **@payloadcms/plugin-multi-tenant** - Multi-tenancy with tenant isolation +- **@payloadcms/plugin-sentry** - Sentry error tracking integration +- **@payloadcms/plugin-mcp** - Model Context Protocol for AI integrations + +### Using Plugins + +```ts +import { buildConfig } from 'payload' +import { seoPlugin } from '@payloadcms/plugin-seo' +import { redirectsPlugin } from '@payloadcms/plugin-redirects' + +export default buildConfig({ + plugins: [ + seoPlugin({ + collections: ['posts', 'pages'], + }), + redirectsPlugin({ + collections: ['pages'], + }), + ], + collections: [], + secret: process.env.PAYLOAD_SECRET || '', +}) +``` + +### Creating Plugins + +```ts +import type { Config } from 'payload' + +interface PluginOptions { + enabled?: boolean +} + +export const myPlugin = + (options: PluginOptions) => + (config: Config): Config => ({ + ...config, + collections: [ + ...(config.collections || []), + { + slug: 'plugin-collection', + fields: [{ name: 'title', type: 'text' }], + }, + ], + onInit: async (payload) => { + if (config.onInit) await config.onInit(payload) + // Plugin initialization + }, + }) +``` + +## Localization + +```ts +import { buildConfig } from 'payload' +import type { Field, Payload } from 'payload' + +export default buildConfig({ + localization: { + locales: ['en', 'es', 'de'], + defaultLocale: 'en', + fallback: true, + }, + collections: [], + secret: process.env.PAYLOAD_SECRET || '', +}) + +// Localized field +const localizedField: TextField = { + name: 'title', + type: 'text', + localized: true, +} + +// Query with locale +const posts = await payload.find({ + collection: 'posts', + locale: 'es', +}) +``` + +## TypeScript Type References + +For complete TypeScript type definitions and signatures, reference these files from the Payload source: + +### Core Configuration Types + +- **[All Commonly-Used Types](https://github.com/payloadcms/payload/blob/main/packages/payload/src/index.ts)** - Check here first for commonly used types and interfaces. All core types are exported from this file. + +### Database & Adapters + +- **[Database Adapter Types](https://github.com/payloadcms/payload/blob/main/packages/payload/src/database/types.ts)** - Base adapter interface +- **[MongoDB Adapter](https://github.com/payloadcms/payload/blob/main/packages/db-mongodb/src/index.ts)** - MongoDB-specific options +- **[Postgres Adapter](https://github.com/payloadcms/payload/blob/main/packages/db-postgres/src/index.ts)** - Postgres-specific options + +### Rich Text & Plugins + +- **[Lexical Types](https://github.com/payloadcms/payload/blob/main/packages/richtext-lexical/src/exports/server/index.ts)** - Lexical editor configuration + +When users need detailed type information, fetch these URLs to provide complete signatures and optional parameters. diff --git a/.pi/skills/payload/reference/COLLECTIONS.md b/.pi/skills/payload/reference/COLLECTIONS.md new file mode 100644 index 0000000..e5a582c --- /dev/null +++ b/.pi/skills/payload/reference/COLLECTIONS.md @@ -0,0 +1,303 @@ +# Payload Collections Reference + +Complete reference for collection configurations and patterns. + +## Basic Collection + +```ts +import type { CollectionConfig } from 'payload' + +export const Posts: CollectionConfig = { + slug: 'posts', + labels: { + singular: 'Post', + plural: 'Posts', + }, + admin: { + useAsTitle: 'title', + defaultColumns: ['title', 'author', 'status', 'createdAt'], + group: 'Content', // Organize in admin sidebar + description: 'Blog posts and articles', + listSearchableFields: ['title', 'slug'], + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + index: true, + }, + { + name: 'slug', + type: 'text', + unique: true, + index: true, + admin: { position: 'sidebar' }, + }, + { + name: 'status', + type: 'select', + options: ['draft', 'published'], + defaultValue: 'draft', + }, + ], + defaultSort: '-createdAt', + timestamps: true, +} +``` + +## Auth Collection + +```ts +export const Users: CollectionConfig = { + slug: 'users', + auth: { + tokenExpiration: 7200, // 2 hours + verify: true, + maxLoginAttempts: 5, + lockTime: 600000, // 10 minutes + useAPIKey: true, + }, + admin: { + useAsTitle: 'email', + }, + fields: [ + { + name: 'roles', + type: 'select', + hasMany: true, + options: ['admin', 'editor', 'user'], + required: true, + defaultValue: ['user'], + saveToJWT: true, + }, + { + name: 'name', + type: 'text', + required: true, + }, + ], +} +``` + +## Upload Collection + +```ts +export const Media: CollectionConfig = { + slug: 'media', + upload: { + staticDir: 'media', + mimeTypes: ['image/*'], + imageSizes: [ + { + name: 'thumbnail', + width: 400, + height: 300, + position: 'centre', + }, + { + name: 'card', + width: 768, + height: 1024, + }, + ], + adminThumbnail: 'thumbnail', + focalPoint: true, + crop: true, + }, + access: { + read: () => true, + }, + fields: [ + { + name: 'alt', + type: 'text', + required: true, + }, + { + name: 'caption', + type: 'text', + localized: true, + }, + ], +} +``` + +## Live Preview + +Enable real-time content preview during editing. + +```ts +import type { CollectionConfig } from 'payload' + +const generatePreviewPath = ({ + slug, + collection, + req, +}: { + slug: string + collection: string + req: any +}) => { + const baseUrl = process.env.NEXT_PUBLIC_SERVER_URL + return `${baseUrl}/api/preview?slug=${slug}&collection=${collection}` +} + +export const Pages: CollectionConfig = { + slug: 'pages', + admin: { + useAsTitle: 'title', + // Live preview during editing + livePreview: { + url: ({ data, req }) => + generatePreviewPath({ + slug: data?.slug as string, + collection: 'pages', + req, + }), + }, + // Static preview button + preview: (data, { req }) => + generatePreviewPath({ + slug: data?.slug as string, + collection: 'pages', + req, + }), + }, + fields: [ + { name: 'title', type: 'text' }, + { name: 'slug', type: 'text' }, + ], +} +``` + +## Versioning & Drafts + +Payload maintains version history and supports draft/publish workflows. + +```ts +import type { CollectionConfig } from 'payload' + +// Basic versioning (audit log only) +export const Users: CollectionConfig = { + slug: 'users', + versions: true, // or { maxPerDoc: 100 } + fields: [{ name: 'name', type: 'text' }], +} + +// Drafts enabled (draft/publish workflow) +export const Posts: CollectionConfig = { + slug: 'posts', + versions: { + drafts: true, // Enables _status field + maxPerDoc: 50, + }, + fields: [{ name: 'title', type: 'text' }], +} + +// Full configuration with autosave and scheduled publish +export const Pages: CollectionConfig = { + slug: 'pages', + versions: { + drafts: { + autosave: true, // Auto-save while editing + schedulePublish: true, // Schedule future publish/unpublish + validate: false, // Don't validate drafts (default) + }, + maxPerDoc: 100, // Keep last 100 versions (0 = unlimited) + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +### Draft API Usage + +```ts +// Create draft +await payload.create({ + collection: 'posts', + data: { title: 'Draft Post' }, + draft: true, // Saves as draft, skips required field validation +}) + +// Update as draft +await payload.update({ + collection: 'posts', + id: '123', + data: { title: 'Updated Draft' }, + draft: true, +}) + +// Read with drafts (returns newest draft if available) +const post = await payload.findByID({ + collection: 'posts', + id: '123', + draft: true, // Returns draft version if exists +}) + +// Query only published (REST API) +// GET /api/posts (returns only _status: 'published') + +// Access control for drafts +export const Posts: CollectionConfig = { + slug: 'posts', + versions: { drafts: true }, + access: { + read: ({ req: { user } }) => { + // Public can only see published + if (!user) return { _status: { equals: 'published' } } + // Authenticated can see all + return true + }, + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +### Document Status + +The `_status` field is auto-injected when drafts are enabled: + +- `draft` - Never published +- `published` - Published with no newer drafts +- `changed` - Published but has newer unpublished drafts + +## Globals + +Globals are single-instance documents (not collections). + +```ts +import type { GlobalConfig } from 'payload' + +export const Header: GlobalConfig = { + slug: 'header', + label: 'Header', + admin: { + group: 'Settings', + }, + fields: [ + { + name: 'logo', + type: 'upload', + relationTo: 'media', + required: true, + }, + { + name: 'nav', + type: 'array', + maxRows: 8, + fields: [ + { + name: 'link', + type: 'relationship', + relationTo: 'pages', + }, + { + name: 'label', + type: 'text', + }, + ], + }, + ], +} +``` diff --git a/.pi/skills/payload/reference/ENDPOINTS.md b/.pi/skills/payload/reference/ENDPOINTS.md new file mode 100644 index 0000000..99ef908 --- /dev/null +++ b/.pi/skills/payload/reference/ENDPOINTS.md @@ -0,0 +1,634 @@ +# Payload Custom API Endpoints Reference + +Custom REST API endpoints extend Payload's auto-generated CRUD operations with custom logic, authentication flows, webhooks, and integrations. + +## Quick Reference + +### Endpoint Configuration + +| Property | Type | Description | +| --------- | ------------------------------------------------- | --------------------------------------------------------------- | +| `path` | `string` | Route path after collection/global slug (e.g., `/:id/tracking`) | +| `method` | `'get' \| 'post' \| 'put' \| 'patch' \| 'delete'` | HTTP method (lowercase) | +| `handler` | `(req: PayloadRequest) => Promise` | Async function returning Web API Response | +| `custom` | `Record` | Extension point for plugins/metadata | + +### Request Context + +| Property | Type | Description | +| ----------------- | ----------------------- | ------------------------------------------------------ | +| `req.user` | `User \| null` | Authenticated user (null if not authenticated) | +| `req.payload` | `Payload` | Payload instance for operations (find, create...) | +| `req.routeParams` | `Record` | Path parameters (e.g., `:id`) | +| `req.url` | `string` | Full request URL | +| `req.method` | `string` | HTTP method | +| `req.headers` | `Headers` | Request headers | +| `req.json()` | `() => Promise` | Parse JSON body | +| `req.text()` | `() => Promise` | Read body as text | +| `req.data` | `any` | Parsed body (after `addDataAndFileToRequest()`) | +| `req.file` | `File` | Uploaded file (after `addDataAndFileToRequest()`) | +| `req.locale` | `string` | Request locale (after `addLocalesToRequestFromData()`) | +| `req.i18n` | `I18n` | i18n instance | +| `req.t` | `TFunction` | Translation function | + +## Common Patterns + +### Authentication Check + +Custom endpoints are **not authenticated by default**. Check `req.user` to enforce authentication. + +```ts +import { APIError } from 'payload' + +export const authenticatedEndpoint = { + path: '/protected', + method: 'get', + handler: async (req) => { + if (!req.user) { + throw new APIError('Unauthorized', 401) + } + + // User is authenticated + return Response.json({ message: 'Access granted' }) + }, +} +``` + +### Using Payload Operations + +Use `req.payload` for database operations with access control and hooks. + +```ts +export const getRelatedPosts = { + path: '/:id/related', + method: 'get', + handler: async (req) => { + const { id } = req.routeParams + + // Find related posts + const posts = await req.payload.find({ + collection: 'posts', + where: { + category: { + equals: id, + }, + }, + limit: 5, + sort: '-createdAt', + }) + + return Response.json(posts) + }, +} +``` + +### Route Parameters + +Access path parameters via `req.routeParams`. + +```ts +export const getTrackingEndpoint = { + path: '/:id/tracking', + method: 'get', + handler: async (req) => { + const orderId = req.routeParams.id + + const tracking = await getTrackingInfo(orderId) + + if (!tracking) { + return Response.json({ error: 'not found' }, { status: 404 }) + } + + return Response.json(tracking) + }, +} +``` + +### Request Body Handling + +**Option 1: Manual JSON parsing** + +```ts +export const createEndpoint = { + path: '/create', + method: 'post', + handler: async (req) => { + const data = await req.json() + + const result = await req.payload.create({ + collection: 'posts', + data, + }) + + return Response.json(result) + }, +} +``` + +**Option 2: Using helper (handles JSON + files)** + +```ts +import { addDataAndFileToRequest } from 'payload' + +export const uploadEndpoint = { + path: '/upload', + method: 'post', + handler: async (req) => { + await addDataAndFileToRequest(req) + + // req.data now contains parsed body + // req.file contains uploaded file (if multipart) + + const result = await req.payload.create({ + collection: 'media', + data: req.data, + file: req.file, + }) + + return Response.json(result) + }, +} +``` + +### CORS Headers + +Use `headersWithCors` helper to apply config CORS settings. + +```ts +import { headersWithCors } from 'payload' + +export const corsEndpoint = { + path: '/public-data', + method: 'get', + handler: async (req) => { + const data = await fetchPublicData() + + return Response.json(data, { + headers: headersWithCors({ + headers: new Headers(), + req, + }), + }) + }, +} +``` + +### Error Handling + +Throw `APIError` with status codes for proper error responses. + +```ts +import { APIError } from 'payload' + +export const validateEndpoint = { + path: '/validate', + method: 'post', + handler: async (req) => { + const data = await req.json() + + if (!data.email) { + throw new APIError('Email is required', 400) + } + + // Validation passed + return Response.json({ valid: true }) + }, +} +``` + +### Query Parameters + +Extract query params from URL. + +```ts +export const searchEndpoint = { + path: '/search', + method: 'get', + handler: async (req) => { + const url = new URL(req.url) + const query = url.searchParams.get('q') + const limit = parseInt(url.searchParams.get('limit') || '10') + + const results = await req.payload.find({ + collection: 'posts', + where: { + title: { + contains: query, + }, + }, + limit, + }) + + return Response.json(results) + }, +} +``` + +## Helper Functions + +### addDataAndFileToRequest + +Parses request body and attaches to `req.data` and `req.file`. + +```ts +import { addDataAndFileToRequest } from 'payload' + +export const endpoint = { + path: '/process', + method: 'post', + handler: async (req) => { + await addDataAndFileToRequest(req) + + // req.data: parsed JSON or form data + // req.file: uploaded file (if multipart) + + console.log(req.data) // { title: 'My Post' } + console.log(req.file) // File object or undefined + }, +} +``` + +**Handles:** + +- JSON bodies (`Content-Type: application/json`) +- Form data (`Content-Type: multipart/form-data`) +- File uploads + +### addLocalesToRequestFromData + +Extracts locale from request data and validates against config. + +```ts +import { addLocalesToRequestFromData } from 'payload' + +export const endpoint = { + path: '/translate', + method: 'post', + handler: async (req) => { + await addLocalesToRequestFromData(req) + + // req.locale: validated locale string + // req.fallbackLocale: fallback locale string + + const result = await req.payload.find({ + collection: 'posts', + locale: req.locale, + }) + + return Response.json(result) + }, +} +``` + +### headersWithCors + +Applies CORS headers from Payload config. + +```ts +import { headersWithCors } from 'payload' + +export const endpoint = { + path: '/data', + method: 'get', + handler: async (req) => { + const data = { message: 'Hello' } + + return Response.json(data, { + headers: headersWithCors({ + headers: new Headers({ + 'Cache-Control': 'public, max-age=3600', + }), + req, + }), + }) + }, +} +``` + +## Real-World Examples + +### Multi-Tenant Login Endpoint + +From `examples/multi-tenant`: + +```ts +import { APIError, generatePayloadCookie, headersWithCors } from 'payload' + +export const externalUsersLogin = { + path: '/login-external', + method: 'post', + handler: async (req) => { + const { email, password, tenant } = await req.json() + + if (!email || !password || !tenant) { + throw new APIError('Missing credentials', 400) + } + + // Find user with tenant constraint + const userQuery = await req.payload.find({ + collection: 'users', + where: { + and: [ + { email: { equals: email } }, + { + or: [{ tenants: { equals: tenant } }, { 'tenants.tenant': { equals: tenant } }], + }, + ], + }, + }) + + if (!userQuery.docs.length) { + throw new APIError('Invalid credentials', 401) + } + + // Authenticate user + const result = await req.payload.login({ + collection: 'users', + data: { email, password }, + }) + + return Response.json(result, { + headers: headersWithCors({ + headers: new Headers({ + 'Set-Cookie': generatePayloadCookie({ + collectionAuthConfig: req.payload.config.collections.find((c) => c.slug === 'users') + .auth, + cookiePrefix: req.payload.config.cookiePrefix, + token: result.token, + }), + }), + req, + }), + }) + }, +} +``` + +### Webhook Handler (Stripe) + +From `packages/plugin-ecommerce`: + +```ts +export const webhookEndpoint = { + path: '/webhooks', + method: 'post', + handler: async (req) => { + const body = await req.text() + const signature = req.headers.get('stripe-signature') + + try { + const event = stripe.webhooks.constructEvent(body, signature, webhookSecret) + + // Process event + switch (event.type) { + case 'payment_intent.succeeded': + await handlePaymentSuccess(req.payload, event.data.object) + break + case 'payment_intent.failed': + await handlePaymentFailure(req.payload, event.data.object) + break + } + + return Response.json({ received: true }) + } catch (err) { + req.payload.logger.error(`Webhook error: ${err.message}`) + return Response.json({ error: err.message }, { status: 400 }) + } + }, +} +``` + +### Data Preview Endpoint + +From `packages/plugin-import-export`: + +```ts +import { addDataAndFileToRequest } from 'payload' + +export const previewEndpoint = { + path: '/preview', + method: 'post', + handler: async (req) => { + if (!req.user) { + throw new APIError('Unauthorized', 401) + } + + await addDataAndFileToRequest(req) + + const { collection, where, limit = 10 } = req.data + + // Validate collection exists + const collectionConfig = req.payload.config.collections.find((c) => c.slug === collection) + if (!collectionConfig) { + throw new APIError('Collection not found', 404) + } + + // Preview data + const results = await req.payload.find({ + collection, + where, + limit, + depth: 0, + }) + + return Response.json({ + docs: results.docs, + totalDocs: results.totalDocs, + fields: collectionConfig.fields, + }) + }, +} +``` + +### Reindex Action Endpoint + +From `packages/plugin-search`: + +```ts +export const reindexEndpoint = (pluginConfig) => ({ + path: '/reindex', + method: 'post', + handler: async (req) => { + if (!req.user) { + throw new APIError('Unauthorized', 401) + } + + const { collection } = req.routeParams + + // Reindex collection + const result = await reindexCollection(req.payload, collection, pluginConfig) + + return Response.json({ + message: `Reindexed ${result.count} documents`, + count: result.count, + }) + }, +}) +``` + +## Endpoint Placement + +### Collection Endpoints + +Mounted at `/api/{collection-slug}/{path}`. + +```ts +import type { CollectionConfig } from 'payload' + +export const Orders: CollectionConfig = { + slug: 'orders', + fields: [ + /* ... */ + ], + endpoints: [ + { + path: '/:id/tracking', + method: 'get', + handler: async (req) => { + // Available at: /api/orders/:id/tracking + const orderId = req.routeParams.id + return Response.json({ orderId }) + }, + }, + ], +} +``` + +### Global Endpoints + +Mounted at `/api/globals/{global-slug}/{path}`. + +```ts +import type { GlobalConfig } from 'payload' + +export const Settings: GlobalConfig = { + slug: 'settings', + fields: [ + /* ... */ + ], + endpoints: [ + { + path: '/clear-cache', + method: 'post', + handler: async (req) => { + // Available at: /api/globals/settings/clear-cache + await clearCache() + return Response.json({ message: 'Cache cleared' }) + }, + }, + ], +} +``` + +## Advanced Patterns + +### Factory Functions + +Create reusable endpoint factories for plugins. + +```ts +export const createWebhookEndpoint = (config) => ({ + path: '/webhook', + method: 'post', + handler: async (req) => { + const signature = req.headers.get('x-webhook-signature') + + if (!verifySignature(signature, config.secret)) { + throw new APIError('Invalid signature', 401) + } + + const data = await req.json() + await processWebhook(req.payload, data, config) + + return Response.json({ received: true }) + }, +}) +``` + +### Conditional Endpoints + +Add endpoints based on config options. + +```ts +export const MyCollection: CollectionConfig = { + slug: 'posts', + fields: [ + /* ... */ + ], + endpoints: [ + // Always included + { + path: '/public', + method: 'get', + handler: async (req) => Response.json({ data: [] }), + }, + // Conditionally included + ...(process.env.ENABLE_ANALYTICS + ? [ + { + path: '/analytics', + method: 'get', + handler: async (req) => Response.json({ analytics: [] }), + }, + ] + : []), + ], +} +``` + +### OpenAPI Documentation + +Use `custom` property for API documentation metadata. + +```ts +export const endpoint = { + path: '/search', + method: 'get', + handler: async (req) => { + // Handler implementation + }, + custom: { + openapi: { + summary: 'Search posts', + parameters: [ + { + name: 'q', + in: 'query', + required: true, + schema: { type: 'string' }, + }, + ], + responses: { + 200: { + description: 'Search results', + content: { + 'application/json': { + schema: { type: 'array' }, + }, + }, + }, + }, + }, + }, +} +``` + +## Best Practices + +1. **Always check authentication** - Custom endpoints are not authenticated by default +2. **Use `req.payload` for operations** - Ensures access control and hooks execute +3. **Use helpers for common tasks** - `addDataAndFileToRequest`, `headersWithCors`, etc. +4. **Throw `APIError` for errors** - Provides consistent error responses +5. **Return Web API `Response`** - Use `Response.json()` for consistent responses +6. **Validate input** - Check required fields, validate types +7. **Handle CORS** - Use `headersWithCors` for cross-origin requests +8. **Log errors** - Use `req.payload.logger` for debugging +9. **Document with `custom`** - Add OpenAPI metadata for API docs +10. **Factory pattern for reuse** - Create endpoint factories for plugins + +## Resources + +- REST API Overview: +- Custom Endpoints: +- Access Control: +- Local API: diff --git a/.pi/skills/payload/reference/FIELD-TYPE-GUARDS.md b/.pi/skills/payload/reference/FIELD-TYPE-GUARDS.md new file mode 100644 index 0000000..59ec938 --- /dev/null +++ b/.pi/skills/payload/reference/FIELD-TYPE-GUARDS.md @@ -0,0 +1,553 @@ +# Payload Field Type Guards Reference + +Complete reference with detailed examples and patterns. See [FIELDS.md](FIELDS.md#field-type-guards) for quick reference table of all guards. + +## Structural Guards + +### fieldHasSubFields + +Checks if field contains nested fields (group, array, row, or collapsible). + +```ts +import type { Field } from 'payload' +import { fieldHasSubFields } from 'payload' + +function traverseFields(fields: Field[]): void { + fields.forEach((field) => { + if (fieldHasSubFields(field)) { + // Safe to access field.fields + traverseFields(field.fields) + } + }) +} +``` + +**Signature:** + +```ts +fieldHasSubFields( + field: TField +): field is TField & (FieldWithSubFieldsClient | FieldWithSubFields) +``` + +**Common Pattern - Exclude Arrays:** + +```ts +if (fieldHasSubFields(field) && !fieldIsArrayType(field)) { + // Groups, rows, collapsibles only (not arrays) +} +``` + +### fieldIsArrayType + +Checks if field type is `'array'`. + +```ts +import { fieldIsArrayType } from 'payload' + +if (fieldIsArrayType(field)) { + // field.type === 'array' + console.log(`Min rows: ${field.minRows}`) + console.log(`Max rows: ${field.maxRows}`) +} +``` + +**Signature:** + +```ts +fieldIsArrayType( + field: TField +): field is TField & (ArrayFieldClient | ArrayField) +``` + +### fieldIsBlockType + +Checks if field type is `'blocks'`. + +```ts +import { fieldIsBlockType } from 'payload' + +if (fieldIsBlockType(field)) { + // field.type === 'blocks' + field.blocks.forEach((block) => { + console.log(`Block: ${block.slug}`) + }) +} +``` + +**Signature:** + +```ts +fieldIsBlockType( + field: TField +): field is TField & (BlocksFieldClient | BlocksField) +``` + +**Common Pattern - Distinguish Containers:** + +```ts +if (fieldIsArrayType(field)) { + // Handle array rows +} else if (fieldIsBlockType(field)) { + // Handle block types +} +``` + +### fieldIsGroupType + +Checks if field type is `'group'`. + +```ts +import { fieldIsGroupType } from 'payload' + +if (fieldIsGroupType(field)) { + // field.type === 'group' + console.log(`Interface: ${field.interfaceName}`) +} +``` + +**Signature:** + +```ts +fieldIsGroupType( + field: TField +): field is TField & (GroupFieldClient | GroupField) +``` + +## Capability Guards + +### fieldSupportsMany + +Checks if field can have multiple values (select, relationship, or upload with `hasMany`). + +```ts +import { fieldSupportsMany } from 'payload' + +if (fieldSupportsMany(field)) { + // field.type is 'select' | 'relationship' | 'upload' + // Safe to check field.hasMany + if (field.hasMany) { + console.log('Field accepts multiple values') + } +} +``` + +**Signature:** + +```ts +fieldSupportsMany( + field: TField +): field is TField & (FieldWithManyClient | FieldWithMany) +``` + +### fieldHasMaxDepth + +Checks if field is relationship/upload/join with numeric `maxDepth` property. + +```ts +import { fieldHasMaxDepth } from 'payload' + +if (fieldHasMaxDepth(field)) { + // field.type is 'upload' | 'relationship' | 'join' + // AND field.maxDepth is number + const remainingDepth = field.maxDepth - currentDepth +} +``` + +**Signature:** + +```ts +fieldHasMaxDepth( + field: TField +): field is TField & (FieldWithMaxDepthClient | FieldWithMaxDepth) +``` + +### fieldShouldBeLocalized + +Checks if field needs localization handling (accounts for parent localization). + +```ts +import { fieldShouldBeLocalized } from 'payload' + +function processField(field: Field, parentIsLocalized: boolean) { + if (fieldShouldBeLocalized({ field, parentIsLocalized })) { + // Create locale-specific table or index + } +} +``` + +**Signature:** + +```ts +fieldShouldBeLocalized({ + field, + parentIsLocalized, +}: { + field: ClientField | ClientTab | Field | Tab + parentIsLocalized: boolean +}): boolean +``` + +```ts +// Accounts for parent localization +if (fieldShouldBeLocalized({ field, parentIsLocalized: false })) { + /* ... */ +} +``` + +### fieldIsVirtual + +Checks if field is virtual (computed or virtual relationship). + +```ts +import { fieldIsVirtual } from 'payload' + +if (fieldIsVirtual(field)) { + // field.virtual is truthy + if (typeof field.virtual === 'string') { + // Virtual relationship path + console.log(`Virtual path: ${field.virtual}`) + } else { + // Computed virtual field (uses hooks) + } +} +``` + +**Signature:** + +```ts +fieldIsVirtual(field: Field | Tab): boolean +``` + +## Data Guards + +### fieldAffectsData + +**Most commonly used guard.** Checks if field stores data (has name and is not UI-only). + +```ts +import { fieldAffectsData } from 'payload' + +function generateSchema(fields: Field[]) { + fields.forEach((field) => { + if (fieldAffectsData(field)) { + // Safe to access field.name + schema[field.name] = getFieldType(field) + } + }) +} +``` + +**Signature:** + +```ts +fieldAffectsData( + field: TField +): field is TField & (FieldAffectingDataClient | FieldAffectingData) +``` + +**Pattern - Data Fields Only:** + +```ts +const dataFields = fields.filter(fieldAffectsData) +``` + +### fieldIsPresentationalOnly + +Checks if field is UI-only (type `'ui'`). + +```ts +import { fieldIsPresentationalOnly } from 'payload' + +if (fieldIsPresentationalOnly(field)) { + // field.type === 'ui' + // Skip in data operations, GraphQL schema, etc. + return +} +``` + +**Signature:** + +```ts +fieldIsPresentationalOnly( + field: TField +): field is TField & (UIFieldClient | UIField) +``` + +### fieldIsID + +Checks if field name is exactly `'id'`. + +```ts +import { fieldIsID } from 'payload' + +if (fieldIsID(field)) { + // field.name === 'id' + // Special handling for ID field +} +``` + +**Signature:** + +```ts +fieldIsID( + field: TField +): field is { name: 'id' } & TField +``` + +### fieldIsHiddenOrDisabled + +Checks if field is hidden or admin-disabled. + +```ts +import { fieldIsHiddenOrDisabled } from 'payload' + +const visibleFields = fields.filter((field) => !fieldIsHiddenOrDisabled(field)) +``` + +**Signature:** + +```ts +fieldIsHiddenOrDisabled( + field: TField +): field is { admin: { hidden: true } } & TField +``` + +## Layout Guards + +### fieldIsSidebar + +Checks if field is positioned in sidebar. + +```ts +import { fieldIsSidebar } from 'payload' + +const [mainFields, sidebarFields] = fields.reduce( + ([main, sidebar], field) => { + if (fieldIsSidebar(field)) { + return [main, [...sidebar, field]] + } + return [[...main, field], sidebar] + }, + [[], []], +) +``` + +**Signature:** + +```ts +fieldIsSidebar( + field: TField +): field is { admin: { position: 'sidebar' } } & TField +``` + +## Tab & Group Guards + +### tabHasName + +Checks if tab is named (stores data under tab name). + +```ts +import { tabHasName } from 'payload' + +tabs.forEach((tab) => { + if (tabHasName(tab)) { + // tab.name exists + dataPath.push(tab.name) + } + // Process tab.fields +}) +``` + +**Signature:** + +```ts +tabHasName( + tab: TField +): tab is NamedTab & TField +``` + +### groupHasName + +Checks if group is named (stores data under group name). + +```ts +import { groupHasName } from 'payload' + +if (groupHasName(group)) { + // group.name exists + return data[group.name] +} +``` + +**Signature:** + +```ts +groupHasName(group: Partial): group is NamedGroupFieldClient +``` + +## Option & Value Guards + +### optionIsObject + +Checks if option is object format `{label, value}` vs string. + +```ts +import { optionIsObject } from 'payload' + +field.options.forEach((option) => { + if (optionIsObject(option)) { + console.log(`${option.label}: ${option.value}`) + } else { + console.log(option) // string value + } +}) +``` + +**Signature:** + +```ts +optionIsObject(option: Option): option is OptionObject +``` + +### optionsAreObjects + +Checks if entire options array contains objects. + +```ts +import { optionsAreObjects } from 'payload' + +if (optionsAreObjects(field.options)) { + // All options are OptionObject[] + const labels = field.options.map((opt) => opt.label) +} +``` + +**Signature:** + +```ts +optionsAreObjects(options: Option[]): options is OptionObject[] +``` + +### optionIsValue + +Checks if option is string value (not object). + +```ts +import { optionIsValue } from 'payload' + +if (optionIsValue(option)) { + // option is string + const value = option +} +``` + +**Signature:** + +```ts +optionIsValue(option: Option): option is string +``` + +### valueIsValueWithRelation + +Checks if relationship value is polymorphic format `{relationTo, value}`. + +```ts +import { valueIsValueWithRelation } from 'payload' + +if (valueIsValueWithRelation(fieldValue)) { + // fieldValue.relationTo exists + // fieldValue.value exists + console.log(`Related to ${fieldValue.relationTo}: ${fieldValue.value}`) +} +``` + +**Signature:** + +```ts +valueIsValueWithRelation(value: unknown): value is ValueWithRelation +``` + +## Common Patterns + +### Recursive Field Traversal + +```ts +import { fieldAffectsData, fieldHasSubFields } from 'payload' + +function traverseFields(fields: Field[], callback: (field: Field) => void) { + fields.forEach((field) => { + if (fieldAffectsData(field)) { + callback(field) + } + + if (fieldHasSubFields(field)) { + traverseFields(field.fields, callback) + } + }) +} +``` + +### Filter Data-Bearing Fields + +```ts +import { fieldAffectsData, fieldIsPresentationalOnly, fieldIsHiddenOrDisabled } from 'payload' + +const dataFields = fields.filter( + (field) => + fieldAffectsData(field) && !fieldIsPresentationalOnly(field) && !fieldIsHiddenOrDisabled(field), +) +``` + +### Container Type Switching + +```ts +import { fieldIsArrayType, fieldIsBlockType, fieldHasSubFields } from 'payload' + +if (fieldIsArrayType(field)) { + // Handle array-specific logic +} else if (fieldIsBlockType(field)) { + // Handle blocks-specific logic +} else if (fieldHasSubFields(field)) { + // Handle group/row/collapsible +} +``` + +### Safe Property Access + +```ts +import { fieldSupportsMany, fieldHasMaxDepth } from 'payload' + +// Without guard - TypeScript error +// if (field.hasMany) { /* ... */ } + +// With guard - safe access +if (fieldSupportsMany(field) && field.hasMany) { + console.log('Multiple values supported') +} + +if (fieldHasMaxDepth(field)) { + const depth = field.maxDepth // TypeScript knows this is number +} +``` + +## Type Preservation + +All guards preserve the original type constraint: + +```ts +import type { ClientField, Field } from 'payload' +import { fieldHasSubFields } from 'payload' + +function processServerField(field: Field) { + if (fieldHasSubFields(field)) { + // field is Field & FieldWithSubFields (not ClientField) + } +} + +function processClientField(field: ClientField) { + if (fieldHasSubFields(field)) { + // field is ClientField & FieldWithSubFieldsClient + } +} +``` diff --git a/.pi/skills/payload/reference/FIELDS.md b/.pi/skills/payload/reference/FIELDS.md new file mode 100644 index 0000000..997db7d --- /dev/null +++ b/.pi/skills/payload/reference/FIELDS.md @@ -0,0 +1,744 @@ +# Payload Field Types Reference + +Complete reference for all Payload field types with examples. + +## Text Field + +```ts +import type { TextField } from 'payload' + +const textField: TextField = { + name: 'title', + type: 'text', + required: true, + unique: true, + minLength: 5, + maxLength: 100, + index: true, + localized: true, + defaultValue: 'Default Title', + validate: (value) => Boolean(value) || 'Required', + admin: { + placeholder: 'Enter title...', + position: 'sidebar', + condition: (data) => data.showTitle === true, + }, +} +``` + +### Slug Field Helper + +Built-in helper for auto-generating slugs: + +```ts +import { slugField } from 'payload' +import type { CollectionConfig } from 'payload' + +export const Pages: CollectionConfig = { + slug: 'pages', + fields: [ + { name: 'title', type: 'text', required: true }, + slugField({ + name: 'slug', // defaults to 'slug' + useAsSlug: 'title', // defaults to 'title' + checkboxName: 'generateSlug', // defaults to 'generateSlug' + localized: true, + required: true, + overrides: (defaultField) => { + // Customize the generated fields if needed + return defaultField + }, + }), + ], +} +``` + +## Rich Text (Lexical) + +```ts +import type { RichTextField } from 'payload' +import { lexicalEditor } from '@payloadcms/richtext-lexical' +import { HeadingFeature, LinkFeature } from '@payloadcms/richtext-lexical' + +const richTextField: RichTextField = { + name: 'content', + type: 'richText', + required: true, + localized: true, + editor: lexicalEditor({ + features: ({ defaultFeatures }) => [ + ...defaultFeatures, + HeadingFeature({ + enabledHeadingSizes: ['h1', 'h2', 'h3'], + }), + LinkFeature({ + enabledCollections: ['posts', 'pages'], + }), + ], + }), +} +``` + +### Advanced Lexical Configuration + +```ts +import { + BoldFeature, + EXPERIMENTAL_TableFeature, + FixedToolbarFeature, + HeadingFeature, + IndentFeature, + InlineToolbarFeature, + ItalicFeature, + LinkFeature, + OrderedListFeature, + UnderlineFeature, + UnorderedListFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +// Global editor config with full features +export default buildConfig({ + editor: lexicalEditor({ + features: () => { + return [ + UnderlineFeature(), + BoldFeature(), + ItalicFeature(), + OrderedListFeature(), + UnorderedListFeature(), + LinkFeature({ + enabledCollections: ['pages'], + fields: ({ defaultFields }) => { + const defaultFieldsWithoutUrl = defaultFields.filter((field) => { + if ('name' in field && field.name === 'url') return false + return true + }) + + return [ + ...defaultFieldsWithoutUrl, + { + name: 'url', + type: 'text', + admin: { + condition: ({ linkType }) => linkType !== 'internal', + }, + label: ({ t }) => t('fields:enterURL'), + required: true, + }, + ] + }, + }), + IndentFeature(), + EXPERIMENTAL_TableFeature(), + ] + }, + }), +}) + +// Field-specific editor with custom toolbar +const richTextWithToolbars: RichTextField = { + name: 'richText', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h2', 'h3', 'h4'] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + ] + }, + }), + label: false, +} +``` + +## Relationship + +```ts +import type { RelationshipField } from 'payload' + +// Single relationship +const singleRelationship: RelationshipField = { + name: 'author', + type: 'relationship', + relationTo: 'users', + required: true, + maxDepth: 2, +} + +// Multiple relationships (hasMany) +const multipleRelationship: RelationshipField = { + name: 'categories', + type: 'relationship', + relationTo: 'categories', + hasMany: true, + filterOptions: { + active: { equals: true }, + }, +} + +// Polymorphic relationship +const polymorphicRelationship: PolymorphicRelationshipField = { + name: 'relatedContent', + type: 'relationship', + relationTo: ['posts', 'pages'], + hasMany: true, +} +``` + +## Array + +```ts +import type { ArrayField } from 'payload' + +const arrayField: ArrayField = { + name: 'slides', + type: 'array', + minRows: 2, + maxRows: 10, + labels: { + singular: 'Slide', + plural: 'Slides', + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + }, + { + name: 'image', + type: 'upload', + relationTo: 'media', + }, + ], + admin: { + initCollapsed: true, + }, +} +``` + +## Blocks + +```ts +import type { BlocksField, Block } from 'payload' + +const HeroBlock: Block = { + slug: 'hero', + interfaceName: 'HeroBlock', + fields: [ + { + name: 'heading', + type: 'text', + required: true, + }, + { + name: 'background', + type: 'upload', + relationTo: 'media', + }, + ], +} + +const ContentBlock: Block = { + slug: 'content', + fields: [ + { + name: 'text', + type: 'richText', + }, + ], +} + +const blocksField: BlocksField = { + name: 'layout', + type: 'blocks', + blocks: [HeroBlock, ContentBlock], +} +``` + +## Select + +```ts +import type { SelectField } from 'payload' + +const selectField: SelectField = { + name: 'status', + type: 'select', + options: [ + { label: 'Draft', value: 'draft' }, + { label: 'Published', value: 'published' }, + ], + defaultValue: 'draft', + required: true, +} + +// Multiple select +const multiSelectField: SelectField = { + name: 'tags', + type: 'select', + hasMany: true, + options: ['tech', 'news', 'sports'], +} +``` + +## Upload + +```ts +import type { UploadField } from 'payload' + +const uploadField: UploadField = { + name: 'featuredImage', + type: 'upload', + relationTo: 'media', + required: true, + filterOptions: { + mimeType: { contains: 'image' }, + }, +} +``` + +## Point (Geolocation) + +Point fields store geographic coordinates with automatic 2dsphere indexing for geospatial queries. + +```ts +import type { PointField } from 'payload' + +const locationField: PointField = { + name: 'location', + type: 'point', + label: 'Location', + required: true, +} + +// Returns [longitude, latitude] +// Example: [-122.4194, 37.7749] for San Francisco +``` + +### Geospatial Queries + +```ts +// Query by distance (sorted by nearest first) +const nearbyLocations = await payload.find({ + collection: 'stores', + where: { + location: { + near: [10, 20], // [longitude, latitude] + maxDistance: 5000, // in meters + minDistance: 1000, + }, + }, +}) + +// Query within polygon area +const polygon: Point[] = [ + [9.0, 19.0], // bottom-left + [9.0, 21.0], // top-left + [11.0, 21.0], // top-right + [11.0, 19.0], // bottom-right + [9.0, 19.0], // closing point +] + +const withinArea = await payload.find({ + collection: 'stores', + where: { + location: { + within: { + type: 'Polygon', + coordinates: [polygon], + }, + }, + }, +}) + +// Query intersecting area +const intersecting = await payload.find({ + collection: 'stores', + where: { + location: { + intersects: { + type: 'Polygon', + coordinates: [polygon], + }, + }, + }, +}) +``` + +**Note**: Point fields are not supported in SQLite. + +## Join Fields + +Join fields create reverse relationships, allowing you to access related documents from the "other side" of a relationship. + +```ts +import type { JoinField } from 'payload' + +// From Users collection - show user's orders +const ordersJoinField: JoinField = { + name: 'orders', + type: 'join', + collection: 'orders', + on: 'customer', // The field in 'orders' that references this user + admin: { + allowCreate: false, + defaultColumns: ['id', 'createdAt', 'total', 'currency', 'items'], + }, +} + +// From Users collection - show user's cart +const cartJoinField: JoinField = { + name: 'cart', + type: 'join', + collection: 'carts', + on: 'customer', + admin: { + allowCreate: false, + defaultColumns: ['id', 'createdAt', 'total', 'currency'], + }, +} +``` + +## Virtual Fields + +```ts +import type { TextField } from 'payload' + +// Computed from siblings +const computedVirtualField: TextField = { + name: 'fullName', + type: 'text', + virtual: true, + hooks: { + afterRead: [({ siblingData }) => `${siblingData.firstName} ${siblingData.lastName}`], + }, +} + +// From relationship path +const pathVirtualField: TextField = { + name: 'authorName', + type: 'text', + virtual: 'author.name', +} +``` + +## Conditional Fields + +```ts +import type { UploadField, CheckboxField } from 'payload' + +// Simple boolean condition +const enableFeatureField: CheckboxField = { + name: 'enableFeature', + type: 'checkbox', +} + +const conditionalField: TextField = { + name: 'featureText', + type: 'text', + admin: { + condition: (data) => data.enableFeature === true, + }, +} + +// Sibling data condition (from hero field pattern) +const typeField: SelectField = { + name: 'type', + type: 'select', + options: ['none', 'highImpact', 'mediumImpact', 'lowImpact'], + defaultValue: 'lowImpact', +} + +const mediaField: UploadField = { + name: 'media', + type: 'upload', + relationTo: 'media', + admin: { + condition: (_, { type } = {}) => ['highImpact', 'mediumImpact'].includes(type), + }, + required: true, +} +``` + +## Radio + +Radio fields present options as radio buttons for single selection. + +```ts +import type { RadioField } from 'payload' + +const radioField: RadioField = { + name: 'priority', + type: 'radio', + options: [ + { label: 'Low', value: 'low' }, + { label: 'Medium', value: 'medium' }, + { label: 'High', value: 'high' }, + ], + defaultValue: 'medium', + admin: { + layout: 'horizontal', // or 'vertical' + }, +} +``` + +## Row (Layout) + +Row fields arrange fields horizontally in the admin panel (presentational only). + +```ts +import type { RowField } from 'payload' + +const rowField: RowField = { + type: 'row', + fields: [ + { + name: 'firstName', + type: 'text', + admin: { width: '50%' }, + }, + { + name: 'lastName', + type: 'text', + admin: { width: '50%' }, + }, + ], +} +``` + +## Collapsible (Layout) + +Collapsible fields group fields in an expandable/collapsible section. + +```ts +import type { CollapsibleField } from 'payload' + +const collapsibleField: CollapsibleField = { + label: ({ data }) => data?.title || 'Advanced Options', + type: 'collapsible', + admin: { + initCollapsed: true, + }, + fields: [ + { name: 'customCSS', type: 'textarea' }, + { name: 'customJS', type: 'code' }, + ], +} +``` + +## UI (Custom Components) + +UI fields allow fully custom React components in the admin (no data stored). + +```ts +import type { UIField } from 'payload' + +const uiField: UIField = { + name: 'customMessage', + type: 'ui', + admin: { + components: { + Field: '/path/to/CustomFieldComponent', + Cell: '/path/to/CustomCellComponent', // For list view + }, + }, +} +``` + +## Tabs & Groups + +```ts +import type { TabsField, GroupField } from 'payload' + +// Tabs +const tabsField: TabsField = { + type: 'tabs', + tabs: [ + { + label: 'Content', + fields: [ + { name: 'title', type: 'text' }, + { name: 'body', type: 'richText' }, + ], + }, + { + label: 'SEO', + fields: [ + { name: 'metaTitle', type: 'text' }, + { name: 'metaDescription', type: 'textarea' }, + ], + }, + ], +} + +// Group (named) +const groupField: GroupField = { + name: 'meta', + type: 'group', + fields: [ + { name: 'title', type: 'text' }, + { name: 'description', type: 'textarea' }, + ], +} +``` + +## Reusable Field Factories + +Create composable field patterns that can be customized with overrides. + +```ts +import type { Field, GroupField } from 'payload' + +// Utility for deep merging +const deepMerge = (target: T, source: Partial): T => { + // Implementation would deeply merge objects + return { ...target, ...source } +} + +// Reusable link field factory +type LinkType = (options?: { + appearances?: ('default' | 'outline')[] | false + disableLabel?: boolean + overrides?: Record +}) => GroupField + +export const link: LinkType = ({ appearances, disableLabel = false, overrides = {} } = {}) => { + const linkField: GroupField = { + name: 'link', + type: 'group', + admin: { + hideGutter: true, + }, + fields: [ + { + type: 'row', + fields: [ + { + name: 'type', + type: 'radio', + options: [ + { label: 'Internal link', value: 'reference' }, + { label: 'Custom URL', value: 'custom' }, + ], + defaultValue: 'reference', + admin: { + layout: 'horizontal', + width: '50%', + }, + }, + { + name: 'newTab', + type: 'checkbox', + label: 'Open in new tab', + admin: { + width: '50%', + style: { + alignSelf: 'flex-end', + }, + }, + }, + ], + }, + { + name: 'reference', + type: 'relationship', + relationTo: ['pages'], + required: true, + maxDepth: 1, + admin: { + condition: (_, siblingData) => siblingData?.type === 'reference', + }, + }, + { + name: 'url', + type: 'text', + label: 'Custom URL', + required: true, + admin: { + condition: (_, siblingData) => siblingData?.type === 'custom', + }, + }, + ], + } + + if (!disableLabel) { + linkField.fields.push({ + name: 'label', + type: 'text', + required: true, + }) + } + + if (appearances !== false) { + linkField.fields.push({ + name: 'appearance', + type: 'select', + defaultValue: 'default', + options: [ + { label: 'Default', value: 'default' }, + { label: 'Outline', value: 'outline' }, + ], + }) + } + + return deepMerge(linkField, overrides) as GroupField +} + +// Usage +const navItem = link({ appearances: false }) +const ctaButton = link({ + overrides: { + name: 'cta', + admin: { + description: 'Call to action button', + }, + }, +}) +``` + +## Field Type Guards + +Type guards for runtime field type checking and safe type narrowing. + +| Type Guard | Checks For | Use When | +| --------------------------- | ----------------------------------------------------------- | ---------------------------------------- | +| `fieldAffectsData` | Field stores data (has name, not UI-only) | Need to access field data or name | +| `fieldHasSubFields` | Field contains nested fields (group/array/row/collapsible) | Need to recursively traverse fields | +| `fieldIsArrayType` | Field is array type | Distinguish arrays from other containers | +| `fieldIsBlockType` | Field is blocks type | Handle blocks-specific logic | +| `fieldIsGroupType` | Field is group type | Handle group-specific logic | +| `fieldSupportsMany` | Field can have multiple values (select/relationship/upload) | Check for `hasMany` support | +| `fieldHasMaxDepth` | Field supports population depth control | Control relationship/upload/join depth | +| `fieldIsPresentationalOnly` | Field is UI-only (no data storage) | Exclude from data operations | +| `fieldIsSidebar` | Field positioned in sidebar | Separate sidebar rendering | +| `fieldIsID` | Field name is 'id' | Special ID field handling | +| `fieldIsHiddenOrDisabled` | Field is hidden or disabled | Filter from UI operations | +| `fieldShouldBeLocalized` | Field needs localization handling | Proper locale table checks | +| `fieldIsVirtual` | Field is virtual (computed/no DB column) | Skip in database transforms | +| `tabHasName` | Tab is named (stores data) | Distinguish named vs unnamed tabs | +| `groupHasName` | Group is named (stores data) | Distinguish named vs unnamed groups | +| `optionIsObject` | Option is `{label, value}` format | Access option properties safely | +| `optionsAreObjects` | All options are objects | Batch option processing | +| `optionIsValue` | Option is string value | Handle string options | +| `valueIsValueWithRelation` | Value is polymorphic relationship | Handle polymorphic relationships | + +```ts +import { fieldAffectsData, fieldHasSubFields, fieldIsArrayType } from 'payload' + +function processField(field: Field) { + if (fieldAffectsData(field)) { + // Safe to access field.name + console.log(field.name) + } + + if (fieldHasSubFields(field)) { + // Safe to access field.fields + field.fields.forEach(processField) + } +} +``` + +See [FIELD-TYPE-GUARDS.md](FIELD-TYPE-GUARDS.md) for detailed usage patterns. diff --git a/.pi/skills/payload/reference/HOOKS.md b/.pi/skills/payload/reference/HOOKS.md new file mode 100644 index 0000000..b67556e --- /dev/null +++ b/.pi/skills/payload/reference/HOOKS.md @@ -0,0 +1,186 @@ +# Payload Hooks Reference + +Complete reference for collection hooks, field hooks, and hook context patterns. + +## Collection Hooks + +```ts +export const Posts: CollectionConfig = { + slug: 'posts', + hooks: { + // Before validation + beforeValidate: [ + async ({ data, operation }) => { + if (operation === 'create') { + data.slug = slugify(data.title) + } + return data + }, + ], + + // Before save + beforeChange: [ + async ({ data, req, operation, originalDoc }) => { + if (operation === 'update' && data.status === 'published') { + data.publishedAt = new Date() + } + return data + }, + ], + + // After save + afterChange: [ + async ({ doc, req, operation, previousDoc }) => { + if (operation === 'create') { + await sendNotification(doc) + } + return doc + }, + ], + + // After read + afterRead: [ + async ({ doc, req }) => { + doc.viewCount = await getViewCount(doc.id) + return doc + }, + ], + + // Before delete + beforeDelete: [ + async ({ req, id }) => { + await cleanupRelatedData(id) + }, + ], + }, +} +``` + +## Field Hooks + +```ts +import type { EmailField, FieldHook } from 'payload' + +const beforeValidateHook: FieldHook = ({ value }) => { + return value.trim().toLowerCase() +} + +const afterReadHook: FieldHook = ({ value, req }) => { + // Hide email from non-admins + if (!req.user?.roles?.includes('admin')) { + return value.replace(/(.{2})(.*)(@.*)/, '$1***$3') + } + return value +} + +const emailField: EmailField = { + name: 'email', + type: 'email', + hooks: { + beforeValidate: [beforeValidateHook], + afterRead: [afterReadHook], + }, +} +``` + +## Hook Context + +Share data between hooks or control hook behavior using request context: + +```ts +import type { CollectionConfig } from 'payload' + +export const Posts: CollectionConfig = { + slug: 'posts', + hooks: { + beforeChange: [ + async ({ context }) => { + context.expensiveData = await fetchExpensiveData() + }, + ], + afterChange: [ + async ({ context, doc }) => { + // Reuse from previous hook + await processData(doc, context.expensiveData) + }, + ], + }, + fields: [{ name: 'title', type: 'text' }], +} +``` + +## Next.js Revalidation with Context Control + +```ts +import type { CollectionAfterChangeHook, CollectionAfterDeleteHook } from 'payload' +import { revalidatePath } from 'next/cache' +import type { Page } from '../payload-types' + +export const revalidatePage: CollectionAfterChangeHook = ({ + doc, + previousDoc, + req: { payload, context }, +}) => { + if (!context.disableRevalidate) { + if (doc._status === 'published') { + const path = doc.slug === 'home' ? '/' : `/${doc.slug}` + payload.logger.info(`Revalidating page at path: ${path}`) + revalidatePath(path) + } + + // Revalidate old path if unpublished + if (previousDoc?._status === 'published' && doc._status !== 'published') { + const oldPath = previousDoc.slug === 'home' ? '/' : `/${previousDoc.slug}` + payload.logger.info(`Revalidating old page at path: ${oldPath}`) + revalidatePath(oldPath) + } + } + return doc +} + +export const revalidateDelete: CollectionAfterDeleteHook = ({ doc, req: { context } }) => { + if (!context.disableRevalidate) { + const path = doc?.slug === 'home' ? '/' : `/${doc?.slug}` + revalidatePath(path) + } + return doc +} +``` + +## Date Field Auto-Set + +Automatically set date when document is published: + +```ts +import type { DateField } from 'payload' + +const publishedOnField: DateField = { + name: 'publishedOn', + type: 'date', + admin: { + date: { + pickerAppearance: 'dayAndTime', + }, + position: 'sidebar', + }, + hooks: { + beforeChange: [ + ({ siblingData, value }) => { + if (siblingData._status === 'published' && !value) { + return new Date() + } + return value + }, + ], + }, +} +``` + +## Hook Patterns Best Practices + +- Use `beforeValidate` for data formatting +- Use `beforeChange` for business logic +- Use `afterChange` for side effects +- Use `afterRead` for computed fields +- Store expensive operations in `context` +- Pass `req` to nested operations for transaction safety (see [ADAPTERS.md#threading-req-through-operations](ADAPTERS.md#threading-req-through-operations)) diff --git a/.pi/skills/payload/reference/PLUGIN-DEVELOPMENT.md b/.pi/skills/payload/reference/PLUGIN-DEVELOPMENT.md new file mode 100644 index 0000000..f852dd7 --- /dev/null +++ b/.pi/skills/payload/reference/PLUGIN-DEVELOPMENT.md @@ -0,0 +1,1436 @@ +# Payload Plugin Development + +Complete guide to creating Payload plugins with TypeScript patterns, package structure, and best practices from the official Payload plugin template. + +## Plugin Architecture + +Plugins are functions that receive configuration options and return a function that transforms the Payload config: + +```ts +import type { Config, Plugin } from 'payload' + +interface MyPluginConfig { + enabled?: boolean + collections?: string[] +} + +export const myPlugin = + (options: MyPluginConfig): Plugin => + (config: Config): Config => ({ + ...config, + // Transform config here + }) +``` + +**Key Pattern:** Double arrow function (currying) + +- First function: Accepts plugin options, returns plugin function +- Second function: Accepts Payload config, returns modified config + +## Plugin Package Structure + +### Simple Structure + +``` +plugin-/ +├── package.json # Package metadata and dependencies +├── README.md # Plugin documentation +├── LICENSE.md # License file +└── src/ + ├── index.ts # Entry point, re-exports plugin and config types + ├── plugin.ts # Plugin implementation + ├── types.ts # TypeScript type definitions + └── exports/ # Additional entry points (optional) + └── types.ts # Type-only exports +``` + +### Exhaustive Structure + +``` +plugin-/ +├── .swcrc # SWC compiler config +├── package.json # Package metadata and dependencies +├── tsconfig.json # TypeScript config +├── README.md # Plugin documentation +├── LICENSE.md # License file +├── eslint.config.js # ESLint configuration (optional) +├── vitest.config.js # Vitest test configuration (optional) +├── playwright.config.js # Playwright e2e tests (optional) +└── src/ + ├── index.ts # Entry point, re-exports plugin and config types + ├── plugin.ts # Plugin implementation + ├── types.ts # TypeScript type definitions + ├── defaults.ts # Default configuration values (optional) + ├── endpoints/ # Custom API endpoints (optional) + │ └── handler.ts + ├── components/ # React components (optional) + │ ├── ClientComponent.tsx # 'use client' components + │ └── ServerComponent.tsx # RSC components + ├── fields/ # Custom field components (optional) + │ ├── FieldName/ + │ │ ├── index.ts # Field config + │ │ └── Component.tsx # Client component + ├── exports/ # Additional entry points + │ ├── types.ts # Type-only exports + │ ├── fields.ts # Field-only exports + │ ├── client.ts # Re-export client components + │ └── rsc.ts # Re-export server components (RSC) + ├── translations/ # i18n translations (optional) + │ └── index.ts + └── ui/ # Admin UI components (optional) + └── Component.tsx +``` + +**Key additions from official template:** + +- **dev/** directory with complete Payload project for local testing +- **src/exports/rsc.ts** for React Server Component exports +- **src/components/** for organizing React components +- **src/endpoints/** for custom API endpoint handlers +- Test configuration files (vitest.config.js, playwright.config.js) + +## Package.json Configuration + +```json +{ + "name": "payload-plugin-example", + "version": "1.0.0", + "description": "A Payload plugin", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "./types": { + "import": "./dist/exports/types.js", + "types": "./dist/exports/types.d.ts" + }, + "./client": { + "import": "./dist/exports/client.js", + "types": "./dist/exports/client.d.ts" + }, + "./rsc": { + "import": "./dist/exports/rsc.js", + "types": "./dist/exports/rsc.d.ts" + } + }, + "files": ["dist"], + "scripts": { + "build": "npm run copyfiles && npm run build:types && npm run build:swc", + "build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths", + "build:types": "tsc --emitDeclarationOnly --outDir dist", + "clean": "rimraf dist *.tsbuildinfo", + "copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/", + "dev": "next dev dev --turbo", + "dev:generate-types": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload generate:types", + "dev:payload": "cross-env PAYLOAD_CONFIG_PATH=./dev/payload.config.ts payload", + "test": "npm run test:int && npm run test:e2e", + "test:int": "vitest", + "test:e2e": "playwright test", + "lint": "eslint", + "lint:fix": "eslint ./src --fix", + "prepublishOnly": "npm run clean && npm run build" + }, + "dependencies": { + "@payloadcms/translations": "^3.0.0", + "@payloadcms/ui": "^3.0.0" + }, + "devDependencies": { + "@payloadcms/db-mongodb": "^3.0.0", + "@payloadcms/next": "^3.0.0", + "@payloadcms/richtext-lexical": "^3.0.0", + "@playwright/test": "^1.40.0", + "@swc/cli": "^0.1.62", + "@swc/core": "^1.3.0", + "copyfiles": "^2.4.1", + "cross-env": "^7.0.3", + "eslint": "^9.0.0", + "next": "^15.4.10", + "payload": "^3.0.0", + "react": "^19.2.1", + "react-dom": "^19.2.1", + "rimraf": "^5.0.0", + "typescript": "^5.0.0", + "vitest": "^3.0.0" + }, + "peerDependencies": { + "payload": "^3.0.0" + } +} +``` + +**Key Points:** + +- `type: "module"` for ESM +- Compiled output in `./dist`, source in `./src` +- Payload as peer dependency (user installs it) +- Multiple export entry points: main, `/types`, `/client`, `/rsc` +- `/client` for client components, `/rsc` for React Server Components +- SWC for fast compilation +- Dev scripts for local development with Next.js +- Test scripts for both integration (Vitest) and e2e (Playwright) tests +- `prepublishOnly` ensures build before publish + +## Plugin Patterns + +### Adding Fields to Collections + +```ts +import type { Config, Plugin, Field } from 'payload' + +export const seoPlugin = + (options: { collections?: string[] }): Plugin => + (config: Config): Config => { + const seoFields: Field[] = [ + { + name: 'meta', + type: 'group', + fields: [ + { name: 'title', type: 'text' }, + { name: 'description', type: 'textarea' }, + ], + }, + ] + + return { + ...config, + collections: config.collections?.map((collection) => { + if (options.collections?.includes(collection.slug)) { + return { + ...collection, + fields: [...(collection.fields || []), ...seoFields], + } + } + return collection + }), + } + } +``` + +### Adding New Collections + +```ts +import type { Config, Plugin, CollectionConfig } from 'payload' + +export const redirectsPlugin = + (options: { overrides?: Partial }): Plugin => + (config: Config): Config => { + const redirectsCollection: CollectionConfig = { + slug: 'redirects', + access: { read: () => true }, + fields: [ + { name: 'from', type: 'text', required: true, unique: true }, + { name: 'to', type: 'text', required: true }, + ], + ...options.overrides, + } + + return { + ...config, + collections: [...(config.collections || []), redirectsCollection], + } + } +``` + +### Adding Hooks + +```ts +import type { Config, Plugin, CollectionAfterChangeHook } from 'payload' + +const resaveChildrenHook: CollectionAfterChangeHook = async ({ doc, req, operation }) => { + if (operation === 'update') { + // Resave child documents + const children = await req.payload.find({ + collection: 'pages', + where: { parent: { equals: doc.id } }, + }) + + for (const child of children.docs) { + await req.payload.update({ + collection: 'pages', + id: child.id, + data: child, + }) + } + } + return doc +} + +export const nestedDocsPlugin = + (options: { collections: string[] }): Plugin => + (config: Config): Config => ({ + ...config, + collections: (config.collections || []).map((collection) => { + if (options.collections.includes(collection.slug)) { + return { + ...collection, + hooks: { + ...(collection.hooks || {}), + afterChange: [resaveChildrenHook, ...(collection.hooks?.afterChange || [])], + }, + } + } + return collection + }), + }) +``` + +### Adding Root-Level Endpoints + +Add endpoints at the root config level (accessible at `/api/`): + +```ts +import type { Config, Plugin, Endpoint } from 'payload' + +export const seoPlugin = + (options: { generateTitle?: (doc: any) => string }): Plugin => + (config: Config): Config => { + const generateTitleEndpoint: Endpoint = { + path: '/plugin-seo/generate-title', + method: 'post', + handler: async (req) => { + const data = await req.json?.() + const result = options.generateTitle ? options.generateTitle(data.doc) : '' + return Response.json({ result }) + }, + } + + return { + ...config, + endpoints: [...(config.endpoints ?? []), generateTitleEndpoint], + } + } +``` + +**Example webhook endpoint:** + +```ts +// Useful for integrations like Stripe +const webhookEndpoint: Endpoint = { + path: '/stripe/webhook', + method: 'post', + handler: async (req) => { + const signature = req.headers.get('stripe-signature') + const event = stripe.webhooks.constructEvent( + await req.text(), + signature, + process.env.STRIPE_WEBHOOK_SECRET, + ) + // Handle webhook + return Response.json({ received: true }) + }, +} +``` + +### Field Overrides with Defaults + +```ts +import type { Config, Plugin, Field } from 'payload' + +type FieldsOverride = (args: { defaultFields: Field[] }) => Field[] + +interface PluginConfig { + collections?: string[] + fields?: FieldsOverride +} + +export const myPlugin = + (options: PluginConfig): Plugin => + (config: Config): Config => { + const defaultFields: Field[] = [ + { name: 'title', type: 'text' }, + { name: 'description', type: 'textarea' }, + ] + + const fields = + options.fields && typeof options.fields === 'function' + ? options.fields({ defaultFields }) + : defaultFields + + return { + ...config, + collections: config.collections?.map((collection) => { + if (options.collections?.includes(collection.slug)) { + return { + ...collection, + fields: [...(collection.fields || []), ...fields], + } + } + return collection + }), + } + } +``` + +### Tabs UI Pattern + +```ts +import type { Config, Plugin, TabsField, GroupField } from 'payload' + +export const seoPlugin = + (options: { tabbedUI?: boolean }): Plugin => + (config: Config): Config => { + const seoFields: GroupField[] = [ + { + name: 'meta', + type: 'group', + fields: [{ name: 'title', type: 'text' }], + }, + ] + + return { + ...config, + collections: config.collections?.map((collection) => { + if (options.tabbedUI) { + const seoTabs: TabsField[] = [ + { + type: 'tabs', + tabs: [ + // If existing tabs, preserve them + ...(collection.fields?.[0]?.type === 'tabs' + ? collection.fields[0].tabs + : [ + { + label: 'Content', + fields: collection.fields || [], + }, + ]), + // Add SEO tab + { + label: 'SEO', + fields: seoFields, + }, + ], + }, + ] + + return { + ...collection, + fields: [ + ...seoTabs, + ...(collection.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []), + ], + } + } + + return { + ...collection, + fields: [...(collection.fields || []), ...seoFields], + } + }), + } + } +``` + +### Disable Plugin Pattern + +Allow users to disable plugin without removing it (important for database schema consistency): + +```ts +import type { Config, Plugin } from 'payload' + +interface PluginConfig { + disabled?: boolean + collections?: string[] +} + +export const myPlugin = + (options: PluginConfig): Plugin => + (config: Config): Config => { + // Always add collections/fields for database schema consistency + if (!config.collections) { + config.collections = [] + } + + config.collections.push({ + slug: 'plugin-collection', + fields: [{ name: 'title', type: 'text' }], + }) + + // Add fields to specified collections + if (options.collections) { + for (const collectionSlug of options.collections) { + const collection = config.collections.find((c) => c.slug === collectionSlug) + if (collection) { + collection.fields.push({ + name: 'addedByPlugin', + type: 'text', + }) + } + } + } + + // If disabled, return early but keep schema changes + if (options.disabled) { + return config + } + + // Add endpoints, hooks, components only when enabled + config.endpoints = [ + ...(config.endpoints ?? []), + { + path: '/my-endpoint', + method: 'get', + handler: async () => Response.json({ message: 'Hello' }), + }, + ] + + return config + } +``` + +### Admin Components + +Add custom UI components to the admin panel: + +```ts +import type { Config, Plugin } from 'payload' + +export const myPlugin = + (options: PluginConfig): Plugin => + (config: Config): Config => { + if (!config.admin) config.admin = {} + if (!config.admin.components) config.admin.components = {} + if (!config.admin.components.beforeDashboard) { + config.admin.components.beforeDashboard = [] + } + + // Add client component + config.admin.components.beforeDashboard.push('my-plugin-name/client#BeforeDashboardClient') + + // Add server component (RSC) + config.admin.components.beforeDashboard.push('my-plugin-name/rsc#BeforeDashboardServer') + + return config + } +``` + +**Component file structure:** + +```tsx +// src/components/BeforeDashboardClient.tsx +'use client' +import { useConfig } from '@payloadcms/ui' +import { useEffect, useState } from 'react' +import { formatAdminURL } from 'payload/shared' + +export const BeforeDashboardClient = () => { + const { config } = useConfig() + const [data, setData] = useState('') + + useEffect(() => { + fetch( + formatAdminURL({ + apiRoute: config.routes.api, + path: '/my-endpoint', + }), + ) + .then((res) => res.json()) + .then(setData) + }, [config.serverURL, config.routes.api]) + + return
Client Component: {data}
+} + +// src/components/BeforeDashboardServer.tsx +export const BeforeDashboardServer = () => { + return
Server Component
+} + +// src/exports/client.ts +export { BeforeDashboardClient } from '../components/BeforeDashboardClient.js' + +// src/exports/rsc.ts +export { BeforeDashboardServer } from '../components/BeforeDashboardServer.js' +``` + +### Translations (i18n) + +```ts +// src/translations/index.ts +export const translations = { + en: { + 'plugin-name:fieldLabel': 'Field Label', + 'plugin-name:fieldDescription': 'Field description', + }, + es: { + 'plugin-name:fieldLabel': 'Etiqueta del campo', + 'plugin-name:fieldDescription': 'Descripción del campo', + }, +} + +// src/plugin.ts +import { deepMergeSimple } from 'payload/shared' +import { translations } from './translations/index.js' + +export const myPlugin = + (options: PluginConfig): Plugin => + (config: Config): Config => ({ + ...config, + i18n: { + ...config.i18n, + translations: deepMergeSimple(translations, config.i18n?.translations ?? {}), + }, + }) +``` + +### onInit Hook + +```ts +export const myPlugin = + (options: PluginConfig): Plugin => + (config: Config): Config => { + const incomingOnInit = config.onInit + + config.onInit = async (payload) => { + // IMPORTANT: Call existing onInit first + if (incomingOnInit) await incomingOnInit(payload) + + // Plugin initialization + payload.logger.info('Plugin initialized') + + // Example: Seed data + const { totalDocs } = await payload.count({ + collection: 'plugin-collection', + where: { id: { equals: 'seeded-by-plugin' } }, + }) + + if (totalDocs === 0) { + await payload.create({ + collection: 'plugin-collection', + data: { id: 'seeded-by-plugin' }, + }) + } + } + + return config + } +``` + +## TypeScript Patterns + +### Plugin Config Types + +```ts +import type { CollectionSlug, GlobalSlug, Field, CollectionConfig } from 'payload' + +export type FieldsOverride = (args: { defaultFields: Field[] }) => Field[] + +export interface MyPluginConfig { + /** + * Collections to enable this plugin for + */ + collections?: CollectionSlug[] + /** + * Globals to enable this plugin for + */ + globals?: GlobalSlug[] + /** + * Override default fields + */ + fields?: FieldsOverride + /** + * Enable tabbed UI + */ + tabbedUI?: boolean + /** + * Override collection config + */ + overrides?: Partial +} +``` + +### Export Types + +```ts +// src/exports/types.ts +export type { MyPluginConfig, FieldsOverride } from '../types.js' + +// Usage +import type { MyPluginConfig } from '@payloadcms/plugin-example/types' +``` + +## Client Components + +### Custom Field Component + +```tsx +// src/fields/CustomField/Component.tsx +'use client' +import { useField } from '@payloadcms/ui' +import type { TextFieldClientComponent } from 'payload' + +export const CustomFieldComponent: TextFieldClientComponent = ({ field, path }) => { + const { value, setValue } = useField({ path }) + + return ( +
+ + setValue(e.target.value)} /> +
+ ) +} +``` + +```ts +// src/fields/CustomField/index.ts +import type { Field } from 'payload' + +export const CustomField = (overrides?: Partial): Field => ({ + name: 'customField', + type: 'text', + admin: { + components: { + Field: '/fields/CustomField/Component#CustomFieldComponent', + }, + }, + ...overrides, +}) +``` + +## Best Practices + +### Preserve Existing Config + +Always spread existing config and add to arrays: + +```ts +// ✅ Good +collections: [...(config.collections || []), newCollection] + +// ❌ Bad +collections: [newCollection] +``` + +### Respect User Overrides + +Allow users to override plugin defaults: + +```ts +const collection: CollectionConfig = { + slug: 'redirects', + fields: defaultFields, + ...options.overrides, // User overrides last +} +``` + +### Conditional Logic + +Check if collections/globals are enabled: + +```ts +collections: config.collections?.map((collection) => { + const isEnabled = options.collections?.includes(collection.slug) + if (isEnabled) { + // Transform collection + } + return collection +}) +``` + +### Hook Composition + +Preserve existing hooks: + +```ts +hooks: { + ...collection.hooks, + afterChange: [ + myHook, + ...(collection.hooks?.afterChange || []), + ], +} +``` + +### Type Safety + +Use Payload's exported types: + +```ts +import type { Config, Plugin, CollectionConfig, Field, CollectionSlug, GlobalSlug } from 'payload' +``` + +### Field Path Imports + +Use absolute paths for client components: + +```ts +admin: { + components: { + Field: '/fields/CustomField/Component#CustomFieldComponent', + }, +} +``` + +### onInit Pattern + +Always call existing `onInit` before your initialization. See [onInit Hook](#oninit-hook) pattern for full example. + +## Advanced Patterns + +These patterns are extracted from official Payload plugins and represent production-ready techniques for complex plugin development. + +### Advanced Configuration + +#### Async Plugin Function + +Allow plugin function to be async for awaiting collection overrides or async operations: + +```ts +export const myPlugin = + (pluginConfig?: PluginConfig) => + async (incomingConfig: Config): Promise => { + // Can await async operations during initialization + const customCollection = await pluginConfig.collectionOverride?.({ + defaultCollection, + }) + + return { + ...incomingConfig, + collections: [...incomingConfig.collections, customCollection], + } + } +``` + +#### Collection Override with Async Support + +Allow users to override entire collections with async functions: + +```ts +type CollectionOverride = (args: { + defaultCollection: CollectionConfig +}) => CollectionConfig | Promise + +interface PluginConfig { + products?: { + collectionOverride?: CollectionOverride + } +} + +// In plugin +const defaultCollection = createProductsCollection(config) +const finalCollection = config.products?.collectionOverride + ? await config.products.collectionOverride({ defaultCollection }) + : defaultCollection +``` + +#### Config Sanitization Pattern + +Normalize plugin configuration with defaults: + +```ts +export const sanitizePluginConfig = ({ pluginConfig }: Props): SanitizedPluginConfig => { + const config = { ...pluginConfig } as Partial + + // Normalize boolean|object configs + if (typeof config.addresses === 'undefined' || config.addresses === true) { + config.addresses = { addressFields: defaultAddressFields() } + } else if (config.addresses === false) { + config.addresses = null + } + + // Validate required fields + if (!config.stripeSecretKey) { + throw new Error('Stripe secret key is required') + } + + return config as SanitizedPluginConfig +} + +// Use at plugin start +export const myPlugin = + (pluginConfig: PluginConfig): Plugin => + (config) => { + const sanitized = sanitizePluginConfig({ pluginConfig }) + // Use sanitized config throughout + } +``` + +#### Collection Slug Mapping + +Track collection slugs when users can override them: + +```ts +type CollectionSlugMap = { + products: string + variants: string + orders: string +} + +const getCollectionSlugMap = ({ config }: { config: PluginConfig }): CollectionSlugMap => ({ + products: config.products?.slug || 'products', + variants: config.variants?.slug || 'variants', + orders: config.orders?.slug || 'orders', +}) + +// Use throughout plugin +const collectionSlugMap = getCollectionSlugMap({ config: pluginConfig }) + +// When creating relationship fields +{ + name: 'product', + type: 'relationship', + relationTo: collectionSlugMap.products, +} +``` + +#### Multi-Collection Configuration + +Plugin operates on multiple collections with collection-specific config: + +```ts +interface PluginConfig { + sync: Array<{ + collection: string + fields?: string[] + onSync?: (doc: any) => Promise + }> +} + +// In plugin +for (const collection of config.collections!) { + const syncConfig = pluginConfig.sync?.find((s) => s.collection === collection.slug) + if (!syncConfig) continue + + collection.hooks.afterChange = [ + ...(collection.hooks?.afterChange || []), + async ({ doc, operation }) => { + if (operation === 'create' || operation === 'update') { + await syncConfig.onSync?.(doc) + } + }, + ] +} +``` + +### TypeScript Extensions + +#### TypeScript Schema Extension + +Add custom properties to generated TypeScript schema: + +```ts +incomingConfig.typescript = incomingConfig.typescript || {} +incomingConfig.typescript.schema = incomingConfig.typescript.schema || [] + +incomingConfig.typescript.schema.push((args) => { + const { jsonSchema } = args + + jsonSchema.properties.ecommerce = { + type: 'object', + properties: { + collections: { + type: 'object', + properties: { + products: { type: 'string' }, + orders: { type: 'string' }, + }, + }, + }, + } + + return jsonSchema +}) +``` + +#### Module Declaration Augmentation + +Extend Payload types for plugin-specific field properties: + +```ts +// In plugin types file +declare module 'payload' { + export interface FieldCustom { + 'plugin-import-export'?: { + disabled?: boolean + toCSV?: (value: any) => string + fromCSV?: (value: string) => any + } + } +} + +// Usage with TypeScript support +{ + name: 'price', + type: 'number', + custom: { + 'plugin-import-export': { + toCSV: (value) => `$${value.toFixed(2)}`, + fromCSV: (value) => parseFloat(value.replace('$', '')), + }, + }, +} +``` + +### Advanced Hooks + +#### Global Error Hooks + +Add global error handling: + +```ts +return { + ...config, + hooks: { + afterError: [ + ...(config.hooks?.afterError ?? []), + async (args) => { + const { error } = args + const status = (error as APIError).status ?? 500 + + if (status >= 500 || captureErrors.includes(status)) { + captureException(error, { + tags: { + collection: args.collection?.slug, + operation: args.operation, + }, + user: args.req?.user ? { id: args.req.user.id } : undefined, + }) + } + }, + ], + }, +} +``` + +#### Multiple Hook Types on Same Collection + +Coordinate multiple lifecycle hooks together for complex workflows (e.g., validation → sync → cache → cleanup): + +```ts +collection.hooks = { + ...collection.hooks, + + beforeValidate: [ + ...(collection.hooks?.beforeValidate || []), + async ({ data }) => { + // Normalize before validation + return data + }, + ], + + beforeChange: [ + ...(collection.hooks?.beforeChange || []), + async ({ data, operation }) => { + // Sync to external service + if (operation === 'create') { + data.externalId = await externalService.create(data) + } + return data + }, + ], + + afterChange: [ + ...(collection.hooks?.afterChange || []), + async ({ doc }) => { + // Invalidate cache + await cache.invalidate(`doc:${doc.id}`) + }, + ], + + afterDelete: [ + ...(collection.hooks?.afterDelete || []), + async ({ doc }) => { + // Cleanup external resources + await externalService.delete(doc.externalId) + }, + ], +} +``` + +### Access Control & Filtering + +#### Access Control Wrapper Pattern + +Wrap existing access control with plugin-specific logic: + +```ts +// From plugin-multi-tenant +export const multiTenantPlugin = + (pluginOptions: PluginOptions) => + (config: Config): Config => ({ + ...config, + collections: (config.collections || []).map((collection) => { + if (!pluginOptions.collections.includes(collection.slug)) { + return collection + } + + return { + ...collection, + access: { + ...collection.access, + read: ({ req }) => { + // Inject tenant filter + return { + and: [ + collection.access?.read ? collection.access.read({ req }) : {}, + { tenant: { equals: req.user?.tenant } }, + ], + } + }, + }, + } + }), + }) +``` + +#### BaseFilter Composition + +Combine plugin filters with existing baseListFilter: + +```ts +// From plugin-multi-tenant +const existingBaseFilter = collection.admin?.baseListFilter +const tenantFilter = { tenant: { equals: req.user?.tenant } } + +collection.admin = { + ...collection.admin, + baseListFilter: existingBaseFilter ? { and: [existingBaseFilter, tenantFilter] } : tenantFilter, +} +``` + +#### Relationship FilterOptions Modification + +Add filters to relationship field options: + +```ts +// From plugin-multi-tenant +collection.fields = collection.fields.map((field) => { + if (field.type === 'relationship') { + return { + ...field, + filterOptions: ({ relationTo }) => { + return { + and: [field.filterOptions?.(relationTo) || {}, { tenant: { equals: req.user?.tenant } }], + } + }, + } + } + return field +}) +``` + +### Admin UI Customization + +#### Metadata Storage Pattern + +Use admin.meta for plugin-specific UI state without database fields: + +```ts +// From plugin-nested-docs +export const nestedDocsPlugin = + (pluginOptions: PluginOptions) => + (config: Config): Config => ({ + ...config, + collections: config.collections?.map((collection) => ({ + ...collection, + admin: { + ...collection.admin, + meta: { + ...collection.admin?.meta, + nestedDocs: { + breadcrumbsFieldSlug: pluginOptions.breadcrumbsFieldSlug || 'breadcrumbs', + parentFieldSlug: pluginOptions.parentFieldSlug || 'parent', + }, + }, + }, + })), + }) +``` + +#### Conditional Component Rendering + +Add components based on plugin configuration: + +```ts +// From plugin-seo +const beforeFields = collection.admin?.components?.beforeFields || [] + +if (pluginOptions.uploadsCollection === collection.slug) { + beforeFields.push('/path/to/ImagePreview#ImagePreview') +} + +collection.admin = { + ...collection.admin, + components: { + ...collection.admin?.components, + beforeFields, + }, +} +``` + +#### Custom Provider Pattern + +Inject context providers for shared state: + +```ts +// From plugin-nested-docs +collection.admin = { + ...collection.admin, + components: { + ...collection.admin?.components, + providers: [ + ...(collection.admin?.components?.providers || []), + '/components/NestedDocsProvider#NestedDocsProvider', + ], + }, +} +``` + +#### Custom Actions + +Add collection-level action buttons: + +```ts +// From plugin-import-export +collection.admin = { + ...collection.admin, + components: { + ...collection.admin?.components, + actions: [ + ...(collection.admin?.components?.actions || []), + '/components/ImportButton#ImportButton', + '/components/ExportButton#ExportButton', + ], + }, +} +``` + +#### Custom List Item Views + +Modify how items appear in collection lists: + +```ts +// From plugin-ecommerce +collection.admin = { + ...collection.admin, + components: { + ...collection.admin?.components, + views: { + ...collection.admin?.components?.views, + list: { + ...collection.admin?.components?.views?.list, + Component: '/views/ProductList#ProductList', + }, + }, + }, +} +``` + +#### Custom Collection Endpoints + +Add collection-scoped endpoints (accessible at `/api//`): + +```ts +// From plugin-import-export +collection.endpoints = [ + ...(collection.endpoints || []), + { + path: '/import', + method: 'post', + handler: async (req) => { + // Import logic accessible at /api/posts/import + return Response.json({ success: true }) + }, + }, + { + path: '/export', + method: 'get', + handler: async (req) => { + // Export logic accessible at /api/posts/export + return Response.json({ data: exportedData }) + }, + }, +] +``` + +### Field & Collection Modifications + +#### Admin Folders Override + +Control admin UI organization: + +```ts +// From plugin-redirects +collection.admin = { + ...collection.admin, + group: pluginOptions.group || 'Settings', + hidden: pluginOptions.hidden, + defaultColumns: pluginOptions.defaultColumns || ['from', 'to', 'updatedAt'], +} +``` + +### Background Jobs & Async Operations + +#### Jobs Registration + +Register plugin background tasks: + +```ts +// From plugin-stripe +export const stripePlugin = + (pluginOptions: PluginOptions) => + (config: Config): Config => ({ + ...config, + jobs: { + ...config.jobs, + tasks: [ + ...(config.jobs?.tasks || []), + { + slug: 'syncStripeProducts', + handler: async ({ req }) => { + const products = await stripe.products.list() + // Sync to Payload + return { output: { synced: products.data.length } } + }, + }, + ], + }, + }) +``` + +## Testing Plugins + +### Local Development with dev/ Directory (optional) + +Include a `dev/` directory with a complete Payload project for local development: + +1. Create `dev/.env` from `.env.example`: + +```bash +DATABASE_URL=mongodb://127.0.0.1/plugin-dev +PAYLOAD_SECRET=your-secret-here +``` + +2. Configure `dev/payload.config.ts`: + +```ts +import { buildConfig } from 'payload' +import { mongooseAdapter } from '@payloadcms/db-mongodb' +import { myPlugin } from '../src/index.js' + +export default buildConfig({ + secret: process.env.PAYLOAD_SECRET!, + db: mongooseAdapter({ url: process.env.DATABASE_URL! }), + plugins: [ + myPlugin({ + collections: ['posts'], + }), + ], + collections: [ + { + slug: 'posts', + fields: [{ name: 'title', type: 'text' }], + }, + ], +}) +``` + +3. Run development server: + +```bash +npm run dev # Starts Next.js on http://localhost:3000 +``` + +### Integration Tests (Vitest) (optional) + +Create `dev/int.spec.ts`: + +```ts +import type { Payload } from 'payload' +import config from '@payload-config' +import { createPayloadRequest, getPayload } from 'payload' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' +import { customEndpointHandler } from '../src/endpoints/handler.js' + +let payload: Payload + +beforeAll(async () => { + payload = await getPayload({ config }) +}) + +afterAll(async () => { + await payload.destroy() +}) + +describe('Plugin integration tests', () => { + test('should add field to collection', async () => { + const post = await payload.create({ + collection: 'posts', + data: { + title: 'Test', + addedByPlugin: 'plugin value', + }, + }) + expect(post.addedByPlugin).toBe('plugin value') + }) + + test('should create plugin collection', async () => { + expect(payload.collections['plugin-collection']).toBeDefined() + const { docs } = await payload.find({ collection: 'plugin-collection' }) + expect(docs.length).toBeGreaterThan(0) + }) + + test('should query custom endpoint', async () => { + const request = new Request('http://localhost:3000/api/my-endpoint') + const payloadRequest = await createPayloadRequest({ config, request }) + const response = await customEndpointHandler(payloadRequest) + const data = await response.json() + expect(data).toMatchObject({ message: 'Hello' }) + }) +}) +``` + +Run: `npm run test:int` + +### End-to-End Tests (Playwright) + +Create `dev/e2e.spec.ts`: + +```ts +import { test, expect } from '@playwright/test' + +test.describe('Plugin e2e tests', () => { + test('should render custom admin component', async ({ page }) => { + await page.goto('http://localhost:3000/admin') + await expect(page.getByText('Added by the plugin')).toBeVisible() + }) +}) +``` + +Run: `npm run test:e2e` + +## Common Plugin Types + +### Field Enhancer + +Adds fields to existing collections (SEO, timestamps, audit logs) + +### Collection Provider + +Adds new collections (redirects, forms, logs) + +### Hook Injector + +Adds hooks to collections (nested docs, cache invalidation) + +### UI Enhancer + +Adds custom components (dashboards, field types) + +### Integration + +Connects external services (Stripe, Sentry, storage adapters) + +### Adapter + +Provides infrastructure (database, storage, email) + +## Resources + +- [Plugin Examples](https://github.com/payloadcms/payload/tree/main/packages/) - Official plugins source code, payload-\* prefix +- [Plugin Template](https://github.com/payloadcms/payload/tree/main/templates/plugin) - Starter template for new plugins diff --git a/.pi/skills/payload/reference/QUERIES.md b/.pi/skills/payload/reference/QUERIES.md new file mode 100644 index 0000000..89cfff4 --- /dev/null +++ b/.pi/skills/payload/reference/QUERIES.md @@ -0,0 +1,274 @@ +# Payload Querying Reference + +Complete reference for querying data across Local API, REST, and GraphQL. + +## Query Operators + +```ts +import type { Where } from 'payload' + +// Equals +const equalsQuery: Where = { color: { equals: 'blue' } } + +// Not equals +const notEqualsQuery: Where = { status: { not_equals: 'draft' } } + +// Greater/less than +const greaterThanQuery: Where = { price: { greater_than: 100 } } +const lessThanEqualQuery: Where = { age: { less_than_equal: 65 } } + +// Contains (case-insensitive) +const containsQuery: Where = { title: { contains: 'payload' } } + +// Like (all words present) +const likeQuery: Where = { description: { like: 'cms headless' } } + +// In/not in +const inQuery: Where = { category: { in: ['tech', 'news'] } } + +// Exists +const existsQuery: Where = { image: { exists: true } } + +// Near (point fields) +const nearQuery: Where = { location: { near: '-122.4194,37.7749,10000' } } +``` + +## AND/OR Logic + +```ts +import type { Where } from 'payload' + +const complexQuery: Where = { + or: [ + { color: { equals: 'mint' } }, + { + and: [{ color: { equals: 'white' } }, { featured: { equals: false } }], + }, + ], +} +``` + +## Nested Properties + +```ts +import type { Where } from 'payload' + +const nestedQuery: Where = { + 'author.role': { equals: 'editor' }, + 'meta.featured': { exists: true }, +} +``` + +## Local API + +```ts +// Find documents +const posts = await payload.find({ + collection: 'posts', + where: { + status: { equals: 'published' }, + 'author.name': { contains: 'john' }, + }, + depth: 2, + limit: 10, + page: 1, + sort: '-createdAt', + locale: 'en', + select: { + title: true, + author: true, + }, +}) + +// Find by ID +const post = await payload.findByID({ + collection: 'posts', + id: '123', + depth: 2, +}) + +// Create +const post = await payload.create({ + collection: 'posts', + data: { + title: 'New Post', + status: 'draft', + }, +}) + +// Update +await payload.update({ + collection: 'posts', + id: '123', + data: { + status: 'published', + }, +}) + +// Delete +await payload.delete({ + collection: 'posts', + id: '123', +}) + +// Count +const count = await payload.count({ + collection: 'posts', + where: { + status: { equals: 'published' }, + }, +}) +``` + +### Threading req Parameter + +When performing operations in hooks or nested operations, pass the `req` parameter to maintain transaction context: + +```ts +// ✅ CORRECT: Pass req for transaction safety +const afterChange: CollectionAfterChangeHook = async ({ doc, req }) => { + await req.payload.create({ + collection: 'audit-log', + data: { action: 'created', docId: doc.id }, + req, // Maintains transaction atomicity + }) +} + +// ❌ WRONG: Missing req breaks transaction +const afterChange: CollectionAfterChangeHook = async ({ doc, req }) => { + await req.payload.create({ + collection: 'audit-log', + data: { action: 'created', docId: doc.id }, + // Missing req - runs in separate transaction + }) +} +``` + +This is critical for MongoDB replica sets and Postgres. See [ADAPTERS.md#threading-req-through-operations](ADAPTERS.md#threading-req-through-operations) for details. + +### Access Control in Local API + +**Important**: Local API bypasses access control by default (`overrideAccess: true`). When passing a `user` parameter, you must explicitly set `overrideAccess: false` to respect that user's permissions. + +```ts +// ❌ WRONG: User is passed but access control is bypassed +const posts = await payload.find({ + collection: 'posts', + user: currentUser, + // Missing: overrideAccess: false + // Result: Operation runs with ADMIN privileges, ignoring user's permissions +}) + +// ✅ CORRECT: Respects user's access control permissions +const posts = await payload.find({ + collection: 'posts', + user: currentUser, + overrideAccess: false, // Required to enforce access control + // Result: User only sees posts they have permission to read +}) + +// Administrative operation (intentionally bypass access control) +const allPosts = await payload.find({ + collection: 'posts', + // No user parameter + // overrideAccess defaults to true + // Result: Returns all posts regardless of access control +}) +``` + +**When to use `overrideAccess: false`:** + +- Performing operations on behalf of a user +- Testing access control logic +- API routes that should respect user permissions +- Any operation where `user` parameter is provided + +**When `overrideAccess: true` is appropriate:** + +- Administrative operations (migrations, seeds, cron jobs) +- Internal system operations +- Operations explicitly intended to bypass access control + +See [ACCESS-CONTROL.md#important-notes](ACCESS-CONTROL.md#important-notes) for more details. + +## REST API + +```ts +import { stringify } from 'qs-esm' + +const query = { + status: { equals: 'published' }, +} + +const queryString = stringify( + { + where: query, + depth: 2, + limit: 10, + }, + { addQueryPrefix: true }, +) + +const response = await fetch(`https://api.example.com/api/posts${queryString}`) +const data = await response.json() +``` + +### REST Endpoints + +```txt +GET /api/{collection} - Find documents +GET /api/{collection}/{id} - Find by ID +POST /api/{collection} - Create +PATCH /api/{collection}/{id} - Update +DELETE /api/{collection}/{id} - Delete +GET /api/{collection}/count - Count documents + +GET /api/globals/{slug} - Get global +POST /api/globals/{slug} - Update global +``` + +## GraphQL + +```graphql +query { + Posts(where: { status: { equals: published } }, limit: 10, sort: "-createdAt") { + docs { + id + title + author { + name + } + } + totalDocs + hasNextPage + } +} + +mutation { + createPost(data: { title: "New Post", status: draft }) { + id + title + } +} + +mutation { + updatePost(id: "123", data: { status: published }) { + id + status + } +} + +mutation { + deletePost(id: "123") { + id + } +} +``` + +## Performance Best Practices + +- Set `maxDepth` on relationships to prevent over-fetching +- Use `select` to limit returned fields +- Index frequently queried fields +- Use `virtual` fields for computed data +- Cache expensive operations in hook `context` diff --git a/.pi/trust.json b/.pi/trust.json new file mode 100644 index 0000000..d19131f --- /dev/null +++ b/.pi/trust.json @@ -0,0 +1,3 @@ +{ + "/Users/syntaxbullet": true +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..996b10e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +**/payload-types.ts +.tmp +**/.git +**/.hg +**/.pnp.* +**/.svn +**/.yarn/** +**/build +**/dist/** +**/node_modules +**/temp +**/docs/** +tsconfig.json + diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..cb8ee26 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "printWidth": 100, + "semi": false +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..1d7ac85 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..572ee15 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Next.js: debug full stack", + "type": "node", + "request": "launch", + "program": "${workspaceFolder}/node_modules/next/dist/bin/next", + "runtimeArgs": ["--inspect"], + "skipFiles": ["/**"], + "serverReadyAction": { + "action": "debugWithChrome", + "killOnServerStop": true, + "pattern": "- Local:.+(https?://.+)", + "uriFormat": "%s", + "webRoot": "${workspaceFolder}" + }, + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..d53193e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,41 @@ +{ + "npm.packageManager": "pnpm", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true + }, + "editor.formatOnSaveMode": "file", + "js/ts.tsdk.path": "node_modules/typescript/lib", + "js/ts.tsdk.promptToUseWorkspaceVersion": true, + "[javascript][typescript][typescriptreact]": { + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + } + } +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..99e029a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,71 @@ +# To use this Dockerfile, you have to set `output: 'standalone'` in your next.config.js file. +# From https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile + +FROM node:22.17.0-alpine AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +# Remove this line if you do not have this folder +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD HOSTNAME="0.0.0.0" node server.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..669debe --- /dev/null +++ b/README.md @@ -0,0 +1,303 @@ +# Payload Website Template + +This is the official [Payload Website Template](https://github.com/payloadcms/payload/blob/3.x/templates/website). Use it to power websites, blogs, or portfolios from small to enterprise. This repo includes a fully-working backend, enterprise-grade admin panel, and a beautifully designed, production-ready website. + +This template is right for you if you are working on: + +- A personal or enterprise-grade website, blog, or portfolio +- A content publishing platform with a fully featured publication workflow +- Exploring the capabilities of Payload + +Core features: + +- [Pre-configured Payload Config](#how-it-works) +- [Authentication](#users-authentication) +- [Access Control](#access-control) +- [Layout Builder](#layout-builder) +- [Draft Preview](#draft-preview) +- [Live Preview](#live-preview) +- [On-demand Revalidation](#on-demand-revalidation) +- [SEO](#seo) +- [Search](#search) +- [Redirects](#redirects) +- [Jobs and Scheduled Publishing](#jobs-and-scheduled-publish) +- [Website](#website) + +## Quick Start + +To spin up this example locally, follow these steps: + +### Clone + +If you have not done so already, you need to have standalone copy of this repo on your machine. If you've already cloned this repo, skip to [Development](#development). + +Use the `create-payload-app` CLI to clone this template directly to your machine: + +```bash +pnpx create-payload-app my-project -t website +``` + +### Development + +1. First [clone the repo](#clone) if you have not done so already +1. `cd my-project && cp .env.example .env` to copy the example environment variables +1. `pnpm install && pnpm dev` to install dependencies and start the dev server +1. open `http://localhost:3000` to open the app in your browser + +That's it! Changes made in `./src` will be reflected in your app. Follow the on-screen instructions to login and create your first admin user. Then check out [Production](#production) once you're ready to build and serve your app, and [Deployment](#deployment) when you're ready to go live. + +## How it works + +The Payload config is tailored specifically to the needs of most websites. It is pre-configured in the following ways: + +### Collections + +See the [Collections](https://payloadcms.com/docs/configuration/collections) docs for details on how to extend this functionality. + +- #### Users (Authentication) + + Users are auth-enabled collections that have access to the admin panel and unpublished content. See [Access Control](#access-control) for more details. + + For additional help, see the official [Auth Example](https://github.com/payloadcms/payload/tree/3.x/examples/auth) or the [Authentication](https://payloadcms.com/docs/authentication/overview#authentication-overview) docs. + +- #### Posts + + Posts are used to generate blog posts, news articles, or any other type of content that is published over time. All posts are layout builder enabled so you can generate unique layouts for each post using layout-building blocks, see [Layout Builder](#layout-builder) for more details. Posts are also draft-enabled so you can preview them before publishing them to your website, see [Draft Preview](#draft-preview) for more details. + +- #### Pages + + All pages are layout builder enabled so you can generate unique layouts for each page using layout-building blocks, see [Layout Builder](#layout-builder) for more details. Pages are also draft-enabled so you can preview them before publishing them to your website, see [Draft Preview](#draft-preview) for more details. + +- #### Media + + This is the uploads enabled collection used by pages, posts, and projects to contain media like images, videos, downloads, and other assets. It features pre-configured sizes, focal point and manual resizing to help you manage your pictures. + +- #### Categories + + A taxonomy used to group posts together. Categories can be nested inside of one another, for example "News > Technology". See the official [Payload Nested Docs Plugin](https://payloadcms.com/docs/plugins/nested-docs) for more details. + +### Globals + +See the [Globals](https://payloadcms.com/docs/configuration/globals) docs for details on how to extend this functionality. + +- `Header` + + The data required by the header on your front-end like nav links. + +- `Footer` + + Same as above but for the footer of your site. + +## Access control + +Basic access control is setup to limit access to various content based based on publishing status. + +- `users`: Users can access the admin panel and create or edit content. +- `posts`: Everyone can access published posts, but only users can create, update, or delete them. +- `pages`: Everyone can access published pages, but only users can create, update, or delete them. + +For more details on how to extend this functionality, see the [Payload Access Control](https://payloadcms.com/docs/access-control/overview#access-control) docs. + +## Layout Builder + +Create unique page layouts for any type of content using a powerful layout builder. This template comes pre-configured with the following layout building blocks: + +- Hero +- Content +- Media +- Call To Action +- Archive + +Each block is fully designed and built into the front-end website that comes with this template. See [Website](#website) for more details. + +## Lexical editor + +A deep editorial experience that allows complete freedom to focus just on writing content without breaking out of the flow with support for Payload blocks, media, links and other features provided out of the box. See [Lexical](https://payloadcms.com/docs/rich-text/overview) docs. + +## Draft Preview + +All posts and pages are draft-enabled so you can preview them before publishing them to your website. To do this, these collections use [Versions](https://payloadcms.com/docs/configuration/collections#versions) with `drafts` set to `true`. This means that when you create a new post, project, or page, it will be saved as a draft and will not be visible on your website until you publish it. This also means that you can preview your draft before publishing it to your website. To do this, we automatically format a custom URL which redirects to your front-end to securely fetch the draft version of your content. + +Since the front-end of this template is statically generated, this also means that pages, posts, and projects will need to be regenerated as changes are made to published documents. To do this, we use an `afterChange` hook to regenerate the front-end when a document has changed and its `_status` is `published`. + +For more details on how to extend this functionality, see the official [Draft Preview Example](https://github.com/payloadcms/payload/tree/3.x/examples/draft-preview). + +## Live preview + +In addition to draft previews you can also enable live preview to view your end resulting page as you're editing content with full support for SSR rendering. See [Live preview docs](https://payloadcms.com/docs/live-preview/overview) for more details. + +## On-demand Revalidation + +We've added hooks to collections and globals so that all of your pages, posts, footer, or header changes will automatically be updated in the frontend via on-demand revalidation supported by Nextjs. + +> Note: if an image has been changed, for example it's been cropped, you will need to republish the page it's used on in order to be able to revalidate the Nextjs image cache. + +## SEO + +This template comes pre-configured with the official [Payload SEO Plugin](https://payloadcms.com/docs/plugins/seo) for complete SEO control from the admin panel. All SEO data is fully integrated into the front-end website that comes with this template. See [Website](#website) for more details. + +## Search + +This template also pre-configured with the official [Payload Search Plugin](https://payloadcms.com/docs/plugins/search) to showcase how SSR search features can easily be implemented into Next.js with Payload. See [Website](#website) for more details. + +## Redirects + +If you are migrating an existing site or moving content to a new URL, you can use the `redirects` collection to create a proper redirect from old URLs to new ones. This will ensure that proper request status codes are returned to search engines and that your users are not left with a broken link. This template comes pre-configured with the official [Payload Redirects Plugin](https://payloadcms.com/docs/plugins/redirects) for complete redirect control from the admin panel. All redirects are fully integrated into the front-end website that comes with this template. See [Website](#website) for more details. + +## Jobs and Scheduled Publish + +We have configured [Scheduled Publish](https://payloadcms.com/docs/versions/drafts#scheduled-publish) which uses the [jobs queue](https://payloadcms.com/docs/jobs-queue/jobs) in order to publish or unpublish your content on a scheduled time. The tasks are run on a cron schedule and can also be run as a separate instance if needed. + +> Note: When deployed on Vercel, depending on the plan tier, you may be limited to daily cron only. + +## Website + +This template includes a beautifully designed, production-ready front-end built with the [Next.js App Router](https://nextjs.org), served right alongside your Payload app in a instance. This makes it so that you can deploy both your backend and website where you need it. + +Core features: + +- [Next.js App Router](https://nextjs.org) +- [TypeScript](https://www.typescriptlang.org) +- [React Hook Form](https://react-hook-form.com) +- [Payload Admin Bar](https://github.com/payloadcms/payload/tree/3.x/packages/admin-bar) +- [TailwindCSS styling](https://tailwindcss.com/) +- [shadcn/ui components](https://ui.shadcn.com/) +- User Accounts and Authentication +- Fully featured blog +- Publication workflow +- Dark mode +- Pre-made layout building blocks +- SEO +- Search +- Redirects +- Live preview + +### Cache + +Although Next.js includes a robust set of caching strategies out of the box, Payload Cloud proxies and caches all files through Cloudflare using the [Official Cloud Plugin](https://www.npmjs.com/package/@payloadcms/payload-cloud). This means that Next.js caching is not needed and is disabled by default. If you are hosting your app outside of Payload Cloud, you can easily reenable the Next.js caching mechanisms by removing the `no-store` directive from all fetch requests in `./src/app/_api` and then removing all instances of `export const dynamic = 'force-dynamic'` from pages files, such as `./src/app/(pages)/[slug]/page.tsx`. For more details, see the official [Next.js Caching Docs](https://nextjs.org/docs/app/building-your-application/caching). + +## Development + +To spin up this example locally, follow the [Quick Start](#quick-start). Then [Seed](#seed) the database with a few pages, posts, and projects. + +### Working with Postgres + +Postgres and other SQL-based databases follow a strict schema for managing your data. In comparison to our MongoDB adapter, this means that there's a few extra steps to working with Postgres. + +Note that often times when making big schema changes you can run the risk of losing data if you're not manually migrating it. + +#### Local development + +Ideally we recommend running a local copy of your database so that schema updates are as fast as possible. By default the Postgres adapter has `push: true` for development environments. This will let you add, modify and remove fields and collections without needing to run any data migrations. + +If your database is pointed to production you will want to set `push: false` otherwise you will risk losing data or having your migrations out of sync. + +#### Migrations + +[Migrations](https://payloadcms.com/docs/database/migrations) are essentially SQL code versions that keeps track of your schema. When deploy with Postgres you will need to make sure you create and then run your migrations. + +Locally create a migration + +```bash +pnpm payload migrate:create +``` + +This creates the migration files you will need to push alongside with your new configuration. + +On the server after building and before running `pnpm start` you will want to run your migrations + +```bash +pnpm payload migrate +``` + +This command will check for any migrations that have not yet been run and try to run them and it will keep a record of migrations that have been run in the database. + +### Docker + +Alternatively, you can use [Docker](https://www.docker.com) to spin up this template locally. To do so, follow these steps: + +1. Follow [steps 1 and 2 from above](#development), the docker-compose file will automatically use the `.env` file in your project root +1. Next run `docker-compose up` +1. Follow [steps 4 and 5 from above](#development) to login and create your first admin user + +That's it! The Docker instance will help you get up and running quickly while also standardizing the development environment across your teams. + +### Seed + +To seed the database with a few pages, posts, and projects you can click the 'seed database' link from the admin panel. + +The seed script will also create a demo user for demonstration purposes only: + +- Demo Author + - Email: `demo-author@payloadcms.com` + - Password: `password` + +> NOTICE: seeding the database is destructive because it drops your current database to populate a fresh one from the seed template. Only run this command if you are starting a new project or can afford to lose your current data. + +## Production + +To run Payload in production, you need to build and start the Admin panel. To do so, follow these steps: + +1. Invoke the `next build` script by running `pnpm build` or `npm run build` in your project root. This creates a `.next` directory with a production-ready admin bundle. +1. Finally run `pnpm start` or `npm run start` to run Node in production and serve Payload from the `.build` directory. +1. When you're ready to go live, see Deployment below for more details. + +### Deploying to Vercel + +This template can also be deployed to Vercel for free. You can get started by choosing the Vercel DB adapter during the setup of the template or by manually installing and configuring it: + +```bash +pnpm add @payloadcms/db-vercel-postgres +``` + +```ts +// payload.config.ts +import { vercelPostgresAdapter } from '@payloadcms/db-vercel-postgres' + +export default buildConfig({ + // ... + db: vercelPostgresAdapter({ + pool: { + connectionString: process.env.POSTGRES_URL || '', + }, + }), + // ... +``` + +We also support Vercel's blob storage: + +```bash +pnpm add @payloadcms/storage-vercel-blob +``` + +```ts +// payload.config.ts +import { vercelBlobStorage } from '@payloadcms/storage-vercel-blob' + +export default buildConfig({ + // ... + plugins: [ + vercelBlobStorage({ + collections: { + [Media.slug]: true, + }, + token: process.env.BLOB_READ_WRITE_TOKEN || '', + }), + ], + // ... +``` + +There is also a simplified [one click deploy](https://github.com/payloadcms/payload/tree/3.x/templates/with-vercel-postgres) to Vercel should you need it. + +### Self-hosting + +Before deploying your app, you need to: + +1. Ensure your app builds and serves in production. See [Production](#production) for more details. +2. You can then deploy Payload as you would any other Node.js or Next.js application either directly on a VPS, DigitalOcean's Apps Platform, via Coolify or more. More guides coming soon. + +You can also deploy your app manually, check out the [deployment documentation](https://payloadcms.com/docs/production/deployment) for full details. + +## Questions + +If you have any issues or questions, reach out to us on [Discord](https://discord.com/invite/payload) or start a [GitHub discussion](https://github.com/payloadcms/payload/discussions). diff --git a/bun.lock b/bun.lock deleted file mode 100644 index 9904506..0000000 --- a/bun.lock +++ /dev/null @@ -1,457 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 0, - "workspaces": { - "": { - "name": "bmp-website", - "dependencies": { - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-slot": "^1.2.4", - "@uidotdev/usehooks": "^2.4.1", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "embla-carousel-auto-scroll": "^8.6.0", - "embla-carousel-react": "^8.6.0", - "framer-motion": "^12.36.0", - "lucide-react": "^0.577.0", - "motion": "^12.36.0", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "react-router-dom": "^7.13.1", - "tailwind-merge": "^3.5.0", - }, - "devDependencies": { - "@tailwindcss/vite": "^4.2.1", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.4", - "tailwindcss": "^4.2.1", - "vite": "^5.4.0", - }, - }, - }, - "packages": { - "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], - - "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], - - "@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="], - - "@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="], - - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="], - - "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], - - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], - - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="], - - "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], - - "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], - - "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], - - "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], - - "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], - - "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], - - "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], - - "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], - - "@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="], - - "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], - - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], - - "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], - - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], - - "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], - - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], - - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], - - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], - - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], - - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], - - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], - - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], - - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], - - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], - - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], - - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], - - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], - - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], - - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], - - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], - - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], - - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], - - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], - - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], - - "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "^0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], - - "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "^1.7.5", "@floating-ui/utils": "^0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], - - "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.8", "", { "dependencies": { "@floating-ui/dom": "^1.7.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A=="], - - "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], - - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], - - "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], - - "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], - - "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], - - "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - - "@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="], - - "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], - - "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w=="], - - "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.3.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw=="], - - "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw=="], - - "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], - - "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], - - "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw=="], - - "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], - - "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], - - "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], - - "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], - - "@radix-ui/react-label": ["@radix-ui/react-label@2.1.8", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A=="], - - "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.8", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-rect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw=="], - - "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], - - "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], - - "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], - - "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.3.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ=="], - - "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA=="], - - "@radix-ui/react-select": ["@radix-ui/react-select@2.2.6", "", { "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ=="], - - "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.4", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA=="], - - "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], - - "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], - - "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], - - "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], - - "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], - - "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ=="], - - "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.1", "", { "dependencies": { "@radix-ui/rect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w=="], - - "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ=="], - - "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.2.3", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug=="], - - "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.3", "", {}, "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q=="], - - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], - - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], - - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="], - - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="], - - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="], - - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="], - - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="], - - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="], - - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="], - - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="], - - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="], - - "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="], - - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="], - - "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="], - - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="], - - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="], - - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="], - - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="], - - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="], - - "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="], - - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="], - - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="], - - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="], - - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="], - - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="], - - "@tailwindcss/node": ["@tailwindcss/node@4.2.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.1" } }, "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg=="], - - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.1", "@tailwindcss/oxide-darwin-arm64": "4.2.1", "@tailwindcss/oxide-darwin-x64": "4.2.1", "@tailwindcss/oxide-freebsd-x64": "4.2.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", "@tailwindcss/oxide-linux-x64-musl": "4.2.1", "@tailwindcss/oxide-wasm32-wasi": "4.2.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw=="], - - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg=="], - - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw=="], - - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw=="], - - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA=="], - - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw=="], - - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ=="], - - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ=="], - - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g=="], - - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g=="], - - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.1", "", { "cpu": "none" }, "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q=="], - - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA=="], - - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ=="], - - "@tailwindcss/vite": ["@tailwindcss/vite@4.2.1", "", { "dependencies": { "@tailwindcss/node": "4.2.1", "@tailwindcss/oxide": "4.2.1", "tailwindcss": "4.2.1" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w=="], - - "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], - - "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], - - "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], - - "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], - - "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], - - "@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="], - - "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - - "@uidotdev/usehooks": ["@uidotdev/usehooks@2.4.1", "", { "peerDependencies": { "react": ">=18.0.0", "react-dom": ">=18.0.0" } }, "sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg=="], - - "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.4", "", { "dependencies": { "@babel/core": "^7.29.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA=="], - - "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], - - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.0", "", { "bin": "dist/cli.cjs" }, "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA=="], - - "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": "cli.js" }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], - - "caniuse-lite": ["caniuse-lite@1.0.30001777", "", {}, "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ=="], - - "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "^2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], - - "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], - - "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - - "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], - - "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - - "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], - - "electron-to-chromium": ["electron-to-chromium@1.5.307", "", {}, "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg=="], - - "embla-carousel": ["embla-carousel@8.6.0", "", {}, "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="], - - "embla-carousel-auto-scroll": ["embla-carousel-auto-scroll@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-WT9fWhNXFpbQ6kP+aS07oF5IHYLZ1Dx4DkwgCY8Hv2ZyYd2KMCPfMV1q/cA3wFGuLO7GMgKiySLX90/pQkcOdQ=="], - - "embla-carousel-react": ["embla-carousel-react@8.6.0", "", { "dependencies": { "embla-carousel": "8.6.0", "embla-carousel-reactive-utils": "8.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA=="], - - "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.6.0", "", { "peerDependencies": { "embla-carousel": "8.6.0" } }, "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A=="], - - "enhanced-resolve": ["enhanced-resolve@5.20.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ=="], - - "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], - - "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - - "framer-motion": ["framer-motion@12.36.0", "", { "dependencies": { "motion-dom": "^12.36.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-4PqYHAT7gev0ke0wos+PyrcFxI0HScjm3asgU8nSYa8YzJFuwgIvdj3/s3ZaxLq0bUSboIn19A2WS/MHwLCvfw=="], - - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], - - "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], - - "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], - - "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - - "jiti": ["jiti@2.6.1", "", { "bin": "lib/jiti-cli.mjs" }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - - "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - - "jsesc": ["jsesc@3.1.0", "", { "bin": "bin/jsesc" }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], - - "json5": ["json5@2.2.3", "", { "bin": "lib/cli.js" }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], - - "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], - - "lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="], - - "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="], - - "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="], - - "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="], - - "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="], - - "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="], - - "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="], - - "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="], - - "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="], - - "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="], - - "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="], - - "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], - - "lucide-react": ["lucide-react@0.577.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A=="], - - "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - - "motion": ["motion@12.36.0", "", { "dependencies": { "framer-motion": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-5BMQuktYUX8aEByKWYx5tR4X3G08H2OMgp46wTxZ4o7CDDstyy4A0fe9RLNMjZiwvntCWGDvs16sC87/emz4Yw=="], - - "motion-dom": ["motion-dom@12.36.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-Ep1pq8P88rGJ75om8lTCA13zqd7ywPGwCqwuWwin6BKc0hMLkVfcS6qKlRqEo2+t0DwoUcgGJfXwaiFn4AOcQA=="], - - "motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="], - - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - - "nanoid": ["nanoid@3.3.11", "", { "bin": "bin/nanoid.cjs" }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="], - - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="], - - "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], - - "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], - - "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="], - - "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], - - "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], - - "react-router": ["react-router@7.13.1", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA=="], - - "react-router-dom": ["react-router-dom@7.13.1", "", { "dependencies": { "react-router": "7.13.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw=="], - - "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], - - "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], - - "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - - "semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "set-cookie-parser": ["set-cookie-parser@2.7.2", "", {}, "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="], - - "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - - "tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="], - - "tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="], - - "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], - - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - - "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], - - "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], - - "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], - - "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], - - "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - - "@radix-ui/react-collection/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-label/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.4", "", { "dependencies": { "@radix-ui/react-slot": "1.2.4" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg=="], - - "@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - - "@radix-ui/react-select/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" } }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], - } -} diff --git a/components.json b/components.json new file mode 100644 index 0000000..ff4511f --- /dev/null +++ b/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.mjs", + "css": "src/app/(frontend)/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/utilities/ui" + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4c9fc51 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3' + +services: + payload: + image: node:18-alpine + ports: + - '3000:3000' + volumes: + - .:/home/node/app + - node_modules:/home/node/app/node_modules + working_dir: /home/node/app/ + command: sh -c "yarn install && yarn dev" + depends_on: + - mongo + env_file: + - .env + + mongo: + image: mongo:latest + ports: + - '27017:27017' + command: + - --storageEngine=wiredTiger + volumes: + - data:/data/db + logging: + driver: none + +volumes: + data: + node_modules: diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..9896220 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,38 @@ +import { dirname } from 'path' +import { fileURLToPath } from 'url' +import { FlatCompat } from '@eslint/eslintrc' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}) + +const eslintConfig = [ + ...compat.extends('next/core-web-vitals', 'next/typescript'), + { + rules: { + '@typescript-eslint/ban-ts-comment': 'warn', + '@typescript-eslint/no-empty-object-type': 'warn', + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + vars: 'all', + args: 'after-used', + ignoreRestSiblings: false, + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^(_|ignore)', + }, + ], + }, + }, + { + ignores: ['.next/', 'src/payload-types.ts', 'src/payload-generated-schema.ts'], + }, +] + +export default eslintConfig diff --git a/index.html b/index.html deleted file mode 100644 index 7eead68..0000000 --- a/index.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - Bayerischer Mittelstandspreis – Exzellenz im Mittelstand - - - -
- - - - diff --git a/next-sitemap.config.cjs b/next-sitemap.config.cjs new file mode 100644 index 0000000..689f088 --- /dev/null +++ b/next-sitemap.config.cjs @@ -0,0 +1,20 @@ +const SITE_URL = + process.env.NEXT_PUBLIC_SERVER_URL || + process.env.VERCEL_PROJECT_PRODUCTION_URL || + 'https://example.com' + +/** @type {import('next-sitemap').IConfig} */ +module.exports = { + siteUrl: SITE_URL, + generateRobotsTxt: true, + exclude: ['/posts-sitemap.xml', '/pages-sitemap.xml', '/*', '/posts/*'], + robotsTxtOptions: { + policies: [ + { + userAgent: '*', + disallow: '/admin/*', + }, + ], + additionalSitemaps: [`${SITE_URL}/pages-sitemap.xml`, `${SITE_URL}/posts-sitemap.xml`], + }, +} diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..988368c --- /dev/null +++ b/next.config.ts @@ -0,0 +1,54 @@ +import { withPayload } from '@payloadcms/next/withPayload' +import type { NextConfig } from 'next' +import path from 'path' +import { fileURLToPath } from 'url' + +const __filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(__filename) +import { redirects } from './redirects' + +const NEXT_PUBLIC_SERVER_URL = process.env.VERCEL_PROJECT_PRODUCTION_URL + ? `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}` + : process.env.__NEXT_PRIVATE_ORIGIN || 'http://localhost:3000' + +const nextConfig: NextConfig = { + // Temporarily required on Windows until Next.js fixes Turbopack Sass resolution. + // See: https://github.com/vercel/next.js/issues/86431 + sassOptions: { + loadPaths: ['./node_modules/@payloadcms/ui/dist/scss/'], + }, + images: { + localPatterns: [ + { + pathname: '/api/media/file/**', + }, + ], + qualities: [100], + remotePatterns: [ + ...[NEXT_PUBLIC_SERVER_URL /* 'https://example.com' */].map((item) => { + const url = new URL(item) + + return { + hostname: url.hostname, + protocol: url.protocol.replace(':', '') as 'http' | 'https', + } + }), + ], + }, + webpack: (webpackConfig) => { + webpackConfig.resolve.extensionAlias = { + '.cjs': ['.cts', '.cjs'], + '.js': ['.ts', '.tsx', '.js', '.jsx'], + '.mjs': ['.mts', '.mjs'], + } + + return webpackConfig + }, + reactStrictMode: true, + redirects, + turbopack: { + root: path.resolve(dirname), + }, +} + +export default withPayload(nextConfig, { devBundleServerPackages: false }) diff --git a/package-lock.json b/package-lock.json index 6b8cad1..5e594fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,45 +1,177 @@ { - "name": "bmp-website", + "name": "bmp-website-payloadcms", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "bmp-website", + "name": "bmp-website-payloadcms", "version": "1.0.0", + "license": "MIT", "dependencies": { - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-label": "^2.1.8", + "@payloadcms/admin-bar": "3.85.1", + "@payloadcms/db-sqlite": "3.85.1", + "@payloadcms/live-preview-react": "3.85.1", + "@payloadcms/next": "3.85.1", + "@payloadcms/plugin-form-builder": "3.85.1", + "@payloadcms/plugin-nested-docs": "3.85.1", + "@payloadcms/plugin-redirects": "3.85.1", + "@payloadcms/plugin-search": "3.85.1", + "@payloadcms/plugin-seo": "3.85.1", + "@payloadcms/richtext-lexical": "3.85.1", + "@payloadcms/ui": "3.85.1", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-slot": "^1.2.4", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-slot": "^1.0.2", "@uidotdev/usehooks": "^2.4.1", - "class-variance-authority": "^0.7.1", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "cross-env": "^7.0.3", + "dotenv": "16.4.7", "embla-carousel-auto-scroll": "^8.6.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.36.0", - "lucide-react": "^0.577.0", + "geist": "^1.3.0", + "graphql": "^16.8.2", + "lucide-react": "0.563.0", "motion": "^12.36.0", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "react-router-dom": "^7.13.1", - "tailwind-merge": "^3.5.0" + "next": "16.2.6", + "next-sitemap": "^4.2.3", + "payload": "3.85.1", + "prism-react-renderer": "^2.3.1", + "react": "19.2.6", + "react-dom": "19.2.6", + "react-hook-form": "7.71.1", + "sharp": "0.34.2", + "tailwind-merge": "^3.4.0" }, "devDependencies": { - "@tailwindcss/vite": "^4.2.1", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.4", - "tailwindcss": "^4.2.1", - "vite": "^5.4.0" + "@eslint/eslintrc": "^3.2.0", + "@playwright/test": "1.58.2", + "@tailwindcss/postcss": "^4.1.18", + "@tailwindcss/typography": "^0.5.19", + "@testing-library/react": "16.3.0", + "@types/escape-html": "^1.0.2", + "@types/node": "22.19.9", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "@vitejs/plugin-react": "4.5.2", + "autoprefixer": "^10.4.19", + "eslint": "^9.16.0", + "eslint-config-next": "16.2.6", + "jsdom": "28.0.0", + "postcss": "^8.4.38", + "prettier": "^3.4.2", + "tailwindcss": "^4.1.18", + "tsx": "4.22.4", + "tw-animate-css": "^1.4.0", + "typescript": "5.7.3", + "vite-tsconfig-paths": "6.0.5", + "vitest": "4.0.18" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0", + "pnpm": "^9 || ^10" } }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.9.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", + "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", + "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", @@ -95,7 +227,6 @@ "version": "7.29.1", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.0", @@ -129,7 +260,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -139,7 +269,6 @@ "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.28.6", @@ -181,7 +310,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -191,7 +319,6 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -225,7 +352,6 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -269,11 +395,19 @@ "@babel/core": "^7.0.0-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/@babel/template": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.28.6", @@ -288,7 +422,6 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.0", @@ -307,7 +440,6 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -317,10 +449,809 @@ "node": ">=6.9.0" } }, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz", + "integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@corex/deepmerge": { + "version": "4.0.43", + "resolved": "https://registry.npmjs.org/@corex/deepmerge/-/deepmerge-4.0.43.tgz", + "integrity": "sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==", + "license": "MIT" + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.7.tgz", + "integrity": "sha512-CmjJFQTFQx/U/xNJhSjCQ0ilpesPmNQ8+eOUeM/+kDOVW33qsIjeOXc27vrQDdWVkf83ZSWwtg7kXSUvKDJ8cQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.5.tgz", + "integrity": "sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@date-fns/tz": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.2.0.tgz", + "integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg==", + "license": "MIT" + }, + "node_modules/@dnd-kit/accessibility": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz", + "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/core": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz", + "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==", + "license": "MIT", + "dependencies": { + "@dnd-kit/accessibility": "^3.1.1", + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/modifiers": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/modifiers/-/modifiers-9.0.0.tgz", + "integrity": "sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/sortable": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz", + "integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==", + "license": "MIT", + "dependencies": { + "@dnd-kit/utilities": "^3.2.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "@dnd-kit/core": "^6.3.0", + "react": ">=16.8.0" + } + }, + "node_modules/@dnd-kit/utilities": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz", + "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@drizzle-team/brocli": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz", + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==", + "license": "Apache-2.0" + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild-kit/core-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", + "deprecated": "Merged into tsx: https://tsx.is", + "license": "MIT", + "dependencies": { + "esbuild": "~0.18.20", + "source-map-support": "^0.5.21" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/@esbuild-kit/esm-loader": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz", + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", + "deprecated": "Merged into tsx: https://tsx.is", + "license": "MIT", + "dependencies": { + "@esbuild-kit/core-utils": "^3.3.2", + "get-tsconfig": "^4.7.0" + } + }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "cpu": [ "ppc64" ], @@ -331,13 +1262,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "cpu": [ "arm" ], @@ -348,13 +1279,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "cpu": [ "arm64" ], @@ -365,13 +1296,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "cpu": [ "x64" ], @@ -382,13 +1313,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "cpu": [ "arm64" ], @@ -399,13 +1330,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "cpu": [ "x64" ], @@ -416,13 +1347,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "cpu": [ "arm64" ], @@ -433,13 +1364,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "cpu": [ "x64" ], @@ -450,13 +1381,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "cpu": [ "arm" ], @@ -467,13 +1398,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "cpu": [ "arm64" ], @@ -484,13 +1415,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "cpu": [ "ia32" ], @@ -501,13 +1432,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "cpu": [ "loong64" ], @@ -518,13 +1449,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "cpu": [ "mips64el" ], @@ -535,13 +1466,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "cpu": [ "ppc64" ], @@ -552,13 +1483,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "cpu": [ "riscv64" ], @@ -569,13 +1500,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "cpu": [ "s390x" ], @@ -586,13 +1517,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "cpu": [ "x64" ], @@ -603,13 +1534,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "cpu": [ "x64" ], @@ -620,13 +1568,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "cpu": [ "x64" ], @@ -637,13 +1602,30 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "cpu": [ "x64" ], @@ -654,13 +1636,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "cpu": [ "arm64" ], @@ -671,13 +1653,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "cpu": [ "ia32" ], @@ -688,13 +1670,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", + "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "cpu": [ "x64" ], @@ -705,7 +1687,222 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@faceless-ui/modal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@faceless-ui/modal/-/modal-3.0.0.tgz", + "integrity": "sha512-o3oEFsot99EQ8RJc1kL3s/nNMHX+y+WMXVzSSmca9L0l2MR6ez2QM1z1yIelJX93jqkLXQ9tW+R9tmsYa+O4Qg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/jacobsfletch" + } + ], + "license": "MIT", + "dependencies": { + "body-scroll-lock": "4.0.0-beta.0", + "focus-trap": "7.5.4", + "react-transition-group": "4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@faceless-ui/scroll-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@faceless-ui/scroll-info/-/scroll-info-2.0.0.tgz", + "integrity": "sha512-BkyJ9OQ4bzpKjE3UhI8BhcG36ZgfB4run8TmlaR4oMFUbl59dfyarNfjveyimrxIso9RhFEja/AJ5nQmbcR9hw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/jacobsfletch" + } + ], + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@faceless-ui/window-info": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@faceless-ui/window-info/-/window-info-3.0.1.tgz", + "integrity": "sha512-uPjdJYE/j7hqVNelE9CRUNOeXuXDdPxR4DMe+oz3xwyZi2Y4CxsfpfdPTqqwmNAZa1P33O+ZiCyIkBEeNed0kw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/jacobsfletch" + } + ], + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/@floating-ui/core": { @@ -727,6 +1924,21 @@ "@floating-ui/utils": "^0.2.11" } }, + "node_modules/@floating-ui/react": { + "version": "0.27.19", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.19.tgz", + "integrity": "sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.8", + "@floating-ui/utils": "^0.2.11", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=17.0.0", + "react-dom": ">=17.0.0" + } + }, "node_modules/@floating-ui/react-dom": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz", @@ -746,11 +1958,558 @@ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", "license": "MIT" }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.2.tgz", + "integrity": "sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.1.0.tgz", + "integrity": "sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.1.0.tgz", + "integrity": "sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.1.0.tgz", + "integrity": "sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.1.0.tgz", + "integrity": "sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.1.0.tgz", + "integrity": "sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.1.0.tgz", + "integrity": "sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.1.0.tgz", + "integrity": "sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.1.0.tgz", + "integrity": "sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.2.tgz", + "integrity": "sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.2.tgz", + "integrity": "sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64/node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.2.tgz", + "integrity": "sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.1.0" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.2.tgz", + "integrity": "sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.2.tgz", + "integrity": "sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.2.tgz", + "integrity": "sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.1.0" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.2.tgz", + "integrity": "sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.4.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.2.tgz", + "integrity": "sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.2.tgz", + "integrity": "sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.2.tgz", + "integrity": "sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -772,7 +2531,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -782,20 +2540,1019 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "license": "MIT" + }, + "node_modules/@lexical/clipboard": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.41.0.tgz", + "integrity": "sha512-Ex5lPkb4NBBX1DCPzOAIeHBJFH1bJcmATjREaqpnTfxCbuOeQkt44wchezUA0oDl+iAxNZ3+pLLWiUju9icoSA==", + "license": "MIT", + "dependencies": { + "@lexical/html": "0.41.0", + "@lexical/list": "0.41.0", + "@lexical/selection": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/code": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/code/-/code-0.41.0.tgz", + "integrity": "sha512-0hoNi1KC9/N3SBOGcOcFqnT0OpwmcRRAhfxTKMGqfCtCvAMzULVwZ8RWc9/NV9bKYESgBTW5D9xkDANP2mspHg==", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.41.0", + "lexical": "0.41.0", + "prismjs": "^1.30.0" + } + }, + "node_modules/@lexical/devtools-core": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.41.0.tgz", + "integrity": "sha512-FzJtluBhBc8bKS11TUZe72KoZN/hnzIyiiM0SPJAsPwGpoXuM01jqpXQGybWf/1bWB+bmmhOae7O4Nywi/Csuw==", + "license": "MIT", + "dependencies": { + "@lexical/html": "0.41.0", + "@lexical/link": "0.41.0", + "@lexical/mark": "0.41.0", + "@lexical/table": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/dragon": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.41.0.tgz", + "integrity": "sha512-gBEqkk8Q6ZPruvDaRcOdF1EK9suCVBODzOCcR+EnoJTaTjfDkCM7pkPAm4w90Wa1wCZEtFHvCfas+jU9MDSumg==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/extension": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/extension/-/extension-0.41.0.tgz", + "integrity": "sha512-sF4SPiP72yXvIGchmmIZ7Yg2XZTxNLOpFEIIzdqG7X/1fa1Ham9P/T7VbrblWpF6Ei5LJtK9JgNVB0hb4l3o1g==", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.41.0", + "@preact/signals-core": "^1.11.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/hashtag": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.41.0.tgz", + "integrity": "sha512-tFWM74RW4KU0E/sj2aowfWl26vmLUTp331CgVESnhQKcZBfT40KJYd57HEqBDTfQKn4MUhylQCCA0hbpw6EeFQ==", + "license": "MIT", + "dependencies": { + "@lexical/text": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/headless": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/headless/-/headless-0.41.0.tgz", + "integrity": "sha512-MH8oDuUKdM/Jq0c9vlEEkCL9pEQg4SwyrABBGIbFf+87VBJ5EWDdG9g1vJq7fKSDxfhFux7F5+i+zgUnxOQR/g==", + "license": "MIT", + "dependencies": { + "happy-dom": "^20.0.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/history": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.41.0.tgz", + "integrity": "sha512-kGoVWsiOn62+RMjRolRa+NXZl8jFwxav6GNDiHH8yzivtoaH8n1SwUfLJELXCzeqzs81HySqD4q30VLJVTGoDg==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/html": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.41.0.tgz", + "integrity": "sha512-3RyZy+H/IDKz2D66rNN/NqYx87xVFrngfEbyu1OWtbY963RUFnopiVHCQvsge/8kT04QSZ7U/DzjVFqeNS6clg==", + "license": "MIT", + "dependencies": { + "@lexical/selection": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/link": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.41.0.tgz", + "integrity": "sha512-Rjtx5cGWAkKcnacncbVsZ1TqRnUB2Wm4eEVKpaAEG41+kHgqghzM2P+UGT15yROroxJu8KvAC9ISiYFiU4XE1w==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/list": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.41.0.tgz", + "integrity": "sha512-RXvB+xcbzVoQLGRDOBRCacztG7V+bI95tdoTwl8pz5xvgPtAaRnkZWMDP+yMNzMJZsqEChdtpxbf0NgtMkun6g==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.41.0", + "@lexical/selection": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/mark": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.41.0.tgz", + "integrity": "sha512-UO5WVs9uJAYIKHSlYh4Z1gHrBBchTOi21UCYBIZ7eAs4suK84hPzD+3/LAX5CB7ZltL6ke5Sly3FOwNXv/wfpA==", + "license": "MIT", + "dependencies": { + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/markdown": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.41.0.tgz", + "integrity": "sha512-bzI73JMXpjGFhqUWNV6KqfjWcgAWzwFT+J3RHtbCF5rysC8HLldBYojOgAAtPfXqfxyv2mDzsY7SoJ75s9uHZA==", + "license": "MIT", + "dependencies": { + "@lexical/code": "0.41.0", + "@lexical/link": "0.41.0", + "@lexical/list": "0.41.0", + "@lexical/rich-text": "0.41.0", + "@lexical/text": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/offset": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/offset/-/offset-0.41.0.tgz", + "integrity": "sha512-2RHBXZqC8gm3X9C0AyRb0M8w7zJu5dKiasrif+jSKzsxPjAUeF1m95OtIOsWs1XLNUgASOSUqGovDZxKJslZfA==", + "license": "MIT", + "dependencies": { + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/overflow": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.41.0.tgz", + "integrity": "sha512-Iy6ZiJip8X14EBYt1zKPOrXyQ4eG9JLBEoPoSVBTiSbVd+lYicdUvaOThT0k0/qeVTN9nqTaEltBjm56IrVKCQ==", + "license": "MIT", + "dependencies": { + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/plain-text": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.41.0.tgz", + "integrity": "sha512-HIsGgmFUYRUNNyvckun33UQfU7LRzDlxymHUq67+Bxd5bXqdZOrStEKJXuDX+LuLh/GXZbaWNbDLqwLBObfbQg==", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.41.0", + "@lexical/dragon": "0.41.0", + "@lexical/selection": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/react": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.41.0.tgz", + "integrity": "sha512-7+GUdZUm6sofWm+zdsWAs6cFBwKNsvsHezZTrf6k8jrZxL461ZQmbz/16b4DvjCGL9r5P1fR7md9/LCmk8TiCg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.16", + "@lexical/devtools-core": "0.41.0", + "@lexical/dragon": "0.41.0", + "@lexical/extension": "0.41.0", + "@lexical/hashtag": "0.41.0", + "@lexical/history": "0.41.0", + "@lexical/link": "0.41.0", + "@lexical/list": "0.41.0", + "@lexical/mark": "0.41.0", + "@lexical/markdown": "0.41.0", + "@lexical/overflow": "0.41.0", + "@lexical/plain-text": "0.41.0", + "@lexical/rich-text": "0.41.0", + "@lexical/table": "0.41.0", + "@lexical/text": "0.41.0", + "@lexical/utils": "0.41.0", + "@lexical/yjs": "0.41.0", + "lexical": "0.41.0", + "react-error-boundary": "^6.0.0" + }, + "peerDependencies": { + "react": ">=17.x", + "react-dom": ">=17.x" + } + }, + "node_modules/@lexical/react/node_modules/react-error-boundary": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.1.2.tgz", + "integrity": "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, + "node_modules/@lexical/rich-text": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.41.0.tgz", + "integrity": "sha512-yUcr7ZaaVTZNi8bow4CK1M8jy2qyyls1Vr+5dVjwBclVShOL/F/nFyzBOSb6RtXXRbd3Ahuk9fEleppX/RNIdw==", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.41.0", + "@lexical/dragon": "0.41.0", + "@lexical/selection": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/selection": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.41.0.tgz", + "integrity": "sha512-1s7/kNyRzcv5uaTwsUL28NpiisqTf5xZ1zNukLsCN1xY+TWbv9RE9OxIv+748wMm4pxNczQe/UbIBODkbeknLw==", + "license": "MIT", + "dependencies": { + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/table": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.41.0.tgz", + "integrity": "sha512-d3SPThBAr+oZ8O74TXU0iXM3rLbrAVC7/HcOnSAq7/AhWQW8yMutT51JQGN+0fMLP9kqoWSAojNtkdvzXfU/+A==", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.41.0", + "@lexical/extension": "0.41.0", + "@lexical/utils": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/text": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.41.0.tgz", + "integrity": "sha512-gGA+Anc7ck110EXo4KVKtq6Ui3M7Vz3OpGJ4QE6zJHWW8nV5h273koUGSutAMeoZgRVb6t01Izh3ORoFt/j1CA==", + "license": "MIT", + "dependencies": { + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/utils": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.41.0.tgz", + "integrity": "sha512-Wlsokr5NQCq83D+7kxZ9qs5yQ3dU3Qaf2M+uXxLRoPoDaXqW8xTWZq1+ZFoEzsHzx06QoPa4Vu/40BZR91uQPg==", + "license": "MIT", + "dependencies": { + "@lexical/selection": "0.41.0", + "lexical": "0.41.0" + } + }, + "node_modules/@lexical/yjs": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.41.0.tgz", + "integrity": "sha512-PaKTxSbVC4fpqUjQ7vUL9RkNF1PjL8TFl5jRe03PqoPYpE33buf3VXX6+cOUEfv9+uknSqLCPHoBS/4jN3a97w==", + "license": "MIT", + "dependencies": { + "@lexical/offset": "0.41.0", + "@lexical/selection": "0.41.0", + "lexical": "0.41.0" + }, + "peerDependencies": { + "yjs": ">=13.5.22" + } + }, + "node_modules/@libsql/client": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.14.0.tgz", + "integrity": "sha512-/9HEKfn6fwXB5aTEEoMeFh4CtG0ZzbncBb1e++OCdVpgKZ/xyMsIVYXm0w7Pv4RUel803vE6LwniB3PqD72R0Q==", + "license": "MIT", + "dependencies": { + "@libsql/core": "^0.14.0", + "@libsql/hrana-client": "^0.7.0", + "js-base64": "^3.7.5", + "libsql": "^0.4.4", + "promise-limit": "^2.7.0" + } + }, + "node_modules/@libsql/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.14.0.tgz", + "integrity": "sha512-nhbuXf7GP3PSZgdCY2Ecj8vz187ptHlZQ0VRc751oB2C1W8jQUXKKklvt7t1LJiUTQBVJuadF628eUk+3cRi4Q==", + "license": "MIT", + "dependencies": { + "js-base64": "^3.7.5" + } + }, + "node_modules/@libsql/darwin-arm64": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/darwin-arm64/-/darwin-arm64-0.4.7.tgz", + "integrity": "sha512-yOL742IfWUlUevnI5PdnIT4fryY3LYTdLm56bnY0wXBw7dhFcnjuA7jrH3oSVz2mjZTHujxoITgAE7V6Z+eAbg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@libsql/darwin-x64": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/darwin-x64/-/darwin-x64-0.4.7.tgz", + "integrity": "sha512-ezc7V75+eoyyH07BO9tIyJdqXXcRfZMbKcLCeF8+qWK5nP8wWuMcfOVywecsXGRbT99zc5eNra4NEx6z5PkSsA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@libsql/hrana-client": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.7.0.tgz", + "integrity": "sha512-OF8fFQSkbL7vJY9rfuegK1R7sPgQ6kFMkDamiEccNUvieQ+3urzfDFI616oPl8V7T9zRmnTkSjMOImYCAVRVuw==", + "license": "MIT", + "dependencies": { + "@libsql/isomorphic-fetch": "^0.3.1", + "@libsql/isomorphic-ws": "^0.1.5", + "js-base64": "^3.7.5", + "node-fetch": "^3.3.2" + } + }, + "node_modules/@libsql/isomorphic-fetch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@libsql/isomorphic-fetch/-/isomorphic-fetch-0.3.1.tgz", + "integrity": "sha512-6kK3SUK5Uu56zPq/Las620n5aS9xJq+jMBcNSOmjhNf/MUvdyji4vrMTqD7ptY7/4/CAVEAYDeotUz60LNQHtw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@libsql/isomorphic-ws": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@libsql/isomorphic-ws/-/isomorphic-ws-0.1.5.tgz", + "integrity": "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==", + "license": "MIT", + "dependencies": { + "@types/ws": "^8.5.4", + "ws": "^8.13.0" + } + }, + "node_modules/@libsql/linux-arm64-gnu": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.4.7.tgz", + "integrity": "sha512-WlX2VYB5diM4kFfNaYcyhw5y+UJAI3xcMkEUJZPtRDEIu85SsSFrQ+gvoKfcVh76B//ztSeEX2wl9yrjF7BBCA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-arm64-musl": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.4.7.tgz", + "integrity": "sha512-6kK9xAArVRlTCpWeqnNMCoXW1pe7WITI378n4NpvU5EJ0Ok3aNTIC2nRPRjhro90QcnmLL1jPcrVwO4WD1U0xw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-x64-gnu": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.4.7.tgz", + "integrity": "sha512-CMnNRCmlWQqqzlTw6NeaZXzLWI8bydaXDke63JTUCvu8R+fj/ENsLrVBtPDlxQ0wGsYdXGlrUCH8Qi9gJep0yQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-x64-musl": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/linux-x64-musl/-/linux-x64-musl-0.4.7.tgz", + "integrity": "sha512-nI6tpS1t6WzGAt1Kx1n1HsvtBbZ+jHn0m7ogNNT6pQHZQj7AFFTIMeDQw/i/Nt5H38np1GVRNsFe99eSIMs9XA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/win32-x64-msvc": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.4.7.tgz", + "integrity": "sha512-7pJzOWzPm6oJUxml+PCDRzYQ4A1hTMHAciTAHfFK4fkbDZX33nWPVG7Y3vqdKtslcwAzwmrNDc6sXy2nwWnbiw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@monaco-editor/loader": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.7.0.tgz", + "integrity": "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", + "dependencies": { + "@monaco-editor/loader": "^1.5.0" + }, + "peerDependencies": { + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", + "integrity": "sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@neon-rs/load": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.0.4.tgz", + "integrity": "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==", + "license": "MIT" + }, + "node_modules/@next/env": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.6.tgz", + "integrity": "sha512-gd8HoHN4ufj73WmR3JmVolrpJR47ILK6LouP5xElPglaVxir6e1a7VzvTvDWkOoPXT9rkkTzyCxBu4yeZfZwcw==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.6.tgz", + "integrity": "sha512-Z8l6o4JWKUl755x4R+wogD86KPeU+Ckw4K+SYG4kHeOJtRenDeK+OSbGcqZpDtbwn9DsJVdir2UxmwXuinUbUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.6.tgz", + "integrity": "sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.6.tgz", + "integrity": "sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.6.tgz", + "integrity": "sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.6.tgz", + "integrity": "sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.6.tgz", + "integrity": "sha512-DOj182mPV8G3UkrayLoREM5YEYI+Dk5wv7Ox9xl1fFibAELEsFD0lDPfHIeILlutMMfdyhlzYPELG3peuKaurw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.6.tgz", + "integrity": "sha512-HKQ5SP/V/ub73UvF7n/zeJlxk2kLmtL7Wzrg4WfmkjmNos5onJ2tKu7yZOPdL18A6Svfn3max29ym+ry7NkK4g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.6.tgz", + "integrity": "sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.6.tgz", + "integrity": "sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@payloadcms/admin-bar": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/admin-bar/-/admin-bar-3.85.1.tgz", + "integrity": "sha512-PVseO4Ah7jsm/C+9VNSeGvS/LJf61hqNSXWeHFy5RVlfurGP04rIkt5VahyrPV595dfr04MhgTraIDxBT0YR3Q==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/db-sqlite": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/db-sqlite/-/db-sqlite-3.85.1.tgz", + "integrity": "sha512-+5bVk9ClpwJB9w6zoPeaLABRWbsLAxgfgl5dWGBxo+UwTgc8DYrzDukycvZ3cR/TB/pRnyoA+33rP7mEpeVA7g==", + "license": "MIT", + "dependencies": { + "@libsql/client": "0.14.0", + "@payloadcms/drizzle": "3.85.1", + "console-table-printer": "2.12.1", + "drizzle-kit": "0.31.7", + "drizzle-orm": "0.45.2", + "prompts": "2.4.2", + "to-snake-case": "1.0.0", + "uuid": "13.0.2" + }, + "peerDependencies": { + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/drizzle": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/drizzle/-/drizzle-3.85.1.tgz", + "integrity": "sha512-TVvw+tdvINf1y9bhkwjhGYguDybT3BJpTFzftKrsu034HqlN8ecc84ii35PXeiSsPciVWVgfgwAg9TSHQv4DFg==", + "license": "MIT", + "dependencies": { + "console-table-printer": "2.12.1", + "dequal": "2.0.3", + "drizzle-orm": "0.45.2", + "prompts": "2.4.2", + "to-snake-case": "1.0.0", + "uuid": "13.0.2" + }, + "peerDependencies": { + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/graphql": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/graphql/-/graphql-3.85.1.tgz", + "integrity": "sha512-jMrSCiGYmsjOUGmZayX5U7Vh3i8IcO0XMmQ9x5jCIZuB+/sNDiBNeHJWArC+H2cfPYh0G+iv9t+RpPg6FemiMg==", + "license": "MIT", + "dependencies": { + "graphql-scalars": "1.22.2", + "pluralize": "8.0.0", + "ts-essentials": "10.0.3", + "tsx": "4.22.4" + }, + "bin": { + "payload-graphql": "bin.js" + }, + "peerDependencies": { + "graphql": "^16.8.1", + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/live-preview": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/live-preview/-/live-preview-3.85.1.tgz", + "integrity": "sha512-nyHVt38sXx4KFtCdoMnPbFu06y5Isp6iCKhK8Y8biXTnNVk+YyhhaIRVVHMSzttMBft8VEPlXsIUvrwtj5+Z0g==", + "license": "MIT" + }, + "node_modules/@payloadcms/live-preview-react": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/live-preview-react/-/live-preview-react-3.85.1.tgz", + "integrity": "sha512-rfw/US7dDt2+0T4rLlstkKt5heZIoKKLfLs5h6WiYZcnmQKxoch07DcKUIaoQpCgExT5tYdxSTGHQybCIb1QgA==", + "license": "MIT", + "dependencies": { + "@payloadcms/live-preview": "3.85.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/next": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/next/-/next-3.85.1.tgz", + "integrity": "sha512-k/2l2LQNrgfa5r5ibR0o4/nNhLAlQQXtLpwGrJq2/B/yws4Ir6otc+ozTMiprATlvVb6uXcNFT+m1XLYqqSFuQ==", + "license": "MIT", + "dependencies": { + "@dnd-kit/core": "6.3.1", + "@dnd-kit/modifiers": "9.0.0", + "@dnd-kit/sortable": "10.0.0", + "@payloadcms/graphql": "3.85.1", + "@payloadcms/translations": "3.85.1", + "@payloadcms/ui": "3.85.1", + "busboy": "^1.6.0", + "dequal": "2.0.3", + "file-type": "21.3.4", + "graphql-http": "^1.22.0", + "graphql-playground-html": "1.6.30", + "http-status": "2.1.0", + "path-to-regexp": "6.3.0", + "qs-esm": "8.0.1", + "sass": "1.77.4", + "uuid": "13.0.2" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0" + }, + "peerDependencies": { + "graphql": "^16.8.1", + "next": ">=15.2.9 <15.3.0 || >=15.3.9 <15.4.0 || >=15.4.11 <15.5.0 || >=16.2.6 <17.0.0", + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/plugin-form-builder": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/plugin-form-builder/-/plugin-form-builder-3.85.1.tgz", + "integrity": "sha512-pfYeJj8RPoHhKDOQHpALHoKZvA1rCmjndbDYMcbHQbILq1wmqTqHnT9v/WY4MOylooLzOYjJxrXpeq1WzMN9gA==", + "license": "MIT", + "dependencies": { + "@payloadcms/ui": "3.85.1", + "escape-html": "^1.0.3" + }, + "peerDependencies": { + "payload": "3.85.1", + "react": "^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/plugin-nested-docs": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/plugin-nested-docs/-/plugin-nested-docs-3.85.1.tgz", + "integrity": "sha512-SzZmvIgchOwn0OgV/JhEmIfQwT537fgo8FEk35Lh0ENPX4xoF2dF9gMCc/2yHpqCaIrXTCKCYYFbh0DcN128qA==", + "license": "MIT", + "peerDependencies": { + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/plugin-redirects": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/plugin-redirects/-/plugin-redirects-3.85.1.tgz", + "integrity": "sha512-gjwS3BQdMlNAkt9UfRHDNdKcoIxiwxaQxdxYCVvzMvXU51azY9W6tALIMMmUaSWnpVUzz4rwwvvlty0LN9lDEA==", + "license": "MIT", + "dependencies": { + "@payloadcms/translations": "3.85.1", + "payload": "3.85.1" + }, + "peerDependencies": { + "payload": "3.85.1" + } + }, + "node_modules/@payloadcms/plugin-search": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/plugin-search/-/plugin-search-3.85.1.tgz", + "integrity": "sha512-rs8J+IAEJQmIzK8Jb6bCoOatPwUSg518J1/xZ/cDmrt+dm2/0V60URTH3TtgiZZDkSGT+x32WQZbPOasju2+Tw==", + "license": "MIT", + "dependencies": { + "@payloadcms/next": "3.85.1", + "@payloadcms/ui": "3.85.1" + }, + "peerDependencies": { + "payload": "3.85.1", + "react": "^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/plugin-seo": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/plugin-seo/-/plugin-seo-3.85.1.tgz", + "integrity": "sha512-cFuMG6B40WbyCjiWUtPfFf6+4LpxZlltRDqjhpni2bUloIHzJlA9MS3my//Ta+RRFyEVyeVW4mr08hHqWg5lKA==", + "license": "MIT", + "dependencies": { + "@payloadcms/translations": "3.85.1", + "@payloadcms/ui": "3.85.1" + }, + "peerDependencies": { + "payload": "3.85.1", + "react": "^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/richtext-lexical": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/richtext-lexical/-/richtext-lexical-3.85.1.tgz", + "integrity": "sha512-58DXm5MotdtGCK1zStrnTdMlWYAJ2IqckEDjWv04xv2FbJc61FEKksqTjkAb5XgBxZKG2lxHNehgrDy97q+FWQ==", + "license": "MIT", + "dependencies": { + "@lexical/clipboard": "0.41.0", + "@lexical/headless": "0.41.0", + "@lexical/html": "0.41.0", + "@lexical/link": "0.41.0", + "@lexical/list": "0.41.0", + "@lexical/mark": "0.41.0", + "@lexical/react": "0.41.0", + "@lexical/rich-text": "0.41.0", + "@lexical/selection": "0.41.0", + "@lexical/table": "0.41.0", + "@lexical/utils": "0.41.0", + "@payloadcms/translations": "3.85.1", + "@payloadcms/ui": "3.85.1", + "acorn": "8.16.0", + "bson-objectid": "2.0.4", + "csstype": "3.1.3", + "dequal": "2.0.3", + "escape-html": "1.0.3", + "jsox": "1.2.121", + "lexical": "0.41.0", + "mdast-util-from-markdown": "2.0.2", + "mdast-util-mdx-jsx": "3.1.3", + "micromark-extension-mdx-jsx": "3.0.1", + "qs-esm": "8.0.1", + "react-error-boundary": "4.1.2", + "ts-essentials": "10.0.3", + "uuid": "13.0.2" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0" + }, + "peerDependencies": { + "@faceless-ui/modal": "3.0.0", + "@faceless-ui/scroll-info": "2.0.0", + "@payloadcms/next": "3.85.1", + "payload": "3.85.1", + "react": "^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/richtext-lexical/node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/@payloadcms/translations": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/translations/-/translations-3.85.1.tgz", + "integrity": "sha512-1DssESAfPjgkp8/f7Xq1ZOCnMjSXp0Xkpbo0I7Zt0DCaA+QY7Go+kZQuSYazKKRF+lgSGzKEHRJ5CWqzhpKh8w==", + "license": "MIT", + "dependencies": { + "date-fns": "4.1.0" + } + }, + "node_modules/@payloadcms/ui": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/@payloadcms/ui/-/ui-3.85.1.tgz", + "integrity": "sha512-WCJBEKAnwIvEi2Hiykl92dLVjGga6sPGsNlkbkssNMDqieEUh6qNAb3HewlJUa0IFrhxVFLoAEyJOzHr1UJXkQ==", + "license": "MIT", + "dependencies": { + "@date-fns/tz": "1.2.0", + "@dnd-kit/core": "6.3.1", + "@dnd-kit/sortable": "10.0.0", + "@dnd-kit/utilities": "3.2.2", + "@faceless-ui/modal": "3.0.0", + "@faceless-ui/scroll-info": "2.0.0", + "@faceless-ui/window-info": "3.0.1", + "@monaco-editor/react": "4.7.0", + "@payloadcms/translations": "3.85.1", + "bson-objectid": "2.0.4", + "date-fns": "4.1.0", + "dequal": "2.0.3", + "md5": "2.3.0", + "object-to-formdata": "4.5.1", + "qs-esm": "8.0.1", + "react-datepicker": "7.6.0", + "react-image-crop": "10.1.8", + "react-select": "5.9.0", + "scheduler": "0.25.0", + "sonner": "^1.7.2", + "ts-essentials": "10.0.3", + "use-context-selector": "2.0.0", + "uuid": "13.0.2" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0" + }, + "peerDependencies": { + "next": ">=15.2.9 <15.3.0 || >=15.3.9 <15.4.0 || >=15.4.11 <15.5.0 || >=16.2.6 <17.0.0", + "payload": "3.85.1", + "react": "^19.0.1 || ^19.1.2 || ^19.2.1", + "react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1" + } + }, + "node_modules/@payloadcms/ui/node_modules/scheduler": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", + "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "license": "MIT" + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@playwright/test": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", + "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@preact/signals-core": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.2.tgz", + "integrity": "sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -1510,9 +4267,9 @@ "license": "MIT" }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", - "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz", + "integrity": "sha512-L/gAA/hyCSuzTF1ftlzUSI/IKr2POHsv1Dd78GfqkR83KMNuswWD61JxGV2L7nRwBBBSDr6R1gCkdTmoN7W4ag==", "dev": true, "license": "MIT" }, @@ -1866,311 +4623,87 @@ "win32" ] }, - "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.1.tgz", + "integrity": "sha512-dNJuNbdEJT/SWRuXTYP1WSamelsz3ztkUsdtWQPjrexysrTpaEPM40P/71knXiXLYEojqPOEGitVLLpPMS5T6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.3.1", + "@tailwindcss/oxide": "4.3.1", + "postcss": "8.5.15", + "tailwindcss": "4.3.1" + } + }, + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/node": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.1.tgz", + "integrity": "sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", - "enhanced-resolve": "^5.19.0", - "jiti": "^2.6.1", - "lightningcss": "1.31.1", + "enhanced-resolve": "5.21.6", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "tailwindcss": "4.3.1" } }, - "node_modules/@tailwindcss/node/node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", - "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.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" - } - }, - "node_modules/@tailwindcss/node/node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", - "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/@tailwindcss/node/node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", - "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/@tailwindcss/node/node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", - "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/@tailwindcss/node/node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", - "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/@tailwindcss/node/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", - "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/@tailwindcss/node/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", - "cpu": [ - "arm64" - ], - "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/@tailwindcss/node/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", - "cpu": [ - "arm64" - ], - "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/@tailwindcss/node/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", - "cpu": [ - "x64" - ], - "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/@tailwindcss/node/node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", - "cpu": [ - "x64" - ], - "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/@tailwindcss/node/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", - "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/@tailwindcss/node/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", - "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/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.1.tgz", + "integrity": "sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA==", "dev": true, "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "@tailwindcss/oxide-android-arm64": "4.3.1", + "@tailwindcss/oxide-darwin-arm64": "4.3.1", + "@tailwindcss/oxide-darwin-x64": "4.3.1", + "@tailwindcss/oxide-freebsd-x64": "4.3.1", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.1", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.1", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.1", + "@tailwindcss/oxide-linux-x64-musl": "4.3.1", + "@tailwindcss/oxide-wasm32-wasi": "4.3.1", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.1", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.1" } }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.1.tgz", + "integrity": "sha512-SVlyf61g374l5cHyg8x9kf5xmLcOaxvOTsbsqDnSsDJaKOEFZ7GCvi84VAVGpxojYOs1+3K6M0UjXfqPU8vmOQ==", "cpu": [ "arm64" ], @@ -2184,10 +4717,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.1.tgz", + "integrity": "sha512-hVnWLwv+e/l7c4WKyVtHVrIPvYdqWHjRB3MDIqARynzFtnQg85kmQEFCbV9Ja0VVx4xXTIiDWY60Y7iz/iNoDA==", "cpu": [ "arm64" ], @@ -2201,10 +4734,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.1.tgz", + "integrity": "sha512-Cf7abu0WVgbhU7ANgPUnSAvm7nCvMweusHb8FnaHlLfv/Caq4GYaEZg7ZImzzmjx4lIAfuS8q+eLIS7A7IzxIg==", "cpu": [ "x64" ], @@ -2218,10 +4751,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.1.tgz", + "integrity": "sha512-ZZqzX2Y+GXtXXfqSfpJhDm60OoZfvLHLCgm+J7NVqgHHJjG/m9ugZI77RwTsVd4fnBJuCFP6Ae6kTJb71UdS8g==", "cpu": [ "x64" ], @@ -2235,10 +4768,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.1.tgz", + "integrity": "sha512-/Ah/xik0LaMYfv9DZ0S/t4pBlBNYOcqtRwusjgovHkvT8ixueWCLyJjsaF5kQIckjb4IT8Q6K6p/iPmZMixYgg==", "cpu": [ "arm" ], @@ -2252,10 +4785,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.1.tgz", + "integrity": "sha512-gqdFoVJlw444GvpnheZLHmvTzSxI/cOUUh2KSNejQjTcYkW062SVD+En0rUgD+QV91bz1XGIGtt1HJd48xUGbQ==", "cpu": [ "arm64" ], @@ -2269,10 +4802,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.1.tgz", + "integrity": "sha512-Bwv9KwOvE0VKa86xPFif9b9c3Y1NxOV1P0gLti/IYaWEsQYZXDlxfGEtA8mdDZ7SG3wyNXAWYT5SIn3giL57oA==", "cpu": [ "arm64" ], @@ -2286,10 +4819,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.1.tgz", + "integrity": "sha512-Ymi8O8T15HYQdOUWUtTI6ldN0neHP85FC+Qz32xTcZ7iJXtem/x8ITev0o1e9e5rkqj4lONZfTRLvkmin1+tKg==", "cpu": [ "x64" ], @@ -2303,10 +4836,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.1.tgz", + "integrity": "sha512-M+P/91qJ6uILLw4k2G93GMDRAXj61SMvFQYt39AqvUqYgExXpLL5aepfns7sj4HiAQeolirQF9E0lzRvdf4zPQ==", "cpu": [ "x64" ], @@ -2320,10 +4853,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.1.tgz", + "integrity": "sha512-zsM8uOeqvVGHsAXsJxsT28ttosFahLJKCLOTUBqRAtKnVgGSRitds9T432QiT8b77Yga7JIBkulIRRlJPtYhRA==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2339,21 +4872,21 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.8.1", - "@emnapi/runtime": "^1.8.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.1", - "@tybys/wasm-util": "^0.10.1", + "@emnapi/core": "^1.10.0", + "@emnapi/runtime": "^1.10.0", + "@emnapi/wasi-threads": "^1.2.1", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", "tslib": "^2.8.1" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.1.tgz", + "integrity": "sha512-aiNvSq9BsVk8V513lDKlrCFAgf8qBMPZTpgEhInL+NwQqs97mYmupVMrPrgBBSL8Pv/0zXu9MrMF9rMun1ZeNg==", "cpu": [ "arm64" ], @@ -2367,10 +4900,10 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "node_modules/@tailwindcss/postcss/node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.1.tgz", + "integrity": "sha512-xDEyu1rg290472FEGaKHnzyDyh5QH+AlWvsU5hMoMtPpzmKlRI0jaYKCgSHDYtaQWZOYbMaduSyCwFwY4n1HmA==", "cpu": [ "x64" ], @@ -2384,19 +4917,124 @@ "node": ">= 20" } }, - "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "node_modules/@tailwindcss/postcss/node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/@tailwindcss/postcss/node_modules/tailwindcss": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.1.tgz", + "integrity": "sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.20.tgz", + "integrity": "sha512-hwbzQuNUfcPvbegQFatVPl/MY/tcM9KLl963hQ5laJKPh81TEZ1+dNG9PirGvcaDBkp+BCshExAyKVPW91dozw==", "dev": true, "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" + "postcss-selector-parser": "6.0.10" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "tailwindcss": ">=3.0.0 || >=4.0.0 || insiders" + } + }, + "node_modules/@testing-library/react": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz", + "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" } }, "node_modules/@types/babel__core": { @@ -2444,18 +5082,133 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/busboy": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.4.tgz", + "integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/escape-html": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/escape-html/-/escape-html-1.0.4.tgz", + "integrity": "sha512-qZ72SFTgUAZ5a7Tj6kf2SHLetiH5S6f8G5frB2SPQ3EyF02kxdyBFf4Tz4banE3xCgGnKgWLt//a6VuYHKYJTg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.24", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", + "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.9.tgz", + "integrity": "sha512-PD03/U8g1F9T9MI+1OBisaIARhSzeidsUjQaf51fOxrfjeiKN9bLVO06lHuHYjxdnqLWJijJHfqXPSJri2EM2A==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -2465,12 +5218,337 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "devOptional": true, + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "license": "MIT" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz", + "integrity": "sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/type-utils": "8.61.1", + "@typescript-eslint/utils": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.61.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz", + "integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz", + "integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.61.1", + "@typescript-eslint/types": "^8.61.1", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz", + "integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz", + "integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.1.tgz", + "integrity": "sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1", + "@typescript-eslint/utils": "8.61.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz", + "integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz", + "integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.61.1", + "@typescript-eslint/tsconfig-utils": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/visitor-keys": "8.61.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.1.tgz", + "integrity": "sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.61.1", + "@typescript-eslint/types": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz", + "integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.61.1", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@uidotdev/usehooks": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@uidotdev/usehooks/-/usehooks-2.4.1.tgz", @@ -2484,27 +5562,546 @@ "react-dom": ">=18.0.0" } }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", - "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.2.tgz", + "integrity": "sha512-QNVT3/Lxx99nMQWJWF7K4N6apUEuT0KlZA3mx/mVaoGj3smm/8rc8ezz15J1pcbcjDK0V15rpHetVfya08r76Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.29.0", + "@babel/core": "^7.27.4", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-rc.3", + "@rolldown/pluginutils": "1.0.0-beta.11", "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" + "react-refresh": "^0.17.0" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" } }, + "node_modules/@vitest/expect": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", + "integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", + "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", + "integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.18", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", + "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", + "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/aria-hidden": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", @@ -2517,12 +6114,333 @@ "node": ">=10" } }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz", + "integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-lite": "^1.0.30001787", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.37", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz", + "integrity": "sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==", + "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.cjs" }, @@ -2530,10 +6448,61 @@ "node": ">=6.0.0" } }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-scroll-lock": { + "version": "4.0.0-beta.0", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-4.0.0-beta.0.tgz", + "integrity": "sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", "dev": true, "funding": [ { @@ -2551,11 +6520,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -2564,11 +6533,104 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001777", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001777.tgz", - "integrity": "sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==", + "node_modules/bson-objectid": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/bson-objectid/-/bson-objectid-2.0.4.tgz", + "integrity": "sha512-vgnKAUzcDoa+AeyYwXCoHyF2q6u/8H46dxu5JN+4/TZeq/Dlinn0K6GvxsCLb3LHUJl0m/TLiEK31kUwtgocMQ==", + "license": "Apache-2.0" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/buffer-image-size": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/buffer-image-size/-/buffer-image-size-0.6.4.tgz", + "integrity": "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001799", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", + "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==", "funding": [ { "type": "opencollective", @@ -2585,6 +6647,143 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -2597,6 +6796,12 @@ "url": "https://polar.sh/cva" } }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2606,6 +6811,75 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/console-table-printer": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.12.1.tgz", + "integrity": "sha512-wKGOQRRvdnd89pCeH96e2Fn4wkbenSP6LMHfjfyNLMbGuHEFbMqQNuxXqd0oXG9caIOQ1FTvc5Uijp9/4jujnQ==", + "license": "MIT", + "dependencies": { + "simple-wcswidth": "^1.0.1" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2613,31 +6887,270 @@ "dev": true, "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==", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/croner": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/croner/-/croner-10.0.1.tgz", + "integrity": "sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==", + "funding": [ + { + "type": "other", + "url": "https://paypal.me/hexagonpp" + }, + { + "type": "github", + "url": "https://github.com/sponsors/hexagon" + } + ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=18.0" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssfilter": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", + "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==", + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, "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==", - "devOptional": true, "license": "MIT" }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dataloader": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.2.3.tgz", + "integrity": "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA==", + "license": "MIT" + }, + "node_modules/date-fns": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2651,11 +7164,91 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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" @@ -2667,10 +7260,670 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/drizzle-kit": { + "version": "0.31.7", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.7.tgz", + "integrity": "sha512-hOzRGSdyKIU4FcTSFYGKdXEjFsncVwHZ43gY3WU5Bz9j5Iadp6Rh6hxLSQ1IWXpKLBKt/d5y1cpSPcV+FcoQ1A==", + "license": "MIT", + "dependencies": { + "@drizzle-team/brocli": "^0.10.2", + "@esbuild-kit/esm-loader": "^2.5.5", + "esbuild": "^0.25.4", + "esbuild-register": "^3.5.0" + }, + "bin": { + "drizzle-kit": "bin.cjs" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/drizzle-kit/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/drizzle-orm": { + "version": "0.45.2", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.45.2.tgz", + "integrity": "sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==", + "license": "Apache-2.0", + "peerDependencies": { + "@aws-sdk/client-rds-data": ">=3", + "@cloudflare/workers-types": ">=4", + "@electric-sql/pglite": ">=0.2.0", + "@libsql/client": ">=0.10.0", + "@libsql/client-wasm": ">=0.10.0", + "@neondatabase/serverless": ">=0.10.0", + "@op-engineering/op-sqlite": ">=2", + "@opentelemetry/api": "^1.4.1", + "@planetscale/database": ">=1.13", + "@prisma/client": "*", + "@tidbcloud/serverless": "*", + "@types/better-sqlite3": "*", + "@types/pg": "*", + "@types/sql.js": "*", + "@upstash/redis": ">=1.34.7", + "@vercel/postgres": ">=0.8.0", + "@xata.io/client": "*", + "better-sqlite3": ">=7", + "bun-types": "*", + "expo-sqlite": ">=14.0.0", + "gel": ">=2", + "knex": "*", + "kysely": "*", + "mysql2": ">=2", + "pg": ">=8", + "postgres": ">=3", + "sql.js": ">=1", + "sqlite3": ">=5" + }, + "peerDependenciesMeta": { + "@aws-sdk/client-rds-data": { + "optional": true + }, + "@cloudflare/workers-types": { + "optional": true + }, + "@electric-sql/pglite": { + "optional": true + }, + "@libsql/client": { + "optional": true + }, + "@libsql/client-wasm": { + "optional": true + }, + "@neondatabase/serverless": { + "optional": true + }, + "@op-engineering/op-sqlite": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@tidbcloud/serverless": { + "optional": true + }, + "@types/better-sqlite3": { + "optional": true + }, + "@types/pg": { + "optional": true + }, + "@types/sql.js": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/postgres": { + "optional": true + }, + "@xata.io/client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "bun-types": { + "optional": true + }, + "expo-sqlite": { + "optional": true + }, + "gel": { + "optional": true + }, + "knex": { + "optional": true + }, + "kysely": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "postgres": { + "optional": true + }, + "prisma": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + } + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { - "version": "1.5.307", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", - "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", + "version": "1.5.373", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.373.tgz", + "integrity": "sha512-G2Hym8JIf/QreuseqkDibgH8Ci8KfJzqGDKdakbhSx9UltwRBH2cBLAWU/lBX0sCdv0TlhyxQyDCnSfxgMWsjA==", "dev": true, "license": "ISC" }, @@ -2711,24 +7964,265 @@ "embla-carousel": "8.6.0" } }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { - "version": "5.20.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz", - "integrity": "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ==", + "version": "5.21.6", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz", + "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==", "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" + "tapable": "^2.3.3" }, "engines": { "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.3.tgz", + "integrity": "sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.1.tgz", + "integrity": "sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", + "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2736,32 +8230,47 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "node_modules/esbuild-register": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz", + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "peerDependencies": { + "esbuild": ">=0.12 <1" } }, "node_modules/escalade": { @@ -2774,6 +8283,737 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.6.tgz", + "integrity": "sha512-z2ELYSkyrrJ6cuunTU8vhsT/RpouPkjaSah06nVW6Rg2Hpg0Vs8s497/e5s8G8qtdp4ccsiovz5P1rv+5VSW2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "16.2.6", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "16.4.0", + "typescript-eslint": "^8.46.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.13.0.tgz", + "integrity": "sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", + "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-copy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", + "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-type": { + "version": "21.3.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz", + "integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/focus-trap": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", + "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", + "license": "MIT", + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, "node_modules/framer-motion": { "version": "12.36.0", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.36.0.tgz", @@ -2805,7 +9045,6 @@ "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, @@ -2816,6 +9055,68 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/geist": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.7.2.tgz", + "integrity": "sha512-Gu5lDFa3pLRyoBlBPf0QIFHVdWAnpco7fS1bJm41jyLPFoguBgiubseUN2oLXMgqZ7uxAxDoXcHMhCY/fOTTgg==", + "license": "SIL OPEN FONT LICENSE", + "peerDependencies": { + "next": ">=13.2.0" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2826,6 +9127,31 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -2835,6 +9161,113 @@ "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2842,28 +9275,994 @@ "dev": true, "license": "ISC" }, + "node_modules/graphql": { + "version": "16.14.2", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.14.2.tgz", + "integrity": "sha512-Chq1s4CY7jmh8gO2qvLIJyfCDIN+EHLFW/9iShnp1z8FjBQMoodWP1kDC36VAMXXIvAjj4ARa7ntfAV2BrjsbA==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-http": { + "version": "1.22.4", + "resolved": "https://registry.npmjs.org/graphql-http/-/graphql-http-1.22.4.tgz", + "integrity": "sha512-OC3ucK988teMf+Ak/O+ZJ0N2ukcgrEurypp8ePyJFWq83VzwRAmHxxr+XxrMpxO/FIwI4a7m/Fzv3tWGJv0wPA==", + "license": "MIT", + "workspaces": [ + "implementations/**/*" + ], + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "graphql": ">=0.11 <=16" + } + }, + "node_modules/graphql-playground-html": { + "version": "1.6.30", + "resolved": "https://registry.npmjs.org/graphql-playground-html/-/graphql-playground-html-1.6.30.tgz", + "integrity": "sha512-tpCujhsJMva4aqE8ULnF7/l3xw4sNRZcSHu+R00VV+W0mfp+Q20Plvcrp+5UXD+2yS6oyCXncA+zoQJQqhGCEw==", + "license": "MIT", + "dependencies": { + "xss": "^1.0.6" + } + }, + "node_modules/graphql-scalars": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.22.2.tgz", + "integrity": "sha512-my9FB4GtghqXqi/lWSVAOPiTzTnnEzdOXCsAC2bb5V7EFNQjVjwy3cSSbUvgYOtDuDibd+ZsCDhz+4eykYOlhQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/happy-dom": { + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.10.4.tgz", + "integrity": "sha512-bKrsQnFNpcjZG0UPsH7UMN7Oyp3AB42LXk2GuiQmu7l4QFxH7lsw5T1eWEtE2+vbIFrTC45sbNSB2pkB8MTfKA==", + "license": "MIT", + "dependencies": { + "@types/node": ">=20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "@types/ws": "^8.18.1", + "buffer-image-size": "^0.6.4", + "entities": "^7.0.1", + "whatwg-mimetype": "^3.0.0", + "ws": "^8.21.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", + "license": "MIT" + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "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/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-status": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-2.1.0.tgz", + "integrity": "sha512-O5kPr7AW7wYd/BBiOezTwnVAnmSNFY+J7hlZD2X5IOxVBetjcHAiTXhzj0gMrnojQlwy+UT1/Y3H3vJ3UlmvLA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", + "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immutable": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", + "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", + "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-base64": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "license": "BSD-3-Clause" + }, "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==", - "dev": true, "license": "MIT" }, + "node_modules/js-yaml": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", + "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.0.0.tgz", + "integrity": "sha512-KDYJgZ6T2TKdU8yBfYueq5EPG/EylMsBvCaenWMJb2OXmjgczzwveRCoJ+Hgj1lXPDyasvrgneSn4GBuR1hYyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^5.3.7", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.20.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -2872,6 +10271,56 @@ "node": ">=6" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-to-typescript": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.3.tgz", + "integrity": "sha512-iOKdzTUWEVM4nlxpFudFsWyUiu/Jakkga4OZPEt7CGoSEsAsUgdOZqR6pcgx2STBek9Gm4hcarJpXSzIvZ/hKA==", + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^11.5.5", + "@types/json-schema": "^7.0.15", + "@types/lodash": "^4.17.7", + "is-glob": "^4.0.3", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "prettier": "^3.2.5", + "tinyglobby": "^0.2.9" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -2885,6 +10334,446 @@ "node": ">=6" } }, + "node_modules/jsox": { + "version": "1.2.121", + "resolved": "https://registry.npmjs.org/jsox/-/jsox-1.2.121.tgz", + "integrity": "sha512-9Ag50tKhpTwS6r5wh3MJSAvpSof0UBr39Pto8OnzFT32Z/pAbxAsKHzyvsyMEHVslELvHyO/4/jaQELHk8wDcw==", + "license": "MIT", + "bin": { + "jsox": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lexical": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.41.0.tgz", + "integrity": "sha512-pNIm5+n+hVnJHB9gYPDYsIO5Y59dNaDU9rJmPPsfqQhP2ojKFnUoPbcRnrI9FJLXB14sSumcY8LUw7Sq70TZqA==", + "license": "MIT" + }, + "node_modules/libsql": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/libsql/-/libsql-0.4.7.tgz", + "integrity": "sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw==", + "cpu": [ + "x64", + "arm64", + "wasm32" + ], + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32" + ], + "dependencies": { + "@neon-rs/load": "^0.0.4", + "detect-libc": "2.0.2" + }, + "optionalDependencies": { + "@libsql/darwin-arm64": "0.4.7", + "@libsql/darwin-x64": "0.4.7", + "@libsql/linux-arm64-gnu": "0.4.7", + "@libsql/linux-arm64-musl": "0.4.7", + "@libsql/linux-x64-gnu": "0.4.7", + "@libsql/linux-x64-musl": "0.4.7", + "@libsql/win32-x64-msvc": "0.4.7" + } + }, + "node_modules/libsql/node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "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.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "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-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "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-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "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-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "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-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "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/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2896,9 +10785,9 @@ } }, "node_modules/lucide-react": { - "version": "0.577.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.577.0.tgz", - "integrity": "sha512-4LjoFv2eEPwYDPg/CUdBJQSDfPyzXCRrVW1X7jrx/trgxnxkHFjnVZINbzvzxjN70dxychOfg+FTYwBiS3pQ5A==", + "version": "0.563.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.563.0.tgz", + "integrity": "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -2914,6 +10803,697 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", + "license": "MIT", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/motion": { "version": "12.36.0", "resolved": "https://registry.npmjs.org/motion/-/motion-12.36.0.tgz", @@ -2959,14 +11539,12 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "funding": [ { "type": "github", @@ -2981,6 +11559,654 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.2.6", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.6.tgz", + "integrity": "sha512-qOVgKJg1+At15NpeUP+eJgCHvTCgXsogweq87Ri/Ix7PkqQHg4sdaXmSFqKlgaIXE4kW0g25LE68W87UANlHtw==", + "license": "MIT", + "dependencies": { + "@next/env": "16.2.6", + "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.2.6", + "@next/swc-darwin-x64": "16.2.6", + "@next/swc-linux-arm64-gnu": "16.2.6", + "@next/swc-linux-arm64-musl": "16.2.6", + "@next/swc-linux-x64-gnu": "16.2.6", + "@next/swc-linux-x64-musl": "16.2.6", + "@next/swc-win32-arm64-msvc": "16.2.6", + "@next/swc-win32-x64-msvc": "16.2.6", + "sharp": "^0.34.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-sitemap": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/next-sitemap/-/next-sitemap-4.2.3.tgz", + "integrity": "sha512-vjdCxeDuWDzldhCnyFCQipw5bfpl4HmZA7uoo3GAaYGjGgfL4Cxb1CiztPuWGmS+auYs7/8OekRS8C2cjdAsjQ==", + "funding": [ + { + "url": "https://github.com/iamvishnusankar/next-sitemap.git" + } + ], + "license": "MIT", + "dependencies": { + "@corex/deepmerge": "^4.0.43", + "@next/env": "^13.4.3", + "fast-glob": "^3.2.12", + "minimist": "^1.2.8" + }, + "bin": { + "next-sitemap": "bin/next-sitemap.mjs", + "next-sitemap-cjs": "bin/next-sitemap.cjs" + }, + "engines": { + "node": ">=14.18" + }, + "peerDependencies": { + "next": "*" + } + }, + "node_modules/next-sitemap/node_modules/@next/env": { + "version": "13.5.11", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.11.tgz", + "integrity": "sha512-fbb2C7HChgM7CemdCY+y3N1n8pcTKdqtQLbC7/EQtPdLvlMUT9JX/dBYl8MMZAtYG4uVMyPFHXckb68q/NRwqg==", + "license": "MIT" + }, + "node_modules/next/node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/next/node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/next/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/next/node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-exports-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz", + "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/node-releases": { "version": "2.0.36", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", @@ -2988,13 +12214,625 @@ "dev": true, "license": "MIT" }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-to-formdata": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/object-to-formdata/-/object-to-formdata-4.5.1.tgz", + "integrity": "sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==", + "license": "MIT" + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/payload": { + "version": "3.85.1", + "resolved": "https://registry.npmjs.org/payload/-/payload-3.85.1.tgz", + "integrity": "sha512-vfnqwwMOru9wpdiFB3gyb6B+gUt7cjE8+YiNn1g+26dPOyGkAZa9U1QmCMSZfgARj5H42llElQHQw9WX3lYbIw==", + "license": "MIT", + "dependencies": { + "@next/env": "^15.1.5", + "@payloadcms/translations": "3.85.1", + "@types/busboy": "1.5.4", + "ajv": "8.18.0", + "bson-objectid": "2.0.4", + "busboy": "^1.6.0", + "ci-info": "^4.1.0", + "console-table-printer": "2.12.1", + "croner": "10.0.1", + "dataloader": "2.2.3", + "deepmerge": "4.3.1", + "file-type": "21.3.4", + "get-tsconfig": "4.8.1", + "http-status": "2.1.0", + "image-size": "2.0.2", + "ipaddr.js": "2.2.0", + "jose": "5.10.0", + "json-schema-to-typescript": "15.0.3", + "minimist": "1.2.8", + "path-to-regexp": "6.3.0", + "pino": "9.14.0", + "pino-pretty": "13.1.2", + "pluralize": "8.0.0", + "qs-esm": "8.0.1", + "range-parser": "1.2.1", + "sanitize-filename": "1.6.3", + "ts-essentials": "10.0.3", + "tsx": "4.22.4", + "undici": "7.24.4", + "uuid": "13.0.2", + "ws": "^8.16.0" + }, + "bin": { + "payload": "bin.js" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0" + }, + "peerDependencies": { + "graphql": "^16.8.1" + } + }, + "node_modules/payload/node_modules/@next/env": { + "version": "15.5.19", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.19.tgz", + "integrity": "sha512-sWWluFvcv5v3Fxznmf2ZfjyoVQt/64oCnYqS90inQWGzMPK1VjvekPiz3OPHKmFT30EnHrjlbyaHLt3M0vWabw==", + "license": "MIT" + }, + "node_modules/payload/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/payload/node_modules/get-tsconfig": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/payload/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/payload/node_modules/undici": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", + "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "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": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-pretty": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-13.1.2.tgz", + "integrity": "sha512-3cN0tCakkT4f3zo9RXDIhy6GTvtYD6bK4CRBLN9j3E/ePqN1tugAXD5rGVfoChW6s0hiek+eyYlLNqc/BG7vBQ==", + "license": "MIT", + "dependencies": { + "colorette": "^2.0.7", + "dateformat": "^4.6.3", + "fast-copy": "^3.0.2", + "fast-safe-stringify": "^2.1.1", + "help-me": "^5.0.0", + "joycon": "^3.1.1", + "minimist": "^1.2.6", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pump": "^3.0.0", + "secure-json-parse": "^4.0.0", + "sonic-boom": "^4.0.1", + "strip-json-comments": "^5.0.2" + }, + "bin": { + "pino-pretty": "bin.js" + } + }, + "node_modules/pino-pretty/node_modules/strip-json-comments": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.3.tgz", + "integrity": "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/playwright": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.58.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", @@ -3024,31 +12862,280 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", + "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", + "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", + "license": "MIT", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/promise-limit": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz", + "integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==", + "license": "ISC" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "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/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs-esm": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/qs-esm/-/qs-esm-8.0.1.tgz", + "integrity": "sha512-eZ7l+0ZVy3He9c85pEM9KEBR9DFA4jrmWvIjm9wpcHvScwc/vgZDl2TNOF0pm0JsWKw24XBUZOY0Wxn7/nvJnw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/react-datepicker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-7.6.0.tgz", + "integrity": "sha512-9cQH6Z/qa4LrGhzdc3XoHbhrxNcMi9MKjZmYgF/1MNNaJwvdSjv3Xd+jjvrEEbKEf71ZgCA3n7fQbdwd70qCRw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.0", + "clsx": "^2.1.1", + "date-fns": "^3.6.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.9.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, + "node_modules/react-datepicker/node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.4" + "react": "^19.2.6" } }, + "node_modules/react-error-boundary": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.1.2.tgz", + "integrity": "sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/react-hook-form": { + "version": "7.71.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz", + "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-image-crop": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-10.1.8.tgz", + "integrity": "sha512-4rb8XtXNx7ZaOZarKKnckgz4xLMvds/YrU6mpJfGhGAsy2Mg4mIw1x+DCCGngVGq2soTBVVOxx2s/C6mTX9+pA==", + "license": "ISC", + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", "dev": true, "license": "MIT", "engines": { @@ -3102,42 +13189,25 @@ } } }, - "node_modules/react-router": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", - "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", + "node_modules/react-select": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.9.0.tgz", + "integrity": "sha512-nwRKGanVHGjdccsnzhFte/PULziueZxGD8LL2WojON78Mvnq7LdAMEtu2frrwld1fr3geixg3iiMBIc/LLAZpw==", "license": "MIT", "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.2.0" }, "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router-dom": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.1.tgz", - "integrity": "sha512-UJnV3Rxc5TgUPJt2KJpo1Jpy0OKQr0AjgbZzBFjaPJcFOb2Y8jA5H3LT8HUJAiRLlWrEXWHbF1Z4SCZaQjWDHw==", - "license": "MIT", - "dependencies": { - "react-router": "7.13.1" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "node_modules/react-style-singleton": { @@ -3162,6 +13232,148 @@ } } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", @@ -3207,12 +13419,154 @@ "fsevents": "~2.3.2" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sass": { + "version": "1.77.4", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.4.tgz", + "integrity": "sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==", + "license": "MIT", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "node_modules/secure-json-parse": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -3223,22 +13577,587 @@ "semver": "bin/semver.js" } }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", "license": "MIT" }, + "node_modules/simple-wcswidth": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz", + "integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==", + "license": "MIT" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sonner": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.4.tgz", + "integrity": "sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "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/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/state-local": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", + "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strtok3": { + "version": "10.3.5", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz", + "integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tabbable": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", + "license": "MIT" + }, "node_modules/tailwind-merge": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", @@ -3257,9 +14176,9 @@ "license": "MIT" }, "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "dev": true, "license": "MIT", "engines": { @@ -3270,12 +14189,1027 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/thread-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.2.0.tgz", + "integrity": "sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "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/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.3.tgz", + "integrity": "sha512-A3BDQBeeukYPzB4QdQ1DtdlUmp4x2OCH8n5UVhEWbyANxNep8GavottKzd1xYKFJKjUgMyPT7EzOfnBO55s8Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.3" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.3.tgz", + "integrity": "sha512-27ep5H9PzdBrNd5OFM/j3WCU8F3kPwM9D0BOaOf7uYfxMJfyr0K5Tjj69Gri+sZlh2WXd5buIm47NuPF29CDiw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-snake-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", + "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", + "license": "MIT", + "dependencies": { + "to-space-case": "^1.0.0" + } + }, + "node_modules/to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "license": "MIT", + "dependencies": { + "to-no-case": "^1.0.0" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", + "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-essentials": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-10.0.3.tgz", + "integrity": "sha512-/FrVAZ76JLTWxJOERk04fm8hYENDo0PWSP3YLQKxevLwWtxemGcl5JJEzN4iqfDlRve0ckyfFaOBu4xbNH/wZw==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "deprecated": "unmaintained", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.22.4.tgz", + "integrity": "sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==", + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.61.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.1.tgz", + "integrity": "sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.61.1", + "@typescript-eslint/parser": "8.61.1", + "@typescript-eslint/typescript-estree": "8.61.1", + "@typescript-eslint/utils": "8.61.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -3307,6 +15241,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", @@ -3328,6 +15272,30 @@ } } }, + "node_modules/use-context-selector": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/use-context-selector/-/use-context-selector-2.0.0.tgz", + "integrity": "sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==", + "license": "MIT", + "peerDependencies": { + "react": ">=18.0.0", + "scheduler": ">=0.19.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz", + "integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sidecar": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", @@ -3350,22 +15318,65 @@ } } }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/uuid": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.2.tgz", + "integrity": "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz", + "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -3374,19 +15385,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.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 }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -3407,15 +15424,442 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, + "node_modules/vite-tsconfig-paths": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.0.5.tgz", + "integrity": "sha512-f/WvY6ekHykUF1rWJUAbCU7iS/5QYDIugwpqJA+ttwKbxSbzNlqlE8vZSrsnxNQciUW+z6lvhlXMaEyZn9MSig==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3" + }, + "peerDependencies": { + "vite": "*" + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", + "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.18", + "@vitest/mocker": "4.0.18", + "@vitest/pretty-format": "4.0.18", + "@vitest/runner": "4.0.18", + "@vitest/snapshot": "4.0.18", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.18", + "@vitest/browser-preview": "4.0.18", + "@vitest/browser-webdriverio": "4.0.18", + "@vitest/ui": "4.0.18", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xss": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz", + "integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==", + "license": "MIT", + "dependencies": { + "commander": "^2.20.3", + "cssfilter": "0.0.10" + }, + "bin": { + "xss": "bin/xss" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 55f24c0..4f62c76 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,98 @@ { - "name": "bmp-website", - "private": true, + "name": "bmp-website-payloadcms", "version": "1.0.0", + "description": "Website template for Payload", + "license": "MIT", "type": "module", "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "devDependencies": { - "@tailwindcss/vite": "^4.2.1", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.4", - "tailwindcss": "^4.2.1", - "vite": "^5.4.0" + "build": "cross-env NODE_OPTIONS=--no-deprecation next build", + "postbuild": "next-sitemap --config next-sitemap.config.cjs", + "dev": "cross-env NODE_OPTIONS=--no-deprecation next dev", + "dev:prod": "cross-env NODE_OPTIONS=--no-deprecation rm -rf .next && pnpm build && pnpm start", + "generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap", + "generate:types": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types", + "ii": "cross-env NODE_OPTIONS=--no-deprecation pnpm --ignore-workspace install", + "lint": "cross-env NODE_OPTIONS=--no-deprecation eslint .", + "lint:fix": "cross-env NODE_OPTIONS=--no-deprecation eslint . --fix", + "payload": "cross-env NODE_OPTIONS=--no-deprecation payload", + "reinstall": "cross-env NODE_OPTIONS=--no-deprecation rm -rf node_modules && rm pnpm-lock.yaml && pnpm --ignore-workspace install", + "start": "cross-env NODE_OPTIONS=--no-deprecation next start", + "test": "pnpm run test:int && pnpm run test:e2e", + "test:e2e": "cross-env NODE_OPTIONS=\"--no-deprecation --import=tsx/esm\" playwright test --config=playwright.config.ts", + "test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts" }, "dependencies": { - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-slot": "^1.2.4", - "@uidotdev/usehooks": "^2.4.1", - "class-variance-authority": "^0.7.1", + "@payloadcms/admin-bar": "3.85.1", + "@payloadcms/live-preview-react": "3.85.1", + "@payloadcms/next": "3.85.1", + "@payloadcms/plugin-form-builder": "3.85.1", + "@payloadcms/plugin-nested-docs": "3.85.1", + "@payloadcms/plugin-redirects": "3.85.1", + "@payloadcms/plugin-search": "3.85.1", + "@payloadcms/plugin-seo": "3.85.1", + "@payloadcms/richtext-lexical": "3.85.1", + "@payloadcms/ui": "3.85.1", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-slot": "^1.0.2", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "cross-env": "^7.0.3", + "dotenv": "16.4.7", + "geist": "^1.3.0", + "graphql": "^16.8.2", + "lucide-react": "0.563.0", + "next": "16.2.6", + "next-sitemap": "^4.2.3", + "payload": "3.85.1", + "prism-react-renderer": "^2.3.1", + "react": "19.2.6", + "react-dom": "19.2.6", + "react-hook-form": "7.71.1", + "sharp": "0.34.2", + "tailwind-merge": "^3.4.0", + "@payloadcms/db-sqlite": "3.85.1", + "@uidotdev/usehooks": "^2.4.1", "embla-carousel-auto-scroll": "^8.6.0", "embla-carousel-react": "^8.6.0", "framer-motion": "^12.36.0", - "lucide-react": "^0.577.0", "motion": "^12.36.0", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "react-router-dom": "^7.13.1", - "tailwind-merge": "^3.5.0" + "@radix-ui/react-radio-group": "^1.3.8" + }, + "devDependencies": { + "@eslint/eslintrc": "^3.2.0", + "@playwright/test": "1.58.2", + "@tailwindcss/postcss": "^4.1.18", + "@tailwindcss/typography": "^0.5.19", + "@testing-library/react": "16.3.0", + "@types/escape-html": "^1.0.2", + "@types/node": "22.19.9", + "@types/react": "19.2.14", + "@types/react-dom": "19.2.3", + "@vitejs/plugin-react": "4.5.2", + "autoprefixer": "^10.4.19", + "eslint": "^9.16.0", + "eslint-config-next": "16.2.6", + "jsdom": "28.0.0", + "postcss": "^8.4.38", + "prettier": "^3.4.2", + "tailwindcss": "^4.1.18", + "tsx": "4.22.4", + "tw-animate-css": "^1.4.0", + "typescript": "5.7.3", + "vite-tsconfig-paths": "6.0.5", + "vitest": "4.0.18" + }, + "engines": { + "node": "^18.20.2 || >=20.9.0", + "pnpm": "^9 || ^10" + }, + "pnpm": { + "onlyBuiltDependencies": [ + "sharp", + "esbuild", + "unrs-resolver" + ] } } diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..c60fa9d --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,41 @@ +import { defineConfig, devices } from '@playwright/test' + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +import 'dotenv/config' + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './tests/e2e', + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://localhost:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + }, + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'], channel: 'chromium' }, + }, + ], + webServer: { + command: 'pnpm dev', + reuseExistingServer: true, + url: 'http://localhost:3000', + }, +}) diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..ae85b2f --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,7 @@ +const config = { + plugins: { + '@tailwindcss/postcss': {}, + }, +} + +export default config diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..1ec2c191e9b317ccab3be0afe38084ae2dd1f271 GIT binary patch literal 15086 zcmds8XNXlt6uw45V~+(pyI5eO=o-Z+>Y^wb1&I-jtgb)S0xovkpljVH;;I;X1;w_C zVv8{vLW({M=nutc?CA2aMXW2I zMWcOtgVR)FcPqpA+%VqfYa2!pmx=nEN`_Iu0%?$8&Sr)lDD7i2N#;)rR?cJomH86$ zpUjjb!v<{q%$&;%A3@V_Hh6(KS*&jL;VUbEM)YDEmrD`1+CKOO2Cr0s73MPk%dFZg z?L07qn1RU+RcE0em`fX{lRsdp>d=6XxcwQE({EF zlO|1Q%a$!PckW!OQl&~@cB2@9Ri)!xkhC9Qoik?+y?XVE1Vthd8a#M#(zYdhVFmnG zQk`!=4Zz%xIfvP^oyn6Y)3ayKv{3KgzfYq^ zjiQ+|XVUA}ueEaL&!4Am-MV@9AH@vp-+RH|yLWH8diAOn4=M@@3aDz;sure3jT+I8 z9Xk^0?A*DNAm;^36#E%BI?bCmr-KI%Cd6>yzyV54P1R!P+O;cPxNt#h}_hmzBM?(D*Cr-rRMrO^LHH7)ct&OsjQ~Q7Q z>eVHRd-(9-l%1U&m=Cr8@%vK}{n?^L3u~+{Sg;^4A8P-vT)EPd?UpTDI?Cfak|{|1 ze)~T?J)N-TLHnKFm%9EaOZ@m9+PrzQ)tw&-ezA6b`SPWO9SwkTmTAR`71nsh+UxAuvvPIZ^SX8GEP35`P}<`^B_)OS?Aa5CRW7)3;|2{HG{_M< z+EkMG@&0AHckiB@jeEwr!s~jbB=M{BXB=RuVCmAORI_GHSA8yzrLxAqZ{NOzYiAj& z-Lv`)mE`;{bvI%E)VXtK&;2dhfPKZGLx*IO=CcRCp&Yg?HD;MDV$KFO~Ln#k)euq-#RyRg& z(xgfB{P}Ye3ieep2CRn)3kzkKanDDN9HCaNTE*COfom(vWV(>k+Qqkf@#4ieJP#i} zq%mX0P+neM!t)dS#`W*tUu)k18?e`8{>wp5Yk$|SU2)jm6yQ6WI(4ent_wWCT#Fg> z8?$d)I1{>b>5?1Rrp(5T8>wEsdcOTdu>!N8e*BQEJ#)MynpbeXgFQ_UzSssZ%k&dx zlD3U`9dq}aH*c)>ar^dd%FN76+O~ubSXIJx@oVNl{4{Oa)V#l#KYxDE_ZP*C@iP^C zH2*cH|1byAh7zy?Z2g%NQ65*8SNy={hL*EXd27QGH^3#CDg5l~UL)YP1H(5GE-#M* zS@;j;vU(Tr{iPScHnNzP<}qJnF0FRJSBN>CIY>fmOD;2FUCKrL3`Gp1GWRNlI6#6^ z3^pU*Fy10fF$_$$SYhk@=2oBM!)pYIEULW=#9SyV|2*4}JLXVQcNKdswn$ zNz5MI#;@E?_{KLXm&H8eE)(}^D&Z^z=Qs1_%~Pw)GnkPhN5l<~#4s78pvS-hpPPVN2wr$&5&kp{zasiQZwd z{^j>C`^H#m)~s1V-@t|MPEfMrA9iluyy-fY2=R_ZMMc6rB^dv28LRCacWU*P^aNhYob||>*6=SwjSR%&iCbd+f=xxoM#{KneF8RDL^W5YPW5LEOfAU#~xlwd@hsElWz{?j^+EsB%%=JEC0N-5Px!vhT(m);3rV+1(G%o;};dgV+oq&na}RxmBzwuy5VI zeY?4?!u!K|7QfxFA?f1z8uPbGnfczaHx#sc_wKm$N>pbNrwy6!t2U6w|Ii?Y-L8(y z?lMCcgn2t=EOB0^hw|IZ?U-e%$C(1==gc}?)Gc8CgxREUMLq*gJTC~*m=rqD{SWG$ BvZnw5 literal 0 HcmV?d00001 diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..d7ccc5a --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/public/website-template-OG.webp b/public/website-template-OG.webp new file mode 100644 index 0000000000000000000000000000000000000000..ceb0efc471c7503324f6fe561322d264291de2bb GIT binary patch literal 101500 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 z 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�@{-S#_@^{@&hw5z*Fvrz)}r? z3Av0h9EstvCO-JBX9d{LCxgPY0Upc&-2>#ePyh{O+b;|_djzT};m9Rl5dsi>rHIF{ z9%IRL%p7~^>ctK21QDSq_2ZDk*c9ain)7VxTu5FE$RTT}Wx=u>06gHGShDsy*sy(Y zO`#?gTId5_A|8?teaV{bD&3E8oZmvRjdf1A3aQ(;32Zv&Sp=~8;qyR2+^-8-MZn_2 zgYYhB6HO-H`3oKg6Q|>AZtQ}u&C{Oo?Bu}9%ftA4zk09=GL#yR34u}5}Xv7@Asto+>?oG`X$shzzOi(40~D;sf|O1H>qWqn+U!k?&Z4yM9SoDfzYWLs^u!C?)tm ztIskL33T=BlYWVA>}Y!RiaC!E!6kbMuR0-lLSQXzkZd=iK}abf`xnTc$%jJp$)d!{ zWIzdHg$V=(fYJbQ{@j%4{a!WU{`an&RFBmy|O z+@a<(6DdoVpS4VDQp7}f$qz{bc-m!~ILuuFsl7<~d7z2Fh%fsTjx$T$rU57i>N*y3 z_j?df{(;GdS*F6r2IOTI8!#vYKM;P-6-)hW( z?WT2*sW8E4<(9;V$#9}5M}Il;xGZJS_uv~wT`|-aFVwF1d9ai=7#t>92P6pn?aKo7 zLwz(IH}gUtNOaEc?5{p79O|So`Xrh&o6|{Y&m$Pbu>ocs+i~u`{(SKdiqQpP5@UZ~m}0a50Kn}}ga7~l literal 0 HcmV?d00001 diff --git a/redirects.ts b/redirects.ts new file mode 100644 index 0000000..64ea7cd --- /dev/null +++ b/redirects.ts @@ -0,0 +1,18 @@ +import type { NextConfig } from 'next' + +export const redirects: NextConfig['redirects'] = async () => { + const internetExplorerRedirect = { + destination: '/ie-incompatible.html', + has: [ + { + type: 'header' as const, + key: 'user-agent', + value: '(.*Trident.*)', // all ie browsers + }, + ], + permanent: false, + source: '/:path((?!ie-incompatible.html$).*)', // all pages except the incompatibility page + } + + return [internetExplorerRedirect] +} diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index a2ee4f2..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Routes, Route, useLocation } from 'react-router-dom'; -import Layout from '@/components/layout/Layout'; -import ScrollToTop from '@/components/layout/ScrollToTop'; -import Home from '@/pages/Home'; -import Participation from '@/pages/Participation'; -import About from '@/pages/About'; -import Preistraeger from '@/pages/Preistraeger'; -import PreistraegerDetail from '@/pages/PreistraegerDetail'; -import Press from '@/pages/Press'; -import EventDetail from './pages/EventDetail'; -import BlogDetail from './pages/BlogDetail'; -import Contact from '@/pages/Contact'; -import FormularUpload from '@/pages/FormularUpload'; -import Netzwerk from '@/pages/Netzwerk'; -import MitgliedWerden from '@/pages/MitgliedWerden'; -import Datenschutz from '@/pages/Datenschutz'; -import Impressum from '@/pages/Impressum'; - -const App: React.FC = () => { - const [loading, setLoading] = useState(true); - const location = useLocation(); - - useEffect(() => { - // Basic loading simulation for splash - const timer = setTimeout(() => { - setLoading(false); - }, 1500); - return () => clearTimeout(timer); - }, []); - - if (loading) { - return ( -
-
-
-
- BMP -
-
-
- Exzellenz wird geladen... -
-
- ); - } - - return ( - <> - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - {/* Fallback to home */} - } /> - - - - ); -}; - -export default App; diff --git a/src/Footer/Component.tsx b/src/Footer/Component.tsx new file mode 100644 index 0000000..737a295 --- /dev/null +++ b/src/Footer/Component.tsx @@ -0,0 +1,32 @@ +import { getCachedGlobal } from '@/utilities/getGlobals' +import Link from 'next/link' +import React from 'react' + +import { ThemeSelector } from '@/providers/Theme/ThemeSelector' +import { CMSLink } from '@/components/Link' +import { Logo } from '@/components/Logo/Logo' + +export async function Footer() { + const footerData = await getCachedGlobal('footer', 1)() + + const navItems = footerData?.navItems || [] + + return ( +
+
+ + + + +
+ + +
+
+
+ ) +} diff --git a/src/Footer/RowLabel.tsx b/src/Footer/RowLabel.tsx new file mode 100644 index 0000000..a6f9494 --- /dev/null +++ b/src/Footer/RowLabel.tsx @@ -0,0 +1,13 @@ +'use client' +import { Header } from '@/payload-types' +import { RowLabelProps, useRowLabel } from '@payloadcms/ui' + +export const RowLabel: React.FC = () => { + const data = useRowLabel[number]>() + + const label = data?.data?.link?.label + ? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}` + : 'Row' + + return
{label}
+} diff --git a/src/Footer/config.ts b/src/Footer/config.ts new file mode 100644 index 0000000..ca9b54b --- /dev/null +++ b/src/Footer/config.ts @@ -0,0 +1,32 @@ +import type { GlobalConfig } from 'payload' + +import { link } from '@/fields/link' +import { revalidateFooter } from './hooks/revalidateFooter' + +export const Footer: GlobalConfig = { + slug: 'footer', + access: { + read: () => true, + }, + fields: [ + { + name: 'navItems', + type: 'array', + fields: [ + link({ + appearances: false, + }), + ], + maxRows: 6, + admin: { + initCollapsed: true, + components: { + RowLabel: '@/Footer/RowLabel#RowLabel', + }, + }, + }, + ], + hooks: { + afterChange: [revalidateFooter], + }, +} diff --git a/src/Footer/hooks/revalidateFooter.ts b/src/Footer/hooks/revalidateFooter.ts new file mode 100644 index 0000000..1484bf5 --- /dev/null +++ b/src/Footer/hooks/revalidateFooter.ts @@ -0,0 +1,13 @@ +import type { GlobalAfterChangeHook } from 'payload' + +import { revalidateTag } from 'next/cache' + +export const revalidateFooter: GlobalAfterChangeHook = ({ doc, req: { payload, context } }) => { + if (!context.disableRevalidate) { + payload.logger.info(`Revalidating footer`) + + revalidateTag('global_footer', 'max') + } + + return doc +} diff --git a/src/Header/Component.client.tsx b/src/Header/Component.client.tsx new file mode 100644 index 0000000..a4bd658 --- /dev/null +++ b/src/Header/Component.client.tsx @@ -0,0 +1,42 @@ +'use client' +import { useHeaderTheme } from '@/providers/HeaderTheme' +import Link from 'next/link' +import { usePathname } from 'next/navigation' +import React, { useEffect, useState } from 'react' + +import type { Header } from '@/payload-types' + +import { Logo } from '@/components/Logo/Logo' +import { HeaderNav } from './Nav' + +interface HeaderClientProps { + data: Header +} + +export const HeaderClient: React.FC = ({ data }) => { + /* Storing the value in a useState to avoid hydration errors */ + const [theme, setTheme] = useState(null) + const { headerTheme, setHeaderTheme } = useHeaderTheme() + const pathname = usePathname() + + useEffect(() => { + setHeaderTheme(null) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [pathname]) + + useEffect(() => { + if (headerTheme && headerTheme !== theme) setTheme(headerTheme) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [headerTheme]) + + return ( +
+
+ + + + +
+
+ ) +} diff --git a/src/Header/Component.tsx b/src/Header/Component.tsx new file mode 100644 index 0000000..e7beeed --- /dev/null +++ b/src/Header/Component.tsx @@ -0,0 +1,9 @@ +import { HeaderClient } from './Component.client' +import { getCachedGlobal } from '@/utilities/getGlobals' +import React from 'react' + +export async function Header() { + const headerData = await getCachedGlobal('header', 1)() + + return +} diff --git a/src/Header/Nav/index.tsx b/src/Header/Nav/index.tsx new file mode 100644 index 0000000..070fcca --- /dev/null +++ b/src/Header/Nav/index.tsx @@ -0,0 +1,25 @@ +'use client' + +import React from 'react' + +import type { Header as HeaderType } from '@/payload-types' + +import { CMSLink } from '@/components/Link' +import Link from 'next/link' +import { SearchIcon } from 'lucide-react' + +export const HeaderNav: React.FC<{ data: HeaderType }> = ({ data }) => { + const navItems = data?.navItems || [] + + return ( + + ) +} diff --git a/src/Header/RowLabel.tsx b/src/Header/RowLabel.tsx new file mode 100644 index 0000000..a6f9494 --- /dev/null +++ b/src/Header/RowLabel.tsx @@ -0,0 +1,13 @@ +'use client' +import { Header } from '@/payload-types' +import { RowLabelProps, useRowLabel } from '@payloadcms/ui' + +export const RowLabel: React.FC = () => { + const data = useRowLabel[number]>() + + const label = data?.data?.link?.label + ? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}` + : 'Row' + + return
{label}
+} diff --git a/src/Header/config.ts b/src/Header/config.ts new file mode 100644 index 0000000..58fe89c --- /dev/null +++ b/src/Header/config.ts @@ -0,0 +1,32 @@ +import type { GlobalConfig } from 'payload' + +import { link } from '@/fields/link' +import { revalidateHeader } from './hooks/revalidateHeader' + +export const Header: GlobalConfig = { + slug: 'header', + access: { + read: () => true, + }, + fields: [ + { + name: 'navItems', + type: 'array', + fields: [ + link({ + appearances: false, + }), + ], + maxRows: 6, + admin: { + initCollapsed: true, + components: { + RowLabel: '@/Header/RowLabel#RowLabel', + }, + }, + }, + ], + hooks: { + afterChange: [revalidateHeader], + }, +} diff --git a/src/Header/hooks/revalidateHeader.ts b/src/Header/hooks/revalidateHeader.ts new file mode 100644 index 0000000..c6745d3 --- /dev/null +++ b/src/Header/hooks/revalidateHeader.ts @@ -0,0 +1,13 @@ +import type { GlobalAfterChangeHook } from 'payload' + +import { revalidateTag } from 'next/cache' + +export const revalidateHeader: GlobalAfterChangeHook = ({ doc, req: { payload, context } }) => { + if (!context.disableRevalidate) { + payload.logger.info(`Revalidating header`) + + revalidateTag('global_header', 'max') + } + + return doc +} diff --git a/src/access/anyone.ts b/src/access/anyone.ts new file mode 100644 index 0000000..bf37c3a --- /dev/null +++ b/src/access/anyone.ts @@ -0,0 +1,3 @@ +import type { Access } from 'payload' + +export const anyone: Access = () => true diff --git a/src/access/authenticated.ts b/src/access/authenticated.ts new file mode 100644 index 0000000..e2dc34d --- /dev/null +++ b/src/access/authenticated.ts @@ -0,0 +1,9 @@ +import type { AccessArgs } from 'payload' + +import type { User } from '@/payload-types' + +type isAuthenticated = (args: AccessArgs) => boolean + +export const authenticated: isAuthenticated = ({ req: { user } }) => { + return Boolean(user) +} diff --git a/src/access/authenticatedOrPublished.ts b/src/access/authenticatedOrPublished.ts new file mode 100644 index 0000000..e49198f --- /dev/null +++ b/src/access/authenticatedOrPublished.ts @@ -0,0 +1,13 @@ +import type { Access } from 'payload' + +export const authenticatedOrPublished: Access = ({ req: { user } }) => { + if (user) { + return true + } + + return { + _status: { + equals: 'published', + }, + } +} diff --git a/src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts b/src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts new file mode 100644 index 0000000..c73e1ea --- /dev/null +++ b/src/app/(frontend)/(sitemaps)/pages-sitemap.xml/route.ts @@ -0,0 +1,68 @@ +import { getServerSideSitemap } from 'next-sitemap' +import { getPayload } from 'payload' +import config from '@payload-config' +import { unstable_cache } from 'next/cache' + +const getPagesSitemap = unstable_cache( + async () => { + const payload = await getPayload({ config }) + const SITE_URL = + process.env.NEXT_PUBLIC_SERVER_URL || + process.env.VERCEL_PROJECT_PRODUCTION_URL || + 'https://example.com' + + const results = await payload.find({ + collection: 'pages', + overrideAccess: false, + draft: false, + depth: 0, + limit: 1000, + pagination: false, + where: { + _status: { + equals: 'published', + }, + }, + select: { + slug: true, + updatedAt: true, + }, + }) + + const dateFallback = new Date().toISOString() + + const defaultSitemap = [ + { + loc: `${SITE_URL}/search`, + lastmod: dateFallback, + }, + { + loc: `${SITE_URL}/posts`, + lastmod: dateFallback, + }, + ] + + const sitemap = results.docs + ? results.docs + .filter((page) => Boolean(page?.slug)) + .map((page) => { + return { + loc: page?.slug === 'home' ? `${SITE_URL}/` : `${SITE_URL}/${page?.slug}`, + lastmod: page.updatedAt || dateFallback, + } + }) + : [] + + return [...defaultSitemap, ...sitemap] + }, + ['pages-sitemap'], + { + tags: ['pages-sitemap'], + }, +) + +export async function GET() { + const sitemap = await getPagesSitemap() + + return getServerSideSitemap(sitemap) +} diff --git a/src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts b/src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts new file mode 100644 index 0000000..0716abb --- /dev/null +++ b/src/app/(frontend)/(sitemaps)/posts-sitemap.xml/route.ts @@ -0,0 +1,55 @@ +import { getServerSideSitemap } from 'next-sitemap' +import { getPayload } from 'payload' +import config from '@payload-config' +import { unstable_cache } from 'next/cache' + +const getPostsSitemap = unstable_cache( + async () => { + const payload = await getPayload({ config }) + const SITE_URL = + process.env.NEXT_PUBLIC_SERVER_URL || + process.env.VERCEL_PROJECT_PRODUCTION_URL || + 'https://example.com' + + const results = await payload.find({ + collection: 'posts', + overrideAccess: false, + draft: false, + depth: 0, + limit: 1000, + pagination: false, + where: { + _status: { + equals: 'published', + }, + }, + select: { + slug: true, + updatedAt: true, + }, + }) + + const dateFallback = new Date().toISOString() + + const sitemap = results.docs + ? results.docs + .filter((post) => Boolean(post?.slug)) + .map((post) => ({ + loc: `${SITE_URL}/posts/${post?.slug}`, + lastmod: post.updatedAt || dateFallback, + })) + : [] + + return sitemap + }, + ['posts-sitemap'], + { + tags: ['posts-sitemap'], + }, +) + +export async function GET() { + const sitemap = await getPostsSitemap() + + return getServerSideSitemap(sitemap) +} diff --git a/src/app/(frontend)/[[...slug]]/page.tsx b/src/app/(frontend)/[[...slug]]/page.tsx new file mode 100644 index 0000000..7b6d5a8 --- /dev/null +++ b/src/app/(frontend)/[[...slug]]/page.tsx @@ -0,0 +1,12 @@ +import NextApp from '@/spa/NextApp' + +type Args = { + params: Promise<{ slug?: string[] }> +} + +export default async function Page({ params }: Args) { + const { slug = [] } = await params + const pathname = `/${slug.join('/')}`.replace(/\/$/, '') || '/' + + return +} diff --git a/src/app/(frontend)/globals.css b/src/app/(frontend)/globals.css new file mode 100644 index 0000000..74651b0 --- /dev/null +++ b/src/app/(frontend)/globals.css @@ -0,0 +1,124 @@ +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); +@import 'tailwindcss'; + +@theme { + --font-display: "IBM Plex Sans", sans-serif; + --font-body: "Inter", sans-serif; + + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + + --radius-lg: 0.5rem; + --radius-md: calc(0.5rem - 2px); + --radius-sm: calc(0.5rem - 4px); +} + +:root { + --background: #E4E2E3; + --foreground: #020617; + --card: #ffffff; + --card-foreground: #020617; + --popover: #ffffff; + --popover-foreground: #020617; + --primary: #03093A; + --primary-foreground: #ffffff; + --secondary: #f8fafc; + --secondary-foreground: #03093A; + --muted: #f1f5f9; + --muted-foreground: #64748b; + --accent: #EFBF04; + --accent-foreground: #ffffff; + --destructive: #ef4444; + --border: #e2e8f0; + --input: #e2e8f0; + --ring: #03093A; +} + +.dark { + --background: #020617; + --foreground: #f8fafc; + --card: #1e293b; + --card-foreground: #f8fafc; + --popover: #020617; + --popover-foreground: #f8fafc; + --primary: #03093A; + --primary-foreground: #ffffff; + --secondary: #1e293b; + --secondary-foreground: #f8fafc; + --muted: #1e293b; + --muted-foreground: #94a3b8; + --accent: #EFBF04; + --accent-foreground: #ffffff; + --destructive: #7f1d1d; + --border: rgba(255, 255, 255, 0.1); + --input: rgba(255, 255, 255, 0.15); + --ring: #94a3b8; +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground font-body; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + margin: 0; + } + + ::selection { + background: #EFBF04; + color: #03093A; + } + h1, h2, h3, h4, h5, h6 { + @apply font-display font-bold; + } + + blockquote, q, + .quote, [class*="italic"] { + font-family: "Inter", sans-serif; + font-style: italic; + } + + label, + .label { + font-family: "IBM Plex Sans", sans-serif; + } + + input, textarea, select, button { + font-family: "Inter", sans-serif; + } +} + +@keyframes fade-in { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@layer utilities { + .animate-fade-in { + animation: fade-in 0.6s ease-out; + } +} diff --git a/src/app/(frontend)/layout.tsx b/src/app/(frontend)/layout.tsx new file mode 100644 index 0000000..2a8af46 --- /dev/null +++ b/src/app/(frontend)/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata } from 'next' +import React from 'react' + +import './globals.css' + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + + + + + {children} + + ) +} + +export const metadata: Metadata = { + title: 'Bayerischer Mittelstandspreis 2026', + description: 'Der Preis des Bayerischen Mittelstands', +} diff --git a/src/app/(frontend)/next/exit-preview/route.ts b/src/app/(frontend)/next/exit-preview/route.ts new file mode 100644 index 0000000..a8e3e69 --- /dev/null +++ b/src/app/(frontend)/next/exit-preview/route.ts @@ -0,0 +1,7 @@ +import { draftMode } from 'next/headers' + +export async function GET(): Promise { + const draft = await draftMode() + draft.disable() + return new Response('Draft mode is disabled') +} diff --git a/src/app/(frontend)/next/preview/route.ts b/src/app/(frontend)/next/preview/route.ts new file mode 100644 index 0000000..1cdb683 --- /dev/null +++ b/src/app/(frontend)/next/preview/route.ts @@ -0,0 +1,59 @@ +import type { PayloadRequest } from 'payload' +import { getPayload } from 'payload' + +import { draftMode } from 'next/headers' +import { redirect } from 'next/navigation' +import { NextRequest } from 'next/server' + +import configPromise from '@payload-config' + +export type PreviewSearchParams = { + path: string + previewSecret: string +} + +export async function GET(req: NextRequest): Promise { + const payload = await getPayload({ config: configPromise }) + + const { searchParams } = new URL(req.url) + + const path = searchParams.get('path') + const previewSecret = searchParams.get('previewSecret') + + if (previewSecret !== process.env.PREVIEW_SECRET) { + return new Response('You are not allowed to preview this page', { status: 403 }) + } + + if (!path) { + return new Response('Insufficient search params', { status: 404 }) + } + + if (!path.startsWith('/')) { + return new Response('This endpoint can only be used for relative previews', { status: 500 }) + } + + let user + + try { + user = await payload.auth({ + req: req as unknown as PayloadRequest, + headers: req.headers, + }) + } catch (error) { + payload.logger.error({ err: error }, 'Error verifying token for live preview') + return new Response('You are not allowed to preview this page', { status: 403 }) + } + + const draft = await draftMode() + + if (!user) { + draft.disable() + return new Response('You are not allowed to preview this page', { status: 403 }) + } + + // You can add additional checks here to see if the user is allowed to preview this page + + draft.enable() + + redirect(path) +} diff --git a/src/app/(frontend)/next/seed/route.ts b/src/app/(frontend)/next/seed/route.ts new file mode 100644 index 0000000..326b677 --- /dev/null +++ b/src/app/(frontend)/next/seed/route.ts @@ -0,0 +1,31 @@ +import { createLocalReq, getPayload } from 'payload' +import { seed } from '@/endpoints/seed' +import config from '@payload-config' +import { headers } from 'next/headers' + +export const maxDuration = 60 // This function can run for a maximum of 60 seconds + +export async function POST(): Promise { + const payload = await getPayload({ config }) + const requestHeaders = await headers() + + // Authenticate by passing request headers + const { user } = await payload.auth({ headers: requestHeaders }) + + if (!user) { + return new Response('Action forbidden.', { status: 403 }) + } + + try { + // Create a Payload request object to pass to the Local API for transactions + // At this point you should pass in a user, locale, and any other context you need for the Local API + const payloadReq = await createLocalReq({ user }, payload) + + await seed({ payload, req: payloadReq }) + + return Response.json({ success: true }) + } catch (e) { + payload.logger.error({ err: e, message: 'Error seeding data' }) + return new Response('Error seeding data.', { status: 500 }) + } +} diff --git a/src/app/(frontend)/not-found.tsx b/src/app/(frontend)/not-found.tsx new file mode 100644 index 0000000..76ff4e3 --- /dev/null +++ b/src/app/(frontend)/not-found.tsx @@ -0,0 +1,18 @@ +import Link from 'next/link' +import React from 'react' + +import { Button } from '@/components/ui/button' + +export default function NotFound() { + return ( +
+
+

404

+

This page could not be found.

+
+ +
+ ) +} diff --git a/src/app/(payload)/admin/[[...segments]]/not-found.tsx b/src/app/(payload)/admin/[[...segments]]/not-found.tsx new file mode 100644 index 0000000..6410836 --- /dev/null +++ b/src/app/(payload)/admin/[[...segments]]/not-found.tsx @@ -0,0 +1,24 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import type { Metadata } from 'next' + +import config from '@payload-config' +import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views' +import { importMap } from '../importMap' + +type Args = { + params: Promise<{ + segments: string[] + }> + searchParams: Promise<{ + [key: string]: string | string[] + }> +} + +export const generateMetadata = ({ params, searchParams }: Args): Promise => + generatePageMetadata({ config, params, searchParams }) + +const NotFound = ({ params, searchParams }: Args) => + NotFoundPage({ config, params, searchParams, importMap }) + +export default NotFound diff --git a/src/app/(payload)/admin/[[...segments]]/page.tsx b/src/app/(payload)/admin/[[...segments]]/page.tsx new file mode 100644 index 0000000..0de685c --- /dev/null +++ b/src/app/(payload)/admin/[[...segments]]/page.tsx @@ -0,0 +1,24 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import type { Metadata } from 'next' + +import config from '@payload-config' +import { RootPage, generatePageMetadata } from '@payloadcms/next/views' +import { importMap } from '../importMap' + +type Args = { + params: Promise<{ + segments: string[] + }> + searchParams: Promise<{ + [key: string]: string | string[] + }> +} + +export const generateMetadata = ({ params, searchParams }: Args): Promise => + generatePageMetadata({ config, params, searchParams }) + +const Page = ({ params, searchParams }: Args) => + RootPage({ config, params, searchParams, importMap }) + +export default Page diff --git a/src/app/(payload)/admin/importMap.js b/src/app/(payload)/admin/importMap.js new file mode 100644 index 0000000..c5ecaeb --- /dev/null +++ b/src/app/(payload)/admin/importMap.js @@ -0,0 +1,80 @@ +import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { FixedToolbarFeatureClient as FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { OverviewComponent as OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client' +import { MetaTitleComponent as MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client' +import { MetaImageComponent as MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client' +import { MetaDescriptionComponent as MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client' +import { PreviewComponent as PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client' +import { SlugField as SlugField_2b8867833a34864a02ddf429b0728a40 } from '@payloadcms/next/client' +import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { FolderTableCell as FolderTableCell_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' +import { FolderField as FolderField_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' +import { LinkToDoc as LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client' +import { ReindexButton as ReindexButton_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client' +import { FolderTypeField as FolderTypeField_2b8867833a34864a02ddf429b0728a40 } from '@payloadcms/next/client' +import { RowLabel as RowLabel_ec255a65fa6fa8d1faeb09cf35284224 } from '@/Header/RowLabel' +import { RowLabel as RowLabel_1f6ff6ff633e3695d348f4f3c58f1466 } from '@/Footer/RowLabel' +import { default as default_1a7510af427896d367a49dbf838d2de6 } from '@/components/BeforeDashboard' +import { default as default_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin' +import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' + +/** @type import('payload').ImportMap */ +export const importMap = { + '@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell': + RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e, + '@payloadcms/richtext-lexical/rsc#RscEntryLexicalField': + RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e, + '@payloadcms/richtext-lexical/rsc#LexicalDiffComponent': + LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e, + '@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient': + InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#FixedToolbarFeatureClient': + FixedToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#HeadingFeatureClient': + HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#ParagraphFeatureClient': + ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#UnderlineFeatureClient': + UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#BoldFeatureClient': + BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#ItalicFeatureClient': + ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#LinkFeatureClient': + LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/plugin-seo/client#OverviewComponent': + OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860, + '@payloadcms/plugin-seo/client#MetaTitleComponent': + MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860, + '@payloadcms/plugin-seo/client#MetaImageComponent': + MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860, + '@payloadcms/plugin-seo/client#MetaDescriptionComponent': + MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860, + '@payloadcms/plugin-seo/client#PreviewComponent': + PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860, + '@payloadcms/next/client#SlugField': SlugField_2b8867833a34864a02ddf429b0728a40, + '@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient': + HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/richtext-lexical/client#BlocksFeatureClient': + BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + '@payloadcms/next/rsc#FolderTableCell': FolderTableCell_f9c02e79a4aed9a3924487c0cd4cafb1, + '@payloadcms/next/rsc#FolderField': FolderField_f9c02e79a4aed9a3924487c0cd4cafb1, + '@payloadcms/plugin-search/client#LinkToDoc': LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634, + '@payloadcms/plugin-search/client#ReindexButton': ReindexButton_aead06e4cbf6b2620c5c51c9ab283634, + '@payloadcms/next/client#FolderTypeField': FolderTypeField_2b8867833a34864a02ddf429b0728a40, + '@/Header/RowLabel#RowLabel': RowLabel_ec255a65fa6fa8d1faeb09cf35284224, + '@/Footer/RowLabel#RowLabel': RowLabel_1f6ff6ff633e3695d348f4f3c58f1466, + '@/components/BeforeDashboard#default': default_1a7510af427896d367a49dbf838d2de6, + '@/components/BeforeLogin#default': default_8a7ab0eb7ab5c511aba12e68480bfe5e, + '@payloadcms/next/rsc#CollectionCards': CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1, +} diff --git a/src/app/(payload)/api/[...slug]/route.ts b/src/app/(payload)/api/[...slug]/route.ts new file mode 100644 index 0000000..c3de612 --- /dev/null +++ b/src/app/(payload)/api/[...slug]/route.ts @@ -0,0 +1,20 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import config from '@payload-config' +import '@payloadcms/next/css' +import { + REST_DELETE, + REST_GET, + REST_OPTIONS, + REST_PATCH, + REST_POST, + REST_PUT, +} from '@payloadcms/next/routes' + +export const GET = REST_GET(config) +export const POST = REST_POST(config) +export const DELETE = REST_DELETE(config) +export const PATCH = REST_PATCH(config) + +export const PUT = REST_PUT(config) +export const OPTIONS = REST_OPTIONS(config) diff --git a/src/app/(payload)/api/graphql-playground/route.ts b/src/app/(payload)/api/graphql-playground/route.ts new file mode 100644 index 0000000..17d2954 --- /dev/null +++ b/src/app/(payload)/api/graphql-playground/route.ts @@ -0,0 +1,7 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import config from '@payload-config' +import '@payloadcms/next/css' +import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes' + +export const GET = GRAPHQL_PLAYGROUND_GET(config) diff --git a/src/app/(payload)/api/graphql/route.ts b/src/app/(payload)/api/graphql/route.ts new file mode 100644 index 0000000..2069ff8 --- /dev/null +++ b/src/app/(payload)/api/graphql/route.ts @@ -0,0 +1,8 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import config from '@payload-config' +import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes' + +export const POST = GRAPHQL_POST(config) + +export const OPTIONS = REST_OPTIONS(config) diff --git a/src/app/(payload)/custom.scss b/src/app/(payload)/custom.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/(payload)/layout.tsx b/src/app/(payload)/layout.tsx new file mode 100644 index 0000000..8df141a --- /dev/null +++ b/src/app/(payload)/layout.tsx @@ -0,0 +1,31 @@ +/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */ +/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */ +import config from '@payload-config' +import '@payloadcms/next/css' +import type { ServerFunctionClient } from 'payload' +import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts' +import React from 'react' + +import { importMap } from './admin/importMap.js' +import './custom.scss' + +type Args = { + children: React.ReactNode +} + +const serverFunction: ServerFunctionClient = async function (args) { + 'use server' + return handleServerFunctions({ + ...args, + config, + importMap, + }) +} + +const Layout = ({ children }: Args) => ( + + {children} + +) + +export default Layout diff --git a/src/blocks/ArchiveBlock/Component.tsx b/src/blocks/ArchiveBlock/Component.tsx new file mode 100644 index 0000000..48a57ec --- /dev/null +++ b/src/blocks/ArchiveBlock/Component.tsx @@ -0,0 +1,65 @@ +import type { Post, ArchiveBlock as ArchiveBlockProps } from '@/payload-types' + +import configPromise from '@payload-config' +import { getPayload } from 'payload' +import React from 'react' +import RichText from '@/components/RichText' + +import { CollectionArchive } from '@/components/CollectionArchive' + +export const ArchiveBlock: React.FC< + ArchiveBlockProps & { + id?: string + } +> = async (props) => { + const { id, categories, introContent, limit: limitFromProps, populateBy, selectedDocs } = props + + const limit = limitFromProps || 3 + + let posts: Post[] = [] + + if (populateBy === 'collection') { + const payload = await getPayload({ config: configPromise }) + + const flattenedCategories = categories?.map((category) => { + if (typeof category === 'object') return category.id + else return category + }) + + const fetchedPosts = await payload.find({ + collection: 'posts', + depth: 1, + limit, + ...(flattenedCategories && flattenedCategories.length > 0 + ? { + where: { + categories: { + in: flattenedCategories, + }, + }, + } + : {}), + }) + + posts = fetchedPosts.docs + } else { + if (selectedDocs?.length) { + const filteredSelectedPosts = selectedDocs.map((post) => { + if (typeof post.value === 'object') return post.value + }) as Post[] + + posts = filteredSelectedPosts + } + } + + return ( +
+ {introContent && ( +
+ +
+ )} + +
+ ) +} diff --git a/src/blocks/ArchiveBlock/config.ts b/src/blocks/ArchiveBlock/config.ts new file mode 100644 index 0000000..f87a376 --- /dev/null +++ b/src/blocks/ArchiveBlock/config.ts @@ -0,0 +1,94 @@ +import type { Block } from 'payload' + +import { + FixedToolbarFeature, + HeadingFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +export const Archive: Block = { + slug: 'archive', + interfaceName: 'ArchiveBlock', + fields: [ + { + name: 'introContent', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + ] + }, + }), + label: 'Intro Content', + }, + { + name: 'populateBy', + type: 'select', + defaultValue: 'collection', + options: [ + { + label: 'Collection', + value: 'collection', + }, + { + label: 'Individual Selection', + value: 'selection', + }, + ], + }, + { + name: 'relationTo', + type: 'select', + admin: { + condition: (_, siblingData) => siblingData.populateBy === 'collection', + }, + defaultValue: 'posts', + label: 'Collections To Show', + options: [ + { + label: 'Posts', + value: 'posts', + }, + ], + }, + { + name: 'categories', + type: 'relationship', + admin: { + condition: (_, siblingData) => siblingData.populateBy === 'collection', + }, + hasMany: true, + label: 'Categories To Show', + relationTo: 'categories', + }, + { + name: 'limit', + type: 'number', + admin: { + condition: (_, siblingData) => siblingData.populateBy === 'collection', + step: 1, + }, + defaultValue: 10, + label: 'Limit', + }, + { + name: 'selectedDocs', + type: 'relationship', + admin: { + condition: (_, siblingData) => siblingData.populateBy === 'selection', + }, + hasMany: true, + label: 'Selection', + relationTo: ['posts'], + }, + ], + labels: { + plural: 'Archives', + singular: 'Archive', + }, +} diff --git a/src/blocks/Banner/Component.tsx b/src/blocks/Banner/Component.tsx new file mode 100644 index 0000000..6abb8ad --- /dev/null +++ b/src/blocks/Banner/Component.tsx @@ -0,0 +1,26 @@ +import type { BannerBlock as BannerBlockProps } from 'src/payload-types' + +import { cn } from '@/utilities/ui' +import React from 'react' +import RichText from '@/components/RichText' + +type Props = { + className?: string +} & BannerBlockProps + +export const BannerBlock: React.FC = ({ className, content, style }) => { + return ( +
+
+ +
+
+ ) +} diff --git a/src/blocks/Banner/config.ts b/src/blocks/Banner/config.ts new file mode 100644 index 0000000..53e46b5 --- /dev/null +++ b/src/blocks/Banner/config.ts @@ -0,0 +1,37 @@ +import type { Block } from 'payload' + +import { + FixedToolbarFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +export const Banner: Block = { + slug: 'banner', + fields: [ + { + name: 'style', + type: 'select', + defaultValue: 'info', + options: [ + { label: 'Info', value: 'info' }, + { label: 'Warning', value: 'warning' }, + { label: 'Error', value: 'error' }, + { label: 'Success', value: 'success' }, + ], + required: true, + }, + { + name: 'content', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [...rootFeatures, FixedToolbarFeature(), InlineToolbarFeature()] + }, + }), + label: false, + required: true, + }, + ], + interfaceName: 'BannerBlock', +} diff --git a/src/blocks/CallToAction/Component.tsx b/src/blocks/CallToAction/Component.tsx new file mode 100644 index 0000000..6b3771c --- /dev/null +++ b/src/blocks/CallToAction/Component.tsx @@ -0,0 +1,23 @@ +import React from 'react' + +import type { CallToActionBlock as CTABlockProps } from '@/payload-types' + +import RichText from '@/components/RichText' +import { CMSLink } from '@/components/Link' + +export const CallToActionBlock: React.FC = ({ links, richText }) => { + return ( +
+
+
+ {richText && } +
+
+ {(links || []).map(({ link }, i) => { + return + })} +
+
+
+ ) +} diff --git a/src/blocks/CallToAction/config.ts b/src/blocks/CallToAction/config.ts new file mode 100644 index 0000000..f4ffa77 --- /dev/null +++ b/src/blocks/CallToAction/config.ts @@ -0,0 +1,42 @@ +import type { Block } from 'payload' + +import { + FixedToolbarFeature, + HeadingFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +import { linkGroup } from '../../fields/linkGroup' + +export const CallToAction: Block = { + slug: 'cta', + interfaceName: 'CallToActionBlock', + fields: [ + { + name: 'richText', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + ] + }, + }), + label: false, + }, + linkGroup({ + appearances: ['default', 'outline'], + overrides: { + maxRows: 2, + }, + }), + ], + labels: { + plural: 'Calls to Action', + singular: 'Call to Action', + }, +} diff --git a/src/blocks/Code/Component.client.tsx b/src/blocks/Code/Component.client.tsx new file mode 100644 index 0000000..fc8fb62 --- /dev/null +++ b/src/blocks/Code/Component.client.tsx @@ -0,0 +1,33 @@ +'use client' +import { Highlight, themes } from 'prism-react-renderer' +import React from 'react' +import { CopyButton } from './CopyButton' + +type Props = { + code: string + language?: string +} + +export const Code: React.FC = ({ code, language = '' }) => { + if (!code) return null + + return ( + + {({ getLineProps, getTokenProps, tokens }) => ( +
+          {tokens.map((line, i) => (
+            
+ {i + 1} + + {line.map((token, key) => ( + + ))} + +
+ ))} + +
+ )} +
+ ) +} diff --git a/src/blocks/Code/Component.tsx b/src/blocks/Code/Component.tsx new file mode 100644 index 0000000..7f776d7 --- /dev/null +++ b/src/blocks/Code/Component.tsx @@ -0,0 +1,21 @@ +import React from 'react' + +import { Code } from './Component.client' + +export type CodeBlockProps = { + code: string + language?: string + blockType: 'code' +} + +type Props = CodeBlockProps & { + className?: string +} + +export const CodeBlock: React.FC = ({ className, code, language }) => { + return ( +
+ +
+ ) +} diff --git a/src/blocks/Code/CopyButton.tsx b/src/blocks/Code/CopyButton.tsx new file mode 100644 index 0000000..8d204bf --- /dev/null +++ b/src/blocks/Code/CopyButton.tsx @@ -0,0 +1,33 @@ +'use client' +import { Button } from '@/components/ui/button' +import { CopyIcon } from '@payloadcms/ui/icons/Copy' +import { useState } from 'react' + +export function CopyButton({ code }: { code: string }) { + const [text, setText] = useState('Copy') + + function updateCopyStatus() { + if (text === 'Copy') { + setText(() => 'Copied!') + setTimeout(() => { + setText(() => 'Copy') + }, 1000) + } + } + + return ( +
+ +
+ ) +} diff --git a/src/blocks/Code/config.ts b/src/blocks/Code/config.ts new file mode 100644 index 0000000..7b26f80 --- /dev/null +++ b/src/blocks/Code/config.ts @@ -0,0 +1,33 @@ +import type { Block } from 'payload' + +export const Code: Block = { + slug: 'code', + interfaceName: 'CodeBlock', + fields: [ + { + name: 'language', + type: 'select', + defaultValue: 'typescript', + options: [ + { + label: 'Typescript', + value: 'typescript', + }, + { + label: 'Javascript', + value: 'javascript', + }, + { + label: 'CSS', + value: 'css', + }, + ], + }, + { + name: 'code', + type: 'code', + label: false, + required: true, + }, + ], +} diff --git a/src/blocks/Content/Component.tsx b/src/blocks/Content/Component.tsx new file mode 100644 index 0000000..2c2550b --- /dev/null +++ b/src/blocks/Content/Component.tsx @@ -0,0 +1,43 @@ +import { cn } from '@/utilities/ui' +import React from 'react' +import RichText from '@/components/RichText' + +import type { ContentBlock as ContentBlockProps } from '@/payload-types' + +import { CMSLink } from '../../components/Link' + +export const ContentBlock: React.FC = (props) => { + const { columns } = props + + const colsSpanClasses = { + full: '12', + half: '6', + oneThird: '4', + twoThirds: '8', + } + + return ( +
+
+ {columns && + columns.length > 0 && + columns.map((col, index) => { + const { enableLink, link, richText, size } = col + + return ( +
+ {richText && } + + {enableLink && } +
+ ) + })} +
+
+ ) +} diff --git a/src/blocks/Content/config.ts b/src/blocks/Content/config.ts new file mode 100644 index 0000000..5c2fb07 --- /dev/null +++ b/src/blocks/Content/config.ts @@ -0,0 +1,79 @@ +import type { Block, Field } from 'payload' + +import { + FixedToolbarFeature, + HeadingFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +import { link } from '@/fields/link' + +const columnFields: Field[] = [ + { + name: 'size', + type: 'select', + defaultValue: 'oneThird', + options: [ + { + label: 'One Third', + value: 'oneThird', + }, + { + label: 'Half', + value: 'half', + }, + { + label: 'Two Thirds', + value: 'twoThirds', + }, + { + label: 'Full', + value: 'full', + }, + ], + }, + { + name: 'richText', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h2', 'h3', 'h4'] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + ] + }, + }), + label: false, + }, + { + name: 'enableLink', + type: 'checkbox', + }, + link({ + overrides: { + admin: { + condition: (_data, siblingData) => { + return Boolean(siblingData?.enableLink) + }, + }, + }, + }), +] + +export const Content: Block = { + slug: 'content', + interfaceName: 'ContentBlock', + fields: [ + { + name: 'columns', + type: 'array', + admin: { + initCollapsed: true, + }, + fields: columnFields, + }, + ], +} diff --git a/src/blocks/Form/Checkbox/index.tsx b/src/blocks/Form/Checkbox/index.tsx new file mode 100644 index 0000000..633d5db --- /dev/null +++ b/src/blocks/Form/Checkbox/index.tsx @@ -0,0 +1,45 @@ +import type { CheckboxField } from '@payloadcms/plugin-form-builder/types' +import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form' + +import { useFormContext } from 'react-hook-form' + +import { Checkbox as CheckboxUi } from '@/components/ui/checkbox' +import { Label } from '@/components/ui/label' +import React from 'react' + +import { Error } from '../Error' +import { Width } from '../Width' + +export const Checkbox: React.FC< + CheckboxField & { + errors: Partial + register: UseFormRegister + } +> = ({ name, defaultValue, errors, label, register, required, width }) => { + const props = register(name, { required: required }) + const { setValue } = useFormContext() + + return ( + +
+ { + setValue(props.name, checked) + }} + /> + +
+ {errors[name] && } +
+ ) +} diff --git a/src/blocks/Form/Component.tsx b/src/blocks/Form/Component.tsx new file mode 100644 index 0000000..428265e --- /dev/null +++ b/src/blocks/Form/Component.tsx @@ -0,0 +1,163 @@ +'use client' +import type { FormFieldBlock, Form as FormType } from '@payloadcms/plugin-form-builder/types' + +import { useRouter } from 'next/navigation' +import React, { useCallback, useState } from 'react' +import { useForm, FormProvider } from 'react-hook-form' +import RichText from '@/components/RichText' +import { Button } from '@/components/ui/button' +import type { DefaultTypedEditorState } from '@payloadcms/richtext-lexical' + +import { fields } from './fields' +import { getClientSideURL } from '@/utilities/getURL' + +export type FormBlockType = { + blockName?: string + blockType?: 'formBlock' + enableIntro: boolean + form: FormType + introContent?: DefaultTypedEditorState +} + +export const FormBlock: React.FC< + { + id?: string + } & FormBlockType +> = (props) => { + const { + enableIntro, + form: formFromProps, + form: { id: formID, confirmationMessage, confirmationType, redirect, submitButtonLabel } = {}, + introContent, + } = props + + const formMethods = useForm({ + defaultValues: formFromProps.fields, + }) + const { + control, + formState: { errors }, + handleSubmit, + register, + } = formMethods + + const [isLoading, setIsLoading] = useState(false) + const [hasSubmitted, setHasSubmitted] = useState() + const [error, setError] = useState<{ message: string; status?: string } | undefined>() + const router = useRouter() + + const onSubmit = useCallback( + (data: FormFieldBlock[]) => { + let loadingTimerID: ReturnType + const submitForm = async () => { + setError(undefined) + + const dataToSend = Object.entries(data).map(([name, value]) => ({ + field: name, + value, + })) + + // delay loading indicator by 1s + loadingTimerID = setTimeout(() => { + setIsLoading(true) + }, 1000) + + try { + const req = await fetch(`${getClientSideURL()}/api/form-submissions`, { + body: JSON.stringify({ + form: formID, + submissionData: dataToSend, + }), + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + }) + + const res = await req.json() + + clearTimeout(loadingTimerID) + + if (req.status >= 400) { + setIsLoading(false) + + setError({ + message: res.errors?.[0]?.message || 'Internal Server Error', + status: res.status, + }) + + return + } + + setIsLoading(false) + setHasSubmitted(true) + + if (confirmationType === 'redirect' && redirect) { + const { url } = redirect + + const redirectUrl = url + + if (redirectUrl) router.push(redirectUrl) + } + } catch (err) { + console.warn(err) + setIsLoading(false) + setError({ + message: 'Something went wrong.', + }) + } + } + + void submitForm() + }, + [router, formID, redirect, confirmationType], + ) + + return ( +
+ {enableIntro && introContent && !hasSubmitted && ( + + )} +
+ + {!isLoading && hasSubmitted && confirmationType === 'message' && ( + + )} + {isLoading && !hasSubmitted &&

Loading, please wait...

} + {error &&
{`${error.status || '500'}: ${error.message || ''}`}
} + {!hasSubmitted && ( +
+
+ {formFromProps && + formFromProps.fields && + formFromProps.fields?.map((field, index) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const Field: React.FC = fields?.[field.blockType as keyof typeof fields] + if (Field) { + return ( +
+ +
+ ) + } + return null + })} +
+ + +
+ )} +
+
+
+ ) +} diff --git a/src/blocks/Form/Country/index.tsx b/src/blocks/Form/Country/index.tsx new file mode 100644 index 0000000..9c85b75 --- /dev/null +++ b/src/blocks/Form/Country/index.tsx @@ -0,0 +1,65 @@ +import type { CountryField } from '@payloadcms/plugin-form-builder/types' +import type { Control, FieldErrorsImpl } from 'react-hook-form' + +import { Label } from '@/components/ui/label' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import React from 'react' +import { Controller } from 'react-hook-form' + +import { Error } from '../Error' +import { Width } from '../Width' +import { countryOptions } from './options' + +export const Country: React.FC< + CountryField & { + control: Control + errors: Partial + } +> = ({ name, control, errors, label, required, width }) => { + return ( + + + { + const controlledValue = countryOptions.find((t) => t.value === value) + + return ( + + ) + }} + rules={{ required }} + /> + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/Country/options.ts b/src/blocks/Form/Country/options.ts new file mode 100644 index 0000000..f952c1d --- /dev/null +++ b/src/blocks/Form/Country/options.ts @@ -0,0 +1,982 @@ +export const countryOptions = [ + { + label: 'Afghanistan', + value: 'AF', + }, + { + label: 'Åland Islands', + value: 'AX', + }, + { + label: 'Albania', + value: 'AL', + }, + { + label: 'Algeria', + value: 'DZ', + }, + { + label: 'American Samoa', + value: 'AS', + }, + { + label: 'Andorra', + value: 'AD', + }, + { + label: 'Angola', + value: 'AO', + }, + { + label: 'Anguilla', + value: 'AI', + }, + { + label: 'Antarctica', + value: 'AQ', + }, + { + label: 'Antigua and Barbuda', + value: 'AG', + }, + { + label: 'Argentina', + value: 'AR', + }, + { + label: 'Armenia', + value: 'AM', + }, + { + label: 'Aruba', + value: 'AW', + }, + { + label: 'Australia', + value: 'AU', + }, + { + label: 'Austria', + value: 'AT', + }, + { + label: 'Azerbaijan', + value: 'AZ', + }, + { + label: 'Bahamas', + value: 'BS', + }, + { + label: 'Bahrain', + value: 'BH', + }, + { + label: 'Bangladesh', + value: 'BD', + }, + { + label: 'Barbados', + value: 'BB', + }, + { + label: 'Belarus', + value: 'BY', + }, + { + label: 'Belgium', + value: 'BE', + }, + { + label: 'Belize', + value: 'BZ', + }, + { + label: 'Benin', + value: 'BJ', + }, + { + label: 'Bermuda', + value: 'BM', + }, + { + label: 'Bhutan', + value: 'BT', + }, + { + label: 'Bolivia', + value: 'BO', + }, + { + label: 'Bosnia and Herzegovina', + value: 'BA', + }, + { + label: 'Botswana', + value: 'BW', + }, + { + label: 'Bouvet Island', + value: 'BV', + }, + { + label: 'Brazil', + value: 'BR', + }, + { + label: 'British Indian Ocean Territory', + value: 'IO', + }, + { + label: 'Brunei Darussalam', + value: 'BN', + }, + { + label: 'Bulgaria', + value: 'BG', + }, + { + label: 'Burkina Faso', + value: 'BF', + }, + { + label: 'Burundi', + value: 'BI', + }, + { + label: 'Cambodia', + value: 'KH', + }, + { + label: 'Cameroon', + value: 'CM', + }, + { + label: 'Canada', + value: 'CA', + }, + { + label: 'Cape Verde', + value: 'CV', + }, + { + label: 'Cayman Islands', + value: 'KY', + }, + { + label: 'Central African Republic', + value: 'CF', + }, + { + label: 'Chad', + value: 'TD', + }, + { + label: 'Chile', + value: 'CL', + }, + { + label: 'China', + value: 'CN', + }, + { + label: 'Christmas Island', + value: 'CX', + }, + { + label: 'Cocos (Keeling) Islands', + value: 'CC', + }, + { + label: 'Colombia', + value: 'CO', + }, + { + label: 'Comoros', + value: 'KM', + }, + { + label: 'Congo', + value: 'CG', + }, + { + label: 'Congo, The Democratic Republic of the', + value: 'CD', + }, + { + label: 'Cook Islands', + value: 'CK', + }, + { + label: 'Costa Rica', + value: 'CR', + }, + { + label: "Cote D'Ivoire", + value: 'CI', + }, + { + label: 'Croatia', + value: 'HR', + }, + { + label: 'Cuba', + value: 'CU', + }, + { + label: 'Cyprus', + value: 'CY', + }, + { + label: 'Czech Republic', + value: 'CZ', + }, + { + label: 'Denmark', + value: 'DK', + }, + { + label: 'Djibouti', + value: 'DJ', + }, + { + label: 'Dominica', + value: 'DM', + }, + { + label: 'Dominican Republic', + value: 'DO', + }, + { + label: 'Ecuador', + value: 'EC', + }, + { + label: 'Egypt', + value: 'EG', + }, + { + label: 'El Salvador', + value: 'SV', + }, + { + label: 'Equatorial Guinea', + value: 'GQ', + }, + { + label: 'Eritrea', + value: 'ER', + }, + { + label: 'Estonia', + value: 'EE', + }, + { + label: 'Ethiopia', + value: 'ET', + }, + { + label: 'Falkland Islands (Malvinas)', + value: 'FK', + }, + { + label: 'Faroe Islands', + value: 'FO', + }, + { + label: 'Fiji', + value: 'FJ', + }, + { + label: 'Finland', + value: 'FI', + }, + { + label: 'France', + value: 'FR', + }, + { + label: 'French Guiana', + value: 'GF', + }, + { + label: 'French Polynesia', + value: 'PF', + }, + { + label: 'French Southern Territories', + value: 'TF', + }, + { + label: 'Gabon', + value: 'GA', + }, + { + label: 'Gambia', + value: 'GM', + }, + { + label: 'Georgia', + value: 'GE', + }, + { + label: 'Germany', + value: 'DE', + }, + { + label: 'Ghana', + value: 'GH', + }, + { + label: 'Gibraltar', + value: 'GI', + }, + { + label: 'Greece', + value: 'GR', + }, + { + label: 'Greenland', + value: 'GL', + }, + { + label: 'Grenada', + value: 'GD', + }, + { + label: 'Guadeloupe', + value: 'GP', + }, + { + label: 'Guam', + value: 'GU', + }, + { + label: 'Guatemala', + value: 'GT', + }, + { + label: 'Guernsey', + value: 'GG', + }, + { + label: 'Guinea', + value: 'GN', + }, + { + label: 'Guinea-Bissau', + value: 'GW', + }, + { + label: 'Guyana', + value: 'GY', + }, + { + label: 'Haiti', + value: 'HT', + }, + { + label: 'Heard Island and Mcdonald Islands', + value: 'HM', + }, + { + label: 'Holy See (Vatican City State)', + value: 'VA', + }, + { + label: 'Honduras', + value: 'HN', + }, + { + label: 'Hong Kong', + value: 'HK', + }, + { + label: 'Hungary', + value: 'HU', + }, + { + label: 'Iceland', + value: 'IS', + }, + { + label: 'India', + value: 'IN', + }, + { + label: 'Indonesia', + value: 'ID', + }, + { + label: 'Iran, Islamic Republic Of', + value: 'IR', + }, + { + label: 'Iraq', + value: 'IQ', + }, + { + label: 'Ireland', + value: 'IE', + }, + { + label: 'Isle of Man', + value: 'IM', + }, + { + label: 'Israel', + value: 'IL', + }, + { + label: 'Italy', + value: 'IT', + }, + { + label: 'Jamaica', + value: 'JM', + }, + { + label: 'Japan', + value: 'JP', + }, + { + label: 'Jersey', + value: 'JE', + }, + { + label: 'Jordan', + value: 'JO', + }, + { + label: 'Kazakhstan', + value: 'KZ', + }, + { + label: 'Kenya', + value: 'KE', + }, + { + label: 'Kiribati', + value: 'KI', + }, + { + label: "Democratic People's Republic of Korea", + value: 'KP', + }, + { + label: 'Korea, Republic of', + value: 'KR', + }, + { + label: 'Kosovo', + value: 'XK', + }, + { + label: 'Kuwait', + value: 'KW', + }, + { + label: 'Kyrgyzstan', + value: 'KG', + }, + { + label: "Lao People's Democratic Republic", + value: 'LA', + }, + { + label: 'Latvia', + value: 'LV', + }, + { + label: 'Lebanon', + value: 'LB', + }, + { + label: 'Lesotho', + value: 'LS', + }, + { + label: 'Liberia', + value: 'LR', + }, + { + label: 'Libyan Arab Jamahiriya', + value: 'LY', + }, + { + label: 'Liechtenstein', + value: 'LI', + }, + { + label: 'Lithuania', + value: 'LT', + }, + { + label: 'Luxembourg', + value: 'LU', + }, + { + label: 'Macao', + value: 'MO', + }, + { + label: 'Macedonia, The Former Yugoslav Republic of', + value: 'MK', + }, + { + label: 'Madagascar', + value: 'MG', + }, + { + label: 'Malawi', + value: 'MW', + }, + { + label: 'Malaysia', + value: 'MY', + }, + { + label: 'Maldives', + value: 'MV', + }, + { + label: 'Mali', + value: 'ML', + }, + { + label: 'Malta', + value: 'MT', + }, + { + label: 'Marshall Islands', + value: 'MH', + }, + { + label: 'Martinique', + value: 'MQ', + }, + { + label: 'Mauritania', + value: 'MR', + }, + { + label: 'Mauritius', + value: 'MU', + }, + { + label: 'Mayotte', + value: 'YT', + }, + { + label: 'Mexico', + value: 'MX', + }, + { + label: 'Micronesia, Federated States of', + value: 'FM', + }, + { + label: 'Moldova, Republic of', + value: 'MD', + }, + { + label: 'Monaco', + value: 'MC', + }, + { + label: 'Mongolia', + value: 'MN', + }, + { + label: 'Montenegro', + value: 'ME', + }, + { + label: 'Montserrat', + value: 'MS', + }, + { + label: 'Morocco', + value: 'MA', + }, + { + label: 'Mozambique', + value: 'MZ', + }, + { + label: 'Myanmar', + value: 'MM', + }, + { + label: 'Namibia', + value: 'NA', + }, + { + label: 'Nauru', + value: 'NR', + }, + { + label: 'Nepal', + value: 'NP', + }, + { + label: 'Netherlands', + value: 'NL', + }, + { + label: 'Netherlands Antilles', + value: 'AN', + }, + { + label: 'New Caledonia', + value: 'NC', + }, + { + label: 'New Zealand', + value: 'NZ', + }, + { + label: 'Nicaragua', + value: 'NI', + }, + { + label: 'Niger', + value: 'NE', + }, + { + label: 'Nigeria', + value: 'NG', + }, + { + label: 'Niue', + value: 'NU', + }, + { + label: 'Norfolk Island', + value: 'NF', + }, + { + label: 'Northern Mariana Islands', + value: 'MP', + }, + { + label: 'Norway', + value: 'NO', + }, + { + label: 'Oman', + value: 'OM', + }, + { + label: 'Pakistan', + value: 'PK', + }, + { + label: 'Palau', + value: 'PW', + }, + { + label: 'Palestinian Territory, Occupied', + value: 'PS', + }, + { + label: 'Panama', + value: 'PA', + }, + { + label: 'Papua New Guinea', + value: 'PG', + }, + { + label: 'Paraguay', + value: 'PY', + }, + { + label: 'Peru', + value: 'PE', + }, + { + label: 'Philippines', + value: 'PH', + }, + { + label: 'Pitcairn', + value: 'PN', + }, + { + label: 'Poland', + value: 'PL', + }, + { + label: 'Portugal', + value: 'PT', + }, + { + label: 'Puerto Rico', + value: 'PR', + }, + { + label: 'Qatar', + value: 'QA', + }, + { + label: 'Reunion', + value: 'RE', + }, + { + label: 'Romania', + value: 'RO', + }, + { + label: 'Russian Federation', + value: 'RU', + }, + { + label: 'Rwanda', + value: 'RW', + }, + { + label: 'Saint Helena', + value: 'SH', + }, + { + label: 'Saint Kitts and Nevis', + value: 'KN', + }, + { + label: 'Saint Lucia', + value: 'LC', + }, + { + label: 'Saint Pierre and Miquelon', + value: 'PM', + }, + { + label: 'Saint Vincent and the Grenadines', + value: 'VC', + }, + { + label: 'Samoa', + value: 'WS', + }, + { + label: 'San Marino', + value: 'SM', + }, + { + label: 'Sao Tome and Principe', + value: 'ST', + }, + { + label: 'Saudi Arabia', + value: 'SA', + }, + { + label: 'Senegal', + value: 'SN', + }, + { + label: 'Serbia', + value: 'RS', + }, + { + label: 'Seychelles', + value: 'SC', + }, + { + label: 'Sierra Leone', + value: 'SL', + }, + { + label: 'Singapore', + value: 'SG', + }, + { + label: 'Slovakia', + value: 'SK', + }, + { + label: 'Slovenia', + value: 'SI', + }, + { + label: 'Solomon Islands', + value: 'SB', + }, + { + label: 'Somalia', + value: 'SO', + }, + { + label: 'South Africa', + value: 'ZA', + }, + { + label: 'South Georgia and the South Sandwich Islands', + value: 'GS', + }, + { + label: 'Spain', + value: 'ES', + }, + { + label: 'Sri Lanka', + value: 'LK', + }, + { + label: 'Sudan', + value: 'SD', + }, + { + label: 'Suriname', + value: 'SR', + }, + { + label: 'Svalbard and Jan Mayen', + value: 'SJ', + }, + { + label: 'Swaziland', + value: 'SZ', + }, + { + label: 'Sweden', + value: 'SE', + }, + { + label: 'Switzerland', + value: 'CH', + }, + { + label: 'Syrian Arab Republic', + value: 'SY', + }, + { + label: 'Taiwan', + value: 'TW', + }, + { + label: 'Tajikistan', + value: 'TJ', + }, + { + label: 'Tanzania, United Republic of', + value: 'TZ', + }, + { + label: 'Thailand', + value: 'TH', + }, + { + label: 'Timor-Leste', + value: 'TL', + }, + { + label: 'Togo', + value: 'TG', + }, + { + label: 'Tokelau', + value: 'TK', + }, + { + label: 'Tonga', + value: 'TO', + }, + { + label: 'Trinidad and Tobago', + value: 'TT', + }, + { + label: 'Tunisia', + value: 'TN', + }, + { + label: 'Turkey', + value: 'TR', + }, + { + label: 'Turkmenistan', + value: 'TM', + }, + { + label: 'Turks and Caicos Islands', + value: 'TC', + }, + { + label: 'Tuvalu', + value: 'TV', + }, + { + label: 'Uganda', + value: 'UG', + }, + { + label: 'Ukraine', + value: 'UA', + }, + { + label: 'United Arab Emirates', + value: 'AE', + }, + { + label: 'United Kingdom', + value: 'GB', + }, + { + label: 'United States', + value: 'US', + }, + { + label: 'United States Minor Outlying Islands', + value: 'UM', + }, + { + label: 'Uruguay', + value: 'UY', + }, + { + label: 'Uzbekistan', + value: 'UZ', + }, + { + label: 'Vanuatu', + value: 'VU', + }, + { + label: 'Venezuela', + value: 'VE', + }, + { + label: 'Viet Nam', + value: 'VN', + }, + { + label: 'Virgin Islands, British', + value: 'VG', + }, + { + label: 'Virgin Islands, U.S.', + value: 'VI', + }, + { + label: 'Wallis and Futuna', + value: 'WF', + }, + { + label: 'Western Sahara', + value: 'EH', + }, + { + label: 'Yemen', + value: 'YE', + }, + { + label: 'Zambia', + value: 'ZM', + }, + { + label: 'Zimbabwe', + value: 'ZW', + }, +] diff --git a/src/blocks/Form/Email/index.tsx b/src/blocks/Form/Email/index.tsx new file mode 100644 index 0000000..fc9fd28 --- /dev/null +++ b/src/blocks/Form/Email/index.tsx @@ -0,0 +1,38 @@ +import type { EmailField } from '@payloadcms/plugin-form-builder/types' +import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form' + +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import React from 'react' + +import { Error } from '../Error' +import { Width } from '../Width' + +export const Email: React.FC< + EmailField & { + errors: Partial + register: UseFormRegister + } +> = ({ name, defaultValue, errors, label, register, required, width }) => { + return ( + + + + + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/Error/index.tsx b/src/blocks/Form/Error/index.tsx new file mode 100644 index 0000000..a7b9e47 --- /dev/null +++ b/src/blocks/Form/Error/index.tsx @@ -0,0 +1,15 @@ +'use client' + +import * as React from 'react' +import { useFormContext } from 'react-hook-form' + +export const Error = ({ name }: { name: string }) => { + const { + formState: { errors }, + } = useFormContext() + return ( +
+ {(errors[name]?.message as string) || 'This field is required'} +
+ ) +} diff --git a/src/blocks/Form/Message/index.tsx b/src/blocks/Form/Message/index.tsx new file mode 100644 index 0000000..85f5f75 --- /dev/null +++ b/src/blocks/Form/Message/index.tsx @@ -0,0 +1,13 @@ +import RichText from '@/components/RichText' +import React from 'react' + +import { Width } from '../Width' +import { DefaultTypedEditorState } from '@payloadcms/richtext-lexical' + +export const Message: React.FC<{ message: DefaultTypedEditorState }> = ({ message }) => { + return ( + + {message && } + + ) +} diff --git a/src/blocks/Form/Number/index.tsx b/src/blocks/Form/Number/index.tsx new file mode 100644 index 0000000..f26e54a --- /dev/null +++ b/src/blocks/Form/Number/index.tsx @@ -0,0 +1,36 @@ +import type { TextField } from '@payloadcms/plugin-form-builder/types' +import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form' + +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import React from 'react' + +import { Error } from '../Error' +import { Width } from '../Width' +export const Number: React.FC< + TextField & { + errors: Partial + register: UseFormRegister + } +> = ({ name, defaultValue, errors, label, register, required, width }) => { + return ( + + + + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/Select/index.tsx b/src/blocks/Form/Select/index.tsx new file mode 100644 index 0000000..30c0e83 --- /dev/null +++ b/src/blocks/Form/Select/index.tsx @@ -0,0 +1,63 @@ +import type { SelectField } from '@payloadcms/plugin-form-builder/types' +import type { Control, FieldErrorsImpl } from 'react-hook-form' + +import { Label } from '@/components/ui/label' +import { + Select as SelectComponent, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import React from 'react' +import { Controller } from 'react-hook-form' + +import { Error } from '../Error' +import { Width } from '../Width' + +export const Select: React.FC< + SelectField & { + control: Control + errors: Partial + } +> = ({ name, control, errors, label, options, required, width, defaultValue }) => { + return ( + + + { + const controlledValue = options.find((t) => t.value === value) + + return ( + onChange(val)} value={controlledValue?.value}> + + + + + {options.map(({ label, value }) => { + return ( + + {label} + + ) + })} + + + ) + }} + rules={{ required }} + /> + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/State/index.tsx b/src/blocks/Form/State/index.tsx new file mode 100644 index 0000000..29e49ca --- /dev/null +++ b/src/blocks/Form/State/index.tsx @@ -0,0 +1,64 @@ +import type { StateField } from '@payloadcms/plugin-form-builder/types' +import type { Control, FieldErrorsImpl } from 'react-hook-form' + +import { Label } from '@/components/ui/label' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import React from 'react' +import { Controller } from 'react-hook-form' + +import { Error } from '../Error' +import { Width } from '../Width' +import { stateOptions } from './options' + +export const State: React.FC< + StateField & { + control: Control + errors: Partial + } +> = ({ name, control, errors, label, required, width }) => { + return ( + + + { + const controlledValue = stateOptions.find((t) => t.value === value) + + return ( + + ) + }} + rules={{ required }} + /> + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/State/options.ts b/src/blocks/Form/State/options.ts new file mode 100644 index 0000000..8dff991 --- /dev/null +++ b/src/blocks/Form/State/options.ts @@ -0,0 +1,52 @@ +export const stateOptions = [ + { label: 'Alabama', value: 'AL' }, + { label: 'Alaska', value: 'AK' }, + { label: 'Arizona', value: 'AZ' }, + { label: 'Arkansas', value: 'AR' }, + { label: 'California', value: 'CA' }, + { label: 'Colorado', value: 'CO' }, + { label: 'Connecticut', value: 'CT' }, + { label: 'Delaware', value: 'DE' }, + { label: 'Florida', value: 'FL' }, + { label: 'Georgia', value: 'GA' }, + { label: 'Hawaii', value: 'HI' }, + { label: 'Idaho', value: 'ID' }, + { label: 'Illinois', value: 'IL' }, + { label: 'Indiana', value: 'IN' }, + { label: 'Iowa', value: 'IA' }, + { label: 'Kansas', value: 'KS' }, + { label: 'Kentucky', value: 'KY' }, + { label: 'Louisiana', value: 'LA' }, + { label: 'Maine', value: 'ME' }, + { label: 'Maryland', value: 'MD' }, + { label: 'Massachusetts', value: 'MA' }, + { label: 'Michigan', value: 'MI' }, + { label: 'Minnesota', value: 'MN' }, + { label: 'Mississippi', value: 'MS' }, + { label: 'Missouri', value: 'MO' }, + { label: 'Montana', value: 'MT' }, + { label: 'Nebraska', value: 'NE' }, + { label: 'Nevada', value: 'NV' }, + { label: 'New Hampshire', value: 'NH' }, + { label: 'New Jersey', value: 'NJ' }, + { label: 'New Mexico', value: 'NM' }, + { label: 'New York', value: 'NY' }, + { label: 'North Carolina', value: 'NC' }, + { label: 'North Dakota', value: 'ND' }, + { label: 'Ohio', value: 'OH' }, + { label: 'Oklahoma', value: 'OK' }, + { label: 'Oregon', value: 'OR' }, + { label: 'Pennsylvania', value: 'PA' }, + { label: 'Rhode Island', value: 'RI' }, + { label: 'South Carolina', value: 'SC' }, + { label: 'South Dakota', value: 'SD' }, + { label: 'Tennessee', value: 'TN' }, + { label: 'Texas', value: 'TX' }, + { label: 'Utah', value: 'UT' }, + { label: 'Vermont', value: 'VT' }, + { label: 'Virginia', value: 'VA' }, + { label: 'Washington', value: 'WA' }, + { label: 'West Virginia', value: 'WV' }, + { label: 'Wisconsin', value: 'WI' }, + { label: 'Wyoming', value: 'WY' }, +] diff --git a/src/blocks/Form/Text/index.tsx b/src/blocks/Form/Text/index.tsx new file mode 100644 index 0000000..be1e0ff --- /dev/null +++ b/src/blocks/Form/Text/index.tsx @@ -0,0 +1,32 @@ +import type { TextField } from '@payloadcms/plugin-form-builder/types' +import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form' + +import { Input } from '@/components/ui/input' +import { Label } from '@/components/ui/label' +import React from 'react' + +import { Error } from '../Error' +import { Width } from '../Width' + +export const Text: React.FC< + TextField & { + errors: Partial + register: UseFormRegister + } +> = ({ name, defaultValue, errors, label, register, required, width }) => { + return ( + + + + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/Textarea/index.tsx b/src/blocks/Form/Textarea/index.tsx new file mode 100644 index 0000000..ecb6e21 --- /dev/null +++ b/src/blocks/Form/Textarea/index.tsx @@ -0,0 +1,40 @@ +import type { TextField } from '@payloadcms/plugin-form-builder/types' +import type { FieldErrorsImpl, FieldValues, UseFormRegister } from 'react-hook-form' + +import { Label } from '@/components/ui/label' +import { Textarea as TextAreaComponent } from '@/components/ui/textarea' +import React from 'react' + +import { Error } from '../Error' +import { Width } from '../Width' + +export const Textarea: React.FC< + TextField & { + errors: Partial + register: UseFormRegister + rows?: number + } +> = ({ name, defaultValue, errors, label, register, required, rows = 3, width }) => { + return ( + + + + + + {errors[name] && } + + ) +} diff --git a/src/blocks/Form/Width/index.tsx b/src/blocks/Form/Width/index.tsx new file mode 100644 index 0000000..bcc51a3 --- /dev/null +++ b/src/blocks/Form/Width/index.tsx @@ -0,0 +1,13 @@ +import * as React from 'react' + +export const Width: React.FC<{ + children: React.ReactNode + className?: string + width?: number | string +}> = ({ children, className, width }) => { + return ( +
+ {children} +
+ ) +} diff --git a/src/blocks/Form/config.ts b/src/blocks/Form/config.ts new file mode 100644 index 0000000..5334289 --- /dev/null +++ b/src/blocks/Form/config.ts @@ -0,0 +1,51 @@ +import type { Block } from 'payload' + +import { + FixedToolbarFeature, + HeadingFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +export const FormBlock: Block = { + slug: 'formBlock', + interfaceName: 'FormBlock', + fields: [ + { + name: 'form', + type: 'relationship', + relationTo: 'forms', + required: true, + }, + { + name: 'enableIntro', + type: 'checkbox', + label: 'Enable Intro Content', + }, + { + name: 'introContent', + type: 'richText', + admin: { + condition: (_, { enableIntro }) => Boolean(enableIntro), + }, + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + ] + }, + }), + label: 'Intro Content', + }, + ], + graphQL: { + singularName: 'FormBlock', + }, + labels: { + plural: 'Form Blocks', + singular: 'Form Block', + }, +} diff --git a/src/blocks/Form/fields.tsx b/src/blocks/Form/fields.tsx new file mode 100644 index 0000000..fa660f7 --- /dev/null +++ b/src/blocks/Form/fields.tsx @@ -0,0 +1,21 @@ +import { Checkbox } from './Checkbox' +import { Country } from './Country' +import { Email } from './Email' +import { Message } from './Message' +import { Number } from './Number' +import { Select } from './Select' +import { State } from './State' +import { Text } from './Text' +import { Textarea } from './Textarea' + +export const fields = { + checkbox: Checkbox, + country: Country, + email: Email, + message: Message, + number: Number, + select: Select, + state: State, + text: Text, + textarea: Textarea, +} diff --git a/src/blocks/MediaBlock/Component.tsx b/src/blocks/MediaBlock/Component.tsx new file mode 100644 index 0000000..a88896a --- /dev/null +++ b/src/blocks/MediaBlock/Component.tsx @@ -0,0 +1,67 @@ +import type { StaticImageData } from 'next/image' + +import { cn } from '@/utilities/ui' +import React from 'react' +import RichText from '@/components/RichText' + +import type { MediaBlock as MediaBlockProps } from '@/payload-types' + +import { Media } from '../../components/Media' + +type Props = MediaBlockProps & { + breakout?: boolean + captionClassName?: string + className?: string + enableGutter?: boolean + imgClassName?: string + staticImage?: StaticImageData + disableInnerContainer?: boolean +} + +export const MediaBlock: React.FC = (props) => { + const { + captionClassName, + className, + enableGutter = true, + imgClassName, + media, + staticImage, + disableInnerContainer, + } = props + + let caption + if (media && typeof media === 'object') caption = media.caption + + return ( +
+ {(media || staticImage) && ( + + )} + {caption && ( +
+ +
+ )} +
+ ) +} diff --git a/src/blocks/MediaBlock/config.ts b/src/blocks/MediaBlock/config.ts new file mode 100644 index 0000000..7beb79b --- /dev/null +++ b/src/blocks/MediaBlock/config.ts @@ -0,0 +1,14 @@ +import type { Block } from 'payload' + +export const MediaBlock: Block = { + slug: 'mediaBlock', + interfaceName: 'MediaBlock', + fields: [ + { + name: 'media', + type: 'upload', + relationTo: 'media', + required: true, + }, + ], +} diff --git a/src/blocks/RelatedPosts/Component.tsx b/src/blocks/RelatedPosts/Component.tsx new file mode 100644 index 0000000..976c0cb --- /dev/null +++ b/src/blocks/RelatedPosts/Component.tsx @@ -0,0 +1,32 @@ +import clsx from 'clsx' +import React from 'react' +import RichText from '@/components/RichText' + +import type { Post } from '@/payload-types' + +import { Card } from '../../components/Card' +import { DefaultTypedEditorState } from '@payloadcms/richtext-lexical' + +export type RelatedPostsProps = { + className?: string + docs?: Post[] + introContent?: DefaultTypedEditorState +} + +export const RelatedPosts: React.FC = (props) => { + const { className, docs, introContent } = props + + return ( +
+ {introContent && } + +
+ {docs?.map((doc, index) => { + if (typeof doc === 'string') return null + + return + })} +
+
+ ) +} diff --git a/src/blocks/RenderBlocks.tsx b/src/blocks/RenderBlocks.tsx new file mode 100644 index 0000000..c84634a --- /dev/null +++ b/src/blocks/RenderBlocks.tsx @@ -0,0 +1,51 @@ +import React, { Fragment } from 'react' + +import type { Page } from '@/payload-types' + +import { ArchiveBlock } from '@/blocks/ArchiveBlock/Component' +import { CallToActionBlock } from '@/blocks/CallToAction/Component' +import { ContentBlock } from '@/blocks/Content/Component' +import { FormBlock } from '@/blocks/Form/Component' +import { MediaBlock } from '@/blocks/MediaBlock/Component' + +const blockComponents = { + archive: ArchiveBlock, + content: ContentBlock, + cta: CallToActionBlock, + formBlock: FormBlock, + mediaBlock: MediaBlock, +} + +export const RenderBlocks: React.FC<{ + blocks: Page['layout'][0][] +}> = (props) => { + const { blocks } = props + + const hasBlocks = blocks && Array.isArray(blocks) && blocks.length > 0 + + if (hasBlocks) { + return ( + + {blocks.map((block, index) => { + const { blockType } = block + + if (blockType && blockType in blockComponents) { + const Block = blockComponents[blockType] + + if (Block) { + return ( +
+ {/* @ts-expect-error there may be some mismatch between the expected types here */} + +
+ ) + } + } + return null + })} +
+ ) + } + + return null +} diff --git a/src/collections/Categories.ts b/src/collections/Categories.ts new file mode 100644 index 0000000..cca3fc1 --- /dev/null +++ b/src/collections/Categories.ts @@ -0,0 +1,28 @@ +import type { CollectionConfig } from 'payload' + +import { anyone } from '../access/anyone' +import { authenticated } from '../access/authenticated' +import { slugField } from 'payload' + +export const Categories: CollectionConfig = { + slug: 'categories', + access: { + create: authenticated, + delete: authenticated, + read: anyone, + update: authenticated, + }, + admin: { + useAsTitle: 'title', + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + }, + slugField({ + position: undefined, + }), + ], +} diff --git a/src/collections/Media.ts b/src/collections/Media.ts new file mode 100644 index 0000000..ae94c0c --- /dev/null +++ b/src/collections/Media.ts @@ -0,0 +1,81 @@ +import type { CollectionConfig } from 'payload' + +import { + FixedToolbarFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' +import path from 'path' +import { fileURLToPath } from 'url' + +import { anyone } from '../access/anyone' +import { authenticated } from '../access/authenticated' + +const filename = fileURLToPath(import.meta.url) +const dirname = path.dirname(filename) + +export const Media: CollectionConfig = { + slug: 'media', + folders: true, + access: { + create: authenticated, + delete: authenticated, + read: anyone, + update: authenticated, + }, + fields: [ + { + name: 'alt', + type: 'text', + //required: true, + }, + { + name: 'caption', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [...rootFeatures, FixedToolbarFeature(), InlineToolbarFeature()] + }, + }), + }, + ], + upload: { + // Upload to the public/media directory in Next.js making them publicly accessible even outside of Payload + staticDir: path.resolve(dirname, '../../public/media'), + adminThumbnail: 'thumbnail', + focalPoint: true, + imageSizes: [ + { + name: 'thumbnail', + width: 300, + }, + { + name: 'square', + width: 500, + height: 500, + }, + { + name: 'small', + width: 600, + }, + { + name: 'medium', + width: 900, + }, + { + name: 'large', + width: 1400, + }, + { + name: 'xlarge', + width: 1920, + }, + { + name: 'og', + width: 1200, + height: 630, + crop: 'center', + }, + ], + }, +} diff --git a/src/collections/Pages/hooks/revalidatePage.ts b/src/collections/Pages/hooks/revalidatePage.ts new file mode 100644 index 0000000..29b92bf --- /dev/null +++ b/src/collections/Pages/hooks/revalidatePage.ts @@ -0,0 +1,43 @@ +import type { CollectionAfterChangeHook, CollectionAfterDeleteHook } from 'payload' + +import { revalidatePath, revalidateTag } from 'next/cache' + +import type { Page } from '../../../payload-types' + +export const revalidatePage: CollectionAfterChangeHook = ({ + doc, + previousDoc, + req: { payload, context }, +}) => { + if (!context.disableRevalidate) { + if (doc._status === 'published') { + const path = doc.slug === 'home' ? '/' : `/${doc.slug}` + + payload.logger.info(`Revalidating page at path: ${path}`) + + revalidatePath(path) + revalidateTag('pages-sitemap', 'max') + } + + // If the page was previously published, we need to revalidate the old path + if (previousDoc?._status === 'published' && doc._status !== 'published') { + const oldPath = previousDoc.slug === 'home' ? '/' : `/${previousDoc.slug}` + + payload.logger.info(`Revalidating old page at path: ${oldPath}`) + + revalidatePath(oldPath) + revalidateTag('pages-sitemap', 'max') + } + } + return doc +} + +export const revalidateDelete: CollectionAfterDeleteHook = ({ doc, req: { context } }) => { + if (!context.disableRevalidate) { + const path = doc?.slug === 'home' ? '/' : `/${doc?.slug}` + revalidatePath(path) + revalidateTag('pages-sitemap', 'max') + } + + return doc +} diff --git a/src/collections/Pages/index.ts b/src/collections/Pages/index.ts new file mode 100644 index 0000000..0f380a7 --- /dev/null +++ b/src/collections/Pages/index.ts @@ -0,0 +1,136 @@ +import type { CollectionConfig } from 'payload' + +import { authenticated } from '../../access/authenticated' +import { authenticatedOrPublished } from '../../access/authenticatedOrPublished' +import { Archive } from '../../blocks/ArchiveBlock/config' +import { CallToAction } from '../../blocks/CallToAction/config' +import { Content } from '../../blocks/Content/config' +import { FormBlock } from '../../blocks/Form/config' +import { MediaBlock } from '../../blocks/MediaBlock/config' +import { hero } from '@/heros/config' +import { slugField } from 'payload' +import { populatePublishedAt } from '../../hooks/populatePublishedAt' +import { generatePreviewPath } from '../../utilities/generatePreviewPath' +import { revalidateDelete, revalidatePage } from './hooks/revalidatePage' + +import { + MetaDescriptionField, + MetaImageField, + MetaTitleField, + OverviewField, + PreviewField, +} from '@payloadcms/plugin-seo/fields' + +export const Pages: CollectionConfig<'pages'> = { + slug: 'pages', + access: { + create: authenticated, + delete: authenticated, + read: authenticatedOrPublished, + update: authenticated, + }, + // This config controls what's populated by default when a page is referenced + // https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property + // Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'pages'> + defaultPopulate: { + title: true, + slug: true, + }, + admin: { + defaultColumns: ['title', 'slug', 'updatedAt'], + livePreview: { + url: ({ data, req }) => + generatePreviewPath({ + slug: data?.slug, + collection: 'pages', + req, + }), + }, + preview: (data, { req }) => + generatePreviewPath({ + slug: data?.slug as string, + collection: 'pages', + req, + }), + useAsTitle: 'title', + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + }, + { + type: 'tabs', + tabs: [ + { + fields: [hero], + label: 'Hero', + }, + { + fields: [ + { + name: 'layout', + type: 'blocks', + blocks: [CallToAction, Content, MediaBlock, Archive, FormBlock], + required: true, + admin: { + initCollapsed: true, + }, + }, + ], + label: 'Content', + }, + { + name: 'meta', + label: 'SEO', + fields: [ + OverviewField({ + titlePath: 'meta.title', + descriptionPath: 'meta.description', + imagePath: 'meta.image', + }), + MetaTitleField({ + hasGenerateFn: true, + }), + MetaImageField({ + relationTo: 'media', + }), + + MetaDescriptionField({}), + PreviewField({ + // if the `generateUrl` function is configured + hasGenerateFn: true, + + // field paths to match the target field for data + titlePath: 'meta.title', + descriptionPath: 'meta.description', + }), + ], + }, + ], + }, + { + name: 'publishedAt', + type: 'date', + admin: { + position: 'sidebar', + }, + }, + slugField(), + ], + hooks: { + afterChange: [revalidatePage], + beforeChange: [populatePublishedAt], + afterDelete: [revalidateDelete], + }, + versions: { + drafts: { + autosave: { + interval: 100, // We set this interval for optimal live preview + }, + schedulePublish: true, + }, + maxPerDoc: 50, + }, +} diff --git a/src/collections/Posts/hooks/populateAuthors.ts b/src/collections/Posts/hooks/populateAuthors.ts new file mode 100644 index 0000000..40b4fe5 --- /dev/null +++ b/src/collections/Posts/hooks/populateAuthors.ts @@ -0,0 +1,37 @@ +import type { CollectionAfterReadHook } from 'payload' +import { User } from 'src/payload-types' + +// The `user` collection has access control locked so that users are not publicly accessible +// This means that we need to populate the authors manually here to protect user privacy +// GraphQL will not return mutated user data that differs from the underlying schema +// So we use an alternative `populatedAuthors` field to populate the user data, hidden from the admin UI +export const populateAuthors: CollectionAfterReadHook = async ({ doc, req, req: { payload } }) => { + if (doc?.authors && doc?.authors?.length > 0) { + const authorDocs: User[] = [] + + for (const author of doc.authors) { + try { + const authorDoc = await payload.findByID({ + id: typeof author === 'object' ? author?.id : author, + collection: 'users', + depth: 0, + }) + + if (authorDoc) { + authorDocs.push(authorDoc) + } + + if (authorDocs.length > 0) { + doc.populatedAuthors = authorDocs.map((authorDoc) => ({ + id: authorDoc.id, + name: authorDoc.name, + })) + } + } catch { + // swallow error + } + } + } + + return doc +} diff --git a/src/collections/Posts/hooks/revalidatePost.ts b/src/collections/Posts/hooks/revalidatePost.ts new file mode 100644 index 0000000..1d0c0bb --- /dev/null +++ b/src/collections/Posts/hooks/revalidatePost.ts @@ -0,0 +1,44 @@ +import type { CollectionAfterChangeHook, CollectionAfterDeleteHook } from 'payload' + +import { revalidatePath, revalidateTag } from 'next/cache' + +import type { Post } from '../../../payload-types' + +export const revalidatePost: CollectionAfterChangeHook = ({ + doc, + previousDoc, + req: { payload, context }, +}) => { + if (!context.disableRevalidate) { + if (doc._status === 'published') { + const path = `/posts/${doc.slug}` + + payload.logger.info(`Revalidating post at path: ${path}`) + + revalidatePath(path) + revalidateTag('posts-sitemap', 'max') + } + + // If the post was previously published, we need to revalidate the old path + if (previousDoc._status === 'published' && doc._status !== 'published') { + const oldPath = `/posts/${previousDoc.slug}` + + payload.logger.info(`Revalidating old post at path: ${oldPath}`) + + revalidatePath(oldPath) + revalidateTag('posts-sitemap', 'max') + } + } + return doc +} + +export const revalidateDelete: CollectionAfterDeleteHook = ({ doc, req: { context } }) => { + if (!context.disableRevalidate) { + const path = `/posts/${doc?.slug}` + + revalidatePath(path) + revalidateTag('posts-sitemap', 'max') + } + + return doc +} diff --git a/src/collections/Posts/index.ts b/src/collections/Posts/index.ts new file mode 100644 index 0000000..68ee399 --- /dev/null +++ b/src/collections/Posts/index.ts @@ -0,0 +1,233 @@ +import type { CollectionConfig } from 'payload' + +import { + BlocksFeature, + FixedToolbarFeature, + HeadingFeature, + HorizontalRuleFeature, + InlineToolbarFeature, + lexicalEditor, +} from '@payloadcms/richtext-lexical' + +import { authenticated } from '../../access/authenticated' +import { authenticatedOrPublished } from '../../access/authenticatedOrPublished' +import { Banner } from '../../blocks/Banner/config' +import { Code } from '../../blocks/Code/config' +import { MediaBlock } from '../../blocks/MediaBlock/config' +import { generatePreviewPath } from '../../utilities/generatePreviewPath' +import { populateAuthors } from './hooks/populateAuthors' +import { revalidateDelete, revalidatePost } from './hooks/revalidatePost' + +import { + MetaDescriptionField, + MetaImageField, + MetaTitleField, + OverviewField, + PreviewField, +} from '@payloadcms/plugin-seo/fields' +import { slugField } from 'payload' + +export const Posts: CollectionConfig<'posts'> = { + slug: 'posts', + access: { + create: authenticated, + delete: authenticated, + read: authenticatedOrPublished, + update: authenticated, + }, + // This config controls what's populated by default when a post is referenced + // https://payloadcms.com/docs/queries/select#defaultpopulate-collection-config-property + // Type safe if the collection slug generic is passed to `CollectionConfig` - `CollectionConfig<'posts'> + defaultPopulate: { + title: true, + slug: true, + categories: true, + meta: { + image: true, + description: true, + }, + }, + admin: { + defaultColumns: ['title', 'slug', 'updatedAt'], + livePreview: { + url: ({ data, req }) => + generatePreviewPath({ + slug: data?.slug, + collection: 'posts', + req, + }), + }, + preview: (data, { req }) => + generatePreviewPath({ + slug: data?.slug as string, + collection: 'posts', + req, + }), + useAsTitle: 'title', + }, + fields: [ + { + name: 'title', + type: 'text', + required: true, + }, + { + type: 'tabs', + tabs: [ + { + fields: [ + { + name: 'heroImage', + type: 'upload', + relationTo: 'media', + }, + { + name: 'content', + type: 'richText', + editor: lexicalEditor({ + features: ({ rootFeatures }) => { + return [ + ...rootFeatures, + HeadingFeature({ enabledHeadingSizes: ['h1', 'h2', 'h3', 'h4'] }), + BlocksFeature({ blocks: [Banner, Code, MediaBlock] }), + FixedToolbarFeature(), + InlineToolbarFeature(), + HorizontalRuleFeature(), + ] + }, + }), + label: false, + required: true, + }, + ], + label: 'Content', + }, + { + fields: [ + { + name: 'relatedPosts', + type: 'relationship', + admin: { + position: 'sidebar', + }, + filterOptions: ({ id }) => { + return { + id: { + not_in: [id], + }, + } + }, + hasMany: true, + relationTo: 'posts', + }, + { + name: 'categories', + type: 'relationship', + admin: { + position: 'sidebar', + }, + hasMany: true, + relationTo: 'categories', + }, + ], + label: 'Meta', + }, + { + name: 'meta', + label: 'SEO', + fields: [ + OverviewField({ + titlePath: 'meta.title', + descriptionPath: 'meta.description', + imagePath: 'meta.image', + }), + MetaTitleField({ + hasGenerateFn: true, + }), + MetaImageField({ + relationTo: 'media', + }), + + MetaDescriptionField({}), + PreviewField({ + // if the `generateUrl` function is configured + hasGenerateFn: true, + + // field paths to match the target field for data + titlePath: 'meta.title', + descriptionPath: 'meta.description', + }), + ], + }, + ], + }, + { + name: 'publishedAt', + type: 'date', + admin: { + date: { + pickerAppearance: 'dayAndTime', + }, + position: 'sidebar', + }, + hooks: { + beforeChange: [ + ({ siblingData, value }) => { + if (siblingData._status === 'published' && !value) { + return new Date() + } + return value + }, + ], + }, + }, + { + name: 'authors', + type: 'relationship', + admin: { + position: 'sidebar', + }, + hasMany: true, + relationTo: 'users', + }, + // This field is only used to populate the user data via the `populateAuthors` hook + // This is because the `user` collection has access control locked to protect user privacy + // GraphQL will also not return mutated user data that differs from the underlying schema + { + name: 'populatedAuthors', + type: 'array', + access: { + update: () => false, + }, + admin: { + disabled: true, + readOnly: true, + }, + fields: [ + { + name: 'id', + type: 'text', + }, + { + name: 'name', + type: 'text', + }, + ], + }, + slugField(), + ], + hooks: { + afterChange: [revalidatePost], + afterRead: [populateAuthors], + afterDelete: [revalidateDelete], + }, + versions: { + drafts: { + autosave: { + interval: 100, // We set this interval for optimal live preview + }, + schedulePublish: true, + }, + maxPerDoc: 50, + }, +} diff --git a/src/collections/Users/index.ts b/src/collections/Users/index.ts new file mode 100644 index 0000000..f0555a7 --- /dev/null +++ b/src/collections/Users/index.ts @@ -0,0 +1,26 @@ +import type { CollectionConfig } from 'payload' + +import { authenticated } from '../../access/authenticated' + +export const Users: CollectionConfig = { + slug: 'users', + access: { + admin: authenticated, + create: authenticated, + delete: authenticated, + read: authenticated, + update: authenticated, + }, + admin: { + defaultColumns: ['name', 'email'], + useAsTitle: 'name', + }, + auth: true, + fields: [ + { + name: 'name', + type: 'text', + }, + ], + timestamps: true, +} diff --git a/src/components/AdminBar/index.scss b/src/components/AdminBar/index.scss new file mode 100644 index 0000000..2d14086 --- /dev/null +++ b/src/components/AdminBar/index.scss @@ -0,0 +1,7 @@ +@import '@payloadcms/ui/scss'; + +.admin-bar { + @include small-break { + display: none; + } +} diff --git a/src/components/AdminBar/index.tsx b/src/components/AdminBar/index.tsx new file mode 100644 index 0000000..08c5c6c --- /dev/null +++ b/src/components/AdminBar/index.tsx @@ -0,0 +1,89 @@ +'use client' + +import type { PayloadAdminBarProps, PayloadMeUser } from '@payloadcms/admin-bar' + +import { cn } from '@/utilities/ui' +import { useSelectedLayoutSegments } from 'next/navigation' +import { PayloadAdminBar } from '@payloadcms/admin-bar' +import React, { useState } from 'react' +import { useRouter } from 'next/navigation' + +import './index.scss' + +import { getClientSideURL } from '@/utilities/getURL' + +const baseClass = 'admin-bar' + +const collectionLabels = { + pages: { + plural: 'Pages', + singular: 'Page', + }, + posts: { + plural: 'Posts', + singular: 'Post', + }, + projects: { + plural: 'Projects', + singular: 'Project', + }, +} + +const Title: React.FC = () => Dashboard + +export const AdminBar: React.FC<{ + adminBarProps?: PayloadAdminBarProps +}> = (props) => { + const { adminBarProps } = props || {} + const segments = useSelectedLayoutSegments() + const [show, setShow] = useState(false) + const collection = ( + collectionLabels[segments?.[1] as keyof typeof collectionLabels] ? segments[1] : 'pages' + ) as keyof typeof collectionLabels + const router = useRouter() + + const onAuthChange = React.useCallback((user: PayloadMeUser) => { + setShow(Boolean(user?.id)) + }, []) + + return ( +
+
+ } + onAuthChange={onAuthChange} + onPreviewExit={() => { + fetch('/next/exit-preview').then(() => { + router.push('/') + router.refresh() + }) + }} + style={{ + backgroundColor: 'transparent', + padding: 0, + position: 'relative', + zIndex: 'unset', + }} + /> +
+
+ ) +} diff --git a/src/components/BeforeDashboard/SeedButton/index.scss b/src/components/BeforeDashboard/SeedButton/index.scss new file mode 100644 index 0000000..3ed9bcb --- /dev/null +++ b/src/components/BeforeDashboard/SeedButton/index.scss @@ -0,0 +1,12 @@ +.seedButton { + appearance: none; + background: none; + border: none; + padding: 0; + text-decoration: underline; + + &:hover { + cursor: pointer; + opacity: 0.85; + } +} diff --git a/src/components/BeforeDashboard/SeedButton/index.tsx b/src/components/BeforeDashboard/SeedButton/index.tsx new file mode 100644 index 0000000..87abdf8 --- /dev/null +++ b/src/components/BeforeDashboard/SeedButton/index.tsx @@ -0,0 +1,88 @@ +'use client' + +import React, { Fragment, useCallback, useState } from 'react' +import { toast } from '@payloadcms/ui' + +import './index.scss' + +const SuccessMessage: React.FC = () => ( +
+ Database seeded! You can now{' '} + + visit your website + +
+) + +export const SeedButton: React.FC = () => { + const [loading, setLoading] = useState(false) + const [seeded, setSeeded] = useState(false) + const [error, setError] = useState(null) + + const handleClick = useCallback( + async (e: React.MouseEvent) => { + e.preventDefault() + + if (seeded) { + toast.info('Database already seeded.') + return + } + if (loading) { + toast.info('Seeding already in progress.') + return + } + if (error) { + toast.error(`An error occurred, please refresh and try again.`) + return + } + + setLoading(true) + + try { + toast.promise( + new Promise((resolve, reject) => { + try { + fetch('/next/seed', { method: 'POST', credentials: 'include' }) + .then((res) => { + if (res.ok) { + resolve(true) + setSeeded(true) + } else { + reject('An error occurred while seeding.') + } + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }), + { + loading: 'Seeding with data....', + success: , + error: 'An error occurred while seeding.', + }, + ) + } catch (err) { + const error = err instanceof Error ? err.message : String(err) + setError(error) + } + }, + [loading, seeded, error], + ) + + let message = '' + if (loading) message = ' (seeding...)' + if (seeded) message = ' (done!)' + if (error) message = ` (error: ${error})` + + return ( + + + {message} + + ) +} diff --git a/src/components/BeforeDashboard/index.scss b/src/components/BeforeDashboard/index.scss new file mode 100644 index 0000000..239fac9 --- /dev/null +++ b/src/components/BeforeDashboard/index.scss @@ -0,0 +1,24 @@ +@import '@payloadcms/ui/scss'; + +.dashboard .before-dashboard { + margin-bottom: base(1.5); + + &__banner { + & h4 { + margin: 0; + } + } + + &__instructions { + list-style: decimal; + margin-bottom: base(0.5); + + & li { + width: 100%; + } + } + + & a:hover { + opacity: 0.85; + } +} diff --git a/src/components/BeforeDashboard/index.tsx b/src/components/BeforeDashboard/index.tsx new file mode 100644 index 0000000..25a95d8 --- /dev/null +++ b/src/components/BeforeDashboard/index.tsx @@ -0,0 +1,69 @@ +import { Banner } from '@payloadcms/ui/elements/Banner' +import React from 'react' + +import { SeedButton } from './SeedButton' +import './index.scss' + +const baseClass = 'before-dashboard' + +const BeforeDashboard: React.FC = () => { + return ( +
+ +

Welcome to your dashboard!

+
+ Here's what to do next: +
    +
  • + + {' with a few pages, posts, and projects to jump-start your new site, then '} + + visit your website + + {' to see the results.'} +
  • +
  • + {'Modify your '} + + collections + + {' and add more '} + + fields + + {' as needed. If you are new to Payload, we also recommend you check out the '} + + Getting Started + + {' docs.'} +
  • +
  • + Commit and push your changes to the repository to trigger a redeployment of your project. +
  • +
+ {'Pro Tip: This block is a '} + + custom component + + , you can remove it at any time by updating your payload.config. +
+ ) +} + +export default BeforeDashboard diff --git a/src/components/BeforeLogin/index.tsx b/src/components/BeforeLogin/index.tsx new file mode 100644 index 0000000..8768831 --- /dev/null +++ b/src/components/BeforeLogin/index.tsx @@ -0,0 +1,14 @@ +import React from 'react' + +const BeforeLogin: React.FC = () => { + return ( +
+

+ Welcome to your dashboard! + {' This is where site admins will log in to manage your website.'} +

+
+ ) +} + +export default BeforeLogin diff --git a/src/components/Card/index.tsx b/src/components/Card/index.tsx new file mode 100644 index 0000000..6c7878e --- /dev/null +++ b/src/components/Card/index.tsx @@ -0,0 +1,80 @@ +'use client' +import { cn } from '@/utilities/ui' +import useClickableCard from '@/utilities/useClickableCard' +import Link from 'next/link' +import React, { Fragment } from 'react' + +import type { Post } from '@/payload-types' + +import { Media } from '@/components/Media' + +export type CardPostData = Pick + +export const Card: React.FC<{ + alignItems?: 'center' + className?: string + doc?: CardPostData + relationTo?: 'posts' + showCategories?: boolean + title?: string +}> = (props) => { + const { card, link } = useClickableCard({}) + const { className, doc, relationTo, showCategories, title: titleFromProps } = props + + const { slug, categories, meta, title } = doc || {} + const { description, image: metaImage } = meta || {} + + const hasCategories = categories && Array.isArray(categories) && categories.length > 0 + const titleToUse = titleFromProps || title + const sanitizedDescription = description?.replace(/\s/g, ' ') // replace non-breaking space with white space + const href = `/${relationTo}/${slug}` + + return ( +
+
+ {!metaImage &&
No image
} + {metaImage && typeof metaImage !== 'string' && } +
+
+ {showCategories && hasCategories && ( +
+ {categories?.map((category, index) => { + if (typeof category === 'object') { + const { title: titleFromCategory } = category + + const categoryTitle = titleFromCategory || 'Untitled category' + + const isLast = index === categories.length - 1 + + return ( + + {categoryTitle} + {!isLast && ,  } + + ) + } + + return null + })} +
+ )} + {titleToUse && ( +
+

+ + {titleToUse} + +

+
+ )} + {description &&
{description &&

{sanitizedDescription}

}
} +
+
+ ) +} diff --git a/src/components/CollectionArchive/index.tsx b/src/components/CollectionArchive/index.tsx new file mode 100644 index 0000000..b0a2a1c --- /dev/null +++ b/src/components/CollectionArchive/index.tsx @@ -0,0 +1,32 @@ +import { cn } from '@/utilities/ui' +import React from 'react' + +import { Card, CardPostData } from '@/components/Card' + +export type Props = { + posts: CardPostData[] +} + +export const CollectionArchive: React.FC = (props) => { + const { posts } = props + + return ( +
+
+
+ {posts?.map((result, index) => { + if (typeof result === 'object' && result !== null) { + return ( +
+ +
+ ) + } + + return null + })} +
+
+
+ ) +} diff --git a/src/components/Link/index.tsx b/src/components/Link/index.tsx new file mode 100644 index 0000000..0cf220e --- /dev/null +++ b/src/components/Link/index.tsx @@ -0,0 +1,66 @@ +import { Button, type ButtonProps } from '@/components/ui/button' +import { cn } from '@/utilities/ui' +import Link from 'next/link' +import React from 'react' + +import type { Page, Post } from '@/payload-types' + +type CMSLinkType = { + appearance?: 'inline' | ButtonProps['variant'] + children?: React.ReactNode + className?: string + label?: string | null + newTab?: boolean | null + reference?: { + relationTo: 'pages' | 'posts' + value: Page | Post | string | number + } | null + size?: ButtonProps['size'] | null + type?: 'custom' | 'reference' | null + url?: string | null +} + +export const CMSLink: React.FC = (props) => { + const { + type, + appearance = 'inline', + children, + className, + label, + newTab, + reference, + size: sizeFromProps, + url, + } = props + + const href = + type === 'reference' && typeof reference?.value === 'object' && reference.value.slug + ? `${reference?.relationTo !== 'pages' ? `/${reference?.relationTo}` : ''}/${ + reference.value.slug + }` + : url + + if (!href) return null + + const size = appearance === 'link' ? 'clear' : sizeFromProps + const newTabProps = newTab ? { rel: 'noopener noreferrer', target: '_blank' } : {} + + /* Ensure we don't break any styles set by richText */ + if (appearance === 'inline') { + return ( + + {label && label} + {children && children} + + ) + } + + return ( + + ) +} diff --git a/src/components/LivePreviewListener/index.tsx b/src/components/LivePreviewListener/index.tsx new file mode 100644 index 0000000..8b40675 --- /dev/null +++ b/src/components/LivePreviewListener/index.tsx @@ -0,0 +1,10 @@ +'use client' +import { getClientSideURL } from '@/utilities/getURL' +import { RefreshRouteOnSave as PayloadLivePreview } from '@payloadcms/live-preview-react' +import { useRouter } from 'next/navigation' +import React from 'react' + +export const LivePreviewListener: React.FC = () => { + const router = useRouter() + return +} diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx new file mode 100644 index 0000000..c8c82af --- /dev/null +++ b/src/components/Logo/Logo.tsx @@ -0,0 +1,29 @@ +import clsx from 'clsx' +import React from 'react' + +interface Props { + className?: string + loading?: 'lazy' | 'eager' + priority?: 'auto' | 'high' | 'low' +} + +export const Logo = (props: Props) => { + const { loading: loadingFromProps, priority: priorityFromProps, className } = props + + const loading = loadingFromProps || 'lazy' + const priority = priorityFromProps || 'low' + + return ( + /* eslint-disable @next/next/no-img-element */ + Payload Logo + ) +} diff --git a/src/components/Media/ImageMedia/index.tsx b/src/components/Media/ImageMedia/index.tsx new file mode 100644 index 0000000..0caf826 --- /dev/null +++ b/src/components/Media/ImageMedia/index.tsx @@ -0,0 +1,105 @@ +'use client' + +import type { StaticImageData } from 'next/image' + +import { cn } from '@/utilities/ui' +import NextImage from 'next/image' +import React from 'react' + +import type { Props as MediaProps } from '../types' + +import { cssVariables } from '@/cssVariables' +import { getMediaUrl } from '@/utilities/getMediaUrl' + +const { breakpoints } = cssVariables + +// A base64 encoded image to use as a placeholder while the image is loading +const placeholderBlur = + 'data:image/png;base64,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' + +/** + * ImageMedia + * + * This component passes a **relative** `src` (e.g. `/media/...`) to Next.js Image. + * The `getMediaUrl` utility constructs the full URL by prepending the base URL from env vars + * (NEXT_PUBLIC_SERVER_URL). Next.js then optimizes this using `remotePatterns` configured + * in next.config.js — no custom `loader` needed. + * + * Flow: + * 1. Resource URL from Payload: `/media/image-123.jpg` + * 2. getMediaUrl() adds base URL: `https://yourdomain.com/media/image-123.jpg` + * 3. Next.js Image optimizes via remotePatterns: `/_next/image?url=...&w=1200&q=75` + * + * If your storage/plugin returns **external CDN URLs** (e.g. `https://cdn.example.com/...`), + * choose ONE of the following: + * A) Allow the remote host in next.config.js: + * images: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com' }] } + * B) Provide a **custom loader** for CDN-specific transforms: + * const imageLoader: ImageLoader = ({ src, width, quality }) => + * `https://cdn.example.com${src}?w=${width}&q=${quality ?? 75}` + * + * C) Skip optimization: + * + * + * TL;DR: Template uses relative URLs + getMediaUrl() to construct full URLs, then relies on + * remotePatterns for optimization. Only add `loader` if using external CDNs with custom transforms. + */ + +export const ImageMedia: React.FC = (props) => { + const { + alt: altFromProps, + fill, + pictureClassName, + imgClassName, + priority, + resource, + size: sizeFromProps, + src: srcFromProps, + loading: loadingFromProps, + } = props + + let width: number | undefined + let height: number | undefined + let alt = altFromProps + let src: StaticImageData | string = srcFromProps || '' + + if (!src && resource && typeof resource === 'object') { + const { alt: altFromResource, height: fullHeight, url, width: fullWidth } = resource + + width = fullWidth! + height = fullHeight! + alt = altFromResource || '' + + const cacheTag = resource.updatedAt + + src = getMediaUrl(url, cacheTag) + } + + const loading = loadingFromProps || (!priority ? 'lazy' : undefined) + + // NOTE: this is used by the browser to determine which image to download at different screen sizes + const sizes = sizeFromProps + ? sizeFromProps + : Object.entries(breakpoints) + .map(([, value]) => `(max-width: ${value}px) ${value * 2}w`) + .join(', ') + + return ( + + + + ) +} diff --git a/src/components/Media/VideoMedia/index.tsx b/src/components/Media/VideoMedia/index.tsx new file mode 100644 index 0000000..ccff66e --- /dev/null +++ b/src/components/Media/VideoMedia/index.tsx @@ -0,0 +1,46 @@ +'use client' + +import { cn } from '@/utilities/ui' +import React, { useEffect, useRef } from 'react' + +import type { Props as MediaProps } from '../types' + +import { getMediaUrl } from '@/utilities/getMediaUrl' + +export const VideoMedia: React.FC = (props) => { + const { onClick, resource, videoClassName } = props + + const videoRef = useRef(null) + // const [showFallback] = useState() + + useEffect(() => { + const { current: video } = videoRef + if (video) { + video.addEventListener('suspend', () => { + // setShowFallback(true); + // console.warn('Video was suspended, rendering fallback image.') + }) + } + }, []) + + if (resource && typeof resource === 'object') { + const { filename } = resource + + return ( + + ) + } + + return null +} diff --git a/src/components/Media/index.tsx b/src/components/Media/index.tsx new file mode 100644 index 0000000..a4e2b9d --- /dev/null +++ b/src/components/Media/index.tsx @@ -0,0 +1,25 @@ +import React, { Fragment } from 'react' + +import type { Props } from './types' + +import { ImageMedia } from './ImageMedia' +import { VideoMedia } from './VideoMedia' + +export const Media: React.FC = (props) => { + const { className, htmlElement = 'div', resource } = props + + const isVideo = typeof resource === 'object' && resource?.mimeType?.includes('video') + const Tag = htmlElement || Fragment + + return ( + + {isVideo ? : } + + ) +} diff --git a/src/components/Media/types.ts b/src/components/Media/types.ts new file mode 100644 index 0000000..3bbbf22 --- /dev/null +++ b/src/components/Media/types.ts @@ -0,0 +1,22 @@ +import type { StaticImageData } from 'next/image' +import type { ElementType, Ref } from 'react' + +import type { Media as MediaType } from '@/payload-types' + +export interface Props { + alt?: string + className?: string + fill?: boolean // for NextImage only + htmlElement?: ElementType | null + pictureClassName?: string + imgClassName?: string + onClick?: () => void + onLoad?: () => void + loading?: 'lazy' | 'eager' // for NextImage only + priority?: boolean // for NextImage only + ref?: Ref + resource?: MediaType | string | number | null // for Payload media + size?: string // for NextImage only + src?: StaticImageData // for static media + videoClassName?: string +} diff --git a/src/components/PageRange/index.tsx b/src/components/PageRange/index.tsx new file mode 100644 index 0000000..2a3a39d --- /dev/null +++ b/src/components/PageRange/index.tsx @@ -0,0 +1,57 @@ +import React from 'react' + +const defaultLabels = { + plural: 'Docs', + singular: 'Doc', +} + +const defaultCollectionLabels = { + posts: { + plural: 'Posts', + singular: 'Post', + }, +} + +export const PageRange: React.FC<{ + className?: string + collection?: keyof typeof defaultCollectionLabels + collectionLabels?: { + plural?: string + singular?: string + } + currentPage?: number + limit?: number + totalDocs?: number +}> = (props) => { + const { + className, + collection, + collectionLabels: collectionLabelsFromProps, + currentPage, + limit, + totalDocs, + } = props + + let indexStart = (currentPage ? currentPage - 1 : 1) * (limit || 1) + 1 + if (totalDocs && indexStart > totalDocs) indexStart = 0 + + let indexEnd = (currentPage || 1) * (limit || 1) + if (totalDocs && indexEnd > totalDocs) indexEnd = totalDocs + + const { plural, singular } = + collectionLabelsFromProps || + (collection ? defaultCollectionLabels[collection] : undefined) || + defaultLabels || + {} + + return ( +
+ {(typeof totalDocs === 'undefined' || totalDocs === 0) && 'Search produced no results.'} + {typeof totalDocs !== 'undefined' && + totalDocs > 0 && + `Showing ${indexStart}${indexStart > 0 ? ` - ${indexEnd}` : ''} of ${totalDocs} ${ + totalDocs > 1 ? plural : singular + }`} +
+ ) +} diff --git a/src/components/Pagination/index.tsx b/src/components/Pagination/index.tsx new file mode 100644 index 0000000..448b301 --- /dev/null +++ b/src/components/Pagination/index.tsx @@ -0,0 +1,101 @@ +'use client' +import { + Pagination as PaginationComponent, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from '@/components/ui/pagination' +import { cn } from '@/utilities/ui' +import { useRouter } from 'next/navigation' +import React from 'react' + +export const Pagination: React.FC<{ + className?: string + page: number + totalPages: number +}> = (props) => { + const router = useRouter() + + const { className, page, totalPages } = props + const hasNextPage = page < totalPages + const hasPrevPage = page > 1 + + const hasExtraPrevPages = page - 1 > 1 + const hasExtraNextPages = page + 1 < totalPages + + return ( +
+ + + + { + router.push(`/posts/page/${page - 1}`) + }} + /> + + + {hasExtraPrevPages && ( + + + + )} + + {hasPrevPage && ( + + { + router.push(`/posts/page/${page - 1}`) + }} + > + {page - 1} + + + )} + + + { + router.push(`/posts/page/${page}`) + }} + > + {page} + + + + {hasNextPage && ( + + { + router.push(`/posts/page/${page + 1}`) + }} + > + {page + 1} + + + )} + + {hasExtraNextPages && ( + + + + )} + + + { + router.push(`/posts/page/${page + 1}`) + }} + /> + + + +
+ ) +} diff --git a/src/components/PayloadRedirects/index.tsx b/src/components/PayloadRedirects/index.tsx new file mode 100644 index 0000000..d239771 --- /dev/null +++ b/src/components/PayloadRedirects/index.tsx @@ -0,0 +1,48 @@ +import type React from 'react' +import type { Page, Post } from '@/payload-types' + +import { getCachedDocument } from '@/utilities/getDocument' +import { getCachedRedirects } from '@/utilities/getRedirects' +import { notFound, redirect } from 'next/navigation' + +interface Props { + disableNotFound?: boolean + url: string +} + +/* This component helps us with SSR based dynamic redirects */ +export const PayloadRedirects: React.FC = async ({ disableNotFound, url }) => { + const redirects = await getCachedRedirects()() + + const redirectItem = redirects.find((redirect) => redirect.from === url) + + if (redirectItem) { + if (redirectItem.to?.url) { + redirect(redirectItem.to.url) + } + + let redirectUrl: string + + if (typeof redirectItem.to?.reference?.value === 'string') { + const collection = redirectItem.to?.reference?.relationTo + const id = redirectItem.to?.reference?.value + + const document = (await getCachedDocument(collection, id)()) as Page | Post + redirectUrl = `${redirectItem.to?.reference?.relationTo !== 'pages' ? `/${redirectItem.to?.reference?.relationTo}` : ''}/${ + document?.slug + }` + } else { + redirectUrl = `${redirectItem.to?.reference?.relationTo !== 'pages' ? `/${redirectItem.to?.reference?.relationTo}` : ''}/${ + typeof redirectItem.to?.reference?.value === 'object' + ? redirectItem.to?.reference?.value?.slug + : '' + }` + } + + if (redirectUrl) redirect(redirectUrl) + } + + if (disableNotFound) return null + + notFound() +} diff --git a/src/components/RichText/index.tsx b/src/components/RichText/index.tsx new file mode 100644 index 0000000..1994159 --- /dev/null +++ b/src/components/RichText/index.tsx @@ -0,0 +1,81 @@ +import { MediaBlock } from '@/blocks/MediaBlock/Component' +import { + DefaultNodeTypes, + SerializedBlockNode, + SerializedLinkNode, + type DefaultTypedEditorState, +} from '@payloadcms/richtext-lexical' +import { + JSXConvertersFunction, + LinkJSXConverter, + RichText as ConvertRichText, +} from '@payloadcms/richtext-lexical/react' + +import { CodeBlock, CodeBlockProps } from '@/blocks/Code/Component' + +import type { + BannerBlock as BannerBlockProps, + CallToActionBlock as CTABlockProps, + MediaBlock as MediaBlockProps, +} from '@/payload-types' +import { BannerBlock } from '@/blocks/Banner/Component' +import { CallToActionBlock } from '@/blocks/CallToAction/Component' +import { cn } from '@/utilities/ui' + +type NodeTypes = + | DefaultNodeTypes + | SerializedBlockNode + +const internalDocToHref = ({ linkNode }: { linkNode: SerializedLinkNode }) => { + const { value, relationTo } = linkNode.fields.doc! + if (typeof value !== 'object') { + throw new Error('Expected value to be an object') + } + const slug = value.slug + return relationTo === 'posts' ? `/posts/${slug}` : `/${slug}` +} + +const jsxConverters: JSXConvertersFunction = ({ defaultConverters }) => ({ + ...defaultConverters, + ...LinkJSXConverter({ internalDocToHref }), + blocks: { + banner: ({ node }) => , + mediaBlock: ({ node }) => ( + + ), + code: ({ node }) => , + cta: ({ node }) => , + }, +}) + +type Props = { + data: DefaultTypedEditorState + enableGutter?: boolean + enableProse?: boolean +} & React.HTMLAttributes + +export default function RichText(props: Props) { + const { className, enableProse = true, enableGutter = true, ...rest } = props + return ( + + ) +} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 590e11b..27a45a1 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -1,53 +1,44 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" +import { cn } from '@/utilities/ui' +import { Slot } from '@radix-ui/react-slot' +import { type VariantProps, cva } from 'class-variance-authority' +import * as React from 'react' const buttonVariants = cva( - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0", { variants: { variant: { - default: - "bg-[#EFBF04] text-[#101828] shadow-xs hover:bg-[#03093A] hover:text-white", - destructive: - "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + default: 'bg-primary text-primary-foreground shadow-sm hover:bg-primary/90', + destructive: 'bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90', outline: - "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", - secondary: - "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80", - ghost: - "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", - link: "text-primary underline-offset-4 hover:underline", - accent: - "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90", + 'border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground', + secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline', }, size: { - default: "h-9 px-4 py-2 has-[>svg]:px-3 max-md:min-h-11", - sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5 max-md:min-h-11", - lg: "h-10 rounded-md px-6 has-[>svg]:px-4 max-md:min-h-11", - icon: "size-9 max-md:min-h-11 max-md:min-w-11", + clear: '', + default: 'h-10 px-4 py-2 has-[>svg]:px-3', + sm: 'h-9 rounded-md px-3 has-[>svg]:px-2.5', + lg: 'h-11 rounded-md px-8 has-[>svg]:px-4', + icon: 'size-10', }, }, defaultVariants: { - variant: "default", - size: "default", + variant: 'default', + size: 'default', }, - } + }, ) -function Button({ - className, - variant, - size, - asChild = false, - ...props -}: React.ComponentProps<"button"> & - VariantProps & { - asChild?: boolean - }) { - const Comp = asChild ? Slot : "button" +export interface ButtonProps + extends React.ComponentProps<'button'>, + VariantProps { + asChild?: boolean +} + +const Button: React.FC = ({ asChild = false, className, size, variant, ...props }) => { + const Comp = asChild ? Slot : 'button' return ( ) { +const Card: React.FC> = ({ className, ...props }) => { return (
) } -function CardHeader({ className, ...props }: React.ComponentProps<"div">) { +const CardHeader: React.FC> = ({ className, ...props }) => { return (
) } -function CardTitle({ className, ...props }: React.ComponentProps<"div">) { +const CardTitle: React.FC> = ({ className, ...props }) => { return ( -
) } -function CardDescription({ className, ...props }: React.ComponentProps<"div">) { +const CardDescription: React.FC> = ({ + className, + ...props +}) => { return ( -
) } -function CardAction({ className, ...props }: React.ComponentProps<"div">) { - return ( -
- ) +const CardContent: React.FC> = ({ className, ...props }) => { + return
} -function CardContent({ className, ...props }: React.ComponentProps<"div">) { - return ( -
- ) -} - -function CardFooter({ className, ...props }: React.ComponentProps<"div">) { +const CardFooter: React.FC> = ({ className, ...props }) => { return (
) } -export { - Card, - CardHeader, - CardFooter, - CardTitle, - CardAction, - CardDescription, - CardContent, -} +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx new file mode 100644 index 0000000..607785e --- /dev/null +++ b/src/components/ui/checkbox.tsx @@ -0,0 +1,29 @@ +'use client' + +import { cn } from '@/utilities/ui' +import * as CheckboxPrimitive from '@radix-ui/react-checkbox' +import { Check } from 'lucide-react' +import * as React from 'react' + +const Checkbox: React.FC> = ({ + className, + ...props +}) => ( + + + + + +) + +export { Checkbox } diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx index 5279b64..c12a974 100644 --- a/src/components/ui/input.tsx +++ b/src/components/ui/input.tsx @@ -1,23 +1,22 @@ -import * as React from "react" -import { cn } from "@/lib/utils" +import { cn } from '@/utilities/ui' +import * as React from 'react' -export interface InputProps extends React.InputHTMLAttributes {} - -const Input = React.forwardRef( - ({ className, type, ...props }, ref) => { - return ( - - ) - } -) -Input.displayName = "Input" +const Input: React.FC> = ({ + className, + type, + ...props +}) => { + return ( + + ) +} export { Input } diff --git a/src/components/ui/label.tsx b/src/components/ui/label.tsx index ff135da..d9c07ef 100644 --- a/src/components/ui/label.tsx +++ b/src/components/ui/label.tsx @@ -1,20 +1,19 @@ -import * as React from "react" -import * as LabelPrimitive from "@radix-ui/react-label" -import { cn } from "@/lib/utils" +'use client' -const Label = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -Label.displayName = LabelPrimitive.Root.displayName +import { cn } from '@/utilities/ui' +import * as LabelPrimitive from '@radix-ui/react-label' +import { type VariantProps, cva } from 'class-variance-authority' +import * as React from 'react' + +const labelVariants = cva( + 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', +) + +const Label: React.FC< + { ref?: React.Ref } & React.ComponentProps & + VariantProps +> = ({ className, ref, ...props }) => ( + +) export { Label } diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx new file mode 100644 index 0000000..b09be5b --- /dev/null +++ b/src/components/ui/pagination.tsx @@ -0,0 +1,92 @@ +import type { ButtonProps } from '@/components/ui/button' + +import { buttonVariants } from '@/components/ui/button' +import { cn } from '@/utilities/ui' +import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react' +import * as React from 'react' + +const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( +