From dd6787c4295aeaf9d0115abc96f1d4f44a8f6076 Mon Sep 17 00:00:00 2001 From: Riccardo La Rosa Date: Thu, 19 Dec 2024 13:12:58 -0500 Subject: [PATCH] feat: reset password using Accounts and Integration Hub --- examples/password-reset/.composablerc | 6 + examples/password-reset/.eslintrc.json | 12 + examples/password-reset/.gitignore | 45 + examples/password-reset/.lintstagedrc.js | 32 + examples/password-reset/.prettierignore | 1 + examples/password-reset/.prettierrc | 1 + examples/password-reset/README.md | 91 + .../password-reset/e2e/checkout-flow.spec.ts | 41 + examples/password-reset/e2e/home-page.spec.ts | 10 + .../e2e/models/d2c-cart-page.ts | 23 + .../e2e/models/d2c-checkout-page.ts | 48 + .../e2e/models/d2c-home-page.ts | 15 + .../e2e/models/d2c-product-detail-page.ts | 132 + .../e2e/product-details-page.spec.ts | 29 + .../e2e/product-list-page.spec.ts | 46 + .../e2e/util/enter-payment-information.ts | 10 + .../e2e/util/epcc-admin-client.ts | 14 + .../password-reset/e2e/util/epcc-client.ts | 12 + .../e2e/util/fill-form-field.ts | 48 + .../password-reset/e2e/util/gateway-check.ts | 13 + .../e2e/util/gateway-is-enabled.ts | 10 + .../password-reset/e2e/util/get-cart-id.ts | 14 + .../e2e/util/has-published-catalog.ts | 12 + .../e2e/util/missing-published-catalog.ts | 10 + .../e2e/util/resolver-product-from-store.ts | 84 + .../password-reset/e2e/util/skip-ci-env.ts | 8 + examples/password-reset/license.md | 21 + examples/password-reset/next-env.d.ts | 5 + examples/password-reset/next.config.js | 43 + examples/password-reset/package-lock.json | 14538 ++++++++++++++++ examples/password-reset/package.json | 90 + examples/password-reset/playwright.config.ts | 72 + examples/password-reset/postcss.config.js | 6 + examples/password-reset/public/favicon.ico | Bin 0 -> 15086 bytes .../account-member-credentials-schema.ts | 23 + .../password-reset/src/app/(auth)/actions.ts | 200 + .../src/app/(auth)/forgot-password/actions.ts | 50 + .../src/app/(auth)/forgot-password/page.tsx | 54 + .../password-reset/src/app/(auth)/layout.tsx | 51 + .../src/app/(auth)/login/LoginForm.tsx | 79 + .../src/app/(auth)/login/page.tsx | 49 + .../src/app/(auth)/not-found.tsx | 13 + .../src/app/(auth)/register/page.tsx | 97 + .../src/app/(auth)/reset-password/actions.ts | 75 + .../src/app/(auth)/reset-password/page.tsx | 90 + .../(checkout)/checkout/AccountCheckout.tsx | 52 + .../(checkout)/checkout/AccountDisplay.tsx | 82 + .../app/(checkout)/checkout/BillingForm.tsx | 233 + .../(checkout)/checkout/CheckoutFooter.tsx | 30 + .../(checkout)/checkout/CheckoutSidebar.tsx | 103 + .../app/(checkout)/checkout/CheckoutViews.tsx | 15 + .../checkout/ConfirmationSidebar.tsx | 108 + .../app/(checkout)/checkout/DeliveryForm.tsx | 108 + .../src/app/(checkout)/checkout/FormInput.tsx | 73 + .../app/(checkout)/checkout/GuestCheckout.tsx | 51 + .../(checkout)/checkout/GuestInformation.tsx | 56 + .../(checkout)/checkout/OrderConfirmation.tsx | 93 + .../app/(checkout)/checkout/PaymentForm.tsx | 30 + .../app/(checkout)/checkout/ShippingForm.tsx | 217 + .../(checkout)/checkout/ShippingSelector.tsx | 99 + .../checkout/SubmitCheckoutButton.tsx | 29 + .../(checkout)/checkout/checkout-provider.tsx | 103 + .../src/app/(checkout)/checkout/page.tsx | 44 + .../checkout/usePaymentComplete.tsx | 129 + .../(checkout)/checkout/useShippingMethod.tsx | 39 + .../src/app/(checkout)/layout.tsx | 51 + .../src/app/(checkout)/not-found.tsx | 13 + .../src/app/(store)/about/page.tsx | 5 + .../app/(store)/account/AccountNavigation.tsx | 54 + .../account/addresses/DeleteAddressBtn.tsx | 42 + .../addresses/[addressId]/UpdateForm.tsx | 208 + .../account/addresses/[addressId]/page.tsx | 64 + .../app/(store)/account/addresses/actions.ts | 200 + .../(store)/account/addresses/add/AddForm.tsx | 188 + .../(store)/account/addresses/add/page.tsx | 43 + .../app/(store)/account/addresses/page.tsx | 90 + .../src/app/(store)/account/breadcrumb.tsx | 85 + .../src/app/(store)/account/layout.tsx | 17 + .../app/(store)/account/orders/OrderItem.tsx | 70 + .../account/orders/OrderItemWithDetails.tsx | 32 + .../orders/[orderId]/OrderLineItem.tsx | 42 + .../orders/[orderId]/ProductThumbnail.tsx | 22 + .../(store)/account/orders/[orderId]/page.tsx | 206 + .../src/app/(store)/account/orders/page.tsx | 128 + .../(store)/account/summary/YourInfoForm.tsx | 59 + .../app/(store)/account/summary/actions.ts | 220 + .../src/app/(store)/account/summary/page.tsx | 113 + .../src/app/(store)/cart/CartItem.tsx | 61 + .../src/app/(store)/cart/CartItemWide.tsx | 61 + .../src/app/(store)/cart/CartSidebar.tsx | 47 + .../src/app/(store)/cart/CartView.tsx | 55 + .../src/app/(store)/cart/YourBag.tsx | 25 + .../src/app/(store)/cart/page.tsx | 5 + .../src/app/(store)/faq/page.tsx | 5 + .../password-reset/src/app/(store)/layout.tsx | 64 + .../src/app/(store)/not-found.tsx | 13 + .../password-reset/src/app/(store)/page.tsx | 38 + .../app/(store)/products/[productId]/page.tsx | 52 + .../products/[productId]/product-display.tsx | 49 + .../app/(store)/search/[[...node]]/layout.tsx | 11 + .../app/(store)/search/[[...node]]/page.tsx | 186 + .../src/app/(store)/search/search.tsx | 17 + .../src/app/(store)/shipping/page.tsx | 5 + .../src/app/(store)/terms/page.tsx | 5 + .../src/app/configuration-error/page.tsx | 69 + examples/password-reset/src/app/error.tsx | 31 + examples/password-reset/src/app/layout.tsx | 10 + examples/password-reset/src/app/not-found.tsx | 13 + examples/password-reset/src/app/providers.tsx | 44 + .../src/components/Checkbox.tsx | 29 + .../src/components/LoadingDots.tsx | 13 + .../password-reset/src/components/NoImage.tsx | 12 + .../password-reset/src/components/Spinner.tsx | 30 + .../src/components/accordion/Accordion.tsx | 51 + .../src/components/alert/Alert.tsx | 59 + .../src/components/breadcrumb.tsx | 36 + .../src/components/button/Button.tsx | 68 + .../components/button/FormStatusButton.tsx | 41 + .../src/components/button/LoaderIcon.tsx | 17 + .../src/components/button/StatusButton.tsx | 47 + .../src/components/button/TextButton.tsx | 41 + .../src/components/cart/CartDiscounts.tsx | 96 + .../src/components/cart/CartSheet.tsx | 168 + .../components/checkout-item/CheckoutItem.tsx | 32 + .../checkout-sidebar/AddPromotion.tsx | 73 + .../checkout-sidebar/ItemSidebar.tsx | 166 + .../components/checkout-sidebar/actions.ts | 43 + .../form-schema/checkout-form-schema.ts | 90 + .../featured-products/FeaturedProducts.tsx | 86 + .../fetchFeaturedProducts.ts | 19 + .../src/components/footer/Footer.tsx | 72 + .../src/components/form/Form.tsx | 183 + .../components/header/AccountMobileMenu.tsx | 159 + .../src/components/header/Header.tsx | 40 + .../components/header/account/AccountMenu.tsx | 194 + .../header/account/AccountSwitcher.tsx | 52 + .../header/account/switch-button.tsx | 57 + .../navigation/MobileAccountSwitcher.tsx | 70 + .../header/navigation/MobileNavBar.tsx | 32 + .../header/navigation/MobileNavBarButton.tsx | 64 + .../components/header/navigation/NavBar.tsx | 17 + .../header/navigation/NavBarPopover.tsx | 86 + .../header/navigation/NavItemContent.tsx | 59 + .../components/header/navigation/NavMenu.tsx | 48 + .../src/components/icons/cart.tsx | 16 + .../src/components/icons/ep-icon.tsx | 20 + .../src/components/icons/ep-logo.tsx | 31 + .../src/components/icons/github-icon.tsx | 16 + .../src/components/input/Input.tsx | 41 + .../src/components/label/Label.tsx | 18 + .../navigation-menu/NavigationMenu.tsx | 122 + .../number-input/EditQuantityButton.tsx | 54 + .../components/number-input/NumberInput.tsx | 50 + .../components/number-input/use-counter.ts | 277 + .../src/components/pagination/Pagination.tsx | 145 + .../pagination/ResourcePagination.tsx | 114 + .../src/components/product/Price.tsx | 17 + .../src/components/product/ProductDetails.tsx | 28 + .../components/product/ProductExtensions.tsx | 69 + .../src/components/product/ProductSummary.tsx | 45 + .../src/components/product/SimpleProduct.tsx | 62 + .../src/components/product/StrikePrice.tsx | 19 + .../product/bundles/BundleProduct.tsx | 98 + .../product/bundles/ProductComponent.tsx | 166 + .../product/bundles/ProductComponents.tsx | 33 + .../product/bundles/form-parsers.test.ts | 72 + .../product/bundles/form-parsers.ts | 51 + .../product/bundles/sort-by-order.ts | 6 + .../product/bundles/validation-schema.test.ts | 136 + .../product/bundles/validation-schema.ts | 38 + .../product/carousel/CarouselListener.tsx | 22 + .../product/carousel/HorizontalCarousel.tsx | 93 + .../carousel/ProductCarousel.module.css | 20 + .../product/carousel/ProductCarousel.tsx | 52 + .../carousel/ProductHighlightCarousel.tsx | 89 + .../variations/ProductVariationColor.tsx | 55 + .../variations/ProductVariationStandard.tsx | 55 + .../product/variations/ProductVariations.tsx | 108 + .../product/variations/VariationProduct.tsx | 60 + .../promotion-banner/PromotionBanner.tsx | 62 + .../src/components/radio-group/RadioGroup.tsx | 43 + .../src/components/search/Hit.tsx | 87 + .../src/components/search/Hits.tsx | 32 + .../src/components/search/MobileFilters.tsx | 74 + .../src/components/search/NoResults.tsx | 23 + .../src/components/search/NodeMenu.tsx | 87 + .../src/components/search/Pagination.tsx | 56 + .../components/search/ProductsProvider.tsx | 50 + .../src/components/search/SearchResults.tsx | 75 + .../src/components/select/Select.tsx | 183 + .../src/components/separator/Separator.tsx | 29 + .../src/components/shared/blurb.tsx | 76 + .../src/components/sheet/Sheet.tsx | 134 + .../password-reset/src/components/shimmer.tsx | 13 + .../src/components/skeleton/Skeleton.tsx | 15 + .../src/components/toast/toaster.tsx | 23 + .../src/hooks/use-countries.tsx | 18 + .../password-reset/src/lib/all-countries.ts | 258 + .../src/lib/build-breadcrumb-lookup.ts | 19 + .../src/lib/build-site-navigation.ts | 104 + .../src/lib/cart-cookie-server.ts | 18 + examples/password-reset/src/lib/cn.tsx | 6 + .../password-reset/src/lib/color-lookup.ts | 10 + .../lib/connect-products-with-main-images.ts | 29 + examples/password-reset/src/lib/constants.ts | 6 + .../src/lib/cookie-constants.ts | 4 + .../src/lib/create-breadcrumb.ts | 31 + .../src/lib/custom-rule-headers.ts | 17 + .../password-reset/src/lib/epcc-errors.ts | 27 + .../src/lib/epcc-implicit-client.ts | 37 + .../src/lib/epcc-server-client.ts | 29 + .../epcc-server-side-credentials-client.ts | 49 + .../lib/epcc-server-side-implicit-client.ts | 48 + .../src/lib/file-lookup.test.ts | 204 + .../password-reset/src/lib/file-lookup.ts | 39 + .../src/lib/form-url-encode-body.ts | 10 + .../src/lib/format-currency.tsx | 20 + .../src/lib/format-iso-date-string.ts | 8 + .../src/lib/get-error-message.ts | 15 + .../src/lib/get-store-initial-state.ts | 20 + .../lib/is-account-member-authenticated.ts | 13 + .../password-reset/src/lib/is-empty-object.ts | 2 + .../src/lib/is-supported-extension.ts | 9 + .../src/lib/middleware/apply-set-cookie.ts | 31 + .../lib/middleware/cart-cookie-middleware.ts | 121 + ...create-missing-environment-variable-url.ts | 36 + .../middleware/implicit-auth-middleware.ts | 102 + .../src/lib/middleware/middleware-runner.ts | 63 + .../password-reset/src/lib/product-context.ts | 10 + .../src/lib/product-helper.test.ts | 273 + .../password-reset/src/lib/product-helper.ts | 81 + .../src/lib/product-util.test.ts | 315 + .../password-reset/src/lib/product-util.ts | 54 + .../src/lib/resolve-cart-env.ts | 11 + .../src/lib/resolve-ep-currency-code.ts | 13 + .../src/lib/resolve-epcc-env.ts | 21 + .../retrieve-account-member-credentials.ts | 49 + .../src/lib/sort-alphabetically.ts | 4 + examples/password-reset/src/lib/to-base-64.ts | 4 + .../password-reset/src/lib/token-expired.ts | 3 + .../src/lib/types/breadcrumb-lookup.ts | 7 + .../src/lib/types/deep-partial.ts | 3 + .../src/lib/types/matrix-object-entry.ts | 5 + .../src/lib/types/non-empty-array.ts | 3 + .../src/lib/types/product-types.ts | 31 + .../lib/types/read-only-non-empty-array.ts | 7 + .../password-reset/src/lib/types/unpacked.ts | 7 + .../password-reset/src/lib/use-debounced.ts | 14 + examples/password-reset/src/middleware.ts | 21 + examples/password-reset/src/services/cart.ts | 9 + .../password-reset/src/services/hierarchy.ts | 28 + .../password-reset/src/services/products.ts | 68 + .../password-reset/src/styles/globals.css | 27 + examples/password-reset/tailwind.config.ts | 78 + examples/password-reset/tsconfig.json | 36 + examples/password-reset/vite.config.ts | 10 + 256 files changed, 29140 insertions(+) create mode 100644 examples/password-reset/.composablerc create mode 100644 examples/password-reset/.eslintrc.json create mode 100644 examples/password-reset/.gitignore create mode 100644 examples/password-reset/.lintstagedrc.js create mode 100644 examples/password-reset/.prettierignore create mode 100644 examples/password-reset/.prettierrc create mode 100644 examples/password-reset/README.md create mode 100644 examples/password-reset/e2e/checkout-flow.spec.ts create mode 100644 examples/password-reset/e2e/home-page.spec.ts create mode 100644 examples/password-reset/e2e/models/d2c-cart-page.ts create mode 100644 examples/password-reset/e2e/models/d2c-checkout-page.ts create mode 100644 examples/password-reset/e2e/models/d2c-home-page.ts create mode 100644 examples/password-reset/e2e/models/d2c-product-detail-page.ts create mode 100644 examples/password-reset/e2e/product-details-page.spec.ts create mode 100644 examples/password-reset/e2e/product-list-page.spec.ts create mode 100644 examples/password-reset/e2e/util/enter-payment-information.ts create mode 100644 examples/password-reset/e2e/util/epcc-admin-client.ts create mode 100644 examples/password-reset/e2e/util/epcc-client.ts create mode 100644 examples/password-reset/e2e/util/fill-form-field.ts create mode 100644 examples/password-reset/e2e/util/gateway-check.ts create mode 100644 examples/password-reset/e2e/util/gateway-is-enabled.ts create mode 100644 examples/password-reset/e2e/util/get-cart-id.ts create mode 100644 examples/password-reset/e2e/util/has-published-catalog.ts create mode 100644 examples/password-reset/e2e/util/missing-published-catalog.ts create mode 100644 examples/password-reset/e2e/util/resolver-product-from-store.ts create mode 100644 examples/password-reset/e2e/util/skip-ci-env.ts create mode 100644 examples/password-reset/license.md create mode 100644 examples/password-reset/next-env.d.ts create mode 100644 examples/password-reset/next.config.js create mode 100644 examples/password-reset/package-lock.json create mode 100644 examples/password-reset/package.json create mode 100644 examples/password-reset/playwright.config.ts create mode 100644 examples/password-reset/postcss.config.js create mode 100644 examples/password-reset/public/favicon.ico create mode 100644 examples/password-reset/src/app/(auth)/account-member-credentials-schema.ts create mode 100644 examples/password-reset/src/app/(auth)/actions.ts create mode 100644 examples/password-reset/src/app/(auth)/forgot-password/actions.ts create mode 100644 examples/password-reset/src/app/(auth)/forgot-password/page.tsx create mode 100644 examples/password-reset/src/app/(auth)/layout.tsx create mode 100644 examples/password-reset/src/app/(auth)/login/LoginForm.tsx create mode 100644 examples/password-reset/src/app/(auth)/login/page.tsx create mode 100644 examples/password-reset/src/app/(auth)/not-found.tsx create mode 100644 examples/password-reset/src/app/(auth)/register/page.tsx create mode 100644 examples/password-reset/src/app/(auth)/reset-password/actions.ts create mode 100644 examples/password-reset/src/app/(auth)/reset-password/page.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/AccountCheckout.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/AccountDisplay.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/BillingForm.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/CheckoutFooter.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/CheckoutSidebar.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/CheckoutViews.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/ConfirmationSidebar.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/DeliveryForm.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/FormInput.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/GuestCheckout.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/GuestInformation.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/OrderConfirmation.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/PaymentForm.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/ShippingForm.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/ShippingSelector.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/SubmitCheckoutButton.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/checkout-provider.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/page.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/usePaymentComplete.tsx create mode 100644 examples/password-reset/src/app/(checkout)/checkout/useShippingMethod.tsx create mode 100644 examples/password-reset/src/app/(checkout)/layout.tsx create mode 100644 examples/password-reset/src/app/(checkout)/not-found.tsx create mode 100644 examples/password-reset/src/app/(store)/about/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/AccountNavigation.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/DeleteAddressBtn.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/[addressId]/UpdateForm.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/[addressId]/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/actions.ts create mode 100644 examples/password-reset/src/app/(store)/account/addresses/add/AddForm.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/add/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/addresses/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/breadcrumb.tsx create mode 100644 examples/password-reset/src/app/(store)/account/layout.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/OrderItem.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/OrderItemWithDetails.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/[orderId]/OrderLineItem.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/[orderId]/ProductThumbnail.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/[orderId]/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/orders/page.tsx create mode 100644 examples/password-reset/src/app/(store)/account/summary/YourInfoForm.tsx create mode 100644 examples/password-reset/src/app/(store)/account/summary/actions.ts create mode 100644 examples/password-reset/src/app/(store)/account/summary/page.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/CartItem.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/CartItemWide.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/CartSidebar.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/CartView.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/YourBag.tsx create mode 100644 examples/password-reset/src/app/(store)/cart/page.tsx create mode 100644 examples/password-reset/src/app/(store)/faq/page.tsx create mode 100644 examples/password-reset/src/app/(store)/layout.tsx create mode 100644 examples/password-reset/src/app/(store)/not-found.tsx create mode 100644 examples/password-reset/src/app/(store)/page.tsx create mode 100644 examples/password-reset/src/app/(store)/products/[productId]/page.tsx create mode 100644 examples/password-reset/src/app/(store)/products/[productId]/product-display.tsx create mode 100644 examples/password-reset/src/app/(store)/search/[[...node]]/layout.tsx create mode 100644 examples/password-reset/src/app/(store)/search/[[...node]]/page.tsx create mode 100644 examples/password-reset/src/app/(store)/search/search.tsx create mode 100644 examples/password-reset/src/app/(store)/shipping/page.tsx create mode 100644 examples/password-reset/src/app/(store)/terms/page.tsx create mode 100644 examples/password-reset/src/app/configuration-error/page.tsx create mode 100644 examples/password-reset/src/app/error.tsx create mode 100644 examples/password-reset/src/app/layout.tsx create mode 100644 examples/password-reset/src/app/not-found.tsx create mode 100644 examples/password-reset/src/app/providers.tsx create mode 100644 examples/password-reset/src/components/Checkbox.tsx create mode 100644 examples/password-reset/src/components/LoadingDots.tsx create mode 100644 examples/password-reset/src/components/NoImage.tsx create mode 100644 examples/password-reset/src/components/Spinner.tsx create mode 100644 examples/password-reset/src/components/accordion/Accordion.tsx create mode 100644 examples/password-reset/src/components/alert/Alert.tsx create mode 100644 examples/password-reset/src/components/breadcrumb.tsx create mode 100644 examples/password-reset/src/components/button/Button.tsx create mode 100644 examples/password-reset/src/components/button/FormStatusButton.tsx create mode 100644 examples/password-reset/src/components/button/LoaderIcon.tsx create mode 100644 examples/password-reset/src/components/button/StatusButton.tsx create mode 100644 examples/password-reset/src/components/button/TextButton.tsx create mode 100644 examples/password-reset/src/components/cart/CartDiscounts.tsx create mode 100644 examples/password-reset/src/components/cart/CartSheet.tsx create mode 100644 examples/password-reset/src/components/checkout-item/CheckoutItem.tsx create mode 100644 examples/password-reset/src/components/checkout-sidebar/AddPromotion.tsx create mode 100644 examples/password-reset/src/components/checkout-sidebar/ItemSidebar.tsx create mode 100644 examples/password-reset/src/components/checkout-sidebar/actions.ts create mode 100644 examples/password-reset/src/components/checkout/form-schema/checkout-form-schema.ts create mode 100644 examples/password-reset/src/components/featured-products/FeaturedProducts.tsx create mode 100644 examples/password-reset/src/components/featured-products/fetchFeaturedProducts.ts create mode 100644 examples/password-reset/src/components/footer/Footer.tsx create mode 100644 examples/password-reset/src/components/form/Form.tsx create mode 100644 examples/password-reset/src/components/header/AccountMobileMenu.tsx create mode 100644 examples/password-reset/src/components/header/Header.tsx create mode 100644 examples/password-reset/src/components/header/account/AccountMenu.tsx create mode 100644 examples/password-reset/src/components/header/account/AccountSwitcher.tsx create mode 100644 examples/password-reset/src/components/header/account/switch-button.tsx create mode 100644 examples/password-reset/src/components/header/navigation/MobileAccountSwitcher.tsx create mode 100644 examples/password-reset/src/components/header/navigation/MobileNavBar.tsx create mode 100644 examples/password-reset/src/components/header/navigation/MobileNavBarButton.tsx create mode 100644 examples/password-reset/src/components/header/navigation/NavBar.tsx create mode 100644 examples/password-reset/src/components/header/navigation/NavBarPopover.tsx create mode 100644 examples/password-reset/src/components/header/navigation/NavItemContent.tsx create mode 100644 examples/password-reset/src/components/header/navigation/NavMenu.tsx create mode 100644 examples/password-reset/src/components/icons/cart.tsx create mode 100644 examples/password-reset/src/components/icons/ep-icon.tsx create mode 100644 examples/password-reset/src/components/icons/ep-logo.tsx create mode 100644 examples/password-reset/src/components/icons/github-icon.tsx create mode 100644 examples/password-reset/src/components/input/Input.tsx create mode 100644 examples/password-reset/src/components/label/Label.tsx create mode 100644 examples/password-reset/src/components/navigation-menu/NavigationMenu.tsx create mode 100644 examples/password-reset/src/components/number-input/EditQuantityButton.tsx create mode 100644 examples/password-reset/src/components/number-input/NumberInput.tsx create mode 100644 examples/password-reset/src/components/number-input/use-counter.ts create mode 100644 examples/password-reset/src/components/pagination/Pagination.tsx create mode 100644 examples/password-reset/src/components/pagination/ResourcePagination.tsx create mode 100644 examples/password-reset/src/components/product/Price.tsx create mode 100644 examples/password-reset/src/components/product/ProductDetails.tsx create mode 100644 examples/password-reset/src/components/product/ProductExtensions.tsx create mode 100644 examples/password-reset/src/components/product/ProductSummary.tsx create mode 100644 examples/password-reset/src/components/product/SimpleProduct.tsx create mode 100644 examples/password-reset/src/components/product/StrikePrice.tsx create mode 100644 examples/password-reset/src/components/product/bundles/BundleProduct.tsx create mode 100644 examples/password-reset/src/components/product/bundles/ProductComponent.tsx create mode 100644 examples/password-reset/src/components/product/bundles/ProductComponents.tsx create mode 100644 examples/password-reset/src/components/product/bundles/form-parsers.test.ts create mode 100644 examples/password-reset/src/components/product/bundles/form-parsers.ts create mode 100644 examples/password-reset/src/components/product/bundles/sort-by-order.ts create mode 100644 examples/password-reset/src/components/product/bundles/validation-schema.test.ts create mode 100644 examples/password-reset/src/components/product/bundles/validation-schema.ts create mode 100644 examples/password-reset/src/components/product/carousel/CarouselListener.tsx create mode 100644 examples/password-reset/src/components/product/carousel/HorizontalCarousel.tsx create mode 100644 examples/password-reset/src/components/product/carousel/ProductCarousel.module.css create mode 100644 examples/password-reset/src/components/product/carousel/ProductCarousel.tsx create mode 100644 examples/password-reset/src/components/product/carousel/ProductHighlightCarousel.tsx create mode 100644 examples/password-reset/src/components/product/variations/ProductVariationColor.tsx create mode 100644 examples/password-reset/src/components/product/variations/ProductVariationStandard.tsx create mode 100644 examples/password-reset/src/components/product/variations/ProductVariations.tsx create mode 100644 examples/password-reset/src/components/product/variations/VariationProduct.tsx create mode 100644 examples/password-reset/src/components/promotion-banner/PromotionBanner.tsx create mode 100644 examples/password-reset/src/components/radio-group/RadioGroup.tsx create mode 100644 examples/password-reset/src/components/search/Hit.tsx create mode 100644 examples/password-reset/src/components/search/Hits.tsx create mode 100644 examples/password-reset/src/components/search/MobileFilters.tsx create mode 100644 examples/password-reset/src/components/search/NoResults.tsx create mode 100644 examples/password-reset/src/components/search/NodeMenu.tsx create mode 100644 examples/password-reset/src/components/search/Pagination.tsx create mode 100644 examples/password-reset/src/components/search/ProductsProvider.tsx create mode 100644 examples/password-reset/src/components/search/SearchResults.tsx create mode 100644 examples/password-reset/src/components/select/Select.tsx create mode 100644 examples/password-reset/src/components/separator/Separator.tsx create mode 100644 examples/password-reset/src/components/shared/blurb.tsx create mode 100644 examples/password-reset/src/components/sheet/Sheet.tsx create mode 100644 examples/password-reset/src/components/shimmer.tsx create mode 100644 examples/password-reset/src/components/skeleton/Skeleton.tsx create mode 100644 examples/password-reset/src/components/toast/toaster.tsx create mode 100644 examples/password-reset/src/hooks/use-countries.tsx create mode 100644 examples/password-reset/src/lib/all-countries.ts create mode 100644 examples/password-reset/src/lib/build-breadcrumb-lookup.ts create mode 100644 examples/password-reset/src/lib/build-site-navigation.ts create mode 100644 examples/password-reset/src/lib/cart-cookie-server.ts create mode 100644 examples/password-reset/src/lib/cn.tsx create mode 100644 examples/password-reset/src/lib/color-lookup.ts create mode 100644 examples/password-reset/src/lib/connect-products-with-main-images.ts create mode 100644 examples/password-reset/src/lib/constants.ts create mode 100644 examples/password-reset/src/lib/cookie-constants.ts create mode 100644 examples/password-reset/src/lib/create-breadcrumb.ts create mode 100644 examples/password-reset/src/lib/custom-rule-headers.ts create mode 100644 examples/password-reset/src/lib/epcc-errors.ts create mode 100644 examples/password-reset/src/lib/epcc-implicit-client.ts create mode 100644 examples/password-reset/src/lib/epcc-server-client.ts create mode 100644 examples/password-reset/src/lib/epcc-server-side-credentials-client.ts create mode 100644 examples/password-reset/src/lib/epcc-server-side-implicit-client.ts create mode 100644 examples/password-reset/src/lib/file-lookup.test.ts create mode 100644 examples/password-reset/src/lib/file-lookup.ts create mode 100644 examples/password-reset/src/lib/form-url-encode-body.ts create mode 100644 examples/password-reset/src/lib/format-currency.tsx create mode 100644 examples/password-reset/src/lib/format-iso-date-string.ts create mode 100644 examples/password-reset/src/lib/get-error-message.ts create mode 100644 examples/password-reset/src/lib/get-store-initial-state.ts create mode 100644 examples/password-reset/src/lib/is-account-member-authenticated.ts create mode 100644 examples/password-reset/src/lib/is-empty-object.ts create mode 100644 examples/password-reset/src/lib/is-supported-extension.ts create mode 100644 examples/password-reset/src/lib/middleware/apply-set-cookie.ts create mode 100644 examples/password-reset/src/lib/middleware/cart-cookie-middleware.ts create mode 100644 examples/password-reset/src/lib/middleware/create-missing-environment-variable-url.ts create mode 100644 examples/password-reset/src/lib/middleware/implicit-auth-middleware.ts create mode 100644 examples/password-reset/src/lib/middleware/middleware-runner.ts create mode 100644 examples/password-reset/src/lib/product-context.ts create mode 100644 examples/password-reset/src/lib/product-helper.test.ts create mode 100644 examples/password-reset/src/lib/product-helper.ts create mode 100644 examples/password-reset/src/lib/product-util.test.ts create mode 100644 examples/password-reset/src/lib/product-util.ts create mode 100644 examples/password-reset/src/lib/resolve-cart-env.ts create mode 100644 examples/password-reset/src/lib/resolve-ep-currency-code.ts create mode 100644 examples/password-reset/src/lib/resolve-epcc-env.ts create mode 100644 examples/password-reset/src/lib/retrieve-account-member-credentials.ts create mode 100644 examples/password-reset/src/lib/sort-alphabetically.ts create mode 100644 examples/password-reset/src/lib/to-base-64.ts create mode 100644 examples/password-reset/src/lib/token-expired.ts create mode 100644 examples/password-reset/src/lib/types/breadcrumb-lookup.ts create mode 100644 examples/password-reset/src/lib/types/deep-partial.ts create mode 100644 examples/password-reset/src/lib/types/matrix-object-entry.ts create mode 100644 examples/password-reset/src/lib/types/non-empty-array.ts create mode 100644 examples/password-reset/src/lib/types/product-types.ts create mode 100644 examples/password-reset/src/lib/types/read-only-non-empty-array.ts create mode 100644 examples/password-reset/src/lib/types/unpacked.ts create mode 100644 examples/password-reset/src/lib/use-debounced.ts create mode 100644 examples/password-reset/src/middleware.ts create mode 100644 examples/password-reset/src/services/cart.ts create mode 100644 examples/password-reset/src/services/hierarchy.ts create mode 100644 examples/password-reset/src/services/products.ts create mode 100644 examples/password-reset/src/styles/globals.css create mode 100644 examples/password-reset/tailwind.config.ts create mode 100644 examples/password-reset/tsconfig.json create mode 100644 examples/password-reset/vite.config.ts diff --git a/examples/password-reset/.composablerc b/examples/password-reset/.composablerc new file mode 100644 index 00000000..61e09123 --- /dev/null +++ b/examples/password-reset/.composablerc @@ -0,0 +1,6 @@ +{ + "version": 1, + "cli": { + "packageManager": "yarn" + } +} \ No newline at end of file diff --git a/examples/password-reset/.eslintrc.json b/examples/password-reset/.eslintrc.json new file mode 100644 index 00000000..d7dcbb98 --- /dev/null +++ b/examples/password-reset/.eslintrc.json @@ -0,0 +1,12 @@ +{ + "extends": ["next/core-web-vitals", "prettier"], + "plugins": ["react"], + "parserOptions": { + "ecmaFeatures": { + "jsx": true + } + }, + "rules": { + "react/jsx-curly-brace-presence": "error" + } +} diff --git a/examples/password-reset/.gitignore b/examples/password-reset/.gitignore new file mode 100644 index 00000000..537bd7aa --- /dev/null +++ b/examples/password-reset/.gitignore @@ -0,0 +1,45 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.idea/ + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local +.env.* + +# vercel +.vercel + +# typescript +*.tsbuildinfo + +# Being generated by the moltin js-sdk during dev server from server side requests +/localStorage + +test-results \ No newline at end of file diff --git a/examples/password-reset/.lintstagedrc.js b/examples/password-reset/.lintstagedrc.js new file mode 100644 index 00000000..0fadc0d4 --- /dev/null +++ b/examples/password-reset/.lintstagedrc.js @@ -0,0 +1,32 @@ +const path = require("path"); + +/** + * Using next lint with lint-staged requires this setup + * https://nextjs.org/docs/basic-features/eslint#lint-staged + */ + +const buildEslintCommand = (filenames) => + `next lint --fix --file ${filenames + .map((f) => path.relative(process.cwd(), f)) + .join(" --file ")}`; + +/** + * () => "npm run type:check" + * needs to be a function because arguments are getting passed from lint-staged + * when those arguments get through to the "tsc" command that "npm run type:check" + * is calling the args cause "tsc" to ignore the tsconfig.json in our root directory. + * https://github.com/microsoft/TypeScript/issues/27379 + */ +module.exports = { + "*.{js,jsx}": [ + "npm run format:fix", + buildEslintCommand, + "npm run format:check", + ], + "*.{ts,tsx}": [ + "npm run format:fix", + () => "npm run type:check", + buildEslintCommand, + "npm run format:check", + ], +}; diff --git a/examples/password-reset/.prettierignore b/examples/password-reset/.prettierignore new file mode 100644 index 00000000..b14c3ee4 --- /dev/null +++ b/examples/password-reset/.prettierignore @@ -0,0 +1 @@ +**/.next/** \ No newline at end of file diff --git a/examples/password-reset/.prettierrc b/examples/password-reset/.prettierrc new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/examples/password-reset/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/examples/password-reset/README.md b/examples/password-reset/README.md new file mode 100644 index 00000000..e3121755 --- /dev/null +++ b/examples/password-reset/README.md @@ -0,0 +1,91 @@ +# password-reset Elastic Path storefront starter + +This project was generated with [Composable CLI](https://www.npmjs.com/package/composable-cli). + +This storefront accelerates the development of a direct-to-consumer ecommerce experience using Elastic Path's modular products. + +## Tech Stack + +- [Elastic Path](https://www.elasticpath.com/products): A family of composable products for businesses that need to quickly & easily create unique experiences and next-level customer engagements that drive revenue. + +- [Next.js](https://nextjs.org/): a React framework for building static and server-side rendered applications + +- [Tailwind CSS](https://tailwindcss.com/): enabling you to get started with a range of out the box components that are + easy to customize + +- [Headless UI](https://headlessui.com/): completely unstyled, fully accessible UI components, designed to integrate + beautifully with Tailwind CSS. + +- [Radix UI Primitives](https://www.radix-ui.com/primitives): Unstyled, accessible, open source React primitives for high-quality web apps and design systems. + +- [Typescript](https://www.typescriptlang.org/): a typed superset of JavaScript that compiles to plain JavaScript + +## Getting Started + +Run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page will hot reload as you edit the file. + +## Deployment + +Deployment is typical for a Next.js site. We recommend using a provider +like [Netlify](https://www.netlify.com/blog/2020/11/30/how-to-deploy-next.js-sites-to-netlify/) +or [Vercel](https://vercel.com/docs/frameworks/nextjs) to get full Next.js feature support. + +## Current feature set reference + +| **Feature** | **Notes** | +|------------------------------------------|-----------------------------------------------------------------------------------------------| +| PDP | Product Display Pages | +| PLP | Product Listing Pages. | +| EPCC PXM product variations | [Learn more](https://elasticpath.dev/docs/pxm/products/pxm-product-variations/pxm-variations) | +| EPCC PXM bundles | [Learn more](https://elasticpath.dev/docs/pxm/products/pxm-bundles/pxm-bundles) | +| EPCC PXM hierarchy-based navigation menu | Main site nav driven directly from your store's hierarchy and node structure | +| Prebuilt helper components | Some basic building blocks for typical ecommerce store features | +| Checkout | [Learn more](https://elasticpath.dev/docs/commerce-cloud/checkout/checkout-workflow) | +| Cart | [Learn more](https://elasticpath.dev/docs/commerce-cloud/carts/carts) | + +## Notes on this starter + +This starter is using the simple store implementation and add the password reset flow. +You'll need to ensure your email service is configured to send the password reset emails. + +Here is how to do it using Composer and Postmark. +- Make sure you have a Postmark account and API key +- In Postmark, create a new template for the password reset email and note the template ID +- Go to Composer in Commerce Manager and select Postmark Email +- Add your Postmark API key +- In Event Mapping, add key `one-time-password-token-request.created` and value: + +```json +{ + "messagingProvider": { + "from": "noreply@.com", + "templateId": 38364654, + "to": "$.payload.user_authentication_info.email" + }, + "dynamicFieldMapping": { + "username": "$.payload.user_authentication_info.email", + "token": "$.payload.one_time_password_token", + "password_profile_id": "$.payload.password_profile_id", + "user_authentication_info_id": "$.payload.user_authentication_info.id", + "user_authentication_password_profile_info_id": "$.payload.user_authentication_password_profile_info.id" + }, + "metadata": { + "user_id": "$.payload.user_authentication_info.id" + } +} +``` +- To learn more about One Time Password tokens, see [here](https://elasticpath.dev/guides/How-To/Authentication/how-to-utilize-one-time-password-tokens) \ No newline at end of file diff --git a/examples/password-reset/e2e/checkout-flow.spec.ts b/examples/password-reset/e2e/checkout-flow.spec.ts new file mode 100644 index 00000000..7e865658 --- /dev/null +++ b/examples/password-reset/e2e/checkout-flow.spec.ts @@ -0,0 +1,41 @@ +import { test } from "@playwright/test"; +import { createD2CProductDetailPage } from "./models/d2c-product-detail-page"; +import { client } from "./util/epcc-client"; +import { createD2CCartPage } from "./models/d2c-cart-page"; +import { createD2CCheckoutPage } from "./models/d2c-checkout-page"; + +test.describe("Checkout flow", async () => { + test("should perform product checkout", async ({ page }) => { + const productDetailPage = createD2CProductDetailPage(page, client); + const cartPage = createD2CCartPage(page); + const checkoutPage = createD2CCheckoutPage(page); + + /* Go to simple product page */ + await productDetailPage.gotoSimpleProduct(); + + /* Add the product to cart */ + await productDetailPage.addProductToCart(); + + /* Go to cart page and checkout */ + await cartPage.goto(); + await cartPage.checkoutCart(); + + /* Enter information */ + await checkoutPage.enterInformation({ + "Email Address": { value: "test@tester.com", fieldType: "input" }, + "First Name": { value: "Jim", fieldType: "input" }, + "Last Name": { value: "Brown", fieldType: "input" }, + Address: { value: "Main Street", fieldType: "input" }, + City: { value: "Brownsville", fieldType: "input" }, + Region: { value: "Browns", fieldType: "input" }, + Postcode: { value: "ABC 123", fieldType: "input" }, + Country: { value: "Algeria", fieldType: "combobox" }, + "Phone Number": { value: "01234567891", fieldType: "input" }, + }); + + await checkoutPage.checkout(); + + /* Continue Shopping */ + await checkoutPage.continueShopping(); + }); +}); diff --git a/examples/password-reset/e2e/home-page.spec.ts b/examples/password-reset/e2e/home-page.spec.ts new file mode 100644 index 00000000..de251ea1 --- /dev/null +++ b/examples/password-reset/e2e/home-page.spec.ts @@ -0,0 +1,10 @@ +import { test } from "@playwright/test"; +import { createD2CHomePage } from "./models/d2c-home-page"; +import { skipIfMissingCatalog } from "./util/missing-published-catalog"; + +test.describe("Home Page", async () => { + test("should load home page", async ({ page }) => { + const d2cHomePage = createD2CHomePage(page); + await d2cHomePage.goto(); + }); +}); diff --git a/examples/password-reset/e2e/models/d2c-cart-page.ts b/examples/password-reset/e2e/models/d2c-cart-page.ts new file mode 100644 index 00000000..34626aca --- /dev/null +++ b/examples/password-reset/e2e/models/d2c-cart-page.ts @@ -0,0 +1,23 @@ +import type { Locator, Page } from "@playwright/test"; + +export interface D2CCartPage { + readonly page: Page; + readonly checkoutBtn: Locator; + readonly goto: () => Promise; + readonly checkoutCart: () => Promise; +} + +export function createD2CCartPage(page: Page): D2CCartPage { + const checkoutBtn = page.getByRole("link", { name: "Checkout" }); + + return { + page, + checkoutBtn, + async goto() { + await page.goto(`/cart`); + }, + async checkoutCart() { + await checkoutBtn.click(); + }, + }; +} diff --git a/examples/password-reset/e2e/models/d2c-checkout-page.ts b/examples/password-reset/e2e/models/d2c-checkout-page.ts new file mode 100644 index 00000000..e1efec42 --- /dev/null +++ b/examples/password-reset/e2e/models/d2c-checkout-page.ts @@ -0,0 +1,48 @@ +import type { Locator, Page } from "@playwright/test"; +import { fillAllFormFields, FormInput } from "../util/fill-form-field"; +import { enterPaymentInformation as _enterPaymentInformation } from "../util/enter-payment-information"; + +export interface D2CCheckoutPage { + readonly page: Page; + readonly payNowBtn: Locator; + readonly checkoutBtn: Locator; + readonly goto: () => Promise; + readonly enterInformation: (values: FormInput) => Promise; + readonly checkout: () => Promise; + readonly enterPaymentInformation: (values: FormInput) => Promise; + readonly submitPayment: () => Promise; + readonly continueShopping: () => Promise; +} + +export function createD2CCheckoutPage(page: Page): D2CCheckoutPage { + const payNowBtn = page.getByRole("button", { name: "Pay $" }); + const checkoutBtn = page.getByRole("button", { name: "Pay $" }); + const continueShoppingBtn = page.getByRole("link", { + name: "Continue shopping", + }); + + return { + page, + payNowBtn, + checkoutBtn, + async goto() { + await page.goto(`/cart`); + }, + async enterPaymentInformation(values: FormInput) { + await _enterPaymentInformation(page, values); + }, + async enterInformation(values: FormInput) { + await fillAllFormFields(page, values); + }, + async submitPayment() { + await payNowBtn.click(); + }, + async checkout() { + await checkoutBtn.click(); + }, + async continueShopping() { + await continueShoppingBtn.click(); + await page.waitForURL("/"); + }, + }; +} diff --git a/examples/password-reset/e2e/models/d2c-home-page.ts b/examples/password-reset/e2e/models/d2c-home-page.ts new file mode 100644 index 00000000..9a847b8b --- /dev/null +++ b/examples/password-reset/e2e/models/d2c-home-page.ts @@ -0,0 +1,15 @@ +import type { Page } from "@playwright/test"; + +export interface D2CHomePage { + readonly page: Page; + readonly goto: () => Promise; +} + +export function createD2CHomePage(page: Page): D2CHomePage { + return { + page, + async goto() { + await page.goto("/"); + }, + }; +} diff --git a/examples/password-reset/e2e/models/d2c-product-detail-page.ts b/examples/password-reset/e2e/models/d2c-product-detail-page.ts new file mode 100644 index 00000000..538ed27e --- /dev/null +++ b/examples/password-reset/e2e/models/d2c-product-detail-page.ts @@ -0,0 +1,132 @@ +import type { Page } from "@playwright/test"; +import { expect, test } from "@playwright/test"; +import { + getProductById, + getSimpleProduct, + getVariationsProduct, +} from "../util/resolver-product-from-store"; +import type {ElasticPath, ProductResponse } from "@elasticpath/js-sdk"; +import { getCartId } from "../util/get-cart-id"; +import { getSkuIdFromOptions } from "../../src/lib/product-helper"; + +const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; + +export interface D2CProductDetailPage { + readonly page: Page; + readonly gotoSimpleProduct: () => Promise; + readonly gotoVariationsProduct: () => Promise; + readonly getCartId: () => Promise; + readonly addProductToCart: () => Promise; + readonly gotoProductVariation: () => Promise; +} + +export function createD2CProductDetailPage( + page: Page, + client: ElasticPath, +): D2CProductDetailPage { + let activeProduct: ProductResponse | undefined; + const addToCartBtn = page.getByRole("button", { name: "Add to Cart" }); + + return { + page, + async gotoSimpleProduct() { + activeProduct = await getSimpleProduct(client); + await skipOrGotoProduct( + page, + "Can't run test because there is no simple product published in the store.", + activeProduct, + ); + }, + async gotoVariationsProduct() { + activeProduct = await getVariationsProduct(client); + await skipOrGotoProduct( + page, + "Can't run test because there is no variation product published in the store.", + activeProduct, + ); + }, + async gotoProductVariation() { + expect( + activeProduct, + "Make sure you call one of the gotoVariationsProduct function first before calling gotoProductVariation", + ).toBeDefined(); + expect(activeProduct?.attributes.base_product).toEqual(true); + + const expectedProductId = await selectOptions(activeProduct!, page); + const product = await getProductById(client, expectedProductId); + + expect(product.data?.id).toBeDefined(); + activeProduct = product.data; + + /* Check to make sure the page has navigated to the selected product */ + await expect(page).toHaveURL(`/products/${expectedProductId}`); + }, + getCartId: getCartId(page), + async addProductToCart() { + expect( + activeProduct, + "Make sure you call one of the gotoProduct function first before calling addProductToCart", + ).toBeDefined(); + /* Get the cart id */ + const cartId = await getCartId(page)(); + + /* Add the product to cart */ + await addToCartBtn.click(); + /* Wait for the cart POST request to complete */ + const reqUrl = `https://${host}/v2/carts/${cartId}/items`; + await page.waitForResponse(reqUrl); + + /* Check to make sure the product has been added to cart */ + const result = await client.Cart(cartId).With("items").Get(); + await expect( + activeProduct?.attributes.price, + "Missing price on active product - make sure the product has a price set can't add to cart without one.", + ).toBeDefined(); + await expect( + result.included?.items.find( + (item) => item.product_id === activeProduct!.id, + ), + ).toHaveProperty("product_id", activeProduct!.id); + }, + }; +} + +async function skipOrGotoProduct( + page: Page, + msg: string, + product?: ProductResponse, +) { + if (!product) { + test.skip(!product, msg); + } else { + await page.goto(`/products/${product.id}`); + } +} + +async function selectOptions( + baseProduct: ProductResponse, + page: Page, +): Promise { + /* select one of each variation option */ + const options = baseProduct.meta.variations?.reduce((acc, variation) => { + return [...acc, ...([variation.options?.[0]] ?? [])]; + }, []); + + if (options && baseProduct.meta.variation_matrix) { + for (const option of options) { + await page.click(`text=${option.name}`); + } + + const variationId = getSkuIdFromOptions( + options.map((x) => x.id), + baseProduct.meta.variation_matrix, + ); + + if (!variationId) { + throw new Error("Unable to resolve variation id."); + } + return variationId; + } + + throw Error("Unable to select options they were not defined."); +} diff --git a/examples/password-reset/e2e/product-details-page.spec.ts b/examples/password-reset/e2e/product-details-page.spec.ts new file mode 100644 index 00000000..b65cad74 --- /dev/null +++ b/examples/password-reset/e2e/product-details-page.spec.ts @@ -0,0 +1,29 @@ +import { test } from "@playwright/test"; +import { createD2CProductDetailPage } from "./models/d2c-product-detail-page"; +import { client } from "./util/epcc-client"; +import { skipIfMissingCatalog } from "./util/missing-published-catalog"; + +test.describe("Product Details Page", async () => { + test("should add a simple product to cart", async ({ page }) => { + const productDetailPage = createD2CProductDetailPage(page, client); + + /* Go to base product page */ + await productDetailPage.gotoSimpleProduct(); + + /* Add the product to cart */ + await productDetailPage.addProductToCart(); + }); + + test("should add variation product to cart", async ({ page }) => { + const productDetailPage = createD2CProductDetailPage(page, client); + + /* Go to base product page */ + await productDetailPage.gotoVariationsProduct(); + + /* Select the product variations */ + await productDetailPage.gotoProductVariation(); + + /* Add the product to cart */ + await productDetailPage.addProductToCart(); + }); +}); diff --git a/examples/password-reset/e2e/product-list-page.spec.ts b/examples/password-reset/e2e/product-list-page.spec.ts new file mode 100644 index 00000000..9d193c82 --- /dev/null +++ b/examples/password-reset/e2e/product-list-page.spec.ts @@ -0,0 +1,46 @@ +import { test, expect } from "@playwright/test"; +import { gateway } from "@elasticpath/js-sdk"; +import { buildSiteNavigation } from "../src/lib/build-site-navigation"; + +const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; +const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; + +const client = gateway({ + client_id, + host, +}); + +test("should be able to use quick view to view full product details", async ({ + page, + isMobile, +}) => { + /* Go to home page */ + await page.goto("/"); + + /* Get the cart id from the cookie */ + const allCookies = await page.context().cookies(); + const cartId = allCookies.find( + (cookie) => cookie.name === "_store_ep_cart", + )?.value; + + const nav = await buildSiteNavigation(client); + + const firstNavItem = nav[0]; + + if (!firstNavItem) { + test.skip( + true, + "No navigation items found can't test product list page flow", + ); + } + + await page.getByRole("button", {name: "Shop Now"}).click(); + + /* Check to make sure the page has navigated to the product list page for Men's / T-Shirts */ + await expect(page).toHaveURL(`/search`); + + await page.locator('[href*="/products/"]').first().click(); + + /* Check to make sure the page has navigated to the product details page for Simple T-Shirt */ + await page.waitForURL(/\/products\//); +}); diff --git a/examples/password-reset/e2e/util/enter-payment-information.ts b/examples/password-reset/e2e/util/enter-payment-information.ts new file mode 100644 index 00000000..738196b7 --- /dev/null +++ b/examples/password-reset/e2e/util/enter-payment-information.ts @@ -0,0 +1,10 @@ +import { Page } from "@playwright/test"; +import { fillAllFormFields, FormInput } from "./fill-form-field"; + +export async function enterPaymentInformation(page: Page, values: FormInput) { + const paymentIframe = await page + .locator('[id="payment-element"]') + .frameLocator("iframe"); + + await fillAllFormFields(paymentIframe, values); +} diff --git a/examples/password-reset/e2e/util/epcc-admin-client.ts b/examples/password-reset/e2e/util/epcc-admin-client.ts new file mode 100644 index 00000000..5fefa8f9 --- /dev/null +++ b/examples/password-reset/e2e/util/epcc-admin-client.ts @@ -0,0 +1,14 @@ +import { gateway, MemoryStorageFactory } from "@elasticpath/js-sdk"; + +const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; +const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; +const client_secret = process.env.EPCC_CLIENT_SECRET; + +export const adminClient = gateway({ + client_id, + client_secret, + host, + throttleEnabled: true, + name: "admin_client", + storage: new MemoryStorageFactory(), +}); diff --git a/examples/password-reset/e2e/util/epcc-client.ts b/examples/password-reset/e2e/util/epcc-client.ts new file mode 100644 index 00000000..e094235c --- /dev/null +++ b/examples/password-reset/e2e/util/epcc-client.ts @@ -0,0 +1,12 @@ +import { gateway, MemoryStorageFactory } from "@elasticpath/js-sdk"; + +const host = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; +const client_id = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; + +export const client = gateway({ + client_id, + host, + throttleEnabled: true, + name: "implicit_client", + storage: new MemoryStorageFactory(), +}); diff --git a/examples/password-reset/e2e/util/fill-form-field.ts b/examples/password-reset/e2e/util/fill-form-field.ts new file mode 100644 index 00000000..92c6ce20 --- /dev/null +++ b/examples/password-reset/e2e/util/fill-form-field.ts @@ -0,0 +1,48 @@ +import { FrameLocator, Page } from "@playwright/test"; + +export type FormInputValue = { + value: string; + fieldType: "input" | "select" | "combobox"; + options?: { exact?: boolean }; +}; +export type FormInput = Record; + +export async function fillAllFormFields( + page: Page | FrameLocator, + input: FormInput, +) { + const fillers = Object.keys(input).map((key) => { + return () => fillFormField(page, key, input[key]); + }); + + for (const filler of fillers) { + await filler(); + } +} + +export async function fillFormField( + page: Page | FrameLocator, + key: string, + { value, fieldType, options }: FormInputValue, +): Promise { + let locator; + if (fieldType === "combobox") { + locator = page.getByRole("combobox"); + } else { + locator = page.getByLabel(key, { exact: true, ...options }); + } + + switch (fieldType) { + case "input": + return locator.fill(value); + case "select": { + await locator.selectOption(value); + return; + } + case "combobox": { + await locator.click(); + await page.getByLabel(value).click(); + return; + } + } +} diff --git a/examples/password-reset/e2e/util/gateway-check.ts b/examples/password-reset/e2e/util/gateway-check.ts new file mode 100644 index 00000000..ceacf531 --- /dev/null +++ b/examples/password-reset/e2e/util/gateway-check.ts @@ -0,0 +1,13 @@ +import type {ElasticPath } from "@elasticpath/js-sdk"; + +export async function gatewayCheck(client: ElasticPath): Promise { + try { + const gateways = await client.Gateways.All(); + const epPaymentGateway = gateways.data.find( + (gateway) => gateway.slug === "elastic_path_payments_stripe", + )?.enabled; + return !!epPaymentGateway; + } catch (err) { + return false; + } +} diff --git a/examples/password-reset/e2e/util/gateway-is-enabled.ts b/examples/password-reset/e2e/util/gateway-is-enabled.ts new file mode 100644 index 00000000..12e55d3a --- /dev/null +++ b/examples/password-reset/e2e/util/gateway-is-enabled.ts @@ -0,0 +1,10 @@ +import { test } from "@playwright/test"; +import { gatewayCheck } from "./gateway-check"; +import { adminClient } from "./epcc-admin-client"; + +export async function gatewayIsEnabled(): Promise { + test.skip( + !(await gatewayCheck(adminClient)), + "Skipping tests because they payment gateway is not enabled.", + ); +} diff --git a/examples/password-reset/e2e/util/get-cart-id.ts b/examples/password-reset/e2e/util/get-cart-id.ts new file mode 100644 index 00000000..e2e7dc8d --- /dev/null +++ b/examples/password-reset/e2e/util/get-cart-id.ts @@ -0,0 +1,14 @@ +import { expect, Page } from "@playwright/test"; + +export function getCartId(page: Page) { + return async function _getCartId(): Promise { + /* Get the cart id from the cookie */ + const allCookies = await page.context().cookies(); + const cartId = allCookies.find( + (cookie) => cookie.name === "_store_ep_cart", + )?.value; + + expect(cartId).toBeDefined(); + return cartId!; + }; +} diff --git a/examples/password-reset/e2e/util/has-published-catalog.ts b/examples/password-reset/e2e/util/has-published-catalog.ts new file mode 100644 index 00000000..983fc901 --- /dev/null +++ b/examples/password-reset/e2e/util/has-published-catalog.ts @@ -0,0 +1,12 @@ +import type {ElasticPath } from "@elasticpath/js-sdk"; + +export async function hasPublishedCatalog( + client: ElasticPath, +): Promise { + try { + await client.ShopperCatalog.Get(); + return false; + } catch (err) { + return true; + } +} diff --git a/examples/password-reset/e2e/util/missing-published-catalog.ts b/examples/password-reset/e2e/util/missing-published-catalog.ts new file mode 100644 index 00000000..d48fec22 --- /dev/null +++ b/examples/password-reset/e2e/util/missing-published-catalog.ts @@ -0,0 +1,10 @@ +import { test } from "@playwright/test"; +import { hasPublishedCatalog } from "./has-published-catalog"; +import { client } from "./epcc-client"; + +export async function skipIfMissingCatalog(): Promise { + test.skip( + await hasPublishedCatalog(client), + "Skipping tests because there is no published catalog.", + ); +} diff --git a/examples/password-reset/e2e/util/resolver-product-from-store.ts b/examples/password-reset/e2e/util/resolver-product-from-store.ts new file mode 100644 index 00000000..3005dd7c --- /dev/null +++ b/examples/password-reset/e2e/util/resolver-product-from-store.ts @@ -0,0 +1,84 @@ +import type { + ElasticPath, + ShopperCatalogResourcePage, + ProductResponse, + ShopperCatalogResource, +} from "@elasticpath/js-sdk"; + +export async function getSimpleProduct( + client: ElasticPath, +): Promise { + const paginator = paginateShopperProducts(client, { limit: 100 }); + + if (paginator) { + for await (const page of paginator) { + const simpleProduct = page.data.find( + (x) => !x.attributes.base_product && !x.attributes.base_product_id, + ); + if (simpleProduct) { + return simpleProduct; + } + } + } +} + +export async function getProductById( + client: ElasticPath, + productId: string, +): Promise> { + return client.ShopperCatalog.Products.Get({ + productId: productId, + }); +} + +export async function getVariationsProduct( + client: ElasticPath, +): Promise { + const paginator = paginateShopperProducts(client, { limit: 100 }); + + if (paginator) { + for await (const page of paginator) { + const variationsProduct = page.data.find( + (x) => x.attributes.base_product, + ); + if (variationsProduct) { + return variationsProduct; + } + } + } +} + +const makePagedClientRequest = async ( + client: ElasticPath, + { limit = 100, offset }: { limit?: number; offset: number }, +): Promise> => { + return await client.ShopperCatalog.Products.Offset(offset).Limit(limit).All(); +}; + +export type Paginator = AsyncGenerator; + +export async function* paginateShopperProducts( + client: ElasticPath, + input: { limit?: number; offset?: number }, +): Paginator> | undefined { + let page: ShopperCatalogResourcePage; + + let nextOffset: number = input.offset ?? 0; + let hasNext = true; + + while (hasNext) { + page = await makePagedClientRequest(client, { + limit: input.limit, + offset: nextOffset, + }); + yield page; + const { + results: { total: totalItems }, + page: { current, limit }, + } = page.meta; + hasNext = current * limit < totalItems; + nextOffset = nextOffset + limit; + } + + return undefined; +} diff --git a/examples/password-reset/e2e/util/skip-ci-env.ts b/examples/password-reset/e2e/util/skip-ci-env.ts new file mode 100644 index 00000000..1f93e2d5 --- /dev/null +++ b/examples/password-reset/e2e/util/skip-ci-env.ts @@ -0,0 +1,8 @@ +import { test } from "@playwright/test"; + +export function skipIfCIEnvironment(): void { + test.skip( + process.env.CI === "true", + "Skipping tests because we are in a CI environment.", + ); +} diff --git a/examples/password-reset/license.md b/examples/password-reset/license.md new file mode 100644 index 00000000..714fa3a8 --- /dev/null +++ b/examples/password-reset/license.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Elastic Path Software Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/password-reset/next-env.d.ts b/examples/password-reset/next-env.d.ts new file mode 100644 index 00000000..40c3d680 --- /dev/null +++ b/examples/password-reset/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/examples/password-reset/next.config.js b/examples/password-reset/next.config.js new file mode 100644 index 00000000..9c013b75 --- /dev/null +++ b/examples/password-reset/next.config.js @@ -0,0 +1,43 @@ +// @ts-check + +/** + * @type {import('next').NextConfig} + **/ +const nextConfig = { + images: { + formats: ["image/avif", "image/webp"], + remotePatterns: [ + { + protocol: "https", + hostname: "**.epusercontent.com", + }, + { + protocol: "https", + hostname: "**.cm.elasticpath.com", + }, + { + protocol: 'https', + hostname: 'assets.adidas.com', + + }, + ], + }, + i18n: { + locales: ["en"], + defaultLocale: "en", + }, + webpack(config) { + config.resolve.fallback = { + ...config.resolve.fallback, + fs: false, + }; + + return config; + }, +}; + +const withBundleAnalyzer = require("@next/bundle-analyzer")({ + enabled: process.env.ANALYZE === "true", +}); + +module.exports = withBundleAnalyzer(nextConfig); diff --git a/examples/password-reset/package-lock.json b/examples/password-reset/package-lock.json new file mode 100644 index 00000000..383ae132 --- /dev/null +++ b/examples/password-reset/package-lock.json @@ -0,0 +1,14538 @@ +{ + "name": "password-reset", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "password-reset", + "dependencies": { + "@elasticpath/js-sdk": "21.0.0", + "@elasticpath/react-shopper-hooks": "0.14.0", + "@floating-ui/react": "^0.26.3", + "@headlessui/react": "^1.7.17", + "@heroicons/react": "^2.0.18", + "@hookform/error-message": "^2.0.1", + "@hookform/resolvers": "^3.3.2", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-navigation-menu": "^1.1.4", + "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slot": "^1.0.2", + "@tanstack/react-query": "^5.51.23", + "class-variance-authority": "^0.7.0", + "clsx": "^1.2.1", + "cookies-next": "^4.0.0", + "focus-visible": "^5.2.0", + "formik": "^2.2.9", + "next": "^14.0.0", + "pure-react-carousel": "^1.29.0", + "rc-slider": "^10.3.0", + "react": "^18.3.1", + "react-device-detect": "^2.2.2", + "react-dom": "^18.3.1", + "react-hook-form": "^7.49.0", + "react-toastify": "^9.1.3", + "server-only": "^0.0.1", + "tailwind-clip-path": "^1.0.0", + "tailwind-merge": "^2.0.0", + "zod": "^3.22.4", + "zod-formik-adapter": "^1.2.0" + }, + "devDependencies": { + "@babel/core": "^7.18.10", + "@next/bundle-analyzer": "^14.0.0", + "@next/env": "^14.0.0", + "@playwright/test": "^1.28.1", + "@svgr/webpack": "^6.3.1", + "@tailwindcss/forms": "^0.5.7", + "@testing-library/jest-dom": "^6.1.3", + "@testing-library/react": "^14.0.0", + "@types/node": "18.7.3", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "@vitest/coverage-istanbul": "^0.34.5", + "autoprefixer": "^10.4.14", + "babel-loader": "^8.2.5", + "encoding": "^0.1.13", + "eslint": "^8.49.0", + "eslint-config-next": "^14.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-react": "^7.33.2", + "lint-staged": "^13.0.3", + "postcss": "^8.4.30", + "prettier": "^3.0.3", + "prettier-eslint": "^15.0.1", + "prettier-eslint-cli": "^7.1.0", + "prettier-plugin-tailwindcss": "^0.5.4", + "tailwindcss": "^3.3.3", + "tailwindcss-animate": "^1.0.7", + "typescript": "^5.2.2", + "vite": "^4.2.1", + "vitest": "^0.34.5" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz", + "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==", + "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/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", + "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.26.3.tgz", + "integrity": "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@elasticpath/js-sdk": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@elasticpath/js-sdk/-/js-sdk-21.0.0.tgz", + "integrity": "sha512-m/4fCXgKws3vQrTWItfgE5gPHuqoLCD/Bs+Yo2/d5ve4iCuqlKSTgS/t7AY6yQmmfYG9bl4WLNOPjDGy7qUPCQ==", + "license": "MIT", + "dependencies": { + "cross-fetch": "^3.1.5", + "es6-promise": "^4.0.5", + "form-data": "^4.0.0", + "inflected": "^2.0.1", + "js-cookie": "^3.0.1", + "node-localstorage": "^2.1.6", + "throttled-queue": "^2.1.4" + } + }, + "node_modules/@elasticpath/react-shopper-hooks": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@elasticpath/react-shopper-hooks/-/react-shopper-hooks-0.14.0.tgz", + "integrity": "sha512-N/jH+phTATHOaD4KCBZZb5i0yJzK+KIdMQidhzfx2kQqbl6AjpFH/WG4e2mT96cZZsIETfrGiQF/ByAQKA1WgA==", + "dependencies": { + "@elasticpath/shopper-common": "0.4.0", + "js-cookie": "^3.0.5", + "jwt-decode": "^3.1.2" + }, + "peerDependencies": { + "@elasticpath/js-sdk": "5.0.0", + "@tanstack/react-query": "^5.51.23", + "react": "^18.3.1", + "react-dom": "^18.3.1" + } + }, + "node_modules/@elasticpath/shopper-common": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@elasticpath/shopper-common/-/shopper-common-0.4.0.tgz", + "integrity": "sha512-ZAKp2HGCvbXzfDprbjCBnmSbxGfrlJ9yhmfOMK22jI5yBp37moGV+Wk7RMS4ij6fngMDCLtgOp6ao1+C9mKtbQ==", + "license": "MIT", + "dependencies": { + "@elasticpath/js-sdk": "5.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@elasticpath/shopper-common/node_modules/@elasticpath/js-sdk": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@elasticpath/js-sdk/-/js-sdk-5.0.0.tgz", + "integrity": "sha512-fPtFrolcaQyjHD4NhWyPXV8NMXYWSA3oSlKYvWbbhkSuHsy9mDyDX1EBWmhgKrAXhydxCnngqjJpf4QrxlWSEw==", + "license": "MIT", + "dependencies": { + "cross-fetch": "^3.1.5", + "es6-promise": "^4.0.5", + "form-data": "^4.0.0", + "inflected": "^2.0.1", + "js-cookie": "^3.0.1", + "node-localstorage": "^2.1.6", + "throttled-queue": "^2.1.4" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "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/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/react": { + "version": "0.26.28", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz", + "integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.1.2", + "@floating-ui/utils": "^0.2.8", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "license": "MIT" + }, + "node_modules/@headlessui/react": { + "version": "1.7.19", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", + "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", + "dependencies": { + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, + "node_modules/@hookform/error-message": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@hookform/error-message/-/error-message-2.0.1.tgz", + "integrity": "sha512-U410sAr92xgxT1idlu9WWOVjndxLdgPUHEB8Schr27C9eh7/xUnITWpCMF93s+lGiG++D4JnbSnrb5A21AdSNg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0", + "react-hook-form": "^7.0.0" + } + }, + "node_modules/@hookform/resolvers": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.1.tgz", + "integrity": "sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==", + "license": "MIT", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.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/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "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" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@messageformat/core": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@messageformat/core/-/core-3.4.0.tgz", + "integrity": "sha512-NgCFubFFIdMWJGN5WuQhHCNmzk7QgiVfrViFxcS99j7F5dDS5EP6raR54I+2ydhe4+5/XTn/YIEppFaqqVWHsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@messageformat/date-skeleton": "^1.0.0", + "@messageformat/number-skeleton": "^1.0.0", + "@messageformat/parser": "^5.1.0", + "@messageformat/runtime": "^3.0.1", + "make-plural": "^7.0.0", + "safe-identifier": "^0.4.1" + } + }, + "node_modules/@messageformat/date-skeleton": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/date-skeleton/-/date-skeleton-1.1.0.tgz", + "integrity": "sha512-rmGAfB1tIPER+gh3p/RgA+PVeRE/gxuQ2w4snFWPF5xtb5mbWR7Cbw7wCOftcUypbD6HVoxrVdyyghPm3WzP5A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@messageformat/number-skeleton": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@messageformat/number-skeleton/-/number-skeleton-1.2.0.tgz", + "integrity": "sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@messageformat/parser": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.1.0.tgz", + "integrity": "sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "moo": "^0.5.1" + } + }, + "node_modules/@messageformat/runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@messageformat/runtime/-/runtime-3.0.1.tgz", + "integrity": "sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "make-plural": "^7.0.0" + } + }, + "node_modules/@next/bundle-analyzer": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-14.2.20.tgz", + "integrity": "sha512-CYbHfYyQlGlcdCh4kytGm1EUlelO+yk+TbsGxHN9yTdnjjGTkDAk3egqtvAwaAwmHMOOk+u5U6Ju9z4Uo67lxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "webpack-bundle-analyzer": "4.10.1" + } + }, + "node_modules/@next/env": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.20.tgz", + "integrity": "sha512-JfDpuOCB0UBKlEgEy/H6qcBSzHimn/YWjUHzKl1jMeUO+QVRdzmTTl8gFJaNO87c8DXmVKhFCtwxQ9acqB3+Pw==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.20.tgz", + "integrity": "sha512-T0JRi706KLbvR1Uc46t56VtawbhR/igdBagzOrA7G+vv4rvjwnlu/Y4/Iq6X9TDVj5UZjyot4lUdkNd3V2kLhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "10.3.10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.20.tgz", + "integrity": "sha512-WDfq7bmROa5cIlk6ZNonNdVhKmbCv38XteVFYsxea1vDJt3SnYGgxLGMTXQNfs5OkFvAhmfKKrwe7Y0Hs+rWOg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.20.tgz", + "integrity": "sha512-XIQlC+NAmJPfa2hruLvr1H1QJJeqOTDV+v7tl/jIdoFvqhoihvSNykLU/G6NMgoeo+e/H7p/VeWSOvMUHKtTIg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.20.tgz", + "integrity": "sha512-pnzBrHTPXIMm5QX3QC8XeMkpVuoAYOmyfsO4VlPn+0NrHraNuWjdhe+3xLq01xR++iCvX+uoeZmJDKcOxI201Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.20.tgz", + "integrity": "sha512-WhJJAFpi6yqmUx1momewSdcm/iRXFQS0HU2qlUGlGE/+98eu7JWLD5AAaP/tkK1mudS/rH2f9E3WCEF2iYDydQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.20.tgz", + "integrity": "sha512-ao5HCbw9+iG1Kxm8XsGa3X174Ahn17mSYBQlY6VGsdsYDAbz/ZP13wSLfvlYoIDn1Ger6uYA+yt/3Y9KTIupRg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.20.tgz", + "integrity": "sha512-CXm/kpnltKTT7945np6Td3w7shj/92TMRPyI/VvveFe8+YE+/YOJ5hyAWK5rpx711XO1jBCgXl211TWaxOtkaA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.20.tgz", + "integrity": "sha512-upJn2HGQgKNDbXVfIgmqT2BN8f3z/mX8ddoyi1I565FHbfowVK5pnMEwauvLvaJf4iijvuKq3kw/b6E9oIVRWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.20.tgz", + "integrity": "sha512-igQW/JWciTGJwj3G1ipalD2V20Xfx3ywQy17IV0ciOUBbFhNfyU1DILWsTi32c8KmqgIDviUEulW/yPb2FF90w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.20.tgz", + "integrity": "sha512-AFmqeLW6LtxeFTuoB+MXFeM5fm5052i3MU6xD0WzJDOwku6SkZaxb1bxjBaRC8uNqTRTSPl0yMFtjNowIVI67w==", + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.1.tgz", + "integrity": "sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prettier/eslint": { + "name": "prettier-eslint", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-15.0.1.tgz", + "integrity": "sha512-mGOWVHixSvpZWARqSDXbdtTL54mMBxc5oQYQ6RAqy8jecuNJBgN3t9E5a81G66F8x8fsKNiR1HWaBV66MJDOpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "^8.4.2", + "@types/prettier": "^2.6.0", + "@typescript-eslint/parser": "^5.10.0", + "common-tags": "^1.4.0", + "dlv": "^1.1.0", + "eslint": "^8.7.0", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.0", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^2.5.1", + "pretty-format": "^23.0.1", + "require-relative": "^0.8.7", + "typescript": "^4.5.4", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@prettier/eslint/node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@prettier/eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@prettier/eslint/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@prettier/eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@prettier/eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@prettier/eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@prettier/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@prettier/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@prettier/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@prettier/eslint/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@prettier/eslint/node_modules/pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "node_modules/@prettier/eslint/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@prettier/eslint/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==", + "license": "MIT" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", + "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.2.tgz", + "integrity": "sha512-b1oh54x4DMCdGsB4/7ahiSrViXxaBwRPotiZNnYXjLha9vfuURSAZErki6qjDoSIV0eXx5v57XnTGVtGwnfp2g==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collapsible": "1.1.2", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", + "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.3.tgz", + "integrity": "sha512-HD7/ocp8f1B3e6OHygH0n7ZKjONkhciy1Nh0yuBgObqThc3oyx+vuMfFHKAknXRHHWVE9XvXStxJFyjUmB8PIw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.2.tgz", + "integrity": "sha512-PliMB63vxz7vggcyq0IxNYk8vGDrLXVWw4+W4B8YnwI1s18x7YZYqlG9PLX7XxAJUi0g2DxP4XKJMFHh/iVh9A==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", + "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz", + "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.4.tgz", + "integrity": "sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", + "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", + "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.1.tgz", + "integrity": "sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.3.tgz", + "integrity": "sha512-IQWAsQ7dsLIYDrn0WqPU+cdM7MONTv9nqrLVYoie3BPiabSfUVDe6Fr+oEt0Cofsr9ONDcDe9xhmJbL1Uq1yKg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", + "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", + "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.2.tgz", + "integrity": "sha512-E0MLLGfOP0l8P/NxgVzfXJ8w3Ch8cdO6UDzJfDChu4EJDy+/WdO5LqpdY8PYnCErkmZH3gZhDL1K7kQ41fAHuQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", + "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.4.tgz", + "integrity": "sha512-pOkb2u8KgO47j/h7AylCj7dJsm69BXcjkrvTqMptFqsE2i0p8lHkfgneXKjAgPzBMivnoMyt8o4KiV4wYzDdyQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.1.tgz", + "integrity": "sha512-RRiNRSrD8iUiXriq/Y5n4/3iE8HzqgLHsusUSg5jVpU2+3tqcUFPJXHDymwEypunc2sWxDUS3UC+rkZRlHedsw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz", + "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.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" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, + "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/@rushstack/eslint-patch": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", + "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", + "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", + "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", + "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", + "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", + "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", + "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", + "@svgr/babel-plugin-remove-jsx-attribute": "*", + "@svgr/babel-plugin-remove-jsx-empty-expression": "*", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", + "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", + "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", + "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", + "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", + "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", + "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.0", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", + "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/hast-util-to-babel-ast": "^6.5.1", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "^6.0.0" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", + "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "svgo": "^2.8.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", + "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.19.6", + "@babel/plugin-transform-react-constant-elements": "^7.18.12", + "@babel/preset-env": "^7.19.4", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@svgr/core": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "@svgr/plugin-svgo": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", + "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.62.8", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.8.tgz", + "integrity": "sha512-4fV31vDsUyvNGrKIOUNPrZztoyL187bThnoQOvAXEVlZbSiuPONpfx53634MKKdvsDir5NyOGm80ShFaoHS/mw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.62.8", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.62.8.tgz", + "integrity": "sha512-8TUstKxF/fysHonZsWg/hnlDVgasTdHx6Q+f1/s/oPKJBJbKUWPZEHwLTMOZgrZuroLMiqYKJ9w69Abm8mWP0Q==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.62.8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.2.tgz", + "integrity": "sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.11.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "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/@tanstack/virtual-core": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz", + "integrity": "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "node_modules/@testing-library/dom/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/@testing-library/dom/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", + "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "lodash": "^4.17.21", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/react": { + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz", + "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai-subset": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", + "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.6.tgz", + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "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==", + "dev": true, + "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/node": { + "version": "18.7.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.3.tgz", + "integrity": "sha512-LJgzOEwWuMTBxHzgBR/fhhBOWrvBjvO+zPteUgbbuQi80rYIZHrk1mNbRUqPZqSLP2H7Rwt1EFLL/tNLD1Xx/w==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.17.tgz", + "integrity": "sha512-opAQ5no6LqJNo9TqnxBKsgnkIYHozW9KSTlFVoSUJYh1Fl/sswkEoqIugRSm7tbh6pABtYjGAjW+GOS23j8qbw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz", + "integrity": "sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.18.1", + "@typescript-eslint/type-utils": "8.18.1", + "@typescript-eslint/utils": "8.18.1", + "@typescript-eslint/visitor-keys": "8.18.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.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.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.18.1.tgz", + "integrity": "sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.18.1", + "@typescript-eslint/types": "8.18.1", + "@typescript-eslint/typescript-estree": "8.18.1", + "@typescript-eslint/visitor-keys": "8.18.1", + "debug": "^4.3.4" + }, + "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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.18.1.tgz", + "integrity": "sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.1", + "@typescript-eslint/visitor-keys": "8.18.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/type-utils": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.18.1.tgz", + "integrity": "sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.18.1", + "@typescript-eslint/utils": "8.18.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.18.1.tgz", + "integrity": "sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw==", + "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.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.1.tgz", + "integrity": "sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.1", + "@typescript-eslint/visitor-keys": "8.18.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.18.1.tgz", + "integrity": "sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.18.1", + "@typescript-eslint/types": "8.18.1", + "@typescript-eslint/typescript-estree": "8.18.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", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.1.tgz", + "integrity": "sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.1", + "eslint-visitor-keys": "^4.2.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": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "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/@ungap/structured-clone": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@vitest/coverage-istanbul": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-0.34.6.tgz", + "integrity": "sha512-5KaBNZPDSk2ybavC3rZ1pWGniw7sJ5usuwVGRUYzJwiBfWvnLpuUer7bjw7qUCRGdKJXrBgb/Dsgif9rkwMX/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.1.5", + "picocolors": "^1.0.0", + "test-exclude": "^6.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": ">=0.32.0 <1" + } + }, + "node_modules/@vitest/expect": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", + "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", + "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "0.34.6", + "p-limit": "^4.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@vitest/snapshot": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", + "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/snapshot/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/spy": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", + "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", + "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.4.3", + "loupe": "^2.3.6", + "pretty-format": "^29.5.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@vitest/utils/node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@vitest/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "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/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "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/ajv-formats/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==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-escapes": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", + "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^1.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "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", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "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.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/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "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.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.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.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "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-loader": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz", + "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^3.3.1", + "loader-utils": "^2.0.4", + "make-dir": "^3.1.0", + "schema-utils": "^2.6.5" + }, + "engines": { + "node": ">= 8.9" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "webpack": ">=2" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.3", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "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/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/boolify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", + "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "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==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "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.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "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.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelcase-keys": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", + "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.3.0", + "map-obj": "^4.1.0", + "quick-lru": "^5.1.1", + "type-fest": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001689", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001689.tgz", + "integrity": "sha512-CmeR2VBycfa+5/jOfnp/NpWPGd06nf1XYiefUvhXFfZE4GkRc9jv+eGPS4nT558WS/8lYCzV8SlANCIPvbWP1g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", + "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-tags": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", + "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "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/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookies-next": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-4.3.0.tgz", + "integrity": "sha512-XxeCwLR30cWwRd94sa9X5lRCDLVujtx73tv+N0doQCFIDl83fuuYdxbu/WQUt9aSV7EJx7bkMvJldjvzuFqr4w==", + "license": "MIT", + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.7.0" + } + }, + "node_modules/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "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/cross-fetch": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", + "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "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/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "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/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-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-freeze": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deep-freeze/-/deep-freeze-0.0.1.tgz", + "integrity": "sha512-Z+z8HiAvsGwmjqlphnHW5oz6yWlOwu6EQfFTjmeTWlDeda3FS2yv3jhq35TX/ewmsnqB+RX2IdsIOyjJCQN5tg==", + "license": "public domain" + }, + "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==", + "dev": true, + "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/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "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/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.74", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.74.tgz", + "integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==", + "dev": true, + "license": "ISC" + }, + "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/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/equals": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/equals/-/equals-1.0.5.tgz", + "integrity": "sha512-wI15a6ZoaaXPv+55+Vh2Kqn3+efKRv8QPtcGTjW5xmanMnQzESdAt566jevtMZyt3W/jwLDTzXpMph5ECDJ2zg==", + "license": "MIT", + "dependencies": { + "jkroso-type": "1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.6.tgz", + "integrity": "sha512-Ifco6n3yj2tMZDWNLyloZrytt9lqqlwvS83P3HtaETR0NUOYnIULGGHpktqYGObGy+8wc1okO25p8TjemhImvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.7", + "get-intrinsic": "^1.2.6", + "get-symbol-description": "^1.0.2", + "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.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.0.0", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-regex-test": "^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.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.3", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", + "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", + "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-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.3", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "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/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.20.tgz", + "integrity": "sha512-gHBvp4RDd51DAaDco7KiWFy731EwcItkDtGUaZH1EUXEnHCzsVRjMceT+b8aThjMLjOScz6Q27MGlePASvK4Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "14.2.20", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "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.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "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.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "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.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "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-import/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/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.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", + "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.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/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/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "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/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/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "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==", + "dev": true, + "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-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/focus-visible": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.1.tgz", + "integrity": "sha512-8Bx950VD1bWTQJEH/AM6SpEk+SU55aVnp4Ujhuuxy3eMEBCRwBnTBnVXr9YAPvZL3/CNjCa8u4IWfNmEO53whA==", + "license": "W3C" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/formik/node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "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/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.7.tgz", + "integrity": "sha512-2g4x+HqTJKM9zcJqBSpjoRmdcPFtJM60J3xJisTQSXBWka5XqyBN/2tNUgma1mztTXyDuUsEtYe5qcs7xYzYQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "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/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.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", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflected": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/inflected/-/inflected-2.1.0.tgz", + "integrity": "sha512-hAEKNxvHf2Iq3H60oMBHkB4wl5jn3TPF3+fXek/sRwAB5gP9xWs4r7aweSF95f99HFoz69pnZTcu8f0SIHV18w==", + "license": "MIT" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "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/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "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-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==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.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==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "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-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "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.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "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-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "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-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2" + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.4.tgz", + "integrity": "sha512-x4WH0BWmrMmg4oHHl+duwubhrvczGlyuGAZu3nvrf0UXOfPu8IhZObFEr7DE/iv01YgVZrsOiRcqw2srkKEDIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "reflect.getprototypeof": "^1.0.8", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jkroso-type": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jkroso-type/-/jkroso-type-1.1.1.tgz", + "integrity": "sha512-zZgay+fPG6PgMUrpyFADmQmvLo39+AZa7Gc5pZhev2RhDxwANEq2etwD8d0e6rTg5NkwOIlQmaEmns3draC6Ng==", + "license": "MIT" + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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" + }, + "engines": { + "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==", + "dev": true, + "license": "MIT" + }, + "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", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "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/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==", + "license": "MIT" + }, + "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/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/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/lint-staged": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-13.3.0.tgz", + "integrity": "sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "5.3.0", + "commander": "11.0.0", + "debug": "4.3.4", + "execa": "7.2.0", + "lilconfig": "2.1.0", + "listr2": "6.6.1", + "micromatch": "4.0.5", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.3.1" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/lint-staged/node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/lint-staged/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lint-staged/node_modules/yaml": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", + "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 14" + } + }, + "node_modules/listr2": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", + "integrity": "sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^5.0.1", + "rfdc": "^1.3.0", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/local-pkg": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", + "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "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.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "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/log-update": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", + "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^5.0.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^5.0.0", + "strip-ansi": "^7.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/loglevel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-colored-level-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", + "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^1.1.3", + "loglevel": "^1.4.1" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loglevel-colored-level-prefix/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "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/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-plural": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-7.4.0.tgz", + "integrity": "sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==", + "dev": true, + "license": "Unicode-DFS-2016" + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.0.0.tgz", + "integrity": "sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "dev": true, + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mlly": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz", + "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^1.1.2", + "pkg-types": "^1.2.1", + "ufo": "^1.5.4" + } + }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "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/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/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/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/next": { + "version": "14.2.20", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.20.tgz", + "integrity": "sha512-yPvIiWsiyVYqJlSQxwmzMIReXn5HxFNq4+tlVQ812N1FbvhmE+fDpIAD7bcS2mGYQwPJ5vAsQouyme2eKsxaug==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.20", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.20", + "@next/swc-darwin-x64": "14.2.20", + "@next/swc-linux-arm64-gnu": "14.2.20", + "@next/swc-linux-arm64-musl": "14.2.20", + "@next/swc-linux-x64-gnu": "14.2.20", + "@next/swc-linux-x64-musl": "14.2.20", + "@next/swc-win32-arm64-msvc": "14.2.20", + "@next/swc-win32-ia32-msvc": "14.2.20", + "@next/swc-win32-x64-msvc": "14.2.20" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "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/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-localstorage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-2.2.1.tgz", + "integrity": "sha512-vv8fJuOUCCvSPjDjBLlMqYMHob4aGjkmrkaE42/mZr0VT+ZAU10jRF8oTnX9+pgU9/vYJ8P7YT3Vd6ajkmzSCw==", + "license": "MIT", + "dependencies": { + "write-file-atomic": "^1.1.4" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", + "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "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.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.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "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" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "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/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "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/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/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/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-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" + } + }, + "node_modules/playwright": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.49.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "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.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "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.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-eslint": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-15.0.1.tgz", + "integrity": "sha512-mGOWVHixSvpZWARqSDXbdtTL54mMBxc5oQYQ6RAqy8jecuNJBgN3t9E5a81G66F8x8fsKNiR1HWaBV66MJDOpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "^8.4.2", + "@types/prettier": "^2.6.0", + "@typescript-eslint/parser": "^5.10.0", + "common-tags": "^1.4.0", + "dlv": "^1.1.0", + "eslint": "^8.7.0", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.0", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^2.5.1", + "pretty-format": "^23.0.1", + "require-relative": "^0.8.7", + "typescript": "^4.5.4", + "vue-eslint-parser": "^8.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/prettier-eslint-cli": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-7.1.0.tgz", + "integrity": "sha512-kMMvV7Mt6VqdJSb25aCkOA7HTIxy5mii2tzBb1vCSmzlIECOzTP2wRPIeAtBky6WdpfN0n1Zxa4E37Atp1IksA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@messageformat/core": "^3.0.1", + "@prettier/eslint": "npm:prettier-eslint@^15.0.1", + "arrify": "^2.0.1", + "boolify": "^1.0.1", + "camelcase-keys": "^7.0.2", + "chalk": "^4.1.2", + "common-tags": "^1.8.2", + "core-js": "^3.24.1", + "eslint": "^8.21.0", + "find-up": "^5.0.0", + "get-stdin": "^8.0.0", + "glob": "^7.2.3", + "ignore": "^5.2.0", + "indent-string": "^4.0.0", + "lodash.memoize": "^4.1.2", + "loglevel-colored-level-prefix": "^1.0.0", + "rxjs": "^7.5.6", + "yargs": "^13.1.1" + }, + "bin": { + "prettier-eslint": "dist/index.js" + }, + "engines": { + "node": ">=12.22" + }, + "peerDependencies": { + "prettier-eslint": "*" + }, + "peerDependenciesMeta": { + "prettier-eslint": { + "optional": true + } + } + }, + "node_modules/prettier-eslint-cli/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/prettier-eslint-cli/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/prettier-eslint/node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/prettier-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/prettier-eslint/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/prettier-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/prettier-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/prettier-eslint/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettier-eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/prettier-eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/prettier-eslint/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-eslint/node_modules/pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "node_modules/prettier-eslint/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettier-eslint/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.14.tgz", + "integrity": "sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "@zackad/prettier-plugin-twig-melody": "*", + "prettier": "^3.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-sort-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "@zackad/prettier-plugin-twig-melody": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-marko": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + } + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT" + }, + "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/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/pure-react-carousel": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/pure-react-carousel/-/pure-react-carousel-1.32.0.tgz", + "integrity": "sha512-RW0zKjjId1Xmspcqdu3v0pmlce3BVDACJ0fzt1+ZPJ4GxqJbIqt2kPAh1e5M19S5BDewihnq6kz4kIaGXleO3w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "deep-freeze": "0.0.1", + "deepmerge": "^2.2.1", + "equals": "^1.0.5", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": "15.x || 16.x || 17.x || 18.x", + "react-dom": "15.x || 16.x || 17.x || 18.x" + } + }, + "node_modules/pure-react-carousel/node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc-slider": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.6.2.tgz", + "integrity": "sha512-FjkoFjyvUQWcBo1F3RgSglky3ar0+qHLM41PlFVYB4Bj3RD8E/Mv7kqMouLFBU+3aFglMzzctAIWRwajEuueSw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.44.2", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.2.tgz", + "integrity": "sha512-uGSk3hpPBLa3/0QAcKhCjgl4SFnhQCJDLvvpoLdbR6KgDuXrujG+dQaUeUvBJr2ZWak1O/9n+cYbJiWmmk95EQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-device-detect": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz", + "integrity": "sha512-buYY3qrCnQVlIFHrC5UcUoAj7iANs/+srdkwsnNjI7anr3Tt7UY6MqNxtMLlr0tMBied0O49UZVK8XKs3ZIiPw==", + "license": "MIT", + "dependencies": { + "ua-parser-js": "^1.0.33" + }, + "peerDependencies": { + "react": ">= 0.14.0", + "react-dom": ">= 0.14.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-hook-form": { + "version": "7.54.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.54.1.tgz", + "integrity": "sha512-PUNzFwQeQ5oHiiTUO7GO/EJXGEtuun2Y1A59rLnZBBj+vNEOWt/3ERTiG1/zt7dVeJEM+4vDX/7XQ/qanuvPMg==", + "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-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-remove-scroll": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz", + "integrity": "sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz", + "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==", + "license": "MIT", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.9.tgz", + "integrity": "sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "dunder-proto": "^1.0.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.9", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", + "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", + "dev": true, + "license": "MIT", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "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==", + "dev": true, + "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/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "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", + "peer": true + }, + "node_modules/safe-identifier": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz", + "integrity": "sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==", + "dev": true, + "license": "ISC" + }, + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", + "license": "MIT" + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "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/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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "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/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "license": "ISC", + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "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==", + "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==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": true, + "license": "MIT" + }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "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/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "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-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "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", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "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.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "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/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/strip-literal": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", + "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "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" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, + "node_modules/tailwind-clip-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tailwind-clip-path/-/tailwind-clip-path-1.0.0.tgz", + "integrity": "sha512-pac3BiCZCEKtX+3In4508PFcX2eZL7JwliZMtfYE0RoqFMjfbCVLmu+uuEFqn1y/f2vrOB5rY4XNcmaOSG1csw==", + "license": "ISC" + }, + "node_modules/tailwind-merge": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz", + "integrity": "sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "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/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/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==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/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==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throttled-queue": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/throttled-queue/-/throttled-queue-2.1.4.tgz", + "integrity": "sha512-YGdk8sdmr4ge3g+doFj/7RLF5kLM+Mi7DEciu9PHxnMJZMeVuZeTj31g4VE7ekUffx/IdbvrtOCiz62afg0mkg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "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/tinypool": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", + "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "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/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "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/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz", + "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz", + "integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true, + "license": "MIT" + }, + "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/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "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", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "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", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "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/vite": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", + "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "mlly": "^1.4.0", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "0.34.6", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", + "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^4.3.5", + "@types/chai-subset": "^1.3.3", + "@types/node": "*", + "@vitest/expect": "0.34.6", + "@vitest/runner": "0.34.6", + "@vitest/snapshot": "0.34.6", + "@vitest/spy": "0.34.6", + "@vitest/utils": "0.34.6", + "acorn": "^8.9.0", + "acorn-walk": "^8.2.0", + "cac": "^6.7.14", + "chai": "^4.3.10", + "debug": "^4.3.4", + "local-pkg": "^0.4.3", + "magic-string": "^0.30.1", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.3.3", + "strip-literal": "^1.0.1", + "tinybench": "^2.5.0", + "tinypool": "^0.7.0", + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", + "vite-node": "0.34.6", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": ">=v14.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@vitest/browser": "*", + "@vitest/ui": "*", + "happy-dom": "*", + "jsdom": "*", + "playwright": "*", + "safaridriver": "*", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "node_modules/vue-eslint-parser": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz", + "integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.2", + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.0.0", + "esquery": "^1.4.0", + "lodash": "^4.17.21", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", + "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.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==", + "dev": true, + "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-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "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/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==", + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "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.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "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": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-formik-adapter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/zod-formik-adapter/-/zod-formik-adapter-1.3.0.tgz", + "integrity": "sha512-qWsVwRYqpRod5BL35pRXHD6UOugiyaEyLPO04rCN/uKTCFCR+VElPEG26+3wNrxGP7y5XmJM+4/0MrABnRYZrw==", + "license": "MIT", + "peerDependencies": { + "formik": "^2.2.9", + "zod": "^3.22.4" + } + } + } +} diff --git a/examples/password-reset/package.json b/examples/password-reset/package.json new file mode 100644 index 00000000..316a1399 --- /dev/null +++ b/examples/password-reset/package.json @@ -0,0 +1,90 @@ +{ + "name": "password-reset", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "lint:fix": "next lint --fix", + "format:check": "prettier --check .", + "format:fix": "prettier --write .", + "type:check": "tsc --noEmit", + "test": "vitest run", + "test:coverage": "vitest run --coverage", + "test:watch": "vitest", + "test:ci:e2e": "NODE_ENV=test yarn build && (yarn start & (sleep 5 && npx playwright install --with-deps && yarn test:e2e && kill $(lsof -t -i tcp:3000)))", + "test:e2e": "NODE_ENV=test playwright test", + "build:e2e": "NODE_ENV=test next build", + "start:e2e": "NODE_ENV=test next start" + }, + "dependencies": { + "@elasticpath/js-sdk": "21.0.0", + "@elasticpath/react-shopper-hooks": "0.14.0", + "clsx": "^1.2.1", + "cookies-next": "^4.0.0", + "focus-visible": "^5.2.0", + "formik": "^2.2.9", + "next": "^14.0.0", + "server-only": "^0.0.1", + "pure-react-carousel": "^1.29.0", + "react": "^18.3.1", + "react-device-detect": "^2.2.2", + "react-dom": "^18.3.1", + "react-toastify": "^9.1.3", + "@heroicons/react": "^2.0.18", + "@headlessui/react": "^1.7.17", + "rc-slider": "^10.3.0", + "zod": "^3.22.4", + "zod-formik-adapter": "^1.2.0", + "@floating-ui/react": "^0.26.3", + "@hookform/resolvers": "^3.3.2", + "@hookform/error-message": "^2.0.1", + "@radix-ui/react-accordion": "^1.1.2", + "@radix-ui/react-checkbox": "^1.0.4", + "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-navigation-menu": "^1.1.4", + "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slot": "^1.0.2", + "@tanstack/react-query": "^5.51.23", + "class-variance-authority": "^0.7.0", + "react-hook-form": "^7.49.0", + "tailwind-clip-path": "^1.0.0", + "tailwind-merge": "^2.0.0" + }, + "devDependencies": { + "@babel/core": "^7.18.10", + "@next/bundle-analyzer": "^14.0.0", + "@next/env": "^14.0.0", + "@svgr/webpack": "^6.3.1", + "@types/node": "18.7.3", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "babel-loader": "^8.2.5", + "eslint": "^8.49.0", + "eslint-config-next": "^14.0.0", + "eslint-config-prettier": "^9.0.0", + "encoding": "^0.1.13", + "eslint-plugin-react": "^7.33.2", + "vite": "^4.2.1", + "vitest": "^0.34.5", + "@vitest/coverage-istanbul": "^0.34.5", + "@testing-library/jest-dom": "^6.1.3", + "@testing-library/react": "^14.0.0", + "@playwright/test": "^1.28.1", + "lint-staged": "^13.0.3", + "prettier": "^3.0.3", + "prettier-eslint": "^15.0.1", + "prettier-eslint-cli": "^7.1.0", + "typescript": "^5.2.2", + "tailwindcss": "^3.3.3", + "autoprefixer": "^10.4.14", + "postcss": "^8.4.30", + "prettier-plugin-tailwindcss": "^0.5.4", + "@tailwindcss/forms": "^0.5.7", + "tailwindcss-animate": "^1.0.7" + } +} diff --git a/examples/password-reset/playwright.config.ts b/examples/password-reset/playwright.config.ts new file mode 100644 index 00000000..86a23119 --- /dev/null +++ b/examples/password-reset/playwright.config.ts @@ -0,0 +1,72 @@ +import { PlaywrightTestConfig, devices } from "@playwright/test"; +import { join } from "path"; +import { loadEnvConfig } from "@next/env"; + +loadEnvConfig(process.env.PWD!); + +// Use process.env.PORT by default and fallback to port 3000 +const PORT = process.env.PORT || 3000; + +// Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port +const baseURL = process.env.BASE_URL ?? `http://localhost:${PORT}`; + +// Reference: https://playwright.dev/docs/test-configuration +const config: PlaywrightTestConfig = { + // Timeout per test + timeout: 15 * 1000, + // Test directory + testDir: join(__dirname, "e2e"), + // If a test fails, retry it additional 2 times + retries: 2, + // Artifacts folder where screenshots, videos, and traces are stored. + outputDir: "test-results/", + + // Run your local dev server before starting the tests: + // https://playwright.dev/docs/test-advanced#launching-a-development-web-server-during-the-tests + // webServer: { + // command: 'yarn run dev', + // url: baseURL, + // timeout: 120 * 1000, + // reuseExistingServer: !process.env.CI, + // }, + + use: { + // Use baseURL so to make navigations relative. + // More information: https://playwright.dev/docs/api/class-testoptions#test-options-base-url + baseURL, + + screenshot: "only-on-failure", + + // Retry a test if its failing with enabled tracing. This allows you to analyse the DOM, console logs, network traffic etc. + // More information: https://playwright.dev/docs/trace-viewer + trace: "retry-with-trace", + + // All available context options: https://playwright.dev/docs/api/class-browser#browser-new-context + // contextOptions: { + // ignoreHTTPSErrors: true, + // }, + }, + + projects: [ + { + name: "Desktop Chrome", + use: { + ...devices["Desktop Chrome"], + }, + }, + { + name: "Desktop Firefox", + use: { + ...devices["Desktop Firefox"], + }, + }, + // Test against mobile viewports. + { + name: "Mobile Chrome", + use: { + ...devices["Pixel 5"], + }, + }, + ], +}; +export default config; diff --git a/examples/password-reset/postcss.config.js b/examples/password-reset/postcss.config.js new file mode 100644 index 00000000..12a703d9 --- /dev/null +++ b/examples/password-reset/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/examples/password-reset/public/favicon.ico b/examples/password-reset/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a61f60f199cfd37e307bfb0ee3cd285f35d733e8 GIT binary patch literal 15086 zcmd^GONbmr7_N2IC@P7H_yE~KBb%A3T~}8`4>CE3B6v~QgBPD5KJX9_HOY2QpK|ab zJ`M^#qA11)isIuSxa%6DPIqr`qbwrGViW||7(sNSrXp`zmWcJu=bM9 zT;&wt{{g8~b`Nv0J#jDQhFjoI*M^hj*RHYriRoU6#(;1edA`%!1pBu_eq`1TedX+- zDt3{@dC&)+mKwjyA1yO}%jLJ08h>-5US|A`SG~N{`2FftWyWv&;-)g=$2#J^GUIQ! z{IN3Q$Nc4&760z0xDeReWyO!!#QnBkyTkTsGjS94p{EyN^`qC%Kf?A4MZuKBF19On zhy3OM#k!Kz&$BGWH-Y`P5Pn)Om!coE-*{cv&3gaiBKwjf*$J4hUhjk5a44iN&Fr5U z1@65O*cAuFe2erw5cY=0UyOxaohM0(TNi=DK-deyLHUe$Ig#BBb|qJ>W{u}HRyqgy zSy|KSN3bi=rMW?4ui|!G`I~9&8y86 z&sIk&I~co2Hl}zubtR1*ja`kMmEGx{Rt0H0QsRi)Zy4<*X+!J& zUd^wBJ3D(s< ze<>1!D?UnVKOBi6Mcu{{gaPL_?|0k5^2G-`4qkn#DVL_C{)PUp4Tdar8(!F}ULWX( z&FQ|F$a9N}r&tI>Vfo@sIXf;91f|81rZ`pAVe_3!#joD01h#gbFiPu!q?wGVfS z%VeSd%m2ClpY!6s%d4Ib-MRT6;^B8~z&&;U!(IF*9h}AXy0b!gv+m@0THn9piR(1? zce1`8L-RXycfLEz6K~$_O`nt&*LCemHiEU#Yd!iseLFxm?k+vmLpS*vrSvdF>kcrW zFWybVAHX~2of~m@=jYqbUe{+s_`_P{m%_e3ZD4!izf5D&5Y+W-A_7Au_X+!8$V9g> zisOsPP+w%Ky9>j@Fz$-WzY({fPz8l4C`3Ww2?|ZjBdy^581mK{QnsWF%C<+O+$d3d zRF>*cU222c3fjaw=^$OC6J;q*K^wLTQYTJ<-uI_S(7ujJwYwiy6x6(Kwti$ zzALdmNgLV^j;p$Q5A5=NvD=_A%@a?A>(lSsXpa?_J6k^=?4|S0*mZTm;LODp&(pZ| z$kN1_l#-624ZrqWn1|(xJCoqR__`y{`tY9@2GvjYLj70hcPC~amgF20J`kMO;a<`+ z)Srp$=7~LF+<1RBt`F$3^v`hpq-z;`12?0-X=9-IpV}b3Q9jp3?6%clY^|;my;EL$ N3^8V%=)GULe*oDd7EAyD literal 0 HcmV?d00001 diff --git a/examples/password-reset/src/app/(auth)/account-member-credentials-schema.ts b/examples/password-reset/src/app/(auth)/account-member-credentials-schema.ts new file mode 100644 index 00000000..19e7a5fc --- /dev/null +++ b/examples/password-reset/src/app/(auth)/account-member-credentials-schema.ts @@ -0,0 +1,23 @@ +import { z } from "zod"; + +export const accountMemberCredentialSchema = z.object({ + account_id: z.string(), + account_name: z.string(), + expires: z.string(), + token: z.string(), + type: z.literal("account_management_authentication_token"), +}); + +export type AccountMemberCredential = z.infer< + typeof accountMemberCredentialSchema +>; + +export const accountMemberCredentialsSchema = z.object({ + accounts: z.record(z.string(), accountMemberCredentialSchema), + selected: z.string(), + accountMemberId: z.string(), +}); + +export type AccountMemberCredentials = z.infer< + typeof accountMemberCredentialsSchema +>; diff --git a/examples/password-reset/src/app/(auth)/actions.ts b/examples/password-reset/src/app/(auth)/actions.ts new file mode 100644 index 00000000..0e18f0d6 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/actions.ts @@ -0,0 +1,200 @@ +"use server"; + +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { z } from "zod"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../lib/cookie-constants"; +import { AccountTokenBase, ResourcePage } from "@elasticpath/js-sdk"; +import { ResponseCookie } from "next/dist/compiled/@edge-runtime/cookies"; +import { + AccountMemberCredential, + AccountMemberCredentials, +} from "./account-member-credentials-schema"; +import { retrieveAccountMemberCredentials } from "../../lib/retrieve-account-member-credentials"; +import { revalidatePath } from "next/cache"; +import { getErrorMessage } from "../../lib/get-error-message"; + +const loginSchema = z.object({ + email: z.string().email(), + password: z.string(), + returnUrl: z.string().optional(), +}); + +const selectedAccountSchema = z.object({ + accountId: z.string(), +}); + +const registerSchema = z.object({ + email: z.string().email(), + password: z.string(), + name: z.string(), +}); + +const PASSWORD_PROFILE_ID = process.env.NEXT_PUBLIC_PASSWORD_PROFILE_ID!; + +const loginErrorMessage = + "Failed to login, make sure your email and password are correct"; + +export async function login(props: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(props.entries()); + + const validatedProps = loginSchema.safeParse(rawEntries); + + if (!validatedProps.success) { + return { + error: loginErrorMessage, + }; + } + + const { email, password, returnUrl } = validatedProps.data; + + try { + const result = await client.AccountMembers.GenerateAccountToken({ + type: "account_management_authentication_token", + authentication_mechanism: "password", + password_profile_id: PASSWORD_PROFILE_ID, + username: email.toLowerCase(), // Known bug for uppercase usernames so we force lowercase. + password, + }); + + const cookieStore = cookies(); + cookieStore.set(createCookieFromGenerateTokenResponse(result)); + } catch (error) { + console.error(getErrorMessage(error)); + return { + error: loginErrorMessage, + }; + } + + redirect(returnUrl ?? "/"); +} + +export async function logout() { + const cookieStore = cookies(); + + cookieStore.delete(ACCOUNT_MEMBER_TOKEN_COOKIE_NAME); + + redirect("/"); +} + +export async function selectedAccount(args: FormData) { + const rawEntries = Object.fromEntries(args.entries()); + + const validatedProps = selectedAccountSchema.safeParse(rawEntries); + + if (!validatedProps.success) { + throw new Error("Invalid account id"); + } + + const { accountId } = validatedProps.data; + + const cookieStore = cookies(); + + const accountMemberCredentials = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCredentials) { + redirect("/login"); + return; + } + + const selectedAccount = accountMemberCredentials?.accounts[accountId]; + + if (!selectedAccount) { + throw new Error("Invalid account id"); + } + + cookieStore.set({ + name: ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + value: JSON.stringify({ + ...accountMemberCredentials, + selected: selectedAccount.account_id, + }), + path: "/", + sameSite: "strict", + expires: new Date( + accountMemberCredentials.accounts[ + Object.keys(accountMemberCredentials.accounts)[0] + ].expires, + ), + }); + + revalidatePath("/account"); +} + +export async function register(data: FormData) { + const client = getServerSideImplicitClient(); + + const validatedProps = registerSchema.safeParse( + Object.fromEntries(data.entries()), + ); + + if (!validatedProps.success) { + throw new Error("Invalid email or password or name"); + } + + const { email, password, name } = validatedProps.data; + + const result = await client.AccountMembers.GenerateAccountToken({ + type: "account_management_authentication_token", + authentication_mechanism: "self_signup", + password_profile_id: PASSWORD_PROFILE_ID, + username: email.toLowerCase(), // Known bug for uppercase usernames so we force lowercase. + password, + name, // TODO update sdk types as name should exist + email, + } as any); + + const cookieStore = cookies(); + cookieStore.set(createCookieFromGenerateTokenResponse(result)); + + redirect("/"); +} + +function createCookieFromGenerateTokenResponse( + response: ResourcePage, +): ResponseCookie { + const { expires } = response.data[0]; // assuming all tokens have shared expiration date/time + + const cookieValue = createAccountMemberCredentialsCookieValue( + response.data, + (response.meta as unknown as { account_member_id: string }) + .account_member_id, // TODO update sdk types + ); + + return { + name: ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + value: JSON.stringify(cookieValue), + path: "/", + sameSite: "strict", + expires: new Date(expires), + }; +} + +function createAccountMemberCredentialsCookieValue( + responseTokens: AccountTokenBase[], + accountMemberId: string, +): AccountMemberCredentials { + return { + accounts: responseTokens.reduce( + (acc, responseToken) => ({ + ...acc, + [responseToken.account_id]: { + account_id: responseToken.account_id, + account_name: responseToken.account_name, + expires: responseToken.expires, + token: responseToken.token, + type: "account_management_authentication_token" as const, + }, + }), + {} as Record, + ), + selected: responseTokens[0].account_id, + accountMemberId, + }; +} diff --git a/examples/password-reset/src/app/(auth)/forgot-password/actions.ts b/examples/password-reset/src/app/(auth)/forgot-password/actions.ts new file mode 100644 index 00000000..6914fcc4 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/forgot-password/actions.ts @@ -0,0 +1,50 @@ +"use server"; + +import { z } from "zod"; +import { getServerSideImplicitClient } from "../../../lib/epcc-server-side-implicit-client"; +import { getErrorMessage } from "../../../lib/get-error-message"; +import { OneTimePasswordTokenRequestBody } from "@elasticpath/js-sdk"; + +const requestPasswordResetSchema = z.object({ + email: z.string().email(), +}); + +const PASSWORD_PROFILE_ID = process.env.NEXT_PUBLIC_PASSWORD_PROFILE_ID!; +const AUTHENTICATION_REALM_ID = process.env.NEXT_PUBLIC_AUTHENTICATION_REALM_ID!; + +export async function requestPasswordReset(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + const validatedProps = requestPasswordResetSchema.safeParse(rawEntries); + + if (!validatedProps.success) { + return { + error: "Please enter a valid email address", + }; + } + + const { email } = validatedProps.data; + const body: OneTimePasswordTokenRequestBody = { + type: "one_time_password_token_request", + username: email.toLowerCase(), + purpose: "reset_password", + } + try { + await client.OneTimePasswordTokenRequest.Create( + AUTHENTICATION_REALM_ID, + PASSWORD_PROFILE_ID, + body, + undefined + ); + + return { + success: true, + }; + } catch (error) { + console.error(getErrorMessage(error)); + return { + error: "Failed to send reset instructions. Please try again.", + }; + } +} \ No newline at end of file diff --git a/examples/password-reset/src/app/(auth)/forgot-password/page.tsx b/examples/password-reset/src/app/(auth)/forgot-password/page.tsx new file mode 100644 index 00000000..a60aa8fe --- /dev/null +++ b/examples/password-reset/src/app/(auth)/forgot-password/page.tsx @@ -0,0 +1,54 @@ +import EpLogo from "../../../components/icons/ep-logo"; +import Link from "next/link"; +import { Label } from "../../../components/label/Label"; +import { Input } from "../../../components/input/Input"; +import { FormStatusButton } from "../../../components/button/FormStatusButton"; +import { requestPasswordReset } from "./actions"; + +export default function ForgotPassword() { + return ( +
+
+ + + +

+ Reset your password +

+
+ +
+
+
+ +
+ +
+
+ +
+ + Send reset instructions + +
+
+ +

+ Remember your password?{" "} + + Sign in + +

+
+
+ ); +} \ No newline at end of file diff --git a/examples/password-reset/src/app/(auth)/layout.tsx b/examples/password-reset/src/app/(auth)/layout.tsx new file mode 100644 index 00000000..b655a9bc --- /dev/null +++ b/examples/password-reset/src/app/(auth)/layout.tsx @@ -0,0 +1,51 @@ +import { Inter } from "next/font/google"; +import { ReactNode } from "react"; +import { getStoreInitialState } from "../../lib/get-store-initial-state"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { Providers } from "../providers"; +import clsx from "clsx"; + +const { SITE_NAME } = process.env; +const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + : "http://localhost:3000"; + +export const metadata = { + metadataBase: new URL(baseUrl), + title: { + default: SITE_NAME!, + template: `%s | ${SITE_NAME}`, + }, + robots: { + follow: true, + index: true, + }, +}; + +const inter = Inter({ + subsets: ["latin"], + display: "swap", + variable: "--font-inter", +}); + +export default async function AuthLayout({ + children, +}: { + children: ReactNode; +}) { + const client = getServerSideImplicitClient(); + const initialState = await getStoreInitialState(client); + + return ( + + + {/* headless ui needs this div - https://github.com/tailwindlabs/headlessui/issues/2752#issuecomment-1745272229 */} +
+ +
{children}
+
+
+ + + ); +} diff --git a/examples/password-reset/src/app/(auth)/login/LoginForm.tsx b/examples/password-reset/src/app/(auth)/login/LoginForm.tsx new file mode 100644 index 00000000..418e61d0 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/login/LoginForm.tsx @@ -0,0 +1,79 @@ +"use client"; + +import { login } from "../actions"; +import { Label } from "../../../components/label/Label"; +import { Input } from "../../../components/input/Input"; +import { FormStatusButton } from "../../../components/button/FormStatusButton"; +import { useState } from "react"; +import Link from "next/link"; + +export function LoginForm({ returnUrl }: { returnUrl?: string }) { + const [error, setError] = useState(undefined); + + async function loginAction(formData: FormData) { + const result = await login(formData); + + if ("error" in result) { + setError(result.error); + } + } + + return ( +
+
+ +
+ +
+
+ +
+
+ +
+ + Forgot password? + +
+
+
+ +
+
+ {returnUrl && ( + + )} + {error && ( +
+ {error} +
+ )} + +
+ Login +
+
+ ); +} diff --git a/examples/password-reset/src/app/(auth)/login/page.tsx b/examples/password-reset/src/app/(auth)/login/page.tsx new file mode 100644 index 00000000..7f814ed2 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/login/page.tsx @@ -0,0 +1,49 @@ +import EpLogo from "../../../components/icons/ep-logo"; +import { cookies } from "next/headers"; +import { isAccountMemberAuthenticated } from "../../../lib/is-account-member-authenticated"; +import { redirect } from "next/navigation"; +import Link from "next/link"; +import { LoginForm } from "./LoginForm"; + +export default function Login({ + searchParams, +}: { + searchParams: { returnUrl?: string }; +}) { + const { returnUrl } = searchParams; + + const cookieStore = cookies(); + + if (isAccountMemberAuthenticated(cookieStore)) { + redirect("/account/summary"); + } + + return ( + <> +
+
+ + + +

+ Sign in to your account +

+
+ +
+ + +

+ Not a member?{" "} + + Register now! + +

+
+
+ + ); +} diff --git a/examples/password-reset/src/app/(auth)/not-found.tsx b/examples/password-reset/src/app/(auth)/not-found.tsx new file mode 100644 index 00000000..d97d88f4 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/not-found.tsx @@ -0,0 +1,13 @@ +import Link from "next/link"; +export default function NotFound() { + return ( +
+ + 404 - The page could not be found. + + + Back to home + +
+ ); +} diff --git a/examples/password-reset/src/app/(auth)/register/page.tsx b/examples/password-reset/src/app/(auth)/register/page.tsx new file mode 100644 index 00000000..125ad4e6 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/register/page.tsx @@ -0,0 +1,97 @@ +import { register } from "../actions"; +import EpLogo from "../../../components/icons/ep-logo"; +import { cookies } from "next/headers"; +import { isAccountMemberAuthenticated } from "../../../lib/is-account-member-authenticated"; +import { redirect } from "next/navigation"; +import Link from "next/link"; +import { Label } from "../../../components/label/Label"; +import { Input } from "../../../components/input/Input"; +import { FormStatusButton } from "../../../components/button/FormStatusButton"; + +export default function Register() { + const cookieStore = cookies(); + if (isAccountMemberAuthenticated(cookieStore)) { + redirect("/account/summary"); + } + + return ( + <> +
+
+ + + +

+ Register for an account +

+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+ Register +
+
+ +

+ Already a member?{" "} + + Login now! + +

+
+
+ + ); +} diff --git a/examples/password-reset/src/app/(auth)/reset-password/actions.ts b/examples/password-reset/src/app/(auth)/reset-password/actions.ts new file mode 100644 index 00000000..ca041ce8 --- /dev/null +++ b/examples/password-reset/src/app/(auth)/reset-password/actions.ts @@ -0,0 +1,75 @@ +"use server"; + +import { z } from "zod"; +import { getServerSideImplicitClient } from "../../../lib/epcc-server-side-implicit-client"; +import { redirect } from "next/navigation"; +import { getErrorMessage } from "../../../lib/get-error-message"; +import { AccountManagementAuthenticationTokenBody } from "@elasticpath/js-sdk"; + +const resetPasswordSchema = z.object({ + token: z.string(), + email: z.string().email(), + password_profile_id: z.string(), + user_authentication_info_id: z.string(), + user_authentication_password_profile_info_id: z.string(), + newPassword: z.string(), + confirmPassword: z.string(), +}).refine((data) => data.newPassword === data.confirmPassword, { + message: "Passwords don't match", + path: ["confirmPassword"], +}); + +const AUTHENTICATION_REALM_ID = process.env.NEXT_PUBLIC_AUTHENTICATION_REALM_ID!; +const PASSWORD_PROFILE_ID = process.env.NEXT_PUBLIC_PASSWORD_PROFILE_ID!; +export async function resetPassword(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + const validatedProps = resetPasswordSchema.safeParse(rawEntries); + + if (!validatedProps.success) { + return { + error: validatedProps.error.errors[0].message, + }; + } + + const { token, email, password_profile_id, newPassword, user_authentication_info_id, user_authentication_password_profile_info_id } = validatedProps.data; + + + try { + // First get the authentication token using the one-time password token + const body: AccountManagementAuthenticationTokenBody = { + type: "account_management_authentication_token", + authentication_mechanism: "passwordless", + password_profile_id: password_profile_id, + username: email, + one_time_password_token: token, + }; + const accMgmtTokenResponse = await client.AccountMembers.GenerateAccountToken(body); + + const bodyUpdate: any = { //UserAuthenticationPasswordProfileUpdateBody + type: "user_authentication_password_profile_info", + id: user_authentication_password_profile_info_id, + // password_profile_id: password_profile_id, + username: email, + password: newPassword + } + // Now update the password + await client.UserAuthenticationPasswordProfile.Update( + AUTHENTICATION_REALM_ID, + user_authentication_info_id, + user_authentication_password_profile_info_id, + { + data: bodyUpdate + }, + accMgmtTokenResponse.data[0].token, + undefined + ); + + redirect("/login?message=Password+reset+successful"); + } catch (error) { + console.log("error", error); + console.error(getErrorMessage(error)); + redirect("/login?message=Failed+to+reset+password.+Please+try+again."); + } +} diff --git a/examples/password-reset/src/app/(auth)/reset-password/page.tsx b/examples/password-reset/src/app/(auth)/reset-password/page.tsx new file mode 100644 index 00000000..377e759a --- /dev/null +++ b/examples/password-reset/src/app/(auth)/reset-password/page.tsx @@ -0,0 +1,90 @@ +import EpLogo from "../../../components/icons/ep-logo"; +import Link from "next/link"; +import { Label } from "../../../components/label/Label"; +import { Input } from "../../../components/input/Input"; +import { FormStatusButton } from "../../../components/button/FormStatusButton"; +import { resetPassword } from "./actions"; + +export default function ResetPassword({ + searchParams, +}: { + searchParams: { + token?: string; + email?: string; + password_profile_id?: string; + user_authentication_info_id?: string; + user_authentication_password_profile_info_id?: string; + }; +}) { + const { token, email, password_profile_id, user_authentication_info_id, user_authentication_password_profile_info_id } = searchParams; + + if (!token || !email || !password_profile_id) { + return ( +
+
+

Missing required parameters

+

+ + Request a new password reset + +

+
+
+ ); + } + + return ( +
+
+ + + +

+ Set new password +

+
+ +
+
+ + + + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + Reset password + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/examples/password-reset/src/app/(checkout)/checkout/AccountCheckout.tsx b/examples/password-reset/src/app/(checkout)/checkout/AccountCheckout.tsx new file mode 100644 index 00000000..e85d1651 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/AccountCheckout.tsx @@ -0,0 +1,52 @@ +import Link from "next/link"; +import EpIcon from "../../../components/icons/ep-icon"; +import { Separator } from "../../../components/separator/Separator"; +import { DeliveryForm } from "./DeliveryForm"; +import { PaymentForm } from "./PaymentForm"; +import { BillingForm } from "./BillingForm"; +import { SubmitCheckoutButton } from "./SubmitCheckoutButton"; +import { CheckoutSidebar } from "./CheckoutSidebar"; +import { AccountDisplay } from "./AccountDisplay"; +import { ShippingSelector } from "./ShippingSelector"; + +export function AccountCheckout() { + return ( +
+
+ + + +
+
+
+
+ + + +
+ +
+ Your Info + +
+
+ Shipping address + +
+ + +
+ +
+
+ +
+
+
+ {/* Sidebar */} + +
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/AccountDisplay.tsx b/examples/password-reset/src/app/(checkout)/checkout/AccountDisplay.tsx new file mode 100644 index 00000000..47f400f4 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/AccountDisplay.tsx @@ -0,0 +1,82 @@ +"use client"; + +import { useAuthedAccountMember } from "@elasticpath/react-shopper-hooks"; +import { Button } from "../../../components/button/Button"; +import { FormControl, FormField } from "../../../components/form/Form"; +import { Input } from "../../../components/input/Input"; +import React, { useEffect, useTransition } from "react"; +import { useFormContext } from "react-hook-form"; +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { logout } from "../../(auth)/actions"; +import { Skeleton } from "../../../components/skeleton/Skeleton"; + +export function AccountDisplay() { + const { data: accountMember } = useAuthedAccountMember(); + + const { control, setValue } = useFormContext(); + + const [isPending, startTransition] = useTransition(); + + useEffect(() => { + if (accountMember?.email && accountMember?.name) { + setValue("account", { + email: accountMember.email, + name: accountMember.name, + }); + } + }, [accountMember, setValue]); + + return ( +
+
+ {accountMember ? ( + <> + {accountMember?.name} + {accountMember?.email} + + ) : ( +
+ + +
+ )} +
+ + {accountMember && ( + <> + ( + + + + )} + /> + ( + + + + )} + /> + + )} +
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/BillingForm.tsx b/examples/password-reset/src/app/(checkout)/checkout/BillingForm.tsx new file mode 100644 index 00000000..0804c54c --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/BillingForm.tsx @@ -0,0 +1,233 @@ +"use client"; + +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { Checkbox } from "../../../components/Checkbox"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../../components/form/Form"; +import { useFormContext, useWatch } from "react-hook-form"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../../components/select/Select"; +import { Input } from "../../../components/input/Input"; +import React, { useEffect } from "react"; +import { useCountries } from "../../../hooks/use-countries"; + +export function BillingForm() { + const { control, resetField } = useFormContext(); + const { data: countries } = useCountries(); + const isSameAsShipping = useWatch({ control, name: "sameAsShipping" }); + + useEffect(() => { + // Reset the billing address fields when the user selects the same as shipping address + if (isSameAsShipping) { + resetField("billingAddress", { + keepDirty: false, + keepTouched: false, + keepError: false, + }); + } + }, [isSameAsShipping, resetField]); + + return ( +
+
+ Billing address +
+
+ ( + + + + +
+ Same as shipping address +
+
+ )} + /> +
+ {!isSameAsShipping && ( +
+ ( + + Country + + + + )} + /> +
+ ( + + First Name + + + + + + )} + /> + ( + + Last Name + + + + + + )} + /> +
+ ( + + Company (optional) + + + + + + )} + /> + ( + + Address + + + + + + )} + /> +
+ ( + + City + + + + + + )} + /> + ( + + Region + + + + + + )} + /> + ( + + Postcode + + + + + + )} + /> +
+
+ )} +
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/CheckoutFooter.tsx b/examples/password-reset/src/app/(checkout)/checkout/CheckoutFooter.tsx new file mode 100644 index 00000000..9882b3a1 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/CheckoutFooter.tsx @@ -0,0 +1,30 @@ +import { Separator } from "../../../components/separator/Separator"; +import Link from "next/link"; +import EpLogo from "../../../components/icons/ep-logo"; +import * as React from "react"; + +export function CheckoutFooter() { + return ( +
+ +
+ + Refund Policy + + + Shipping Policy + + + Privacy Policy + + + Terms of Service + +
+
+ Powered by + +
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/CheckoutSidebar.tsx b/examples/password-reset/src/app/(checkout)/checkout/CheckoutSidebar.tsx new file mode 100644 index 00000000..d3e3f4ea --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/CheckoutSidebar.tsx @@ -0,0 +1,103 @@ +"use client"; +import { Separator } from "../../../components/separator/Separator"; +import { CartDiscounts } from "../../../components/cart/CartDiscounts"; +import * as React from "react"; +import { useCart, useCurrencies } from "@elasticpath/react-shopper-hooks"; +import { + ItemSidebarHideable, + ItemSidebarItems, + ItemSidebarPromotions, + ItemSidebarTotals, + ItemSidebarTotalsDiscount, + ItemSidebarTotalsSubTotal, + ItemSidebarTotalsTax, + resolveTotalInclShipping, +} from "../../../components/checkout-sidebar/ItemSidebar"; +import { staticDeliveryMethods } from "./useShippingMethod"; +import { cn } from "../../../lib/cn"; +import { useWatch } from "react-hook-form"; +import { EP_CURRENCY_CODE } from "../../../lib/resolve-ep-currency-code"; +import { formatCurrency } from "../../../lib/format-currency"; +import { LoadingDots } from "../../../components/LoadingDots"; + +export function CheckoutSidebar() { + const { data } = useCart(); + const state = data?.state; + const shippingMethod = useWatch({ name: "shippingMethod" }); + + const { data: currencyData } = useCurrencies(); + + const storeCurrency = currencyData?.find( + (currency) => currency.code === EP_CURRENCY_CODE, + ); + + if (!state) { + return null; + } + + const shippingAmount = staticDeliveryMethods.find( + (method) => method.value === shippingMethod, + )?.amount; + + const { meta, __extended } = state; + + const formattedTotalAmountInclShipping = + meta?.display_price?.with_tax?.amount !== undefined && + shippingAmount !== undefined && + storeCurrency + ? resolveTotalInclShipping( + shippingAmount, + meta.display_price.with_tax.amount, + storeCurrency, + ) + : undefined; + + return ( + +
+ + + + + {/* Totals */} + + +
+ Shipping + + {shippingAmount === undefined ? ( + "Select delivery method" + ) : storeCurrency ? ( + formatCurrency(shippingAmount, storeCurrency) + ) : ( + + )} + +
+ + +
+ + {/* Sum total incl shipping */} + {formattedTotalAmountInclShipping ? ( +
+ Total +
+ {meta?.display_price?.with_tax?.currency} + + {formattedTotalAmountInclShipping} + +
+
+ ) : ( + + )} +
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/CheckoutViews.tsx b/examples/password-reset/src/app/(checkout)/checkout/CheckoutViews.tsx new file mode 100644 index 00000000..d88c5115 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/CheckoutViews.tsx @@ -0,0 +1,15 @@ +"use client"; + +import { useCheckout } from "./checkout-provider"; +import { ReactNode } from "react"; +import { OrderConfirmation } from "./OrderConfirmation"; + +export function CheckoutViews({ children }: { children: ReactNode }) { + const { confirmationData } = useCheckout(); + + if (confirmationData) { + return ; + } + + return children; +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/ConfirmationSidebar.tsx b/examples/password-reset/src/app/(checkout)/checkout/ConfirmationSidebar.tsx new file mode 100644 index 00000000..708d1549 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/ConfirmationSidebar.tsx @@ -0,0 +1,108 @@ +"use client"; +import { Separator } from "../../../components/separator/Separator"; +import { CartDiscountsReadOnly } from "../../../components/cart/CartDiscounts"; +import * as React from "react"; +import { + groupCartItems, + useCurrencies, +} from "@elasticpath/react-shopper-hooks"; +import { + ItemSidebarHideable, + ItemSidebarItems, + ItemSidebarTotals, + ItemSidebarTotalsDiscount, + ItemSidebarTotalsSubTotal, + ItemSidebarTotalsTax, + resolveTotalInclShipping, +} from "../../../components/checkout-sidebar/ItemSidebar"; +import { useCheckout } from "./checkout-provider"; +import { staticDeliveryMethods } from "./useShippingMethod"; +import { EP_CURRENCY_CODE } from "../../../lib/resolve-ep-currency-code"; +import { LoadingDots } from "../../../components/LoadingDots"; + +export function ConfirmationSidebar() { + const { confirmationData } = useCheckout(); + + const { data: currencyData } = useCurrencies(); + + if (!confirmationData) { + return null; + } + + const { order, cart } = confirmationData; + + const groupedItems = groupCartItems(cart.data); + + const shippingMethodCustomItem = groupedItems.custom.find((item) => + item.sku.startsWith("__shipping_"), + ); + + const meta = { + display_price: order.data.meta.display_price, + }; + + const shippingAmount = staticDeliveryMethods.find( + (method) => + !!shippingMethodCustomItem && + method.value === shippingMethodCustomItem.sku, + )?.amount; + + const storeCurrency = currencyData?.find( + (currency) => currency.code === EP_CURRENCY_CODE, + ); + + const formattedTotalAmountInclShipping = + meta?.display_price?.with_tax?.amount !== undefined && + shippingAmount !== undefined && + storeCurrency + ? resolveTotalInclShipping( + shippingAmount, + meta.display_price.with_tax.amount, + storeCurrency, + ) + : undefined; + + return ( + +
+
+ +
+ Discounts applied + + {/* Totals */} + + + {shippingMethodCustomItem && ( +
+ Shipping + + { + shippingMethodCustomItem.meta.display_price.with_tax.value + .formatted + } + +
+ )} + + +
+ + {/* Sum total incl shipping */} + {formattedTotalAmountInclShipping ? ( +
+ Total +
+ {meta?.display_price?.with_tax?.currency} + + {formattedTotalAmountInclShipping} + +
+
+ ) : ( + + )} +
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/DeliveryForm.tsx b/examples/password-reset/src/app/(checkout)/checkout/DeliveryForm.tsx new file mode 100644 index 00000000..baa58998 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/DeliveryForm.tsx @@ -0,0 +1,108 @@ +"use client"; +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { + RadioGroup, + RadioGroupItem, +} from "../../../components/radio-group/RadioGroup"; +import { Label } from "../../../components/label/Label"; +import { cn } from "../../../lib/cn"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../../components/form/Form"; +import { useFormContext } from "react-hook-form"; +import { useShippingMethod } from "./useShippingMethod"; +import { LightBulbIcon } from "@heroicons/react/24/outline"; +import { + Alert, + AlertDescription, + AlertTitle, +} from "../../../components/alert/Alert"; +import { Skeleton } from "../../../components/skeleton/Skeleton"; + +export function DeliveryForm() { + const { control } = useFormContext(); + const { data: deliveryOptions } = useShippingMethod(); + + return ( +
+
+ Delivery +
+ + + Delivery is using fixed rates! + +

+ Delivery is fixed rate data for testing. You can replace this with a + 3rd party service. +

+
+
+ {!deliveryOptions ? ( +
+ + +
+ ) : ( + ( + + Shipping Method + + + {deliveryOptions.map((option, optionIndex) => { + return ( +
+
+ + +
+ {option.formatted} +
+ ); + })} +
+
+ +
+ )} + /> + )} +
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/FormInput.tsx b/examples/password-reset/src/app/(checkout)/checkout/FormInput.tsx new file mode 100644 index 00000000..c50a2606 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/FormInput.tsx @@ -0,0 +1,73 @@ +import { ErrorMessage } from "@hookform/error-message"; +import React, { forwardRef, useImperativeHandle, useRef } from "react"; +import { get } from "react-hook-form"; +import { Label } from "../../../components/label/Label"; +import { Input } from "../../../components/input/Input"; +import { cn } from "../../../lib/cn"; + +type InputProps = Omit< + Omit, "size">, + "placeholder" +> & { + label: string; + errors?: Record; + touched?: Record; + name: string; +}; + +export const FormInput = forwardRef( + ({ type, name, label, errors, touched, required, ...props }, ref) => { + const inputRef = useRef(null); + + useImperativeHandle(ref, () => inputRef.current!); + + const hasError = get(errors, name) && get(touched, name); + + return ( +
+
+
+

+ + +

+
+
+ {hasError && ( + { + return ( +
+ {message} +
+ ); + }} + /> + )} +
+ ); + }, +); + +FormInput.displayName = "FormInput"; diff --git a/examples/password-reset/src/app/(checkout)/checkout/GuestCheckout.tsx b/examples/password-reset/src/app/(checkout)/checkout/GuestCheckout.tsx new file mode 100644 index 00000000..8fcb4655 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/GuestCheckout.tsx @@ -0,0 +1,51 @@ +import { GuestInformation } from "./GuestInformation"; +import { ShippingForm } from "./ShippingForm"; +import Link from "next/link"; +import EpIcon from "../../../components/icons/ep-icon"; +import { DeliveryForm } from "./DeliveryForm"; +import { PaymentForm } from "./PaymentForm"; +import { BillingForm } from "./BillingForm"; +import { SubmitCheckoutButton } from "./SubmitCheckoutButton"; +import { Separator } from "../../../components/separator/Separator"; +import * as React from "react"; +import { CheckoutSidebar } from "./CheckoutSidebar"; + +export async function GuestCheckout() { + return ( +
+
+ + + +
+
+
+
+ + + +
+ +
+ +
+
+ +
+ + +
+ +
+
+ +
+
+
+ {/* Sidebar */} + +
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/GuestInformation.tsx b/examples/password-reset/src/app/(checkout)/checkout/GuestInformation.tsx new file mode 100644 index 00000000..fa22e559 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/GuestInformation.tsx @@ -0,0 +1,56 @@ +"use client"; + +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../../components/form/Form"; +import { Input } from "../../../components/input/Input"; +import React from "react"; +import { useFormContext } from "react-hook-form"; + +export function GuestInformation() { + const pathname = usePathname(); + + const { control } = useFormContext(); + + return ( +
+
+ Your Info + + Already a customer?{" "} + + Sign in + + +
+ ( + + Email + + + + + + )} + /> +
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/OrderConfirmation.tsx b/examples/password-reset/src/app/(checkout)/checkout/OrderConfirmation.tsx new file mode 100644 index 00000000..0391da30 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/OrderConfirmation.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { useCheckout } from "./checkout-provider"; +import { ConfirmationSidebar } from "./ConfirmationSidebar"; +import Link from "next/link"; +import EpIcon from "../../../components/icons/ep-icon"; +import * as React from "react"; +import { Separator } from "../../../components/separator/Separator"; +import { CheckoutFooter } from "./CheckoutFooter"; +import { Button } from "../../../components/button/Button"; + +export function OrderConfirmation() { + const { confirmationData } = useCheckout(); + + if (!confirmationData) { + return null; + } + + const { order } = confirmationData; + + const customerName = ( + order.data.contact?.name ?? + order.data.customer.name ?? + "" + ).split(" ")[0]; + + const { shipping_address, id: orderId } = order.data; + + return ( +
+
+ + + +
+
+ {/* Confirmation Content */} +
+
+ + + +
+ + + Thanks{customerName ? ` ${customerName}` : ""}! + +
+ +
+ + Order #{orderId} is confirmed. + + {/* Shipping */} +
+

Ship to

+
+ {`${shipping_address.first_name} ${shipping_address.last_name}`} +

{shipping_address.line_1}

+ {`${shipping_address.region}, ${shipping_address.postcode}`} + {shipping_address.phone_number && ( + {shipping_address.phone_number} + )} +
+
+ {/* Delivery Method */} +
+

Delivery Method

+

placeholder

+
+ {/* Contact us */} +
+

Need to make changes?

+

+ Email us or call. Remember to reference order #{orderId} +

+
+ +
+ {/* Confirmation Sidebar */} +
+
+ {`Order #${orderId}`} + + +
+
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/PaymentForm.tsx b/examples/password-reset/src/app/(checkout)/checkout/PaymentForm.tsx new file mode 100644 index 00000000..ad609d01 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/PaymentForm.tsx @@ -0,0 +1,30 @@ +"use client"; +import { LightBulbIcon } from "@heroicons/react/24/outline"; +import { + Alert, + AlertDescription, + AlertTitle, +} from "../../../components/alert/Alert"; + +export function PaymentForm() { + return ( +
+
+ Payment +
+ + + Payments set to manual! + +

+ Manual payments are enabled. To test the checkout flow, configure an + alternate payment gateway to take real payments. +

+

+ To checkout with manual payments you can just complete the order. +

+
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/ShippingForm.tsx b/examples/password-reset/src/app/(checkout)/checkout/ShippingForm.tsx new file mode 100644 index 00000000..5f9ab548 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/ShippingForm.tsx @@ -0,0 +1,217 @@ +"use client"; + +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { useFormContext } from "react-hook-form"; +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "../../../components/form/Form"; +import { Input } from "../../../components/input/Input"; +import React from "react"; +import { useCountries } from "../../../hooks/use-countries"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../../components/select/Select"; + +export function ShippingForm() { + const { control } = useFormContext(); + const { data: countries } = useCountries(); + + return ( +
+
+ Shipping address +
+
+ ( + + Country + + + + )} + /> +
+ ( + + First Name + + + + + + )} + /> + ( + + Last Name + + + + + + )} + /> +
+ ( + + Company (optional) + + + + + + )} + /> + ( + + Address + + + + + + )} + /> +
+ ( + + City + + + + + + )} + /> + ( + + Region + + + + + + )} + /> + ( + + Postcode + + + + + + )} + /> +
+ ( + + Phone Number (optional) + + + + + + )} + /> +
+
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/ShippingSelector.tsx b/examples/password-reset/src/app/(checkout)/checkout/ShippingSelector.tsx new file mode 100644 index 00000000..91f29d50 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/ShippingSelector.tsx @@ -0,0 +1,99 @@ +"use client"; +import { + useAccountAddresses, + useAuthedAccountMember, +} from "@elasticpath/react-shopper-hooks"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../../components/select/Select"; +import { useFormContext, useWatch } from "react-hook-form"; +import { CheckoutForm as CheckoutFormSchemaType } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { AccountAddress } from "@elasticpath/js-sdk"; +import { useEffect } from "react"; +import { Skeleton } from "../../../components/skeleton/Skeleton"; +import { Button } from "../../../components/button/Button"; +import Link from "next/link"; + +export function ShippingSelector() { + const { selectedAccountToken } = useAuthedAccountMember(); + + const { data: accountAddressData } = useAccountAddresses( + selectedAccountToken?.account_id!, + { + ep: { accountMemberToken: selectedAccountToken?.token }, + enabled: !!selectedAccountToken, + }, + ); + + const { setValue } = useFormContext(); + + function updateAddress(addressId: string, addresses: AccountAddress[]) { + const address = addresses.find((address) => address.id === addressId); + + if (address) { + setValue("shippingAddress", { + postcode: address.postcode, + line_1: address.line_1, + line_2: address.line_2, + city: address.city, + county: address.county, + country: address.country, + company_name: address.company_name, + first_name: address.first_name, + last_name: address.last_name, + phone_number: address.phone_number, + instructions: address.instructions, + region: address.region, + }); + } + } + + useEffect(() => { + if (accountAddressData && accountAddressData[0]) { + updateAddress(accountAddressData[0].id, accountAddressData); + } + }, [accountAddressData]); + + return ( +
+ {accountAddressData ? ( + + ) : ( + + )} +
+ ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/SubmitCheckoutButton.tsx b/examples/password-reset/src/app/(checkout)/checkout/SubmitCheckoutButton.tsx new file mode 100644 index 00000000..d67880df --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/SubmitCheckoutButton.tsx @@ -0,0 +1,29 @@ +"use client"; + +import { useCheckout } from "./checkout-provider"; +import { useCart } from "@elasticpath/react-shopper-hooks"; +import { StatusButton } from "../../../components/button/StatusButton"; + +export function SubmitCheckoutButton() { + const { handleSubmit, completePayment, isCompleting } = useCheckout(); + const { data } = useCart(); + + const state = data?.state; + + if (!state) { + return null; + } + + return ( + { + completePayment.mutate({ data: values }); + })} + > + {`Pay ${state.meta?.display_price?.with_tax?.formatted}`} + + ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/checkout-provider.tsx b/examples/password-reset/src/app/(checkout)/checkout/checkout-provider.tsx new file mode 100644 index 00000000..b9aa8216 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/checkout-provider.tsx @@ -0,0 +1,103 @@ +"use client"; + +import React, { createContext, useContext, useState } from "react"; +import { useForm, useFormContext } from "react-hook-form"; +import { + CheckoutForm, + checkoutFormSchema, +} from "../../../components/checkout/form-schema/checkout-form-schema"; +import { + CartState, + useAuthedAccountMember, + useCart, + useCartClear, +} from "@elasticpath/react-shopper-hooks"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { Form } from "../../../components/form/Form"; +import { ShippingMethod, useShippingMethod } from "./useShippingMethod"; +import { usePaymentComplete } from "./usePaymentComplete"; + +type CheckoutContext = { + cart?: CartState; + isLoading: boolean; + completePayment: ReturnType; + isCompleting: boolean; + confirmationData: ReturnType["data"]; + shippingMethods: { + options?: ShippingMethod[]; + isLoading: boolean; + }; +}; + +const CheckoutContext = createContext(null); + +type CheckoutProviderProps = { + children?: React.ReactNode; +}; + +export function CheckoutProvider({ children }: CheckoutProviderProps) { + const { data } = useCart(); + + const state = data?.state; + + const { mutateAsync: mutateClearCart } = useCartClear(); + + const [confirmationData, setConfirmationData] = + useState["data"]>(undefined); + + const formMethods = useForm({ + reValidateMode: "onChange", + resolver: zodResolver(checkoutFormSchema), + defaultValues: { + sameAsShipping: true, + shippingMethod: "__shipping_standard", + }, + }); + + const { selectedAccountToken } = useAuthedAccountMember(); + + const { data: shippingMethods, isLoading: isShippingMethodsLoading } = + useShippingMethod(); + + const paymentComplete = usePaymentComplete( + { + cartId: state?.id, + accountToken: selectedAccountToken?.token, + }, + { + onSuccess: async (data) => { + setConfirmationData(data); + await mutateClearCart(); + }, + }, + ); + + return ( +
+ + {children} + +
+ ); +} + +export const useCheckout = () => { + const context = useContext(CheckoutContext); + const form = useFormContext(); + if (context === null) { + throw new Error("useCheckout must be used within a CheckoutProvider"); + } + return { ...context, ...form }; +}; diff --git a/examples/password-reset/src/app/(checkout)/checkout/page.tsx b/examples/password-reset/src/app/(checkout)/checkout/page.tsx new file mode 100644 index 00000000..df42df74 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/page.tsx @@ -0,0 +1,44 @@ +import { Metadata } from "next"; +import { AccountCheckout } from "./AccountCheckout"; +import { retrieveAccountMemberCredentials } from "../../../lib/retrieve-account-member-credentials"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../lib/cookie-constants"; +import { GuestCheckout } from "./GuestCheckout"; +import { cookies } from "next/headers"; +import { notFound, redirect } from "next/navigation"; +import { COOKIE_PREFIX_KEY } from "../../../lib/resolve-cart-env"; +import { getEpccImplicitClient } from "../../../lib/epcc-implicit-client"; +import { CheckoutProvider } from "./checkout-provider"; +import { CheckoutViews } from "./CheckoutViews"; + +export const metadata: Metadata = { + title: "Checkout", +}; +export default async function CheckoutPage() { + const cookieStore = cookies(); + + const cartCookie = cookieStore.get(`${COOKIE_PREFIX_KEY}_ep_cart`); + const client = getEpccImplicitClient(); + + const cart = await client.Cart(cartCookie?.value).With("items").Get(); + + if (!cart) { + notFound(); + } + + if ((cart.included?.items?.length ?? 0) < 1) { + redirect("/cart"); + } + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + return ( + + + {!accountMemberCookie ? : } + + + ); +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/usePaymentComplete.tsx b/examples/password-reset/src/app/(checkout)/checkout/usePaymentComplete.tsx new file mode 100644 index 00000000..78123154 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/usePaymentComplete.tsx @@ -0,0 +1,129 @@ +import { + useAddCustomItemToCart, + useCheckout as useCheckoutCart, + useCheckoutWithAccount, + usePayments, +} from "@elasticpath/react-shopper-hooks"; +import { useMutation, UseMutationOptions } from "@tanstack/react-query"; +import { CheckoutForm } from "../../../components/checkout/form-schema/checkout-form-schema"; +import { staticDeliveryMethods } from "./useShippingMethod"; +import { + CartItemsResponse, + ConfirmPaymentResponse, + Order, + Resource, +} from "@elasticpath/js-sdk"; + +export type UsePaymentCompleteProps = { + cartId: string | undefined; + accountToken?: string; +}; + +export type UsePaymentCompleteReq = { + data: CheckoutForm; +}; + +export function usePaymentComplete( + { cartId, accountToken }: UsePaymentCompleteProps, + options?: UseMutationOptions< + { + order: Resource; + payment: ConfirmPaymentResponse; + cart: CartItemsResponse; + }, + unknown, + UsePaymentCompleteReq + >, +) { + const { mutateAsync: mutatePayment } = usePayments(); + const { mutateAsync: mutateConvertToOrder } = useCheckoutCart(cartId ?? ""); + const { mutateAsync: mutateConvertToOrderAsAccount } = useCheckoutWithAccount( + cartId ?? "", + ); + const { mutateAsync: mutateAddCustomItemToCart } = useAddCustomItemToCart( + cartId ?? "", + ); + + const paymentComplete = useMutation({ + mutationFn: async ({ data }) => { + const { + shippingAddress, + billingAddress, + sameAsShipping, + shippingMethod, + } = data; + + const customerName = `${shippingAddress.first_name} ${shippingAddress.last_name}`; + + const checkoutProps = { + billingAddress: + billingAddress && !sameAsShipping ? billingAddress : shippingAddress, + shippingAddress: shippingAddress, + }; + + /** + * The handling of shipping options is not production ready. + * You must implement your own based on your business needs. + */ + const shippingAmount = + staticDeliveryMethods.find((method) => method.value === shippingMethod) + ?.amount ?? 0; + + /** + * Using a cart custom_item to represent shipping for demo purposes. + */ + const cartInclShipping = await mutateAddCustomItemToCart({ + type: "custom_item", + name: "Shipping", + sku: shippingMethod, + quantity: 1, + price: { + amount: shippingAmount, + includes_tax: true, + }, + }); + + /** + * 1. Convert our cart to an order we can pay + */ + const createdOrder = await ("guest" in data + ? mutateConvertToOrder({ + customer: { + email: data.guest.email, + name: customerName, + }, + ...checkoutProps, + }) + : mutateConvertToOrderAsAccount({ + contact: { + name: data.account.name, + email: data.account.email, + }, + token: accountToken ?? "", + ...checkoutProps, + })); + + /** + * 2. Perform payment against the order + */ + const confirmedPayment = await mutatePayment({ + orderId: createdOrder.data.id, + payment: { + gateway: "manual", + method: "purchase", + }, + }); + + return { + order: createdOrder, + payment: confirmedPayment, + cart: cartInclShipping, + }; + }, + ...options, + }); + + return { + ...paymentComplete, + }; +} diff --git a/examples/password-reset/src/app/(checkout)/checkout/useShippingMethod.tsx b/examples/password-reset/src/app/(checkout)/checkout/useShippingMethod.tsx new file mode 100644 index 00000000..9703ec2b --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/checkout/useShippingMethod.tsx @@ -0,0 +1,39 @@ +import { useQuery } from "@tanstack/react-query"; + +export type ShippingMethod = { + label: string; + value: string; + amount: number; + formatted: string; +}; + +export const staticDeliveryMethods: ShippingMethod[] = [ + { + label: "Standard", + value: "__shipping_standard", + amount: 0, + formatted: "Free", + }, + { + label: "Express", + value: "__shipping_express", + amount: 1200, + formatted: "$12.00", + }, +]; + +export function useShippingMethod() { + const deliveryMethods = useQuery({ + queryKey: ["delivery-methods"], + queryFn: () => { + /** + * Replace these with your own delivery methods. You can also fetch them from the API. + */ + return staticDeliveryMethods; + }, + }); + + return { + ...deliveryMethods, + }; +} diff --git a/examples/password-reset/src/app/(checkout)/layout.tsx b/examples/password-reset/src/app/(checkout)/layout.tsx new file mode 100644 index 00000000..16f80170 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/layout.tsx @@ -0,0 +1,51 @@ +import { Inter } from "next/font/google"; +import { ReactNode } from "react"; +import { getStoreInitialState } from "../../lib/get-store-initial-state"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { Providers } from "../providers"; +import clsx from "clsx"; + +const { SITE_NAME } = process.env; +const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + : "http://localhost:3000"; + +export const metadata = { + metadataBase: new URL(baseUrl), + title: { + default: SITE_NAME!, + template: `%s | ${SITE_NAME}`, + }, + robots: { + follow: true, + index: true, + }, +}; + +const inter = Inter({ + subsets: ["latin"], + display: "swap", + variable: "--font-inter", +}); + +export default async function CheckoutLayout({ + children, +}: { + children: ReactNode; +}) { + const client = getServerSideImplicitClient(); + const initialState = await getStoreInitialState(client); + + return ( + + + {/* headless ui needs this div - https://github.com/tailwindlabs/headlessui/issues/2752#issuecomment-1745272229 */} +
+ +
{children}
+
+
+ + + ); +} diff --git a/examples/password-reset/src/app/(checkout)/not-found.tsx b/examples/password-reset/src/app/(checkout)/not-found.tsx new file mode 100644 index 00000000..d97d88f4 --- /dev/null +++ b/examples/password-reset/src/app/(checkout)/not-found.tsx @@ -0,0 +1,13 @@ +import Link from "next/link"; +export default function NotFound() { + return ( +
+ + 404 - The page could not be found. + + + Back to home + +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/about/page.tsx b/examples/password-reset/src/app/(store)/about/page.tsx new file mode 100644 index 00000000..fc900ed0 --- /dev/null +++ b/examples/password-reset/src/app/(store)/about/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../../components/shared/blurb"; + +export default function About() { + return ; +} diff --git a/examples/password-reset/src/app/(store)/account/AccountNavigation.tsx b/examples/password-reset/src/app/(store)/account/AccountNavigation.tsx new file mode 100644 index 00000000..f3474312 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/AccountNavigation.tsx @@ -0,0 +1,54 @@ +"use client"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { Button } from "../../../components/button/Button"; +import { logout } from "../../(auth)/actions"; +import { useTransition } from "react"; + +export function AccountNavigation() { + const pathname = usePathname(); + const [isPending, startTransition] = useTransition(); + + return ( + + ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/DeleteAddressBtn.tsx b/examples/password-reset/src/app/(store)/account/addresses/DeleteAddressBtn.tsx new file mode 100644 index 00000000..2230af9d --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/DeleteAddressBtn.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { deleteAddress } from "./actions"; +import { FormStatusButton } from "../../../../components/button/FormStatusButton"; +import { TrashIcon } from "@heroicons/react/24/outline"; +import React from "react"; +import { useQueryClient } from "@tanstack/react-query"; +import { + accountAddressesQueryKeys, + useAuthedAccountMember, +} from "@elasticpath/react-shopper-hooks"; + +export function DeleteAddressBtn({ addressId }: { addressId: string }) { + const queryClient = useQueryClient(); + const { selectedAccountToken } = useAuthedAccountMember(); + + return ( +
{ + await deleteAddress(formData); + await queryClient.invalidateQueries({ + queryKey: [ + ...accountAddressesQueryKeys.list({ + accountId: selectedAccountToken?.account_id, + }), + ], + }); + }} + > + + } + > + Delete + +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/[addressId]/UpdateForm.tsx b/examples/password-reset/src/app/(store)/account/addresses/[addressId]/UpdateForm.tsx new file mode 100644 index 00000000..a32c40e1 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/[addressId]/UpdateForm.tsx @@ -0,0 +1,208 @@ +"use client"; + +import { updateAddress } from "../actions"; +import { Label } from "../../../../../components/label/Label"; +import { Input } from "../../../../../components/input/Input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../../../../components/select/Select"; +import { FormStatusButton } from "../../../../../components/button/FormStatusButton"; +import React from "react"; +import { countries as staticCountries } from "../../../../../lib/all-countries"; +import { AccountAddress } from "@elasticpath/js-sdk"; +import { + accountAddressesQueryKeys, + useAuthedAccountMember, +} from "@elasticpath/react-shopper-hooks"; +import { useQueryClient } from "@tanstack/react-query"; + +export function UpdateForm({ + addressId, + addressData, +}: { + addressId: string; + addressData: AccountAddress; +}) { + const queryClient = useQueryClient(); + const { selectedAccountToken } = useAuthedAccountMember(); + const countries = staticCountries; + + return ( +
{ + await updateAddress(formData); + await queryClient.invalidateQueries({ + queryKey: [ + ...accountAddressesQueryKeys.list({ + accountId: selectedAccountToken?.account_id, + }), + ], + }); + }} + className="flex flex-col gap-5" + > +
+ +
+

+ + +

+
+
+

+ + +

+

+ + +

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + Save changes + +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/[addressId]/page.tsx b/examples/password-reset/src/app/(store)/account/addresses/[addressId]/page.tsx new file mode 100644 index 00000000..8dcd4d4f --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/[addressId]/page.tsx @@ -0,0 +1,64 @@ +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../../lib/retrieve-account-member-credentials"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../../lib/cookie-constants"; +import { getServerSideImplicitClient } from "../../../../../lib/epcc-server-side-implicit-client"; +import { Button } from "../../../../../components/button/Button"; +import Link from "next/link"; +import { ArrowLeftIcon } from "@heroicons/react/24/outline"; +import React from "react"; +import { Separator } from "../../../../../components/separator/Separator"; +import { UpdateForm } from "./UpdateForm"; + +export const dynamic = "force-dynamic"; + +export default async function Address({ + params, +}: { + params: { addressId: string }; +}) { + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + const { addressId } = params; + + const activeAccount = getSelectedAccount(accountMemberCookie); + + const client = getServerSideImplicitClient(); + + const address = await client.AccountAddresses.Get({ + account: activeAccount.account_id, + address: addressId, + token: activeAccount.token, + }); + + const addressData = address.data; + + return ( +
+
+ +
+ +
+

Edit Address

+ +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/actions.ts b/examples/password-reset/src/app/(store)/account/addresses/actions.ts new file mode 100644 index 00000000..a128dad5 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/actions.ts @@ -0,0 +1,200 @@ +"use server"; + +import { z } from "zod"; +import { cookies } from "next/headers"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../lib/retrieve-account-member-credentials"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../lib/cookie-constants"; +import { revalidatePath } from "next/cache"; +import { shippingAddressSchema } from "../../../../components/checkout/form-schema/checkout-form-schema"; +import { AccountAddress, Resource } from "@elasticpath/js-sdk"; +import { redirect } from "next/navigation"; + +const deleteAddressSchema = z.object({ + addressId: z.string(), +}); + +const updateAddressSchema = shippingAddressSchema.merge( + z.object({ + name: z.string(), + addressId: z.string(), + line_2: z + .string() + .optional() + .transform((e) => (e === "" ? undefined : e)), + }), +); + +const addAddressSchema = shippingAddressSchema.merge( + z.object({ + name: z.string(), + line_2: z + .string() + .optional() + .transform((e) => (e === "" ? undefined : e)), + }), +); + +export async function deleteAddress(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = deleteAddressSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + throw new Error("Invalid address id"); + } + + const accountMemberCreds = retrieveAccountMemberCredentials( + cookies(), + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCreds) { + throw new Error("Account member credentials not found"); + } + + const { addressId } = validatedFormData.data; + const selectedAccount = getSelectedAccount(accountMemberCreds); + + try { + // TODO fix the sdk typing for this endpoint + // should be able to include the token in the request + await client.request.send( + `/accounts/${selectedAccount.account_id}/addresses/${addressId}`, + "DELETE", + null, + undefined, + client, + undefined, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + revalidatePath("/accounts/addresses"); + } catch (error) { + console.error(error); + throw new Error("Error deleting address"); + } +} + +export async function updateAddress(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = updateAddressSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + console.error(JSON.stringify(validatedFormData.error)); + throw new Error("Invalid address submission"); + } + + const accountMemberCreds = retrieveAccountMemberCredentials( + cookies(), + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCreds) { + throw new Error("Account member credentials not found"); + } + + const selectedAccount = getSelectedAccount(accountMemberCreds); + + const { addressId, ...addressData } = validatedFormData.data; + + const body = { + data: { + type: "address", + id: addressId, + ...addressData, + }, + }; + + try { + // TODO fix the sdk typing for this endpoint + // should be able to include the token in the request + await client.request.send( + `/accounts/${selectedAccount.account_id}/addresses/${addressId}`, + "PUT", + body, + undefined, + client, + false, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + revalidatePath("/accounts/addresses"); + } catch (error) { + console.error(error); + throw new Error("Error updating address"); + } +} + +export async function addAddress(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = addAddressSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + console.error(JSON.stringify(validatedFormData.error)); + throw new Error("Invalid address submission"); + } + + const accountMemberCreds = retrieveAccountMemberCredentials( + cookies(), + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCreds) { + throw new Error("Account member credentials not found"); + } + + const selectedAccount = getSelectedAccount(accountMemberCreds); + + const { ...addressData } = validatedFormData.data; + + const body = { + data: { + type: "address", + ...addressData, + }, + }; + + let redirectUrl: string | undefined = undefined; + try { + // TODO fix the sdk typing for this endpoint + // should be able to include the token in the request + const result = (await client.request.send( + `/accounts/${selectedAccount.account_id}/addresses`, + "POST", + body, + undefined, + client, + false, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + )) as Resource; + + redirectUrl = `/account/addresses/${result.data.id}`; + } catch (error) { + console.error(error); + throw new Error("Error adding address"); + } + + revalidatePath("/account/addresses"); + redirect(redirectUrl); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/add/AddForm.tsx b/examples/password-reset/src/app/(store)/account/addresses/add/AddForm.tsx new file mode 100644 index 00000000..08339c29 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/add/AddForm.tsx @@ -0,0 +1,188 @@ +"use client"; + +import { addAddress } from "../actions"; +import { Label } from "../../../../../components/label/Label"; +import { Input } from "../../../../../components/input/Input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "../../../../../components/select/Select"; +import { FormStatusButton } from "../../../../../components/button/FormStatusButton"; +import React from "react"; +import { countries as staticCountries } from "../../../../../lib/all-countries"; +import { useQueryClient } from "@tanstack/react-query"; +import { + accountAddressesQueryKeys, + useAuthedAccountMember, +} from "@elasticpath/react-shopper-hooks"; + +export function AddForm() { + const queryClient = useQueryClient(); + const { selectedAccountToken } = useAuthedAccountMember(); + const countries = staticCountries; + + return ( +
{ + await addAddress(formData); + await queryClient.invalidateQueries({ + queryKey: [ + ...accountAddressesQueryKeys.list({ + accountId: selectedAccountToken?.account_id, + }), + ], + }); + }} + className="flex flex-col gap-5" + > +
+
+

+ + +

+
+
+

+ + +

+

+ + +

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + Save changes + +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/add/page.tsx b/examples/password-reset/src/app/(store)/account/addresses/add/page.tsx new file mode 100644 index 00000000..479aed5b --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/add/page.tsx @@ -0,0 +1,43 @@ +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import { retrieveAccountMemberCredentials } from "../../../../../lib/retrieve-account-member-credentials"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../../lib/cookie-constants"; +import { Button } from "../../../../../components/button/Button"; +import Link from "next/link"; +import { ArrowLeftIcon } from "@heroicons/react/24/outline"; +import React from "react"; +import { Separator } from "../../../../../components/separator/Separator"; +import { AddForm } from "./AddForm"; + +export const dynamic = "force-dynamic"; + +export default async function AddAddress() { + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + + return ( +
+
+ +
+ +
+

Add Address

+ +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/addresses/page.tsx b/examples/password-reset/src/app/(store)/account/addresses/page.tsx new file mode 100644 index 00000000..97e0ffa3 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/addresses/page.tsx @@ -0,0 +1,90 @@ +import { + PencilSquareIcon, + PlusIcon, +} from "@heroicons/react/24/outline"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { cookies } from "next/headers"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../lib/cookie-constants"; +import { redirect } from "next/navigation"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../lib/retrieve-account-member-credentials"; +import Link from "next/link"; +import { Button } from "../../../../components/button/Button"; +import { Separator } from "../../../../components/separator/Separator"; +import React from "react"; +import { DeleteAddressBtn } from "./DeleteAddressBtn"; + +export const dynamic = "force-dynamic"; + +export default async function Addresses() { + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + + const selectedAccount = getSelectedAccount(accountMemberCookie); + + const client = getServerSideImplicitClient(); + + const addresses = await client.AccountAddresses.All({ + account: selectedAccount.account_id, + token: selectedAccount.token, + }); + + return ( +
+
+

Your info

+
    + {addresses.data.map((address) => ( +
  • +
    +
    +

    + {address.name} +

    +
    +
    +

    + {address.first_name} {address.last_name} +

    +

    {address.line_1}

    +

    {address.postcode}

    +
    +
    +
    + + +
    +
  • + ))} +
+
+ +
+ +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/breadcrumb.tsx b/examples/password-reset/src/app/(store)/account/breadcrumb.tsx new file mode 100644 index 00000000..1ca7add5 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/breadcrumb.tsx @@ -0,0 +1,85 @@ +"use client"; + +import { HomeIcon } from "@heroicons/react/20/solid"; +import { usePathname } from "next/navigation"; +import Link from "next/link"; +import clsx from "clsx"; + +interface BreadcrumbItem { + label: string; + href?: string; + current: boolean; +} + +export function Breadcrumb() { + const pathname = usePathname(); + + const pathnameParts = pathname.split("/").filter(Boolean); + + // Function to convert pathname to breadcrumb items + const getBreadcrumbItems = (pathname: string): BreadcrumbItem[] => { + const pathSegments = pathname + .split("/") + .filter((segment) => segment !== ""); + + return pathSegments.map((segment, index) => { + const href = + segment === "account" + ? undefined + : `/${pathSegments.slice(0, index + 1).join("/")}`; + return { + label: segment, + href, + current: index === pathSegments.length - 1, // Set current to true for the last segment + }; + }); + }; + + const breadcrumbItems = getBreadcrumbItems(pathname); + + return ( + + ); +} diff --git a/examples/password-reset/src/app/(store)/account/layout.tsx b/examples/password-reset/src/app/(store)/account/layout.tsx new file mode 100644 index 00000000..2bc085fe --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/layout.tsx @@ -0,0 +1,17 @@ +import { ReactNode } from "react"; +import { AccountNavigation } from "./AccountNavigation"; + +export default function AccountLayout({ children }: { children: ReactNode }) { + return ( +
+
+
+
+ +
+
{children}
+
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/orders/OrderItem.tsx b/examples/password-reset/src/app/(store)/account/orders/OrderItem.tsx new file mode 100644 index 00000000..52ff1f43 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/OrderItem.tsx @@ -0,0 +1,70 @@ +import { ReactNode } from "react"; +import { Order, OrderItem as OrderItemType } from "@elasticpath/js-sdk"; +import { ProductThumbnail } from "./[orderId]/ProductThumbnail"; +import Link from "next/link"; +import { formatIsoDateString } from "../../../../lib/format-iso-date-string"; + +export type OrderItemProps = { + children?: ReactNode; + order: Order; + orderItems: OrderItemType[]; + imageUrl?: string; +}; + +export function OrderItem({ children, order, orderItems }: OrderItemProps) { + // Sorted order items are used to determine which image to show + // showing the most expensive item's image + const sortedOrderItems = orderItems.sort( + (a, b) => b.unit_price.amount - a.unit_price.amount, + ); + return ( +
+
+ + + +
+
+ + Order # {order.external_ref ?? order.id} + + +

+ {formatOrderItemsTitle(sortedOrderItems)} +

+ + {children} +
+
+ + {order.meta.display_price.with_tax.formatted} +
+
+ ); +} + +function formatOrderItemsTitle(orderItems: OrderItemType[]): string { + if (orderItems.length === 0) { + return "No items in the order"; + } + + if (orderItems.length === 1) { + return orderItems[0].name; + } + + const firstTwoItems = orderItems.slice(0, 2).map((item) => item.name); + const remainingItemCount = orderItems.length - 2; + + if (remainingItemCount === 0) { + return `${firstTwoItems.join(" and ")} in the order`; + } + + return `${firstTwoItems.join(", ")} and ${remainingItemCount} other item${ + remainingItemCount > 1 ? "s" : "" + }`; +} diff --git a/examples/password-reset/src/app/(store)/account/orders/OrderItemWithDetails.tsx b/examples/password-reset/src/app/(store)/account/orders/OrderItemWithDetails.tsx new file mode 100644 index 00000000..4781054b --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/OrderItemWithDetails.tsx @@ -0,0 +1,32 @@ +import { OrderItem, OrderItemProps } from "./OrderItem"; +import { formatIsoDateString } from "../../../../lib/format-iso-date-string"; + +export function OrderItemWithDetails(props: Omit) { + const sortedOrderItems = props.orderItems.sort( + (a, b) => b.unit_price.amount - a.unit_price.amount, + ); + + return ( + +
+
    + {sortedOrderItems.map((item) => ( +
  • + {item.quantity} × {item.name} +
  • + ))} +
+
+
+ Ordered + +
+
+ + ); +} diff --git a/examples/password-reset/src/app/(store)/account/orders/[orderId]/OrderLineItem.tsx b/examples/password-reset/src/app/(store)/account/orders/[orderId]/OrderLineItem.tsx new file mode 100644 index 00000000..b5295d60 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/[orderId]/OrderLineItem.tsx @@ -0,0 +1,42 @@ +import { ProductThumbnail } from "./ProductThumbnail"; +import { OrderItem } from "@elasticpath/js-sdk"; +import Link from "next/link"; + +export function OrderLineItem({ orderItem }: { orderItem: OrderItem }) { + return ( +
+
+ + + +
+
+
+ +

+ {orderItem.name} +

+ + + Quantity: {orderItem.quantity} + +
+
+ + {orderItem.meta?.display_price?.with_tax?.value.formatted} + + {orderItem.meta?.display_price?.without_discount?.value.amount && + orderItem.meta?.display_price?.without_discount?.value.amount !== + orderItem.meta?.display_price?.with_tax?.value.amount && ( + + { + orderItem.meta?.display_price?.without_discount?.value + .formatted + } + + )} +
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/orders/[orderId]/ProductThumbnail.tsx b/examples/password-reset/src/app/(store)/account/orders/[orderId]/ProductThumbnail.tsx new file mode 100644 index 00000000..9e8f8d50 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/[orderId]/ProductThumbnail.tsx @@ -0,0 +1,22 @@ +"use client"; +import Image from "next/image"; +import { useProduct } from "@elasticpath/react-shopper-hooks"; + +const gray1pxBase64 = + "data:image/gif;base64,R0lGODlhAQABAIAAAMLCwgAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="; + +export function ProductThumbnail({ productId }: { productId: string }) { + const { data, included } = useProduct({ productId }); + + const imageHref = included?.main_images?.[0]?.link.href; + const title = data?.attributes?.name ?? "Loading..."; + return ( + {title} + ); +} diff --git a/examples/password-reset/src/app/(store)/account/orders/[orderId]/page.tsx b/examples/password-reset/src/app/(store)/account/orders/[orderId]/page.tsx new file mode 100644 index 00000000..92419c87 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/[orderId]/page.tsx @@ -0,0 +1,206 @@ +import { cookies } from "next/headers"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../../lib/cookie-constants"; +import { notFound, redirect } from "next/navigation"; +import { getServerSideImplicitClient } from "../../../../../lib/epcc-server-side-implicit-client"; +import { + Order as OrderType, + OrderIncluded, + OrderItem, + RelationshipToMany, +} from "@elasticpath/js-sdk"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../../lib/retrieve-account-member-credentials"; +import { Button } from "../../../../../components/button/Button"; +import { ArrowLeftIcon } from "@heroicons/react/24/outline"; +import Link from "next/link"; +import { formatIsoDateString } from "../../../../../lib/format-iso-date-string"; +import { OrderLineItem } from "./OrderLineItem"; + +export const dynamic = "force-dynamic"; + +export default async function Order({ + params, +}: { + params: { orderId: string }; +}) { + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + + const selectedAccount = getSelectedAccount(accountMemberCookie); + + const client = getServerSideImplicitClient(); + + let result: Awaited> | undefined = + undefined; + try { + result = await client.request.send( + `/orders/${params.orderId}?include=items`, + "GET", + null, + undefined, + client, + undefined, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + } catch (e: any) { + if ( + "errors" in e && + (e.errors as any)[0].detail === "The order does not exist" + ) { + notFound(); + } + throw e; + } + + const shopperOrder = result!.included + ? resolveShopperOrder(result!.data, result!.included) + : { raw: result!.data, items: [] }; + + const shippingAddress = shopperOrder.raw.shipping_address; + + const productItems = shopperOrder.items.filter( + (item) => + item.unit_price.amount >= 0 && !item.sku.startsWith("__shipping_"), + ); + const shippingItem = shopperOrder.items.find((item) => + item.sku.startsWith("__shipping_"), + ); + + return ( +
+
+ +
+
+
+
+

Order # {shopperOrder.raw.id}

+ +
+
+
+
+ Shipping address +

+ {shippingAddress.first_name} {shippingAddress.last_name} +
+ {shippingAddress.line_1} +
+ {shippingAddress.city ?? shippingAddress.county},{" "} + {shippingAddress.postcode} {shippingAddress.country} +

+
+
+ Shipping status + {shopperOrder.raw.shipping} +
+
+ Payment status + {shopperOrder.raw.payment} +
+
+
+
    + {productItems.map((item) => ( +
  • + +
  • + ))} +
+
+
+
+
+ Subtotal + + {shopperOrder.raw.meta.display_price.without_tax.formatted} + +
+
+ Shipping + + {shippingItem?.meta?.display_price?.with_tax?.value.formatted ?? + shopperOrder.raw.meta.display_price.shipping.formatted} + +
+ {shopperOrder.raw.meta.display_price.discount.amount < 0 && ( +
+ Discount + + {shopperOrder.raw.meta.display_price.discount.formatted} + +
+ )} +
+ Sales Tax + + {shopperOrder.raw.meta.display_price.tax.formatted} + +
+
+
+
+ Total + + {shopperOrder.raw.meta.display_price.with_tax.formatted} + +
+
+
+ ); +} + +function resolveOrderItemsFromRelationship( + itemRelationships: RelationshipToMany<"item">["data"], + itemMap: Record, +): OrderItem[] { + return itemRelationships.reduce((orderItems, itemRel) => { + const includedItem: OrderItem | undefined = itemMap[itemRel.id]; + return [...orderItems, ...(includedItem && [includedItem])]; + }, [] as OrderItem[]); +} + +function resolveShopperOrder( + order: OrderType, + included: NonNullable, +): { raw: OrderType; items: OrderItem[] } { + // Create a map of included items by their id + const itemMap = included.items + ? included.items.reduce( + (acc, item) => { + return { ...acc, [item.id]: item }; + }, + {} as Record, + ) + : {}; + + // Map the items in the data array to their corresponding included items + const orderItems = order.relationships?.items?.data + ? resolveOrderItemsFromRelationship(order.relationships.items.data, itemMap) + : []; + + return { + raw: order, + items: orderItems, + }; +} diff --git a/examples/password-reset/src/app/(store)/account/orders/page.tsx b/examples/password-reset/src/app/(store)/account/orders/page.tsx new file mode 100644 index 00000000..d6109361 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/orders/page.tsx @@ -0,0 +1,128 @@ +import { cookies } from "next/headers"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../lib/cookie-constants"; +import { redirect } from "next/navigation"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { + Order, + OrderItem, + RelationshipToMany, + ResourcePage, +} from "@elasticpath/js-sdk"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../lib/retrieve-account-member-credentials"; +import { ResourcePagination } from "../../../../components/pagination/ResourcePagination"; +import { DEFAULT_PAGINATION_LIMIT } from "../../../../lib/constants"; +import { OrderItemWithDetails } from "./OrderItemWithDetails"; + +export const dynamic = "force-dynamic"; + +export default async function Orders({ + searchParams, +}: { + searchParams?: { + limit?: string; + offset?: string; + page?: string; + }; +}) { + const currentPage = Number(searchParams?.page) || 1; + const limit = Number(searchParams?.limit) || DEFAULT_PAGINATION_LIMIT; + const offset = Number(searchParams?.offset) || 0; + + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + + const selectedAccount = getSelectedAccount(accountMemberCookie); + + const client = getServerSideImplicitClient(); + + const result: Awaited> = + await client.request.send( + `/orders?include=items&page[limit]=${limit}&page[offset]=${offset}`, + "GET", + null, + undefined, + client, + undefined, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + const mappedOrders = result.included + ? resolveShopperOrder(result.data, result.included) + : []; + + const totalPages = Math.ceil(result.meta.results.total / limit); + + return ( +
+
+

Order history

+
+
+
    + {mappedOrders.map(({ raw: order, items }) => ( +
  • + +
  • + ))} +
+
+
+ +
+
+ ); +} + +function resolveOrderItemsFromRelationship( + itemRelationships: RelationshipToMany<"item">["data"], + itemMap: Record, +): OrderItem[] { + return itemRelationships.reduce((orderItems, itemRel) => { + const includedItem: OrderItem | undefined = itemMap[itemRel.id]; + return [...orderItems, ...(includedItem && [includedItem])]; + }, [] as OrderItem[]); +} + +function resolveShopperOrder( + data: Order[], + included: NonNullable< + ResourcePage["included"] + >, +): { raw: Order; items: OrderItem[] }[] { + // Create a map of included items by their id + const itemMap = included.items.reduce( + (acc, item) => { + return { ...acc, [item.id]: item }; + }, + {} as Record, + ); + + // Map the items in the data array to their corresponding included items + return data.map((order) => { + const orderItems = order.relationships?.items?.data + ? resolveOrderItemsFromRelationship( + order.relationships.items.data, + itemMap, + ) + : []; + + return { + raw: order, + items: orderItems, + }; + }); +} diff --git a/examples/password-reset/src/app/(store)/account/summary/YourInfoForm.tsx b/examples/password-reset/src/app/(store)/account/summary/YourInfoForm.tsx new file mode 100644 index 00000000..9fb96377 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/summary/YourInfoForm.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { updateAccount } from "./actions"; +import { Label } from "../../../../components/label/Label"; +import { Input } from "../../../../components/input/Input"; +import { FormStatusButton } from "../../../../components/button/FormStatusButton"; +import { useState } from "react"; + +export function YourInfoForm({ + accountId, + defaultValues, +}: { + accountId: string; + defaultValues?: { name?: string; email?: string }; +}) { + const [error, setError] = useState(undefined); + + async function updateAccountAction(formData: FormData) { + const result = await updateAccount(formData); + + if (result && "error" in result) { + setError(result.error); + } + } + + return ( +
+
+ Your information +

+ + +

+

+ + +

+ {error && {error}} +
+
+ Save changes +
+ +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/account/summary/actions.ts b/examples/password-reset/src/app/(store)/account/summary/actions.ts new file mode 100644 index 00000000..5431608d --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/summary/actions.ts @@ -0,0 +1,220 @@ +"use server"; + +import { z } from "zod"; +import { cookies } from "next/headers"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../lib/retrieve-account-member-credentials"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../lib/cookie-constants"; +import { revalidatePath } from "next/cache"; +import { getServerSideCredentialsClient } from "../../../../lib/epcc-server-side-credentials-client"; +import { getErrorMessage } from "../../../../lib/get-error-message"; + +const updateAccountSchema = z.object({ + id: z.string(), + name: z.string(), +}); + +/** + * TODO request not working for implicit token + EP account management token + * @param formData + */ +export async function updateAccount(formData: FormData) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = updateAccountSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + console.error(JSON.stringify(validatedFormData.error)); + throw new Error("Invalid account submission"); + } + + const accountMemberCreds = retrieveAccountMemberCredentials( + cookies(), + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCreds) { + throw new Error("Account member credentials not found"); + } + + const selectedAccount = getSelectedAccount(accountMemberCreds); + + const { name, id } = validatedFormData.data; + + const body = { + data: { + type: "account", + name, + legal_name: name, + }, + }; + + try { + // TODO fix the sdk typing for this endpoint + // should be able to include the token in the request + await client.request.send( + `/accounts/${id}`, + "PUT", + body, + undefined, + client, + false, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + revalidatePath("/accounts/summary"); + } catch (error) { + console.error(getErrorMessage(error)); + return { + error: getErrorMessage(error), + }; + } + + return; +} + +const updateUserAuthenticationPasswordProfileSchema = z.object({ + username: z.string(), + currentPassword: z.string().optional(), + newPassword: z.string().optional(), +}); + +const PASSWORD_PROFILE_ID = process.env.NEXT_PUBLIC_PASSWORD_PROFILE_ID!; +const AUTHENTICATION_REALM_ID = + process.env.NEXT_PUBLIC_AUTHENTICATION_REALM_ID!; + +export async function updateUserAuthenticationPasswordProfile( + formData: FormData, +) { + const client = getServerSideImplicitClient(); + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = + updateUserAuthenticationPasswordProfileSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + console.error(JSON.stringify(validatedFormData.error)); + throw new Error("Invalid submission"); + } + + const accountMemberCreds = retrieveAccountMemberCredentials( + cookies(), + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCreds) { + throw new Error("Account member credentials not found"); + } + + const { username, newPassword, currentPassword } = validatedFormData.data; + + // Re auth the user to check the current password is correct + const reAuthResult = await client.AccountMembers.GenerateAccountToken({ + type: "account_management_authentication_token", + authentication_mechanism: "password", + password_profile_id: PASSWORD_PROFILE_ID, + username, + password: currentPassword, + }); + + const reAuthedSelectedAccount = reAuthResult.data.find( + (entry) => entry.account_id === accountMemberCreds.selected, + ); + + if (!reAuthedSelectedAccount) { + throw new Error("Error re-authenticating user"); + } + + const credsClient = getServerSideCredentialsClient(); + const userAuthenticationPasswordProfileInfoResult = + await credsClient.UserAuthenticationPasswordProfile.All( + AUTHENTICATION_REALM_ID, + accountMemberCreds.accountMemberId, + ); + + const userAuthenticationPasswordProfileInfo = + userAuthenticationPasswordProfileInfoResult.data.find( + (entry) => entry.password_profile_id === PASSWORD_PROFILE_ID, + ); + + if (!userAuthenticationPasswordProfileInfo) { + throw new Error( + "User authentication password profile info not found for password profile", + ); + } + + const body = { + data: { + type: "user_authentication_password_profile_info", + id: userAuthenticationPasswordProfileInfo.id, + password_profile_id: PASSWORD_PROFILE_ID, + ...(username && { username }), + ...(newPassword && { password: newPassword }), + }, + }; + + try { + // TODO fix the sdk typing for this endpoint + // should be able to include the token in the request + await client.request.send( + `/authentication-realms/${AUTHENTICATION_REALM_ID}/user-authentication-info/${accountMemberCreds.accountMemberId}/user-authentication-password-profile-info/${userAuthenticationPasswordProfileInfo.id}`, + "PUT", + body, + undefined, + client, + false, + "v2", + { + "EP-Account-Management-Authentication-Token": + reAuthedSelectedAccount.token, + }, + ); + + revalidatePath("/accounts"); + } catch (error) { + console.error(error); + throw new Error("Error updating account"); + } +} + +// async function getOneTimePasswordToken( +// client: ElasticPath, +// username: string, +// ): Promise { +// const response = await client.OneTimePasswordTokenRequest.Create( +// AUTHENTICATION_REALM_ID, +// PASSWORD_PROFILE_ID, +// { +// type: "one_time_password_token_request", +// username, +// purpose: "reset_password", +// }, +// ); +// +// const result2 = await client.request.send( +// `/authentication-realms/${AUTHENTICATION_REALM_ID}/password-profiles/${PASSWORD_PROFILE_ID}/one-time-password-token-request`, +// "POST", +// { +// data: { +// type: "one_time_password_token_request", +// username, +// purpose: "reset_password", +// }, +// }, +// undefined, +// client, +// false, +// "v2", +// ); +// +// return response; +// } diff --git a/examples/password-reset/src/app/(store)/account/summary/page.tsx b/examples/password-reset/src/app/(store)/account/summary/page.tsx new file mode 100644 index 00000000..89825480 --- /dev/null +++ b/examples/password-reset/src/app/(store)/account/summary/page.tsx @@ -0,0 +1,113 @@ +import { cookies } from "next/headers"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../../../../lib/cookie-constants"; +import { redirect } from "next/navigation"; +import { + getSelectedAccount, + retrieveAccountMemberCredentials, +} from "../../../../lib/retrieve-account-member-credentials"; +import { Label } from "../../../../components/label/Label"; +import { Input } from "../../../../components/input/Input"; +import { FormStatusButton } from "../../../../components/button/FormStatusButton"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { updateUserAuthenticationPasswordProfile } from "./actions"; +import { YourInfoForm } from "./YourInfoForm"; + +export const dynamic = "force-dynamic"; + +export default async function AccountSummary() { + const cookieStore = cookies(); + + const accountMemberCookie = retrieveAccountMemberCredentials( + cookieStore, + ACCOUNT_MEMBER_TOKEN_COOKIE_NAME, + ); + + if (!accountMemberCookie) { + return redirect("/login"); + } + + const client = getServerSideImplicitClient(); + + const selectedAccount = getSelectedAccount(accountMemberCookie); + + const account: Awaited> = + await client.request.send( + `/accounts/${selectedAccount.account_id}`, + "GET", + null, + undefined, + client, + undefined, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + const accountMember: Awaited> = + await client.request.send( + `/account-members/${accountMemberCookie.accountMemberId}`, + "GET", + null, + undefined, + client, + undefined, + "v2", + { + "EP-Account-Management-Authentication-Token": selectedAccount.token, + }, + ); + + return ( +
+
+

Your info

+ +
+
+

Change Password

+
+
+ Password information +

+ + +

+

+ + +

+

+ + +

+
+ +
+ + Save changes + +
+
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/cart/CartItem.tsx b/examples/password-reset/src/app/(store)/cart/CartItem.tsx new file mode 100644 index 00000000..36b2cde6 --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/CartItem.tsx @@ -0,0 +1,61 @@ +"use client"; +import { useCartRemoveItem } from "@elasticpath/react-shopper-hooks"; +import { ProductThumbnail } from "../account/orders/[orderId]/ProductThumbnail"; +import { NumberInput } from "../../../components/number-input/NumberInput"; +import Link from "next/link"; +import { CartItem as CartItemType } from "@elasticpath/js-sdk"; +import { LoadingDots } from "../../../components/LoadingDots"; + +export type CartItemProps = { + item: CartItemType; +}; + +export function CartItem({ item }: CartItemProps) { + const { mutate, isPending } = useCartRemoveItem(); + + return ( +
+
+ +
+
+
+
+ + {item.name} + + + Quantity: {item.quantity} + +
+
+ + {item.meta.display_price.with_tax.value.formatted} + + {item.meta.display_price.without_discount?.value.amount && + item.meta.display_price.without_discount?.value.amount !== + item.meta.display_price.with_tax.value.amount && ( + + {item.meta.display_price.without_discount?.value.formatted} + + )} +
+
+
+ + {isPending ? ( + + ) : ( + + )} +
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/cart/CartItemWide.tsx b/examples/password-reset/src/app/(store)/cart/CartItemWide.tsx new file mode 100644 index 00000000..b7421e3c --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/CartItemWide.tsx @@ -0,0 +1,61 @@ +"use client"; +import { useCartRemoveItem } from "@elasticpath/react-shopper-hooks"; +import { ProductThumbnail } from "../account/orders/[orderId]/ProductThumbnail"; +import Link from "next/link"; +import { NumberInput } from "../../../components/number-input/NumberInput"; +import { CartItemProps } from "./CartItem"; +import { LoadingDots } from "../../../components/LoadingDots"; + +export function CartItemWide({ item }: CartItemProps) { + const { mutate, isPending } = useCartRemoveItem(); + + return ( +
+ {/* Thumbnail */} +
+ +
+ {/* Details */} +
+
+
+ + + {item.name} + + + + Quantity: {item.quantity} + +
+
+ + {isPending ? ( + + ) : ( + + )} +
+
+
+
+ + {item.meta.display_price.with_tax.value.formatted} + + {item.meta.display_price.without_discount?.value.amount && + item.meta.display_price.without_discount?.value.amount !== + item.meta.display_price.with_tax.value.amount && ( + + {item.meta.display_price.without_discount?.value.formatted} + + )} +
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/cart/CartSidebar.tsx b/examples/password-reset/src/app/(store)/cart/CartSidebar.tsx new file mode 100644 index 00000000..2b80fcad --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/CartSidebar.tsx @@ -0,0 +1,47 @@ +"use client"; + +import { useCart } from "@elasticpath/react-shopper-hooks"; +import { Separator } from "../../../components/separator/Separator"; +import { CartDiscounts } from "../../../components/cart/CartDiscounts"; +import * as React from "react"; +import { + ItemSidebarPromotions, + ItemSidebarSumTotal, + ItemSidebarTotals, + ItemSidebarTotalsDiscount, + ItemSidebarTotalsSubTotal, + ItemSidebarTotalsTax, +} from "../../../components/checkout-sidebar/ItemSidebar"; + +export function CartSidebar() { + const { data } = useCart(); + + const state = data?.state; + + if (!state) { + return null; + } + + const { meta } = state; + + return ( +
+ + + + {/* Totals */} + + +
+ Shipping + Calculated at checkout +
+ + +
+ + {/* Sum Total */} + +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/cart/CartView.tsx b/examples/password-reset/src/app/(store)/cart/CartView.tsx new file mode 100644 index 00000000..0e8b7159 --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/CartView.tsx @@ -0,0 +1,55 @@ +"use client"; +import { YourBag } from "./YourBag"; +import { CartSidebar } from "./CartSidebar"; +import { Button } from "../../../components/button/Button"; +import Link from "next/link"; +import { LockClosedIcon } from "@heroicons/react/24/solid"; +import { useCart } from "@elasticpath/react-shopper-hooks"; + +export function CartView() { + const { data } = useCart(); + + const state = data?.state; + + return ( + <> + {state?.items.length && state.items.length > 0 ? ( +
+ {/* Main Content */} +
+
+

Your Bag

+ {/* Cart Items */} + +
+
+ {/* Sidebar */} +
+ + +
+
+ ) : ( + <> + {/* Empty Cart */} +
+

+ Empty Cart +

+

Your cart is empty

+
+ +
+
+ + )} + + ); +} diff --git a/examples/password-reset/src/app/(store)/cart/YourBag.tsx b/examples/password-reset/src/app/(store)/cart/YourBag.tsx new file mode 100644 index 00000000..bda5c894 --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/YourBag.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { CartItemWide } from "./CartItemWide"; +import { useCart } from "@elasticpath/react-shopper-hooks"; + +export function YourBag() { + const { data } = useCart(); + + const state = data?.state; + + return ( +
    + {state?.items.map((item) => { + return ( +
  • + +
  • + ); + })} +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/cart/page.tsx b/examples/password-reset/src/app/(store)/cart/page.tsx new file mode 100644 index 00000000..de5e40bc --- /dev/null +++ b/examples/password-reset/src/app/(store)/cart/page.tsx @@ -0,0 +1,5 @@ +import { CartView } from "./CartView"; + +export default async function CartPage() { + return ; +} diff --git a/examples/password-reset/src/app/(store)/faq/page.tsx b/examples/password-reset/src/app/(store)/faq/page.tsx new file mode 100644 index 00000000..786734bc --- /dev/null +++ b/examples/password-reset/src/app/(store)/faq/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../../components/shared/blurb"; + +export default function FAQ() { + return ; +} diff --git a/examples/password-reset/src/app/(store)/layout.tsx b/examples/password-reset/src/app/(store)/layout.tsx new file mode 100644 index 00000000..26377c29 --- /dev/null +++ b/examples/password-reset/src/app/(store)/layout.tsx @@ -0,0 +1,64 @@ +import { ReactNode, Suspense } from "react"; +import { Inter } from "next/font/google"; +import { getStoreInitialState } from "../../lib/get-store-initial-state"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { Providers } from "../providers"; +import Header from "../../components/header/Header"; +import { Toaster } from "../../components/toast/toaster"; +import Footer from "../../components/footer/Footer"; + +const { SITE_NAME } = process.env; +const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL + ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` + : "http://localhost:3000"; + +export const metadata = { + metadataBase: new URL(baseUrl), + title: { + default: SITE_NAME!, + template: `%s | ${SITE_NAME}`, + }, + robots: { + follow: true, + index: true, + }, +}; + +/** + * Used to revalidate until the js-sdk supports passing of fetch options. + * At that point we can be more intelligent about revalidation. + */ +export const revalidate = 300; + +const inter = Inter({ + subsets: ["latin"], + display: "swap", + variable: "--font-inter", +}); + +export default async function StoreLayout({ + children, +}: { + children: ReactNode; +}) { + const client = getServerSideImplicitClient(); + const initialState = await getStoreInitialState(client); + + return ( + + + {/* headless ui needs this div - https://github.com/tailwindlabs/headlessui/issues/2752#issuecomment-1745272229 */} +
+ +
+ + +
{children}
+
+
+ +
+ + + ); +} diff --git a/examples/password-reset/src/app/(store)/not-found.tsx b/examples/password-reset/src/app/(store)/not-found.tsx new file mode 100644 index 00000000..d97d88f4 --- /dev/null +++ b/examples/password-reset/src/app/(store)/not-found.tsx @@ -0,0 +1,13 @@ +import Link from "next/link"; +export default function NotFound() { + return ( +
+ + 404 - The page could not be found. + + + Back to home + +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/page.tsx b/examples/password-reset/src/app/(store)/page.tsx new file mode 100644 index 00000000..6f87cd28 --- /dev/null +++ b/examples/password-reset/src/app/(store)/page.tsx @@ -0,0 +1,38 @@ +import PromotionBanner from "../../components/promotion-banner/PromotionBanner"; +import FeaturedProducts from "../../components/featured-products/FeaturedProducts"; +import { Suspense } from "react"; + +export default async function Home() { + const promotion = { + title: "Your Elastic Path storefront", + description: + "This marks the beginning, embark on the journey of crafting something truly extraordinary, uniquely yours.", + }; + + return ( +
+ +
+
+
+ + + +
+
+
+
+ ); +} diff --git a/examples/password-reset/src/app/(store)/products/[productId]/page.tsx b/examples/password-reset/src/app/(store)/products/[productId]/page.tsx new file mode 100644 index 00000000..8da9a108 --- /dev/null +++ b/examples/password-reset/src/app/(store)/products/[productId]/page.tsx @@ -0,0 +1,52 @@ +import { Metadata } from "next"; +import { ProductDetailsComponent, ProductProvider } from "./product-display"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { getProductById } from "../../../../services/products"; +import { notFound } from "next/navigation"; +import { parseProductResponse } from "@elasticpath/react-shopper-hooks"; +import React from "react"; + + +export const dynamic = "force-dynamic"; + +type Props = { + params: { productId: string }; +}; + +export async function generateMetadata({ + params: { productId }, +}: Props): Promise { + const client = getServerSideImplicitClient(); + const product = await getProductById(productId, client); + + if (!product) { + notFound(); + } + + return { + title: product.data.attributes.name, + description: product.data.attributes.description, + }; +} + +export default async function ProductPage({ params }: Props) { + const client = getServerSideImplicitClient(); + const product = await getProductById(params.productId, client); + + if (!product) { + notFound(); + } + + const shopperProduct = await parseProductResponse(product, client); + + return ( +
+ + + +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/products/[productId]/product-display.tsx b/examples/password-reset/src/app/(store)/products/[productId]/product-display.tsx new file mode 100644 index 00000000..98ab9c15 --- /dev/null +++ b/examples/password-reset/src/app/(store)/products/[productId]/product-display.tsx @@ -0,0 +1,49 @@ +"use client"; +import React, { ReactElement, ReactNode, useState } from "react"; +import { ShopperProduct } from "@elasticpath/react-shopper-hooks"; +import { VariationProductDetail } from "../../../../components/product/variations/VariationProduct"; +import BundleProductDetail from "../../../../components/product/bundles/BundleProduct"; +import { ProductContext } from "../../../../lib/product-context"; +import SimpleProductDetail from "../../../../components/product/SimpleProduct"; + +export function ProductProvider({ + children, +}: { + children: ReactNode; +}): ReactElement { + const [isChangingSku, setIsChangingSku] = useState(false); + + return ( + + {children} + + ); +} + +export function resolveProductDetailComponent( + product: ShopperProduct, +): JSX.Element { + switch (product.kind) { + case "base-product": + return ; + case "child-product": + return ; + case "simple-product": + return ; + case "bundle-product": + return ; + } +} + +export function ProductDetailsComponent({ + product, +}: { + product: ShopperProduct; +}) { + return resolveProductDetailComponent(product); +} diff --git a/examples/password-reset/src/app/(store)/search/[[...node]]/layout.tsx b/examples/password-reset/src/app/(store)/search/[[...node]]/layout.tsx new file mode 100644 index 00000000..937b6e50 --- /dev/null +++ b/examples/password-reset/src/app/(store)/search/[[...node]]/layout.tsx @@ -0,0 +1,11 @@ +import { ReactNode } from "react"; +import Breadcrumb from "../../../../components/breadcrumb"; + +export default function SearchLayout({ children }: { children: ReactNode }) { + return ( +
+ + {children} +
+ ); +} diff --git a/examples/password-reset/src/app/(store)/search/[[...node]]/page.tsx b/examples/password-reset/src/app/(store)/search/[[...node]]/page.tsx new file mode 100644 index 00000000..ff6de2f9 --- /dev/null +++ b/examples/password-reset/src/app/(store)/search/[[...node]]/page.tsx @@ -0,0 +1,186 @@ +import { Search } from "../search"; +import { Metadata } from "next"; +import { getServerSideImplicitClient } from "../../../../lib/epcc-server-side-implicit-client"; +import { + Hierarchy, + ElasticPath, + ProductResponse, + ShopperCatalogResourcePage, +} from "@elasticpath/js-sdk"; +import { notFound } from "next/navigation"; +import { ShopperProduct } from "@elasticpath/react-shopper-hooks"; +import { + getMainImageForProductResponse, + getOtherImagesForProductResponse, +} from "../../../../lib/file-lookup"; + +export const metadata: Metadata = { + title: "Search", + description: "Search for products", +}; + +export const dynamic = "force-dynamic"; + +type Params = { + node?: string[]; +}; + +type SearchParams = { + limit?: string; + offset?: string; +}; + +export default async function SearchPage({ + searchParams, + params, +}: { + params: Params; + searchParams: SearchParams; +}) { + const client = getServerSideImplicitClient(); + + const { limit, offset } = searchParams; + + if (!params.node || params.node.length === 0) { + const products = await client.ShopperCatalog.Products.With(["main_image"]) + .Limit(processLimit(limit)) + .Offset(processOffset(offset)) + .All(); + return ; + } + + const rootNodeSlug = params.node?.[0]; + + if (!rootNodeSlug) { + return ; + } + + const rootHierarchy = await findHierarchyFromSlug(client, rootNodeSlug); + + if (!rootHierarchy) { + console.warn("No root hierarchy found for slug: ", rootNodeSlug); + return notFound(); + } + + if (params.node.length === 1) { + const products = await getNodeProducts( + client, + rootHierarchy.id, + limit, + offset, + ); + + return ; + } + + const lastNodeSlug = getLastArrayElement(params.node); + + if (!lastNodeSlug) { + console.warn("No last node slug found for node path: ", params.node); + return notFound(); + } + + const leafNodeId = await findLeafNodeId(client, rootHierarchy, lastNodeSlug); + + if (!leafNodeId) { + console.warn("No leaf node id found for slug: ", lastNodeSlug); + return notFound(); + } + + const products = await getNodeProducts(client, leafNodeId, limit, offset); + + return ; +} + +/** + * Works to a maximum of 25 hierarchies (default limit). + * Behavior for more than 25 hierarchies is unpredictable. + */ +async function findHierarchyFromSlug( + client: ElasticPath, + slug: string, +): Promise { + const allHierarchies = await client.ShopperCatalog.Hierarchies.All(); + + return allHierarchies.data.find((hierarchy) => { + return hierarchy.attributes.slug === slug; + }); +} + +function processResult( + page: ShopperCatalogResourcePage, +): ShopperCatalogResourcePage { + const processedData: ShopperProduct[] = page.data.map((product) => { + const mainImage = page.included?.main_images + ? getMainImageForProductResponse(product, page.included.main_images) ?? + null + : null; + + const otherImages = page.included?.files + ? getOtherImagesForProductResponse(product, page.included?.files) ?? [] + : []; + + return { + kind: "simple-product", + response: product, + main_image: mainImage, + otherImages: otherImages, + }; + }); + + return { + ...page, + data: processedData, + }; +} + +/** + * Works to a maximum of 25 Child Nodes (default limit). + * Behavior for more than 25 Child Nodes is unpredictable. + */ +async function findLeafNodeId( + client: ElasticPath, + rootHierarchy: Hierarchy, + leafNodeSlug: string, +): Promise { + const hierarchyChildrenResponse = + await client.ShopperCatalog.Hierarchies.GetHierarchyNodes({ + hierarchyId: rootHierarchy.id, + }); + + const hierarchyChildren = hierarchyChildrenResponse.data; + const hierarchyChild = hierarchyChildren.find((child) => { + return child.attributes.slug === leafNodeSlug; + }); + + return hierarchyChild?.id; +} + +function getLastArrayElement(array: T[]): T | undefined { + return array[array.length - 1]; +} + +async function getNodeProducts( + client: ElasticPath, + nodeId: string, + limit?: string, + offset?: string, +): Promise> { + return client.ShopperCatalog.Nodes.With(["main_image"]) + .Offset(processOffset(offset)) + .Limit(processLimit(limit)) + .GetNodeProducts({ nodeId }); +} + +const DEFAULT_OFFSET = 0; +const DEFAULT_LIMIT = 25; + +function processOffset(offset: string | undefined): number { + const offsetNumber = Number(offset); + return isNaN(offsetNumber) ? DEFAULT_OFFSET : offsetNumber; +} + +function processLimit(limit: string | undefined): number { + const limitNumber = Number(limit); + return isNaN(limitNumber) ? DEFAULT_LIMIT : limitNumber; +} diff --git a/examples/password-reset/src/app/(store)/search/search.tsx b/examples/password-reset/src/app/(store)/search/search.tsx new file mode 100644 index 00000000..00183dbd --- /dev/null +++ b/examples/password-reset/src/app/(store)/search/search.tsx @@ -0,0 +1,17 @@ +"use client"; +import SearchResults from "../../../components/search/SearchResults"; +import React from "react"; +import { ShopperProduct } from "@elasticpath/react-shopper-hooks"; +import { ShopperCatalogResourcePage } from "@elasticpath/js-sdk"; +import { usePathname } from "next/navigation"; + +export function Search({ + page, +}: { + page?: ShopperCatalogResourcePage; +}) { + const pathname = usePathname(); + const nodes = pathname.split("/search/")?.[1]?.split("/"); + + return ; +} diff --git a/examples/password-reset/src/app/(store)/shipping/page.tsx b/examples/password-reset/src/app/(store)/shipping/page.tsx new file mode 100644 index 00000000..d5ee20b4 --- /dev/null +++ b/examples/password-reset/src/app/(store)/shipping/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../../components/shared/blurb"; + +export default function Shipping() { + return ; +} diff --git a/examples/password-reset/src/app/(store)/terms/page.tsx b/examples/password-reset/src/app/(store)/terms/page.tsx new file mode 100644 index 00000000..3b651abc --- /dev/null +++ b/examples/password-reset/src/app/(store)/terms/page.tsx @@ -0,0 +1,5 @@ +import Blurb from "../../../components/shared/blurb"; + +export default function Terms() { + return ; +} diff --git a/examples/password-reset/src/app/configuration-error/page.tsx b/examples/password-reset/src/app/configuration-error/page.tsx new file mode 100644 index 00000000..5b9a5dba --- /dev/null +++ b/examples/password-reset/src/app/configuration-error/page.tsx @@ -0,0 +1,69 @@ +import Link from "next/link"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Configuration Error", + description: "Configuration error page", +}; + +type Props = { + searchParams: { [key: string]: string | string[] | undefined }; +}; + +export default function ConfigurationErrorPage({ searchParams }: Props) { + const { + "missing-env-variable": missingEnvVariables, + authentication, + from, + } = searchParams; + + const issues: { [key: string]: string | string[] } = { + ...(missingEnvVariables && { missingEnvVariables }), + ...(authentication && { authentication }), + }; + const fromProcessed = Array.isArray(from) ? from[0] : from; + + return ( +
+ + There is a problem with the stores setup + + + Refresh + + + + + + + + + + {issues && + Object.keys(issues).map((key) => { + const issue = issues[key]; + return ( + + + + + ); + })} + +
IssueDetails
{key} +
    + {(Array.isArray(issue) ? issue : [issue]).map( + (message) => ( +
  • + {decodeURIComponent(message)} +
  • + ), + )} +
+
+
+ ); +} diff --git a/examples/password-reset/src/app/error.tsx b/examples/password-reset/src/app/error.tsx new file mode 100644 index 00000000..f4724026 --- /dev/null +++ b/examples/password-reset/src/app/error.tsx @@ -0,0 +1,31 @@ +"use client"; +import Link from "next/link"; + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + return ( + + +
+ + {error.digest} - Internal server error. + + + Back to home + + +
+ + + ); +} diff --git a/examples/password-reset/src/app/layout.tsx b/examples/password-reset/src/app/layout.tsx new file mode 100644 index 00000000..d87bb7de --- /dev/null +++ b/examples/password-reset/src/app/layout.tsx @@ -0,0 +1,10 @@ +import { ReactNode } from "react"; +import "../styles/globals.css"; + +export default async function RootLayout({ + children, +}: { + children: ReactNode; +}) { + return <>{children}; +} diff --git a/examples/password-reset/src/app/not-found.tsx b/examples/password-reset/src/app/not-found.tsx new file mode 100644 index 00000000..d97d88f4 --- /dev/null +++ b/examples/password-reset/src/app/not-found.tsx @@ -0,0 +1,13 @@ +import Link from "next/link"; +export default function NotFound() { + return ( +
+ + 404 - The page could not be found. + + + Back to home + +
+ ); +} diff --git a/examples/password-reset/src/app/providers.tsx b/examples/password-reset/src/app/providers.tsx new file mode 100644 index 00000000..acb2a6ba --- /dev/null +++ b/examples/password-reset/src/app/providers.tsx @@ -0,0 +1,44 @@ +"use client"; +import { ReactNode } from "react"; +import { + AccountProvider, + StoreProvider, + ElasticPathProvider, + InitialState, +} from "@elasticpath/react-shopper-hooks"; +import { QueryClient } from "@tanstack/react-query"; +import { getEpccImplicitClient } from "../lib/epcc-implicit-client"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "../lib/cookie-constants"; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + staleTime: 1000 * 60 * 60 * 24, + retry: 1, + }, + }, +}); + +export function Providers({ + children, + initialState, +}: { + children: ReactNode; + initialState: InitialState; +}) { + const client = getEpccImplicitClient(); + + return ( + + + + {children} + + + + ); +} diff --git a/examples/password-reset/src/components/Checkbox.tsx b/examples/password-reset/src/components/Checkbox.tsx new file mode 100644 index 00000000..290cf273 --- /dev/null +++ b/examples/password-reset/src/components/Checkbox.tsx @@ -0,0 +1,29 @@ +"use client"; + +import * as React from "react"; +import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; +import { cn } from "../lib/cn"; +import { CheckIcon } from "@heroicons/react/24/solid"; + +const Checkbox = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + + +)); +Checkbox.displayName = CheckboxPrimitive.Root.displayName; + +export { Checkbox }; diff --git a/examples/password-reset/src/components/LoadingDots.tsx b/examples/password-reset/src/components/LoadingDots.tsx new file mode 100644 index 00000000..5ac56f3d --- /dev/null +++ b/examples/password-reset/src/components/LoadingDots.tsx @@ -0,0 +1,13 @@ +import { cn } from "../lib/cn"; + +const dots = "mx-[1px] inline-block h-1 w-1 animate-blink rounded-md"; + +export function LoadingDots({ className }: { className: string }) { + return ( + + + + + + ); +} diff --git a/examples/password-reset/src/components/NoImage.tsx b/examples/password-reset/src/components/NoImage.tsx new file mode 100644 index 00000000..bf84f253 --- /dev/null +++ b/examples/password-reset/src/components/NoImage.tsx @@ -0,0 +1,12 @@ +import React from "react"; +import { EyeSlashIcon } from "@heroicons/react/24/solid"; + +export const NoImage = (): JSX.Element => { + return ( +
+ +
+ ); +}; + +export default NoImage; diff --git a/examples/password-reset/src/components/Spinner.tsx b/examples/password-reset/src/components/Spinner.tsx new file mode 100644 index 00000000..9bd90a3e --- /dev/null +++ b/examples/password-reset/src/components/Spinner.tsx @@ -0,0 +1,30 @@ +interface IProps { + width: string; + height: string; + absolute: boolean; +} + +const Spinner = (props: IProps) => { + return ( + + ); +}; + +export default Spinner; diff --git a/examples/password-reset/src/components/accordion/Accordion.tsx b/examples/password-reset/src/components/accordion/Accordion.tsx new file mode 100644 index 00000000..6f4f7aef --- /dev/null +++ b/examples/password-reset/src/components/accordion/Accordion.tsx @@ -0,0 +1,51 @@ +"use client"; + +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { cn } from "../../lib/cn"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + {children} + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); + +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/examples/password-reset/src/components/alert/Alert.tsx b/examples/password-reset/src/components/alert/Alert.tsx new file mode 100644 index 00000000..eb8d9cd4 --- /dev/null +++ b/examples/password-reset/src/components/alert/Alert.tsx @@ -0,0 +1,59 @@ +import { cva, type VariantProps } from "class-variance-authority"; + +import { forwardRef, HTMLAttributes } from "react"; +import { cn } from "../../lib/cn"; + +const alertVariants = cva( + "relative w-full rounded-lg border border-black/60 p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-black", + { + variants: { + variant: { + default: "bg-white text-black", + destructive: + "border-red-600/50 text-red-600 dark:border-red-600 [&>svg]:text-red-600", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +const Alert = forwardRef< + HTMLDivElement, + HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)); +Alert.displayName = "Alert"; + +const AlertTitle = forwardRef< + HTMLParagraphElement, + HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +AlertTitle.displayName = "AlertTitle"; + +const AlertDescription = forwardRef< + HTMLParagraphElement, + HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +AlertDescription.displayName = "AlertDescription"; + +export { Alert, AlertTitle, AlertDescription }; diff --git a/examples/password-reset/src/components/breadcrumb.tsx b/examples/password-reset/src/components/breadcrumb.tsx new file mode 100644 index 00000000..950c0130 --- /dev/null +++ b/examples/password-reset/src/components/breadcrumb.tsx @@ -0,0 +1,36 @@ +"use client"; +import { createBreadcrumb } from "../lib/create-breadcrumb"; +import Link from "next/link"; +import { useStore } from "@elasticpath/react-shopper-hooks"; +import { buildBreadcrumbLookup } from "../lib/build-breadcrumb-lookup"; +import { usePathname } from "next/navigation"; + +export default function Breadcrumb(): JSX.Element { + const { nav } = useStore(); + const pathname = usePathname(); + const lookup = buildBreadcrumbLookup(nav ?? []); + const nodes = pathname.replace("/search/", "")?.split("/"); + const crumbs = createBreadcrumb(nodes, lookup); + + return ( +
    + {crumbs.length > 1 && + crumbs.map((entry, index, array) => ( +
  1. + {array.length === index + 1 ? ( + {entry.label} + ) : ( + + {entry.label} + + )} + {array.length !== index + 1 && /} +
  2. + ))} +
+ ); +} diff --git a/examples/password-reset/src/components/button/Button.tsx b/examples/password-reset/src/components/button/Button.tsx new file mode 100644 index 00000000..6d277a4e --- /dev/null +++ b/examples/password-reset/src/components/button/Button.tsx @@ -0,0 +1,68 @@ +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "../../lib/cn"; +import { ButtonHTMLAttributes, forwardRef } from "react"; +import { Slot } from "@radix-ui/react-slot"; + +const buttonVariants = cva( + "inline-flex items-center justify-center hover:opacity-90 whitespace-nowrap rounded-full text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + primary: "bg-black text-white", + secondary: "bg-transparent ring-2 ring-inset ring-black text-black", + ghost: "bg-brand-gray/10 text-black/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "px-8 py-3 text-lg", + medium: "px-6 py-2 text-base", + small: "px-3.5 py-1.5 text-sm", + icon: "w-10", + }, + reversed: { + true: "", + false: "", + }, + }, + compoundVariants: [ + { + variant: "primary", + reversed: true, + className: "bg-white text-black", + }, + { + variant: "secondary", + reversed: true, + className: "ring-white text-white", + }, + ], + defaultVariants: { + variant: "primary", + size: "default", + reversed: false, + }, + }, +); + +export interface ButtonProps + extends ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const Button = forwardRef( + ({ className, variant, asChild = false, size, reversed, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + + return ( + + ); + }, +); +Button.displayName = "Button"; + +export { Button, buttonVariants }; diff --git a/examples/password-reset/src/components/button/FormStatusButton.tsx b/examples/password-reset/src/components/button/FormStatusButton.tsx new file mode 100644 index 00000000..2b46a37e --- /dev/null +++ b/examples/password-reset/src/components/button/FormStatusButton.tsx @@ -0,0 +1,41 @@ +"use client"; +import { cn } from "../../lib/cn"; +import { forwardRef, ReactNode } from "react"; +import { Button, ButtonProps } from "./Button"; +import LoaderIcon from "./LoaderIcon"; +import { useFormStatus } from "react-dom"; +import * as React from "react"; + +export interface FormStatusButtonProps extends ButtonProps { + status?: "loading" | "success" | "error" | "idle"; + icon?: ReactNode; +} + +const FormStatusButton = forwardRef( + ({ children, icon, status = "idle", className, ...props }, ref) => { + const { pending } = useFormStatus(); + return ( + + ); + }, +); +FormStatusButton.displayName = "FormStatusButton"; + +export { FormStatusButton }; diff --git a/examples/password-reset/src/components/button/LoaderIcon.tsx b/examples/password-reset/src/components/button/LoaderIcon.tsx new file mode 100644 index 00000000..92aa3952 --- /dev/null +++ b/examples/password-reset/src/components/button/LoaderIcon.tsx @@ -0,0 +1,17 @@ +import { forwardRef, Ref, SVGProps } from "react"; + +const LoaderIcon = ( + props: SVGProps, + ref: Ref, +) => ( + + + +); +const ForwardRef = forwardRef(LoaderIcon); +export default ForwardRef; diff --git a/examples/password-reset/src/components/button/StatusButton.tsx b/examples/password-reset/src/components/button/StatusButton.tsx new file mode 100644 index 00000000..12ee784a --- /dev/null +++ b/examples/password-reset/src/components/button/StatusButton.tsx @@ -0,0 +1,47 @@ +import { cn } from "../../lib/cn"; +import { forwardRef } from "react"; +import { Button, ButtonProps } from "./Button"; +import { CheckIcon } from "@heroicons/react/24/outline"; +import { XMarkIcon } from "@heroicons/react/24/solid"; +import LoaderIcon from "./LoaderIcon"; + +export interface StatusButtonProps extends ButtonProps { + status?: "loading" | "success" | "error" | "idle"; +} + +const StatusButton = forwardRef( + ({ children, status = "idle", className, ...props }, ref) => { + const Icon = + status === "loading" + ? LoaderIcon + : status === "success" + ? CheckIcon + : status === "error" + ? XMarkIcon + : null; + + return ( + + ); + }, +); +StatusButton.displayName = "StatusButton"; + +export { StatusButton }; diff --git a/examples/password-reset/src/components/button/TextButton.tsx b/examples/password-reset/src/components/button/TextButton.tsx new file mode 100644 index 00000000..e48149af --- /dev/null +++ b/examples/password-reset/src/components/button/TextButton.tsx @@ -0,0 +1,41 @@ +import { cva, VariantProps } from "class-variance-authority"; +import { ButtonHTMLAttributes, forwardRef } from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cn } from "../../lib/cn"; + +const textButtonVariants = cva( + "font-medium text-black flex items-center gap-2 shrink-0", + { + variants: { + size: { + default: "text-lg", + small: "text-base", + }, + }, + defaultVariants: { + size: "default", + }, + }, +); + +export interface TextButtonProps + extends ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; +} + +const TextButton = forwardRef( + ({ className, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + }, +); +TextButton.displayName = "TextButton"; + +export { TextButton, textButtonVariants }; diff --git a/examples/password-reset/src/components/cart/CartDiscounts.tsx b/examples/password-reset/src/components/cart/CartDiscounts.tsx new file mode 100644 index 00000000..d6090d4e --- /dev/null +++ b/examples/password-reset/src/components/cart/CartDiscounts.tsx @@ -0,0 +1,96 @@ +"use client"; + +import { forwardRef, Fragment, HTMLAttributes } from "react"; +import { Separator } from "../separator/Separator"; +import { + PromotionCartItem, + useCartRemoveItem, +} from "@elasticpath/react-shopper-hooks"; +import { LoadingDots } from "../LoadingDots"; +import { XMarkIcon } from "@heroicons/react/24/solid"; +import * as React from "react"; +import { cn } from "../../lib/cn"; + +export function CartDiscounts({ + promotions, +}: { + promotions: PromotionCartItem[]; +}) { + const { mutate, isPending } = useCartRemoveItem(); + + return ( + promotions && + promotions.length > 0 && + promotions.map((promotion) => { + return ( + + + + {promotion.name} + + + + ); + }) + ); +} + +export function CartDiscountsReadOnly({ + promotions, +}: { + promotions: PromotionCartItem[]; +}) { + return ( + promotions && + promotions.length > 0 && + promotions.map((promotion) => { + return ( + + + {promotion.name} + + + + ); + }) + ); +} + +const CartDiscountItem = forwardRef< + HTMLDivElement, + HTMLAttributes +>(({ className, children, ...props }, ref) => { + return ( +
+
{children}
+
+ ); +}); +CartDiscountItem.displayName = "CartDiscountItem"; + +const CartDiscountName = forwardRef< + HTMLSpanElement, + HTMLAttributes +>(({ className, children, ...props }, ref) => { + return ( + + {children} + + ); +}); +CartDiscountName.displayName = "CartDiscountName"; diff --git a/examples/password-reset/src/components/cart/CartSheet.tsx b/examples/password-reset/src/components/cart/CartSheet.tsx new file mode 100644 index 00000000..75f36349 --- /dev/null +++ b/examples/password-reset/src/components/cart/CartSheet.tsx @@ -0,0 +1,168 @@ +"use client"; +import { + Sheet, + SheetClose, + SheetContent, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "../sheet/Sheet"; +import { Button } from "../button/Button"; +import { LockClosedIcon, XMarkIcon } from "@heroicons/react/24/solid"; +import { CartItem } from "../../app/(store)/cart/CartItem"; +import { useCart, useCartRemoveItem } from "@elasticpath/react-shopper-hooks"; +import { Separator } from "../separator/Separator"; +import { ShoppingBagIcon } from "@heroicons/react/24/outline"; +import { Fragment } from "react"; +import { AddPromotion } from "../checkout-sidebar/AddPromotion"; +import Link from "next/link"; +import { LoadingDots } from "../LoadingDots"; + +export function Cart() { + const { data } = useCart(); + + const state = data?.state; + + const { items, __extended } = state ?? {}; + + const { mutate, isPending } = useCartRemoveItem(); + + const discountedValues = ( + state?.meta?.display_price as + | { discount: { amount: number; formatted: string } } + | undefined + )?.discount; + + return ( + + + + + + +
+ + Your Bag + + + + Close + +
+ {items && items.length > 0 ? ( + <> + {/* Items */} +
+
    + {items.map((item) => { + return ( + +
  • + +
  • + +
    + ); + })} +
+
+ {/* Bottom */} + +
+ +
+ {__extended && + __extended.groupedItems.promotion.length > 0 && + __extended.groupedItems.promotion.map((promotion) => { + return ( + + +
+
+ + {promotion.name} +
+
+
+ ); + })} + + {/* Totals */} +
+
+ Sub Total + + {state?.meta?.display_price?.without_tax?.formatted} + +
+ {discountedValues && discountedValues.amount !== 0 && ( +
+ Discount + + {discountedValues.formatted} + +
+ )} +
+ + + + + + + +
+ + ) : ( +
+ +

Your bag is empty.

+
+ )} +
+
+ ); +} diff --git a/examples/password-reset/src/components/checkout-item/CheckoutItem.tsx b/examples/password-reset/src/components/checkout-item/CheckoutItem.tsx new file mode 100644 index 00000000..0bb311bf --- /dev/null +++ b/examples/password-reset/src/components/checkout-item/CheckoutItem.tsx @@ -0,0 +1,32 @@ +"use client"; +import { ProductThumbnail } from "../../app/(store)/account/orders/[orderId]/ProductThumbnail"; +import Link from "next/link"; +import { CartItem } from "@elasticpath/js-sdk"; + +export function CheckoutItem({ item }: { item: CartItem }) { + return ( +
+
+ +
+
+ + {item.name} + + Quantity: {item.quantity} +
+
+ + {item.meta.display_price.with_tax.value.formatted} + + {item.meta.display_price.without_discount?.value.amount && + item.meta.display_price.without_discount?.value.amount !== + item.meta.display_price.with_tax.value.amount && ( + + {item.meta.display_price.without_discount?.value.formatted} + + )} +
+
+ ); +} diff --git a/examples/password-reset/src/components/checkout-sidebar/AddPromotion.tsx b/examples/password-reset/src/components/checkout-sidebar/AddPromotion.tsx new file mode 100644 index 00000000..2b6ad7bb --- /dev/null +++ b/examples/password-reset/src/components/checkout-sidebar/AddPromotion.tsx @@ -0,0 +1,73 @@ +"use client"; + +import { useState } from "react"; +import { TextButton } from "../button/TextButton"; +import { PlusIcon } from "@heroicons/react/24/outline"; +import { Input } from "../input/Input"; +import { Button } from "../button/Button"; +import { applyDiscount } from "./actions"; +import { useQueryClient } from "@tanstack/react-query"; +import { cartQueryKeys, useCart } from "@elasticpath/react-shopper-hooks"; +import { useFormStatus } from "react-dom"; +import { LoadingDots } from "../LoadingDots"; + +export function AddPromotion() { + const [showInput, setShowInput] = useState(false); + const queryClient = useQueryClient(); + const { data } = useCart(); + const [error, setError] = useState(undefined); + + async function clientAction(formData: FormData) { + setError(undefined); + + const result = await applyDiscount(formData); + + setError(result.error); + + data?.cartId && + (await queryClient.invalidateQueries({ + queryKey: cartQueryKeys.detail(data.cartId), + })); + + !result.error && setShowInput(false); + } + + return showInput ? ( +
+
+ + + + {error &&

{error}

} +
+ ) : ( + setShowInput(true)}> + Add discount code + + ); +} + +function ApplyButton() { + const { pending } = useFormStatus(); + + return ( + + ); +} diff --git a/examples/password-reset/src/components/checkout-sidebar/ItemSidebar.tsx b/examples/password-reset/src/components/checkout-sidebar/ItemSidebar.tsx new file mode 100644 index 00000000..8e1b174f --- /dev/null +++ b/examples/password-reset/src/components/checkout-sidebar/ItemSidebar.tsx @@ -0,0 +1,166 @@ +"use client"; +import { Separator } from "../separator/Separator"; +import { AddPromotion } from "./AddPromotion"; +import { CheckoutItem } from "../checkout-item/CheckoutItem"; +import { CartState } from "@elasticpath/react-shopper-hooks"; +import { + Accordion, + AccordionContent, + AccordionTrigger, + AccordionItem, +} from "../accordion/Accordion"; +import { ShoppingBagIcon } from "@heroicons/react/24/outline"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; +import * as React from "react"; +import { Currency } from "@elasticpath/js-sdk"; +import { formatCurrency } from "../../lib/format-currency"; + +export function ItemSidebarItems({ items }: { items: CartState["items"] }) { + return ( + <> + {items && items.length > 0 && ( + <> + {items?.map((item) => )} + + + )} + + ); +} + +export function ItemSidebarPromotions() { + return ( +
+ +
+ ); +} + +export function ItemSidebarSumTotal({ meta }: { meta: CartState["meta"] }) { + return ( +
+ Total +
+ {meta?.display_price?.with_tax?.currency} + + {meta?.display_price?.with_tax?.formatted} + +
+
+ ); +} + +export function ItemSidebarTotals({ children }: { children: React.ReactNode }) { + return ( +
{children}
+ ); +} + +export function ItemSidebarTotalsSubTotal({ + meta, +}: { + meta: CartState["meta"]; +}) { + return ( + + ); +} + +export function ItemSidebarTotalsDiscount({ + meta, +}: { + meta: CartState["meta"]; +}) { + const discountedValues = ( + meta?.display_price as + | { discount: { amount: number; formatted: string } } + | undefined + )?.discount; + + return ( + discountedValues && + discountedValues.amount !== 0 && ( +
+ Discount + + {discountedValues?.formatted ?? ""} + +
+ ) + ); +} + +export function ItemSidebarTotalsTax({ meta }: { meta: CartState["meta"] }) { + return ( + + ); +} + +export function ItemSidebarTotalsItem({ + label, + description, +}: { + label: string; + description: string; +}) { + return ( +
+ {label} + {description} +
+ ); +} + +export function ItemSidebarHideable({ + children, + meta, +}: { + meta: CartState["meta"]; + children: React.ReactNode; +}) { + return ( + <> + + + + + Hide order summary + + + {meta?.display_price?.with_tax?.formatted} + + + {children} + + +
{children}
+ + ); +} + +export function resolveTotalInclShipping( + shippingAmount: number, + totalAmount: number, + storeCurrency: Currency, +): string | undefined { + return formatCurrency(shippingAmount + totalAmount, storeCurrency); +} diff --git a/examples/password-reset/src/components/checkout-sidebar/actions.ts b/examples/password-reset/src/components/checkout-sidebar/actions.ts new file mode 100644 index 00000000..e2d283b8 --- /dev/null +++ b/examples/password-reset/src/components/checkout-sidebar/actions.ts @@ -0,0 +1,43 @@ +"use server"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { cookies } from "next/headers"; +import { revalidatePath } from "next/cache"; +import { z } from "zod"; +import { COOKIE_PREFIX_KEY } from "../../lib/resolve-cart-env"; +import { getErrorMessage } from "../../lib/get-error-message"; + +const applyDiscountSchema = z.object({ + code: z.string(), +}); + +export async function applyDiscount(formData: FormData) { + const client = getServerSideImplicitClient(); + + const cartCookie = cookies().get(`${COOKIE_PREFIX_KEY}_ep_cart`)?.value; + + if (!cartCookie) { + throw new Error("Cart cookie not found"); + } + + const rawEntries = Object.fromEntries(formData.entries()); + + const validatedFormData = applyDiscountSchema.safeParse(rawEntries); + + if (!validatedFormData.success) { + return { + error: "Invalid code", + }; + } + + try { + await client.Cart(cartCookie).AddPromotion(validatedFormData.data.code); + revalidatePath("/cart"); + } catch (error) { + console.error(error); + return { + error: getErrorMessage(error), + }; + } + + return { success: true }; +} diff --git a/examples/password-reset/src/components/checkout/form-schema/checkout-form-schema.ts b/examples/password-reset/src/components/checkout/form-schema/checkout-form-schema.ts new file mode 100644 index 00000000..5c987167 --- /dev/null +++ b/examples/password-reset/src/components/checkout/form-schema/checkout-form-schema.ts @@ -0,0 +1,90 @@ +import { z } from "zod"; + +/** + * Validating optional text input field https://github.com/colinhacks/zod/issues/310 + */ +const emptyStringToUndefined = z.literal("").transform(() => undefined); + +const guestInformationSchema = z.object({ + email: z.string({ required_error: "Required" }).email("Invalid email"), +}); + +const accountMemberInformationSchema = z.object({ + email: z.string({ required_error: "Required" }).email("Invalid email"), + name: z.string({ required_error: "Required" }), +}); + +const billingAddressSchema = z.object({ + first_name: z + .string({ required_error: "You need to provided a first name." }) + .min(2), + last_name: z + .string({ required_error: "You need to provided a last name." }) + .min(2), + company_name: z.string().min(1).optional().or(emptyStringToUndefined), + line_1: z + .string({ required_error: "You need to provided an address." }) + .min(1), + line_2: z.string().min(1).optional().or(emptyStringToUndefined), + city: z.string().min(1).optional().or(emptyStringToUndefined), + county: z.string().min(1).optional().or(emptyStringToUndefined), + region: z + .string({ required_error: "You need to provided a region." }) + .optional() + .or(emptyStringToUndefined), + postcode: z + .string({ required_error: "You need to provided a postcode." }) + .min(1), + country: z + .string({ required_error: "You need to provided a country." }) + .min(1), +}); + +export const shippingAddressSchema = z + .object({ + phone_number: z + .string() + .regex( + /^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/, + "Phone number is not valid", + ) + .optional() + .or(emptyStringToUndefined), + instructions: z.string().min(1).optional().or(emptyStringToUndefined), + }) + .merge(billingAddressSchema); + +export const anonymousCheckoutFormSchema = z.object({ + guest: guestInformationSchema, + shippingAddress: shippingAddressSchema, + sameAsShipping: z.boolean().default(true), + billingAddress: billingAddressSchema.optional().or(emptyStringToUndefined), + shippingMethod: z + .union([z.literal("__shipping_standard"), z.literal("__shipping_express")]) + .default("__shipping_standard"), +}); + +export type AnonymousCheckoutForm = z.TypeOf< + typeof anonymousCheckoutFormSchema +>; + +export const accountMemberCheckoutFormSchema = z.object({ + account: accountMemberInformationSchema, + shippingAddress: shippingAddressSchema, + sameAsShipping: z.boolean().default(true), + billingAddress: billingAddressSchema.optional().or(emptyStringToUndefined), + shippingMethod: z + .union([z.literal("__shipping_standard"), z.literal("__shipping_express")]) + .default("__shipping_standard"), +}); + +export type AccountMemberCheckoutForm = z.TypeOf< + typeof accountMemberCheckoutFormSchema +>; + +export const checkoutFormSchema = z.union([ + anonymousCheckoutFormSchema, + accountMemberCheckoutFormSchema, +]); + +export type CheckoutForm = z.TypeOf; diff --git a/examples/password-reset/src/components/featured-products/FeaturedProducts.tsx b/examples/password-reset/src/components/featured-products/FeaturedProducts.tsx new file mode 100644 index 00000000..909ec1ef --- /dev/null +++ b/examples/password-reset/src/components/featured-products/FeaturedProducts.tsx @@ -0,0 +1,86 @@ +"use server"; +import clsx from "clsx"; +import Link from "next/link"; +import { ArrowRightIcon, EyeSlashIcon } from "@heroicons/react/24/outline"; +import Image from "next/image"; +import { getServerSideImplicitClient } from "../../lib/epcc-server-side-implicit-client"; +import { fetchFeaturedProducts } from "./fetchFeaturedProducts"; + +interface IFeaturedProductsProps { + title: string; + linkProps?: { + link: string; + text: string; + }; +} + +export default async function FeaturedProducts({ + title, + linkProps, +}: IFeaturedProductsProps) { + const client = getServerSideImplicitClient(); + const products = await fetchFeaturedProducts(client); + + return ( +
+
+

+ {title} +

+ {linkProps && ( + + + {linkProps.text} + + + )} +
+
    + {products.map((product) => ( + +
  • +
    +
    + {product.main_image?.link.href ? ( + {product.main_image?.file_name!} + ) : ( +
    + +
    + )} +
    +
    +

    + {product.attributes.name} +

    +

    + {product.meta.display_price?.without_tax?.formatted} +

    +
  • + + ))} +
+
+ ); +} diff --git a/examples/password-reset/src/components/featured-products/fetchFeaturedProducts.ts b/examples/password-reset/src/components/featured-products/fetchFeaturedProducts.ts new file mode 100644 index 00000000..a5b9f7bf --- /dev/null +++ b/examples/password-reset/src/components/featured-products/fetchFeaturedProducts.ts @@ -0,0 +1,19 @@ +import { getProducts } from "../../services/products"; +import { ElasticPath } from "@elasticpath/js-sdk"; +import { ProductResponseWithImage } from "../../lib/types/product-types"; +import { connectProductsWithMainImages } from "../../lib/connect-products-with-main-images"; + +// Fetching the first 4 products of in the catalog to display in the featured-products component +export const fetchFeaturedProducts = async ( + client: ElasticPath, +): Promise => { + const { data: productsResponse, included: productsIncluded } = + await getProducts(client); + + return productsIncluded?.main_images + ? connectProductsWithMainImages( + productsResponse.slice(0, 4), // Only need the first 4 products to feature + productsIncluded?.main_images, + ) + : productsResponse; +}; diff --git a/examples/password-reset/src/components/footer/Footer.tsx b/examples/password-reset/src/components/footer/Footer.tsx new file mode 100644 index 00000000..46759f53 --- /dev/null +++ b/examples/password-reset/src/components/footer/Footer.tsx @@ -0,0 +1,72 @@ +import Link from "next/link"; +import { PhoneIcon, InformationCircleIcon } from "@heroicons/react/24/solid"; +import { GitHubIcon } from "../icons/github-icon"; +import EpLogo from "../icons/ep-logo"; + +const Footer = (): JSX.Element => ( +
+
+
+
+ +
+
+ + Home + + + Shipping + + + FAQ + +
+
+ + About + + + Terms + +
+
+
+ + {" "} + + + + {" "} + + + + + +
+
+
+
+); + +export default Footer; diff --git a/examples/password-reset/src/components/form/Form.tsx b/examples/password-reset/src/components/form/Form.tsx new file mode 100644 index 00000000..4f760fa5 --- /dev/null +++ b/examples/password-reset/src/components/form/Form.tsx @@ -0,0 +1,183 @@ +import * as LabelPrimitive from "@radix-ui/react-label"; +import { Slot } from "@radix-ui/react-slot"; +import { + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form"; +import { cn } from "../../lib/cn"; +import { Label } from "../label/Label"; +import { + ComponentPropsWithoutRef, + createContext, + ElementRef, + forwardRef, + HTMLAttributes, + useContext, + useId, +} from "react"; + +const Form = FormProvider; + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +> = { + name: TName; +}; + +const FormFieldContext = createContext( + {} as FormFieldContextValue, +); + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath, +>({ + ...props +}: ControllerProps) => { + return ( + + + + ); +}; + +const useFormField = () => { + const fieldContext = useContext(FormFieldContext); + const itemContext = useContext(FormItemContext); + const { getFieldState, formState } = useFormContext(); + + const fieldState = getFieldState(fieldContext.name, formState); + + if (!fieldContext) { + throw new Error("useFormField should be used within "); + } + + const { id } = itemContext; + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + }; +}; + +type FormItemContextValue = { + id: string; +}; + +const FormItemContext = createContext( + {} as FormItemContextValue, +); + +const FormItem = forwardRef>( + ({ className, ...props }, ref) => { + const id = useId(); + + return ( + +
+ + ); + }, +); +FormItem.displayName = "FormItem"; + +const FormLabel = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField(); + + return ( +
+
+ ); +}; + +export default ProductVariationColor; diff --git a/examples/password-reset/src/components/product/variations/ProductVariationStandard.tsx b/examples/password-reset/src/components/product/variations/ProductVariationStandard.tsx new file mode 100644 index 00000000..a326191c --- /dev/null +++ b/examples/password-reset/src/components/product/variations/ProductVariationStandard.tsx @@ -0,0 +1,55 @@ +import clsx from "clsx"; +import type { useVariationProduct } from "@elasticpath/react-shopper-hooks"; + +interface ProductVariationOption { + id: string; + description: string; + name: string; +} + +export type UpdateOptionHandler = ( + variationId: string, +) => (optionId: string) => void; + +interface IProductVariation { + variation: { + id: string; + name: string; + options: ProductVariationOption[]; + }; + updateOptionHandler: ReturnType< + typeof useVariationProduct + >["updateSelectedOptions"]; + selectedOptionId?: string; +} + +const ProductVariationStandard = ({ + variation, + selectedOptionId, + updateOptionHandler, +}: IProductVariation): JSX.Element => { + return ( +
+

{variation.name}

+
+ {variation.options.map((o) => ( + + ))} +
+
+ ); +}; + +export default ProductVariationStandard; diff --git a/examples/password-reset/src/components/product/variations/ProductVariations.tsx b/examples/password-reset/src/components/product/variations/ProductVariations.tsx new file mode 100644 index 00000000..4ec4e1e2 --- /dev/null +++ b/examples/password-reset/src/components/product/variations/ProductVariations.tsx @@ -0,0 +1,108 @@ +import type { CatalogsProductVariation } from "@elasticpath/js-sdk"; +import { useRouter } from "next/navigation"; +import { useContext } from "react"; +import { useEffect } from "react"; +import { OptionDict } from "../../../lib/types/product-types"; +import { + allVariationsHaveSelectedOption, + getSkuIdFromOptions, +} from "../../../lib/product-helper"; +import ProductVariationStandard from "./ProductVariationStandard"; +import ProductVariationColor from "./ProductVariationColor"; +import { useVariationProduct } from "@elasticpath/react-shopper-hooks"; +import { ProductContext } from "../../../lib/product-context"; + +const getSelectedOption = ( + variationId: string, + optionLookupObj: OptionDict, +): string => { + return optionLookupObj[variationId]; +}; + +const ProductVariations = (): JSX.Element => { + const { + variations, + variationsMatrix, + product, + selectedOptions, + updateSelectedOptions, + } = useVariationProduct(); + + const currentProductId = product.response.id; + + const context = useContext(ProductContext); + + const router = useRouter(); + + useEffect(() => { + const selectedSkuId = getSkuIdFromOptions( + Object.values(selectedOptions), + variationsMatrix, + ); + + if ( + !context?.isChangingSku && + selectedSkuId && + selectedSkuId !== currentProductId && + allVariationsHaveSelectedOption(selectedOptions, variations) + ) { + context?.setIsChangingSku(true); + router.replace(`/products/${selectedSkuId}`, { scroll: false }); + context?.setIsChangingSku(false); + } + }, [ + selectedOptions, + context, + currentProductId, + router, + variations, + variationsMatrix, + ]); + + return ( +
+ {variations.map((v) => + resolveVariationComponentByName( + v, + updateSelectedOptions, + getSelectedOption(v.id, selectedOptions), + ), + )} +
+ ); +}; + +function resolveVariationComponentByName( + v: CatalogsProductVariation, + updateOptionHandler: ReturnType< + typeof useVariationProduct + >["updateSelectedOptions"], + selectedOptionId?: string, +): JSX.Element { + switch (v.name.toLowerCase()) { + case "color": + return ( + + ); + default: + return ( + + ); + } +} + +export default ProductVariations; diff --git a/examples/password-reset/src/components/product/variations/VariationProduct.tsx b/examples/password-reset/src/components/product/variations/VariationProduct.tsx new file mode 100644 index 00000000..77fb2bc4 --- /dev/null +++ b/examples/password-reset/src/components/product/variations/VariationProduct.tsx @@ -0,0 +1,60 @@ +"use client"; +import { + useCartAddProduct, + useVariationProduct, + VariationProduct, + VariationProductProvider, +} from "@elasticpath/react-shopper-hooks"; +import ProductVariations from "./ProductVariations"; +import ProductCarousel from "../carousel/ProductCarousel"; +import ProductSummary from "../ProductSummary"; +import ProductDetails from "../ProductDetails"; +import ProductExtensions from "../ProductExtensions"; +import { StatusButton } from "../../button/StatusButton"; + +export const VariationProductDetail = ({ + variationProduct, +}: { + variationProduct: VariationProduct; +}): JSX.Element => { + return ( + + + + ); +}; + +export function VariationProductContainer(): JSX.Element { + const { product } = useVariationProduct(); + const { mutate, isPending } = useCartAddProduct(); + + const { response, main_image, otherImages } = product; + const { extensions } = response.attributes; + return ( +
+
+
+ {main_image && ( + + )} +
+
+
+ + + + {extensions && } + mutate({ productId: response.id, quantity: 1 })} + status={isPending ? "loading" : "idle"} + > + ADD TO CART + +
+
+
+
+ ); +} diff --git a/examples/password-reset/src/components/promotion-banner/PromotionBanner.tsx b/examples/password-reset/src/components/promotion-banner/PromotionBanner.tsx new file mode 100644 index 00000000..4430aa13 --- /dev/null +++ b/examples/password-reset/src/components/promotion-banner/PromotionBanner.tsx @@ -0,0 +1,62 @@ +"use client"; +import { useRouter } from "next/navigation"; +import clsx from "clsx"; + +export interface IPromotion { + title?: string; + description?: string; + imageHref?: string; +} + +interface IPromotionBanner { + linkProps?: { + link: string; + text: string; + }; + alignment?: "center" | "left" | "right"; + promotion: IPromotion; +} + +const PromotionBanner = (props: IPromotionBanner): JSX.Element => { + const router = useRouter(); + const { linkProps, promotion } = props; + + const { title, description } = promotion; + + return ( + <> + {promotion && ( +
+
+ {title && ( +

+ {title} +

+ )} + {description && ( +

+ {description} +

+ )} + {linkProps && ( + + )} +
+
+ )} + + ); +}; + +export default PromotionBanner; diff --git a/examples/password-reset/src/components/radio-group/RadioGroup.tsx b/examples/password-reset/src/components/radio-group/RadioGroup.tsx new file mode 100644 index 00000000..b9f3ba24 --- /dev/null +++ b/examples/password-reset/src/components/radio-group/RadioGroup.tsx @@ -0,0 +1,43 @@ +"use client"; + +import * as React from "react"; +import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"; +import { cn } from "../../lib/cn"; + +const RadioGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + ); +}); +RadioGroup.displayName = RadioGroupPrimitive.Root.displayName; + +const RadioGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + return ( + + + + + + + + ); +}); +RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName; + +export { RadioGroup, RadioGroupItem }; diff --git a/examples/password-reset/src/components/search/Hit.tsx b/examples/password-reset/src/components/search/Hit.tsx new file mode 100644 index 00000000..8ec40e55 --- /dev/null +++ b/examples/password-reset/src/components/search/Hit.tsx @@ -0,0 +1,87 @@ +import Link from "next/link"; +import Price from "../product/Price"; +import StrikePrice from "../product/StrikePrice"; +import { EP_CURRENCY_CODE } from "../../lib/resolve-ep-currency-code"; +import Image from "next/image"; +import { EyeSlashIcon } from "@heroicons/react/24/solid"; +import { + ShopperProduct, +} from "@elasticpath/react-shopper-hooks"; + +export default function HitComponent({ + hit, +}: { + hit: ShopperProduct; +}): JSX.Element { + const { + main_image, + response: { + meta: { display_price, original_display_price }, + attributes: { name, description }, + id, + }, + } = hit; + + const ep_main_image_url = main_image?.link.href; + + // const currencyPrice = ep_price?.[EP_CURRENCY_CODE]; + const currencyPrice = display_price?.without_tax.formatted; + + return ( + <> + +
+
+ {ep_main_image_url ? ( + {name} + ) : ( +
+ +
+ )} +
+
+
+ +

{name}

+ + + {description} + +
+
+ {currencyPrice && ( +
+ + {original_display_price?.without_tax.formatted && ( + + )} +
+ )} +
+
+
+ + + ); +} diff --git a/examples/password-reset/src/components/search/Hits.tsx b/examples/password-reset/src/components/search/Hits.tsx new file mode 100644 index 00000000..49dee7f4 --- /dev/null +++ b/examples/password-reset/src/components/search/Hits.tsx @@ -0,0 +1,32 @@ +import NoResults from "./NoResults"; +import HitComponent from "./Hit"; +import { useProducts } from "./ProductsProvider"; + +export default function Hits(): JSX.Element { + const { page } = useProducts(); + + if (!page) { + return ; + } + + if (page.data.length) { + return ( +
+ {page.data.map((hit) => { + const { + response: { id }, + } = hit; + return ( +
+ +
+ ); + })} +
+ ); + } + return ; +} diff --git a/examples/password-reset/src/components/search/MobileFilters.tsx b/examples/password-reset/src/components/search/MobileFilters.tsx new file mode 100644 index 00000000..5683571d --- /dev/null +++ b/examples/password-reset/src/components/search/MobileFilters.tsx @@ -0,0 +1,74 @@ +import { BreadcrumbLookup } from "../../lib/types/breadcrumb-lookup"; +import { Dialog, Transition } from "@headlessui/react"; +import { Dispatch, Fragment, SetStateAction } from "react"; +import { XMarkIcon } from "@heroicons/react/24/solid"; +import NodeMenu from "./NodeMenu"; +import { useStore } from "@elasticpath/react-shopper-hooks"; + +interface IMobileFilters { + lookup?: BreadcrumbLookup; + showFilterMenu: boolean; + setShowFilterMenu: Dispatch>; +} + +export default function MobileFilters({ + showFilterMenu, + setShowFilterMenu, +}: IMobileFilters): JSX.Element { + const { nav } = useStore(); + return ( + + setShowFilterMenu(false)} + > + +
+ +
+
+
+ + +
+ +
+ +
+ Category + {nav && } +
+
+
+
+
+
+
+
+ ); +} diff --git a/examples/password-reset/src/components/search/NoResults.tsx b/examples/password-reset/src/components/search/NoResults.tsx new file mode 100644 index 00000000..22276594 --- /dev/null +++ b/examples/password-reset/src/components/search/NoResults.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { MagnifyingGlassIcon } from "@heroicons/react/24/solid"; + +export const NoResults = ({ + displayIcon = true, +}: { + displayIcon?: boolean; +}): JSX.Element => { + return ( +
+
+ {displayIcon ? ( +
+ +
+ ) : null} + No matching results +
+
+ ); +}; + +export default NoResults; diff --git a/examples/password-reset/src/components/search/NodeMenu.tsx b/examples/password-reset/src/components/search/NodeMenu.tsx new file mode 100644 index 00000000..163eec6f --- /dev/null +++ b/examples/password-reset/src/components/search/NodeMenu.tsx @@ -0,0 +1,87 @@ +import { clsx } from "clsx"; +import { NavigationNode } from "@elasticpath/react-shopper-hooks"; +import { usePathname } from "next/navigation"; +import Link from "next/link"; + +type MenuItemProps = { + item: NavigationNode; +}; + +function isPathActive(activePath: string, providedPath: string): boolean { + const targetPathParts = activePath.split("/").filter(Boolean); + const providedPathParts = providedPath.split("/").filter(Boolean); + + if (providedPathParts.length > targetPathParts.length) { + return false; + } + + return providedPathParts.every( + (part, index) => part === targetPathParts[index], + ); +} + +function MenuItem({ item }: MenuItemProps): JSX.Element { + const pathname = usePathname(); + const activeItem = isPathActive(pathname, `/search/${item.href}`); + + return ( +
  • + + {item.name} + + {activeItem && !!item.children?.length && ( +
    + +
    + )} +
  • + ); +} + +type MenuListProps = { + items: NavigationNode[]; +}; + +function MenuList({ items }: MenuListProps) { + return ( +
      + {items.map((item) => ( + + ))} +
    + ); +} + +type NodeMenuProps = { + nav: NavigationNode[]; +}; + +export default function NodeMenu({ nav }: NodeMenuProps): JSX.Element { + const navWithAllProducts = [ + { + id: "all", + name: "All Products", + href: "/", + slug: "all-products", + children: [], + }, + ...nav, + ]; + return ( +
    + +
    + ); +} diff --git a/examples/password-reset/src/components/search/Pagination.tsx b/examples/password-reset/src/components/search/Pagination.tsx new file mode 100644 index 00000000..35c91e96 --- /dev/null +++ b/examples/password-reset/src/components/search/Pagination.tsx @@ -0,0 +1,56 @@ +import React from "react"; +import { useProducts } from "./ProductsProvider"; +import { usePathname } from "next/navigation"; +import { + Pagination as DisplayPagination, + PaginationContent, + PaginationItem, PaginationLink, +} from "../pagination/Pagination"; + + +function calculateTotalPages(totalItems: number, limit: number): number { + // Ensure both totalItems and limit are positive integers + totalItems = Math.max(0, Math.floor(totalItems)); + limit = Math.max(1, Math.floor(limit)); + + // Calculate the total number of pages using the formula + return Math.ceil(totalItems / limit); +} + +export const Pagination = (): JSX.Element => { + const { page } = useProducts(); + const pathname = usePathname(); + + if (!page) { + return <>; + } + + const { + meta: { + results: { total: totalResults = 0 }, + }, + } = page; + + const totalPages = calculateTotalPages(totalResults, page.meta.page.limit); + + return ( + + + {[...Array(totalPages).keys()].map((pageNumber) => ( + + + {pageNumber + 1} + + + ))} + + + ) +}; + +export default Pagination; diff --git a/examples/password-reset/src/components/search/ProductsProvider.tsx b/examples/password-reset/src/components/search/ProductsProvider.tsx new file mode 100644 index 00000000..488e8046 --- /dev/null +++ b/examples/password-reset/src/components/search/ProductsProvider.tsx @@ -0,0 +1,50 @@ +import { + createContext, + Dispatch, + SetStateAction, + useContext, + useState, +} from "react"; +import type { + ElasticPath, + ShopperCatalogResourcePage, +} from "@elasticpath/js-sdk"; +import { ShopperProduct } from "@elasticpath/react-shopper-hooks"; + +interface ProductsState { + client: ElasticPath; + setClient: Dispatch>; + page?: ShopperCatalogResourcePage; +} + +export const ProductsProviderContext = createContext( + null, +); + +export type ProductsProviderProps = { + children: React.ReactNode; + page?: ShopperCatalogResourcePage; + client: ElasticPath; +}; + +export const ProductsProvider = ({ + children, + page, + client: initialClient, +}: ProductsProviderProps) => { + const [client, setClient] = useState(initialClient); + + return ( + + {children} + + ); +}; + +export function useProducts() { + const context = useContext(ProductsProviderContext); + if (context === null) { + throw new Error("useProducts must be used within a ProductsProvider"); + } + return context; +} diff --git a/examples/password-reset/src/components/search/SearchResults.tsx b/examples/password-reset/src/components/search/SearchResults.tsx new file mode 100644 index 00000000..42a11eef --- /dev/null +++ b/examples/password-reset/src/components/search/SearchResults.tsx @@ -0,0 +1,75 @@ +"use client"; +import Hits from "./Hits"; +import Pagination from "./Pagination"; +import { useState } from "react"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; +import NodeMenu from "./NodeMenu"; +import { ShopperProduct, useStore } from "@elasticpath/react-shopper-hooks"; +import { ProductsProvider } from "./ProductsProvider"; +import { ShopperCatalogResourcePage } from "@elasticpath/js-sdk"; +import { BreadcrumbLookup } from "../../lib/types/breadcrumb-lookup"; +import { buildBreadcrumbLookup } from "../../lib/build-breadcrumb-lookup"; +import MobileFilters from "./MobileFilters"; + +interface ISearchResults { + page?: ShopperCatalogResourcePage; + nodes?: string[]; +} + +export default function SearchResults({ + page, + nodes, +}: ISearchResults): JSX.Element { + let [showFilterMenu, setShowFilterMenu] = useState(false); + const { nav, client } = useStore(); + const lookup = buildBreadcrumbLookup(nav ?? []); + const title = nodes ? resolveTitle(nodes, lookup) : "All Categories"; + + return ( + +
    +
    +
    + {title} +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +

    Category

    + {nav && } +
    + +
    + +
    + +
    +
    +
    +
    +
    + ); +} + +function resolveTitle(slugArray: string[], lookup?: BreadcrumbLookup): string { + return ( + lookup?.[`/${slugArray.join("/")}`]?.name ?? + slugArray[slugArray?.length - 1] + ); +} diff --git a/examples/password-reset/src/components/select/Select.tsx b/examples/password-reset/src/components/select/Select.tsx new file mode 100644 index 00000000..e5195705 --- /dev/null +++ b/examples/password-reset/src/components/select/Select.tsx @@ -0,0 +1,183 @@ +"use client"; + +import * as React from "react"; +import * as SelectPrimitive from "@radix-ui/react-select"; +import { ChevronDownIcon } from "@heroicons/react/24/solid"; +import { cn } from "../../lib/cn"; +import { ChevronUpIcon } from "@heroicons/react/20/solid"; +import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/outline"; +import { cva, VariantProps } from "class-variance-authority"; + +const Select = SelectPrimitive.Root; + +const SelectGroup = SelectPrimitive.Group; + +const SelectValue = SelectPrimitive.Value; + +const selectTriggerVariants = cva( + "flex w-full text-black/80 rounded-lg justify-between items-center border border-black/40 focus-visible:ring-0 focus-visible:border-black bg-white disabled:cursor-not-allowed disabled:opacity-50 leading-[1.6rem]", + { + variants: { + sizeKind: { + default: "px-4 py-[0.78rem]", + medium: "px-4 py-[0.44rem]", + mediumUntilSm: "px-4 py-[0.44rem] sm:px-4 sm:py-[0.78rem]", + }, + }, + defaultVariants: { + sizeKind: "default", + }, + }, +); + +export type SelectTriggerProps = React.ComponentPropsWithoutRef< + typeof SelectPrimitive.Trigger +> & + VariantProps; + +const SelectTrigger = React.forwardRef< + React.ElementRef, + SelectTriggerProps +>(({ className, children, sizeKind, ...props }, ref) => ( + span]:line-clamp-1", + )} + {...props} + > + {children} + + + + +)); +SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; + +const SelectScrollUpButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; + +const SelectScrollDownButton = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +SelectScrollDownButton.displayName = + SelectPrimitive.ScrollDownButton.displayName; + +const SelectContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, position = "popper", ...props }, ref) => ( + + + + + {children} + + + + +)); +SelectContent.displayName = SelectPrimitive.Content.displayName; + +const SelectLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SelectLabel.displayName = SelectPrimitive.Label.displayName; + +const SelectItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + + {children} + +)); +SelectItem.displayName = SelectPrimitive.Item.displayName; + +const SelectSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SelectSeparator.displayName = SelectPrimitive.Separator.displayName; + +export { + Select, + SelectGroup, + SelectValue, + SelectTrigger, + SelectContent, + SelectLabel, + SelectItem, + SelectSeparator, + SelectScrollUpButton, + SelectScrollDownButton, +}; diff --git a/examples/password-reset/src/components/separator/Separator.tsx b/examples/password-reset/src/components/separator/Separator.tsx new file mode 100644 index 00000000..8a98a5e1 --- /dev/null +++ b/examples/password-reset/src/components/separator/Separator.tsx @@ -0,0 +1,29 @@ +"use client"; +import * as React from "react"; +import * as SeparatorPrimitive from "@radix-ui/react-separator"; +import { cn } from "../../lib/cn"; + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref, + ) => ( + + ), +); +Separator.displayName = SeparatorPrimitive.Root.displayName; + +export { Separator }; diff --git a/examples/password-reset/src/components/shared/blurb.tsx b/examples/password-reset/src/components/shared/blurb.tsx new file mode 100644 index 00000000..87df7aae --- /dev/null +++ b/examples/password-reset/src/components/shared/blurb.tsx @@ -0,0 +1,76 @@ +import { ReactNode } from "react"; + +const Para = ({ children }: { children: ReactNode }) => { + return
    {children}
    ; +}; + +interface IBlurbProps { + title: string; +} + +const Blurb = ({ title }: IBlurbProps) => ( +
    +

    {title}

    + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec arcu + lectus, pharetra nec velit in, vehicula suscipit tellus. Quisque id mollis + magna. Cras nec lacinia ligula. Morbi aliquam tristique purus, nec dictum + metus euismod at. Vestibulum mollis metus lobortis lectus sodales + eleifend. Class aptent taciti sociosqu ad litora torquent per conubia + nostra, per inceptos himenaeos. Vivamus eget elementum eros, et ultricies + mi. Donec eget dolor imperdiet, gravida ante a, molestie tortor. Nullam + viverra, orci gravida sollicitudin auctor, urna magna condimentum risus, + vitae venenatis turpis mauris sed ligula. Fusce mattis, mauris ut eleifend + ullamcorper, dui felis tincidunt libero, ut commodo arcu leo a ligula. + Cras congue maximus magna, et porta nisl pulvinar in. Nam congue orci + ornare scelerisque elementum. Quisque purus justo, molestie ut leo at, + tristique pretium dui. + + + + Vestibulum imperdiet commodo egestas. Proin tincidunt leo non purus + euismod dictum. Vivamus sagittis mauris dolor, quis egestas purus placerat + eget. Mauris finibus scelerisque augue ut ultrices. Praesent vitae nulla + lorem. Ut eget accumsan risus, sed fringilla orci. Nunc volutpat, odio vel + ornare ullamcorper, massa mauris dapibus nunc, sed euismod lectus erat + eget ligula. Duis fringilla elit vel eleifend luctus. Quisque non blandit + magna. Vivamus pharetra, dolor sed molestie ultricies, tellus ex egestas + lacus, in posuere risus diam non massa. Phasellus in justo in urna + faucibus cursus. + + + + Nullam nibh nisi, lobortis at rhoncus ut, viverra at turpis. Mauris ac + sollicitudin diam. Phasellus non orci massa. Donec tincidunt odio justo. + Sed gravida leo turpis, vitae blandit sem pharetra sit amet. Vestibulum + ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia + curae; Orci varius natoque penatibus et magnis dis parturient montes, + nascetur ridiculus mus. + + + + In in pulvinar turpis, vel pulvinar ipsum. Praesent vel commodo nisi, id + maximus ex. Integer lorem augue, hendrerit et enim vel, eleifend blandit + felis. Integer egestas risus purus, ac rhoncus orci faucibus ac. + Pellentesque iaculis ligula a mauris aliquam, at ullamcorper est + vestibulum. Proin maximus sagittis purus ac pretium. Ut accumsan vitae + nisl sed viverra. + + + + Vivamus malesuada elit facilisis, fringilla lacus non, vulputate felis. + Curabitur dignissim quis ipsum eget pellentesque. Duis efficitur nec nisl + sit amet porta. Maecenas ac dui a felis finibus elementum feugiat at nibh. + Donec convallis sodales neque. Integer id libero eget diam finibus + tincidunt id id diam. Fusce ut lectus nisi. Donec orci enim, semper ac + feugiat vitae, dignissim non enim. Vestibulum commodo dolor nec sem + viverra gravida. Ut laoreet eu tortor auctor consequat. Nulla quis mauris + mollis, aliquam mi nec, laoreet ligula. Fusce laoreet lorem et malesuada + suscipit. Nullam convallis, risus a posuere ultrices, velit augue + porttitor ante, vitae lobortis ligula velit id justo. Praesent nec lorem + massa. + +
    +); + +export default Blurb; diff --git a/examples/password-reset/src/components/sheet/Sheet.tsx b/examples/password-reset/src/components/sheet/Sheet.tsx new file mode 100644 index 00000000..d117458f --- /dev/null +++ b/examples/password-reset/src/components/sheet/Sheet.tsx @@ -0,0 +1,134 @@ +"use client"; + +import * as React from "react"; +import * as SheetPrimitive from "@radix-ui/react-dialog"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "../../lib/cn"; + +const Sheet = SheetPrimitive.Root; + +const SheetTrigger = SheetPrimitive.Trigger; + +const SheetClose = SheetPrimitive.Close; + +const SheetPortal = SheetPrimitive.Portal; + +const SheetOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetOverlay.displayName = SheetPrimitive.Overlay.displayName; + +const sheetVariants = cva( + "fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500", + { + variants: { + side: { + top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", + bottom: + "inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", + left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-[29.5rem]", + right: + "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-[29.5rem]", + }, + }, + defaultVariants: { + side: "right", + }, + }, +); + +interface SheetContentProps + extends React.ComponentPropsWithoutRef, + VariantProps {} + +const SheetContent = React.forwardRef< + React.ElementRef, + SheetContentProps +>(({ side = "right", className, children, ...props }, ref) => ( + + + + {children} + + +)); +SheetContent.displayName = SheetPrimitive.Content.displayName; + +const SheetHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
    +); +SheetHeader.displayName = "SheetHeader"; + +const SheetFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
    +); +SheetFooter.displayName = "SheetFooter"; + +const SheetTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetTitle.displayName = SheetPrimitive.Title.displayName; + +const SheetDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +SheetDescription.displayName = SheetPrimitive.Description.displayName; + +export { + Sheet, + SheetPortal, + SheetOverlay, + SheetTrigger, + SheetClose, + SheetContent, + SheetHeader, + SheetFooter, + SheetTitle, + SheetDescription, +}; diff --git a/examples/password-reset/src/components/shimmer.tsx b/examples/password-reset/src/components/shimmer.tsx new file mode 100644 index 00000000..208e3f11 --- /dev/null +++ b/examples/password-reset/src/components/shimmer.tsx @@ -0,0 +1,13 @@ +export const shimmer = (w: number, h: number) => ` + + + + + + + + + + + +`; diff --git a/examples/password-reset/src/components/skeleton/Skeleton.tsx b/examples/password-reset/src/components/skeleton/Skeleton.tsx new file mode 100644 index 00000000..788edc09 --- /dev/null +++ b/examples/password-reset/src/components/skeleton/Skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from "../../lib/cn"; + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
    + ); +} + +export { Skeleton }; diff --git a/examples/password-reset/src/components/toast/toaster.tsx b/examples/password-reset/src/components/toast/toaster.tsx new file mode 100644 index 00000000..758c60d7 --- /dev/null +++ b/examples/password-reset/src/components/toast/toaster.tsx @@ -0,0 +1,23 @@ +"use client"; +import { useEffect } from "react"; +import { useEvent } from "@elasticpath/react-shopper-hooks"; +import { ToastContainer, toast } from "react-toastify"; +import "react-toastify/dist/ReactToastify.css"; + +export function Toaster(): JSX.Element { + const { events } = useEvent(); + + useEffect(() => { + const sub = events.subscribe((event) => { + const toastFn = event.type === "success" ? toast.success : toast.error; + toastFn(`${"message" in event ? event.message : undefined}`, { + position: "bottom-center", + autoClose: 3000, + hideProgressBar: true, + }); + }); + return () => sub.unsubscribe(); + }, [events]); + + return ; +} diff --git a/examples/password-reset/src/hooks/use-countries.tsx b/examples/password-reset/src/hooks/use-countries.tsx new file mode 100644 index 00000000..0f836739 --- /dev/null +++ b/examples/password-reset/src/hooks/use-countries.tsx @@ -0,0 +1,18 @@ +import { useQuery } from "@tanstack/react-query"; +import { countries } from "../lib/all-countries"; + +export function useCountries() { + const storeCountries = useQuery({ + queryKey: ["countries"], + queryFn: () => { + /** + * Replace these with your own source for supported delivery countries. You can also fetch them from the API. + */ + return countries; + }, + }); + + return { + ...storeCountries, + }; +} diff --git a/examples/password-reset/src/lib/all-countries.ts b/examples/password-reset/src/lib/all-countries.ts new file mode 100644 index 00000000..0a772b3d --- /dev/null +++ b/examples/password-reset/src/lib/all-countries.ts @@ -0,0 +1,258 @@ +export type CountryValue = { + name: string; + code: string; +}; + +export const countries: CountryValue[] = [ + { name: "Albania", code: "AL" }, + { name: "Åland Islands", code: "AX" }, + { name: "Algeria", code: "DZ" }, + { name: "American Samoa", code: "AS" }, + { name: "Andorra", code: "AD" }, + { name: "Angola", code: "AO" }, + { name: "Anguilla", code: "AI" }, + { name: "Antarctica", code: "AQ" }, + { name: "Antigua and Barbuda", code: "AG" }, + { name: "Argentina", code: "AR" }, + { name: "Armenia", code: "AM" }, + { name: "Aruba", code: "AW" }, + { name: "Australia", code: "AU" }, + { name: "Austria", code: "AT" }, + { name: "Azerbaijan", code: "AZ" }, + { name: "Bahamas (the)", code: "BS" }, + { name: "Bahrain", code: "BH" }, + { name: "Bangladesh", code: "BD" }, + { name: "Barbados", code: "BB" }, + { name: "Belarus", code: "BY" }, + { name: "Belgium", code: "BE" }, + { name: "Belize", code: "BZ" }, + { name: "Benin", code: "BJ" }, + { name: "Bermuda", code: "BM" }, + { name: "Bhutan", code: "BT" }, + { name: "Bolivia (Plurinational State of)", code: "BO" }, + { name: "Bonaire, Sint Eustatius and Saba", code: "BQ" }, + { name: "Bosnia and Herzegovina", code: "BA" }, + { name: "Botswana", code: "BW" }, + { name: "Bouvet Island", code: "BV" }, + { name: "Brazil", code: "BR" }, + { name: "British Indian Ocean Territory (the)", code: "IO" }, + { name: "Brunei Darussalam", code: "BN" }, + { name: "Bulgaria", code: "BG" }, + { name: "Burkina Faso", code: "BF" }, + { name: "Burundi", code: "BI" }, + { name: "Cabo Verde", code: "CV" }, + { name: "Cambodia", code: "KH" }, + { name: "Cameroon", code: "CM" }, + { name: "Canada", code: "CA" }, + { name: "Cayman Islands (the)", code: "KY" }, + { name: "Central African Republic (the)", code: "CF" }, + { name: "Chad", code: "TD" }, + { name: "Chile", code: "CL" }, + { name: "China", code: "CN" }, + { name: "Christmas Island", code: "CX" }, + { name: "Cocos (Keeling) Islands (the)", code: "CC" }, + { name: "Colombia", code: "CO" }, + { name: "Comoros (the)", code: "KM" }, + { name: "Congo (the Democratic Republic of the)", code: "CD" }, + { name: "Congo (the)", code: "CG" }, + { name: "Cook Islands (the)", code: "CK" }, + { name: "Costa Rica", code: "CR" }, + { name: "Croatia", code: "HR" }, + { name: "Cuba", code: "CU" }, + { name: "Curaçao", code: "CW" }, + { name: "Cyprus", code: "CY" }, + { name: "Czechia", code: "CZ" }, + { name: "Côte d'Ivoire", code: "CI" }, + { name: "Denmark", code: "DK" }, + { name: "Djibouti", code: "DJ" }, + { name: "Dominica", code: "DM" }, + { name: "Dominican Republic (the)", code: "DO" }, + { name: "Ecuador", code: "EC" }, + { name: "Egypt", code: "EG" }, + { name: "El Salvador", code: "SV" }, + { name: "Equatorial Guinea", code: "GQ" }, + { name: "Eritrea", code: "ER" }, + { name: "Estonia", code: "EE" }, + { name: "Eswatini", code: "SZ" }, + { name: "Ethiopia", code: "ET" }, + { name: "Falkland Islands (the) [Malvinas]", code: "FK" }, + { name: "Faroe Islands (the)", code: "FO" }, + { name: "Fiji", code: "FJ" }, + { name: "Finland", code: "FI" }, + { name: "France", code: "FR" }, + { name: "French Guiana", code: "GF" }, + { name: "French Polynesia", code: "PF" }, + { name: "French Southern Territories (the)", code: "TF" }, + { name: "Gabon", code: "GA" }, + { name: "Gambia (the)", code: "GM" }, + { name: "Georgia", code: "GE" }, + { name: "Germany", code: "DE" }, + { name: "Ghana", code: "GH" }, + { name: "Gibraltar", code: "GI" }, + { name: "Greece", code: "GR" }, + { name: "Greenland", code: "GL" }, + { name: "Grenada", code: "GD" }, + { name: "Guadeloupe", code: "GP" }, + { name: "Guam", code: "GU" }, + { name: "Guatemala", code: "GT" }, + { name: "Guernsey", code: "GG" }, + { name: "Guinea", code: "GN" }, + { name: "Guinea-Bissau", code: "GW" }, + { name: "Guyana", code: "GY" }, + { name: "Haiti", code: "HT" }, + { name: "Heard Island and McDonald Islands", code: "HM" }, + { name: "Holy See (the)", code: "VA" }, + { name: "Honduras", code: "HN" }, + { name: "Hong Kong", code: "HK" }, + { name: "Hungary", code: "HU" }, + { name: "Iceland", code: "IS" }, + { name: "India", code: "IN" }, + { name: "Indonesia", code: "ID" }, + { name: "Iran (Islamic Republic of)", code: "IR" }, + { name: "Iraq", code: "IQ" }, + { name: "Ireland", code: "IE" }, + { name: "Isle of Man", code: "IM" }, + { name: "Israel", code: "IL" }, + { name: "Italy", code: "IT" }, + { name: "Jamaica", code: "JM" }, + { name: "Japan", code: "JP" }, + { name: "Jersey", code: "JE" }, + { name: "Jordan", code: "JO" }, + { name: "Kazakhstan", code: "KZ" }, + { name: "Kenya", code: "KE" }, + { name: "Kiribati", code: "KI" }, + { name: "Korea (the Democratic People's Republic of)", code: "KP" }, + { name: "Korea (the Republic of)", code: "KR" }, + { name: "Kuwait", code: "KW" }, + { name: "Kyrgyzstan", code: "KG" }, + { name: "Lao People's Democratic Republic (the)", code: "LA" }, + { name: "Latvia", code: "LV" }, + { name: "Lebanon", code: "LB" }, + { name: "Lesotho", code: "LS" }, + { name: "Liberia", code: "LR" }, + { name: "Libya", code: "LY" }, + { name: "Liechtenstein", code: "LI" }, + { name: "Lithuania", code: "LT" }, + { name: "Luxembourg", code: "LU" }, + { name: "Macao", code: "MO" }, + { name: "Madagascar", code: "MG" }, + { name: "Malawi", code: "MW" }, + { name: "Malaysia", code: "MY" }, + { name: "Maldives", code: "MV" }, + { name: "Mali", code: "ML" }, + { name: "Malta", code: "MT" }, + { name: "Marshall Islands (the)", code: "MH" }, + { name: "Martinique", code: "MQ" }, + { name: "Mauritania", code: "MR" }, + { name: "Mauritius", code: "MU" }, + { name: "Mayotte", code: "YT" }, + { name: "Mexico", code: "MX" }, + { name: "Micronesia (Federated States of)", code: "FM" }, + { name: "Moldova (the Republic of)", code: "MD" }, + { name: "Monaco", code: "MC" }, + { name: "Mongolia", code: "MN" }, + { name: "Montenegro", code: "ME" }, + { name: "Montserrat", code: "MS" }, + { name: "Morocco", code: "MA" }, + { name: "Mozambique", code: "MZ" }, + { name: "Myanmar", code: "MM" }, + { name: "Namibia", code: "NA" }, + { name: "Nauru", code: "NR" }, + { name: "Nepal", code: "NP" }, + { name: "Netherlands (the)", code: "NL" }, + { name: "New Caledonia", code: "NC" }, + { name: "New Zealand", code: "NZ" }, + { name: "Nicaragua", code: "NI" }, + { name: "Niger (the)", code: "NE" }, + { name: "Nigeria", code: "NG" }, + { name: "Niue", code: "NU" }, + { name: "Norfolk Island", code: "NF" }, + { name: "Northern Mariana Islands (the)", code: "MP" }, + { name: "Norway", code: "NO" }, + { name: "Oman", code: "OM" }, + { name: "Pakistan", code: "PK" }, + { name: "Palau", code: "PW" }, + { name: "Palestine, State of", code: "PS" }, + { name: "Panama", code: "PA" }, + { name: "Papua New Guinea", code: "PG" }, + { name: "Paraguay", code: "PY" }, + { name: "Peru", code: "PE" }, + { name: "Philippines (the)", code: "PH" }, + { name: "Pitcairn", code: "PN" }, + { name: "Poland", code: "PL" }, + { name: "Portugal", code: "PT" }, + { name: "Puerto Rico", code: "PR" }, + { name: "Qatar", code: "QA" }, + { name: "Republic of North Macedonia", code: "MK" }, + { name: "Romania", code: "RO" }, + { name: "Russian Federation (the)", code: "RU" }, + { name: "Rwanda", code: "RW" }, + { name: "Réunion", code: "RE" }, + { name: "Saint Barthélemy", code: "BL" }, + { name: "Saint Helena, Ascension and Tristan da Cunha", code: "SH" }, + { name: "Saint Kitts and Nevis", code: "KN" }, + { name: "Saint Lucia", code: "LC" }, + { name: "Saint Martin (French part)", code: "MF" }, + { name: "Saint Pierre and Miquelon", code: "PM" }, + { name: "Saint Vincent and the Grenadines", code: "VC" }, + { name: "Samoa", code: "WS" }, + { name: "San Marino", code: "SM" }, + { name: "Sao Tome and Principe", code: "ST" }, + { name: "Saudi Arabia", code: "SA" }, + { name: "Senegal", code: "SN" }, + { name: "Serbia", code: "RS" }, + { name: "Seychelles", code: "SC" }, + { name: "Sierra Leone", code: "SL" }, + { name: "Singapore", code: "SG" }, + { name: "Sint Maarten (Dutch part)", code: "SX" }, + { name: "Slovakia", code: "SK" }, + { name: "Slovenia", code: "SI" }, + { name: "Solomon Islands", code: "SB" }, + { name: "Somalia", code: "SO" }, + { name: "South Africa", code: "ZA" }, + { name: "South Georgia and the South Sandwich Islands", code: "GS" }, + { name: "South Sudan", code: "SS" }, + { name: "Spain", code: "ES" }, + { name: "Sri Lanka", code: "LK" }, + { name: "Sudan (the)", code: "SD" }, + { name: "Suriname", code: "SR" }, + { name: "Svalbard and Jan Mayen", code: "SJ" }, + { name: "Sweden", code: "SE" }, + { name: "Switzerland", code: "CH" }, + { name: "Syrian Arab Republic", code: "SY" }, + { name: "Taiwan (Province of China)", code: "TW" }, + { name: "Tajikistan", code: "TJ" }, + { name: "Tanzania, United Republic of", code: "TZ" }, + { name: "Thailand", code: "TH" }, + { name: "Timor-Leste", code: "TL" }, + { name: "Togo", code: "TG" }, + { name: "Tokelau", code: "TK" }, + { name: "Tonga", code: "TO" }, + { name: "Trinidad and Tobago", code: "TT" }, + { name: "Tunisia", code: "TN" }, + { name: "Turkey", code: "TR" }, + { name: "Turkmenistan", code: "TM" }, + { name: "Turks and Caicos Islands (the)", code: "TC" }, + { name: "Tuvalu", code: "TV" }, + { name: "Uganda", code: "UG" }, + { name: "Ukraine", code: "UA" }, + { name: "United Arab Emirates (the)", code: "AE" }, + { + name: "United Kingdom of Great Britain and Northern Ireland (the)", + code: "GB", + }, + { name: "United States Minor Outlying Islands (the)", code: "UM" }, + { name: "United States of America (the)", code: "US" }, + { name: "Uruguay", code: "UY" }, + { name: "Uzbekistan", code: "UZ" }, + { name: "Vanuatu", code: "VU" }, + { name: "Venezuela (Bolivarian Republic of)", code: "VE" }, + { name: "Viet Nam", code: "VN" }, + { name: "Virgin Islands (British)", code: "VG" }, + { name: "Virgin Islands (U.S.)", code: "VI" }, + { name: "Wallis and Futuna", code: "WF" }, + { name: "Western Sahara", code: "EH" }, + { name: "Yemen", code: "YE" }, + { name: "Zambia", code: "ZM" }, + { name: "Zimbabwe", code: "ZW" }, +]; diff --git a/examples/password-reset/src/lib/build-breadcrumb-lookup.ts b/examples/password-reset/src/lib/build-breadcrumb-lookup.ts new file mode 100644 index 00000000..4d170da9 --- /dev/null +++ b/examples/password-reset/src/lib/build-breadcrumb-lookup.ts @@ -0,0 +1,19 @@ +import { NavigationNode } from "./build-site-navigation"; +import { BreadcrumbLookup } from "./types/breadcrumb-lookup"; + +export function buildBreadcrumbLookup( + nodes: NavigationNode[], +): BreadcrumbLookup { + return nodes.reduce((acc, curr) => { + const { href, name, children, slug } = curr; + return { + ...acc, + [href]: { + href, + name, + slug, + }, + ...(children && buildBreadcrumbLookup(children)), + }; + }, {}); +} diff --git a/examples/password-reset/src/lib/build-site-navigation.ts b/examples/password-reset/src/lib/build-site-navigation.ts new file mode 100644 index 00000000..d50c7f34 --- /dev/null +++ b/examples/password-reset/src/lib/build-site-navigation.ts @@ -0,0 +1,104 @@ +import type { Hierarchy,ElasticPath } from "@elasticpath/js-sdk"; +import { + getHierarchies, + getHierarchyChildren, + getHierarchyNodes, +} from "../services/hierarchy"; + +interface ISchema { + name: string; + slug: string; + href: string; + id: string; + children: ISchema[]; +} + +export interface NavigationNode { + name: string; + slug: string; + href: string; + id: string; + children: NavigationNode[]; +} + +export async function buildSiteNavigation( + client: ElasticPath, +): Promise { + // Fetch hierarchies to be used as top level nav + const hierarchies = await getHierarchies(client); + return constructTree(hierarchies, client); +} + +/** + * Construct hierarchy tree, limited to 5 hierarchies at the top level + */ +function constructTree( + hierarchies: Hierarchy[], + client: ElasticPath, +): Promise { + const tree = hierarchies + .slice(0, 4) + .map((hierarchy) => + createNode({ + name: hierarchy.attributes.name, + id: hierarchy.id, + slug: hierarchy.attributes.slug, + }), + ) + .map(async (hierarchy) => { + // Fetch first-level nav ('parent nodes') - the direct children of each hierarchy + const directChildren = await getHierarchyChildren(hierarchy.id, client); + // Fetch all nodes in each hierarchy (i.e. all 'child nodes' belonging to a hierarchy) + const allNodes = await getHierarchyNodes(hierarchy.id, client); + + // Build 2nd level by finding all 'child nodes' belonging to each first level featured-nodes + const directs = directChildren.slice(0, 4).map((child) => { + const children: ISchema[] = allNodes + .filter((node) => node?.relationships?.parent.data.id === child.id) + .map((node) => + createNode({ + name: node.attributes.name, + id: node.id, + slug: node.attributes.slug, + hrefBase: `${hierarchy.href}/${child.attributes.slug}`, + }), + ); + + return createNode({ + name: child.attributes.name, + id: child.id, + slug: child.attributes.slug, + hrefBase: hierarchy.href, + children, + }); + }); + + return { ...hierarchy, children: directs }; + }); + + return Promise.all(tree); +} + +interface CreateNodeDefinition { + name: string; + id: string; + slug?: string; + hrefBase?: string; + children?: ISchema[]; +} + +function createNode({ + name, + id, + slug = "missing-slug", + hrefBase = "", + children = [], +}: CreateNodeDefinition): ISchema { + return { + name, + id, + slug, + href: `${hrefBase}/${slug}`, + children, + }; +} diff --git a/examples/password-reset/src/lib/cart-cookie-server.ts b/examples/password-reset/src/lib/cart-cookie-server.ts new file mode 100644 index 00000000..86bf8f6f --- /dev/null +++ b/examples/password-reset/src/lib/cart-cookie-server.ts @@ -0,0 +1,18 @@ +import "server-only"; +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; +import { cookies } from "next/headers"; + +const CART_COOKIE_NAME = `${COOKIE_PREFIX_KEY}_ep_cart`; + +/** + * The cart cookie is set by nextjs middleware. + */ +export function getCartCookieServer(): string { + const possibleCartCookie = cookies().get(CART_COOKIE_NAME); + + if (!possibleCartCookie) { + throw Error(`Failed to fetch cart cookie! key ${CART_COOKIE_NAME}`); + } + + return possibleCartCookie.value; +} diff --git a/examples/password-reset/src/lib/cn.tsx b/examples/password-reset/src/lib/cn.tsx new file mode 100644 index 00000000..a5ef1935 --- /dev/null +++ b/examples/password-reset/src/lib/cn.tsx @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/examples/password-reset/src/lib/color-lookup.ts b/examples/password-reset/src/lib/color-lookup.ts new file mode 100644 index 00000000..9c147119 --- /dev/null +++ b/examples/password-reset/src/lib/color-lookup.ts @@ -0,0 +1,10 @@ +export const colorLookup: { [key: string]: string } = { + gray: "gray", + grey: "gray", + red: "red", + white: "white", + teal: "teal", + purple: "purple", + green: "green", + blue: "blue", +}; diff --git a/examples/password-reset/src/lib/connect-products-with-main-images.ts b/examples/password-reset/src/lib/connect-products-with-main-images.ts new file mode 100644 index 00000000..f1976000 --- /dev/null +++ b/examples/password-reset/src/lib/connect-products-with-main-images.ts @@ -0,0 +1,29 @@ +import { File, ProductResponse } from "@elasticpath/js-sdk"; +import { + ProductImageObject, + ProductResponseWithImage, +} from "./types/product-types"; + +export const connectProductsWithMainImages = ( + products: ProductResponse[], + images: File[], +): ProductResponseWithImage[] => { + // Object with image id as a key and File data as a value + let imagesObject: ProductImageObject = {}; + images.forEach((image) => { + imagesObject[image.id] = image; + }); + + const productList: ProductResponseWithImage[] = [...products]; + + productList.forEach((product) => { + if ( + product.relationships.main_image?.data && + imagesObject[product.relationships.main_image.data?.id] + ) { + product.main_image = + imagesObject[product.relationships.main_image.data?.id]; + } + }); + return productList; +}; diff --git a/examples/password-reset/src/lib/constants.ts b/examples/password-reset/src/lib/constants.ts new file mode 100644 index 00000000..eaaf64a1 --- /dev/null +++ b/examples/password-reset/src/lib/constants.ts @@ -0,0 +1,6 @@ +export const DEFAULT_PAGINATION_LIMIT = 25; +export const TAGS = { + cart: "cart", + products: "products", + nodes: "nodes", +}; diff --git a/examples/password-reset/src/lib/cookie-constants.ts b/examples/password-reset/src/lib/cookie-constants.ts new file mode 100644 index 00000000..62392d7f --- /dev/null +++ b/examples/password-reset/src/lib/cookie-constants.ts @@ -0,0 +1,4 @@ +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; + +export const CREDENTIALS_COOKIE_NAME = `${COOKIE_PREFIX_KEY}_ep_credentials`; +export const ACCOUNT_MEMBER_TOKEN_COOKIE_NAME = `${COOKIE_PREFIX_KEY}_ep_account_member_token`; diff --git a/examples/password-reset/src/lib/create-breadcrumb.ts b/examples/password-reset/src/lib/create-breadcrumb.ts new file mode 100644 index 00000000..f3c1c8e2 --- /dev/null +++ b/examples/password-reset/src/lib/create-breadcrumb.ts @@ -0,0 +1,31 @@ +import { BreadcrumbLookup } from "./types/breadcrumb-lookup"; + +export interface BreadcrumbEntry { + value: string; + breadcrumb: string; + label: string; +} + +export function createBreadcrumb( + [head, ...tail]: string[], + lookup?: BreadcrumbLookup, + acc: BreadcrumbEntry[] = [], + breadcrumb?: string, +): BreadcrumbEntry[] { + const updatedBreadcrumb = `${breadcrumb ? `${breadcrumb}/` : ""}${head}`; + + const label = lookup?.[`/${updatedBreadcrumb}`]?.name ?? head; + + const entry = { + value: head, + breadcrumb: updatedBreadcrumb, + label, + }; + if (!head) { + return []; + } + if (tail.length < 1) { + return [...acc, entry]; + } + return createBreadcrumb(tail, lookup, [...acc, entry], updatedBreadcrumb); +} diff --git a/examples/password-reset/src/lib/custom-rule-headers.ts b/examples/password-reset/src/lib/custom-rule-headers.ts new file mode 100644 index 00000000..b320e365 --- /dev/null +++ b/examples/password-reset/src/lib/custom-rule-headers.ts @@ -0,0 +1,17 @@ +import { isEmptyObj } from "./is-empty-object"; + +export function resolveEpccCustomRuleHeaders(): + | { "EP-Context-Tag"?: string; "EP-Channel"?: string } + | undefined { + const { epContextTag, epChannel } = { + epContextTag: process.env.NEXT_PUBLIC_CONTEXT_TAG, + epChannel: process.env.NEXT_PUBLIC_CHANNEL, + }; + + const headers = { + ...(epContextTag ? { "EP-Context-Tag": epContextTag } : {}), + ...(epChannel ? { "EP-Channel": epChannel } : {}), + }; + + return isEmptyObj(headers) ? undefined : headers; +} diff --git a/examples/password-reset/src/lib/epcc-errors.ts b/examples/password-reset/src/lib/epcc-errors.ts new file mode 100644 index 00000000..6f1f58c5 --- /dev/null +++ b/examples/password-reset/src/lib/epcc-errors.ts @@ -0,0 +1,27 @@ +export function isNoDefaultCatalogError( + errors: object[], +): errors is [{ detail: string }] { + const error = errors[0]; + return ( + hasDetail(error) && + error.detail === + "unable to resolve default catalog: no default catalog id can be identified: not found" + ); +} + +function hasDetail(err: object): err is { detail: string } { + return "detail" in err; +} + +export function isEPError(err: unknown): err is { errors: object[] } { + return ( + typeof err === "object" && + !!err && + hasErrors(err) && + Array.isArray(err.errors) + ); +} + +function hasErrors(err: object): err is { errors: object[] } { + return "errors" in err; +} diff --git a/examples/password-reset/src/lib/epcc-implicit-client.ts b/examples/password-reset/src/lib/epcc-implicit-client.ts new file mode 100644 index 00000000..0067d84b --- /dev/null +++ b/examples/password-reset/src/lib/epcc-implicit-client.ts @@ -0,0 +1,37 @@ +import { gateway, StorageFactory } from "@elasticpath/js-sdk"; +import { epccEnv } from "./resolve-epcc-env"; +import { resolveEpccCustomRuleHeaders } from "./custom-rule-headers"; +import { deleteCookie, getCookie, setCookie } from "cookies-next"; +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; +import { EP_CURRENCY_CODE } from "./resolve-ep-currency-code"; + +const headers = resolveEpccCustomRuleHeaders(); + +const { client_id, host } = epccEnv; + +export function getEpccImplicitClient() { + return gateway({ + name: COOKIE_PREFIX_KEY, + client_id, + host, + currency: EP_CURRENCY_CODE, + ...(headers ? { headers } : {}), + storage: createNextCookieStorageFactory(), + }); +} + +function createNextCookieStorageFactory(): StorageFactory { + return { + set: (key: string, value: string): void => { + setCookie(key, value, { + sameSite: "strict", + }); + }, + get: (key: string): any => { + return getCookie(key); + }, + delete: (key: string) => { + deleteCookie(key); + }, + }; +} diff --git a/examples/password-reset/src/lib/epcc-server-client.ts b/examples/password-reset/src/lib/epcc-server-client.ts new file mode 100644 index 00000000..4c59b599 --- /dev/null +++ b/examples/password-reset/src/lib/epcc-server-client.ts @@ -0,0 +1,29 @@ +import { + ConfigOptions, + gateway as EPCCGateway, + MemoryStorageFactory, +} from "@elasticpath/js-sdk"; +import { epccEnv } from "./resolve-epcc-env"; +import { resolveEpccCustomRuleHeaders } from "./custom-rule-headers"; +import { EP_CURRENCY_CODE } from "./resolve-ep-currency-code"; + +const headers = resolveEpccCustomRuleHeaders(); + +const { client_id, client_secret, host } = epccEnv; + +if (typeof client_secret !== "string") { + throw Error( + "Attempted to use client credentials client without a defined client_secret. This is most likely caused by trying to use server side client on the client side.", + ); +} + +const config: ConfigOptions = { + client_id, + client_secret, + host, + currency: EP_CURRENCY_CODE, + storage: new MemoryStorageFactory(), + ...(headers ? { headers } : {}), +}; + +export const epccServerClient = EPCCGateway(config); diff --git a/examples/password-reset/src/lib/epcc-server-side-credentials-client.ts b/examples/password-reset/src/lib/epcc-server-side-credentials-client.ts new file mode 100644 index 00000000..13ca16ef --- /dev/null +++ b/examples/password-reset/src/lib/epcc-server-side-credentials-client.ts @@ -0,0 +1,49 @@ +import "server-only"; +import { gateway, StorageFactory } from "@elasticpath/js-sdk"; +import { epccEnv } from "./resolve-epcc-env"; +import { resolveEpccCustomRuleHeaders } from "./custom-rule-headers"; +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; +import { EP_CURRENCY_CODE } from "./resolve-ep-currency-code"; +import { CREDENTIALS_COOKIE_NAME } from "./cookie-constants"; +import { cookies } from "next/headers"; + +const customHeaders = resolveEpccCustomRuleHeaders(); + +const { client_id, host, client_secret } = epccEnv; + +export function getServerSideCredentialsClient() { + const credentialsCookie = cookies().get(CREDENTIALS_COOKIE_NAME); + + return gateway({ + name: `${COOKIE_PREFIX_KEY}_creds`, + client_id, + client_secret, + host, + currency: EP_CURRENCY_CODE, + ...(customHeaders ? { headers: customHeaders } : {}), + reauth: false, + storage: createServerSideNextCookieStorageFactory(credentialsCookie?.value), + }); +} + +function createServerSideNextCookieStorageFactory( + initialCookieValue?: string, +): StorageFactory { + let state = new Map(); + + if (initialCookieValue) { + state.set(`${COOKIE_PREFIX_KEY}_ep_credentials`, initialCookieValue); + } + + return { + set: (key: string, value: string): void => { + state.set(key, value); + }, + get: (key: string): any => { + return state.get(key); + }, + delete: (key: string) => { + state.delete(key); + }, + }; +} diff --git a/examples/password-reset/src/lib/epcc-server-side-implicit-client.ts b/examples/password-reset/src/lib/epcc-server-side-implicit-client.ts new file mode 100644 index 00000000..dfba3600 --- /dev/null +++ b/examples/password-reset/src/lib/epcc-server-side-implicit-client.ts @@ -0,0 +1,48 @@ +import "server-only"; +import { gateway, StorageFactory } from "@elasticpath/js-sdk"; +import { epccEnv } from "./resolve-epcc-env"; +import { resolveEpccCustomRuleHeaders } from "./custom-rule-headers"; +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; +import { EP_CURRENCY_CODE } from "./resolve-ep-currency-code"; +import { CREDENTIALS_COOKIE_NAME } from "./cookie-constants"; +import { cookies } from "next/headers"; + +const customHeaders = resolveEpccCustomRuleHeaders(); + +const { client_id, host } = epccEnv; + +export function getServerSideImplicitClient() { + const credentialsCookie = cookies().get(CREDENTIALS_COOKIE_NAME); + + return gateway({ + name: COOKIE_PREFIX_KEY, + client_id, + host, + currency: EP_CURRENCY_CODE, + ...(customHeaders ? { headers: customHeaders } : {}), + reauth: false, + storage: createServerSideNextCookieStorageFactory(credentialsCookie?.value), + }); +} + +function createServerSideNextCookieStorageFactory( + initialCookieValue?: string, +): StorageFactory { + let state = new Map(); + + if (initialCookieValue) { + state.set(`${COOKIE_PREFIX_KEY}_ep_credentials`, initialCookieValue); + } + + return { + set: (key: string, value: string): void => { + state.set(key, value); + }, + get: (key: string): any => { + return state.get(key); + }, + delete: (key: string) => { + state.delete(key); + }, + }; +} diff --git a/examples/password-reset/src/lib/file-lookup.test.ts b/examples/password-reset/src/lib/file-lookup.test.ts new file mode 100644 index 00000000..e5874188 --- /dev/null +++ b/examples/password-reset/src/lib/file-lookup.test.ts @@ -0,0 +1,204 @@ +import { describe, test, expect } from "vitest"; +import { ProductResponse, File } from "@elasticpath/js-sdk"; +import { + getMainImageForProductResponse, + getOtherImagesForProductResponse, +} from "./file-lookup"; + +describe("file-lookup", () => { + test("getImagesForProductResponse should return the correct image file object", () => { + const productResp = { + id: "944cef1a-c906-4efc-b920-d2c489ec6181", + relationships: { + files: { + data: [ + { + created_at: "2022-05-27T08:16:58.110Z", + id: "0de087d5-253b-4f10-8a09-0c10ffd6e7fa", + type: "file", + }, + { + created_at: "2022-05-27T08:16:58.110Z", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + type: "file", + }, + { + created_at: "2023-10-28T14:19:20.832Z", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + type: "file", + }, + ], + }, + main_image: { + data: { + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + type: "main_image", + }, + }, + parent: { + data: { + id: "2f435914-03b5-4b9e-80cb-08d3baa4c1d3", + type: "product", + }, + }, + }, + } as Partial; + + const mainImage: Partial[] = [ + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + { + type: "file", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/e5b9fed7-fcef-44d7-9ab1-3b4a277baf21.jpg", + }, + }, + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + ]; + + expect( + getMainImageForProductResponse( + productResp as ProductResponse, + mainImage as File[], + ), + ).toEqual({ + type: "file", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/e5b9fed7-fcef-44d7-9ab1-3b4a277baf21.jpg", + }, + }); + }); + + test("getOtherImagesForProductResponse should return other images for product", () => { + const productResp = { + id: "944cef1a-c906-4efc-b920-d2c489ec6181", + relationships: { + files: { + data: [ + { + created_at: "2022-05-27T08:16:58.110Z", + id: "0de087d5-253b-4f10-8a09-0c10ffd6e7fa", + type: "file", + }, + { + created_at: "2022-05-27T08:16:58.110Z", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + type: "file", + }, + { + created_at: "2023-10-28T14:19:20.832Z", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + type: "file", + }, + ], + }, + main_image: { + data: { + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + type: "main_image", + }, + }, + parent: { + data: { + id: "2f435914-03b5-4b9e-80cb-08d3baa4c1d3", + type: "product", + }, + }, + }, + } as Partial; + + const files = [ + { + type: "file", + id: "0de087d5-253b-4f10-8a09-0c10ffd6e7fa", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/0de087d5-253b-4f10-8a09-0c10ffd6e7fa.jpeg", + }, + }, + { + type: "file", + id: "0de087d5-253b-4f10-8a09-0c10ffd6e7fa", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/0de087d5-253b-4f10-8a09-0c10ffd6e7fa.jpeg", + }, + }, + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + { + type: "file", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/e5b9fed7-fcef-44d7-9ab1-3b4a277baf21.jpg", + }, + }, + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + { + type: "file", + id: "d402c7e2-c8e9-46bc-93f4-30955cd0b9ec", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/d402c7e2-c8e9-46bc-93f4-30955cd0b9ec.jpg", + }, + }, + ] as Partial[]; + + expect( + getOtherImagesForProductResponse( + productResp as ProductResponse, + files as File[], + ), + ).toEqual([ + { + type: "file", + id: "0de087d5-253b-4f10-8a09-0c10ffd6e7fa", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/0de087d5-253b-4f10-8a09-0c10ffd6e7fa.jpeg", + }, + }, + { + type: "file", + id: "1fa7be8b-bdcf-43a0-8748-33e549d2c03e", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/1fa7be8b-bdcf-43a0-8748-33e549d2c03e.jpeg", + }, + }, + { + type: "file", + id: "e5b9fed7-fcef-44d7-9ab1-3b4a277baf21", + link: { + href: "https://files-eu.epusercontent.com/856eeae6-45ea-453f-ab75-e53e84bf3c61/e5b9fed7-fcef-44d7-9ab1-3b4a277baf21.jpg", + }, + }, + ]); + }); +}); diff --git a/examples/password-reset/src/lib/file-lookup.ts b/examples/password-reset/src/lib/file-lookup.ts new file mode 100644 index 00000000..eb46afa4 --- /dev/null +++ b/examples/password-reset/src/lib/file-lookup.ts @@ -0,0 +1,39 @@ +import { File, ProductResponse } from "@elasticpath/js-sdk"; + +export function getMainImageForProductResponse( + productResponse: ProductResponse, + mainImages: File[], +): File | undefined { + const mainImageId = productResponse.relationships?.main_image?.data?.id; + + if (!mainImageId) { + return; + } + + return lookupFileUsingId(mainImageId, mainImages); +} + +export function getOtherImagesForProductResponse( + productResponse: ProductResponse, + allFiles: File[], +): File[] | undefined { + const productFilesIdObj = productResponse.relationships?.files?.data ?? []; + + if (productFilesIdObj?.length === 0) { + return; + } + + return productFilesIdObj.reduce((acc, fileIdObj) => { + const file = lookupFileUsingId(fileIdObj.id, allFiles); + return [...acc, ...(file ? [file] : [])]; + }, [] as File[]); +} + +export function lookupFileUsingId( + fileId: string, + files: File[], +): File | undefined { + return files.find((file) => { + return file.id === fileId; + }); +} diff --git a/examples/password-reset/src/lib/form-url-encode-body.ts b/examples/password-reset/src/lib/form-url-encode-body.ts new file mode 100644 index 00000000..b05c4711 --- /dev/null +++ b/examples/password-reset/src/lib/form-url-encode-body.ts @@ -0,0 +1,10 @@ +export function formUrlEncodeBody(body: Record): string { + return Object.keys(body) + .map( + (k) => + `${encodeURIComponent(k)}=${encodeURIComponent( + body[k as keyof typeof body], + )}`, + ) + .join("&"); +} diff --git a/examples/password-reset/src/lib/format-currency.tsx b/examples/password-reset/src/lib/format-currency.tsx new file mode 100644 index 00000000..fcdb76ba --- /dev/null +++ b/examples/password-reset/src/lib/format-currency.tsx @@ -0,0 +1,20 @@ +import { Currency } from "@elasticpath/js-sdk"; + +export function formatCurrency( + amount: number, + currency: Currency, + options: { + locals?: Parameters[0]; + } = { locals: "en-US" }, +) { + const { decimal_places, code } = currency; + + const resolvedAmount = amount / Math.pow(10, decimal_places); + + return new Intl.NumberFormat(options.locals, { + style: "currency", + maximumFractionDigits: decimal_places, + minimumFractionDigits: decimal_places, + currency: code, + }).format(resolvedAmount); +} diff --git a/examples/password-reset/src/lib/format-iso-date-string.ts b/examples/password-reset/src/lib/format-iso-date-string.ts new file mode 100644 index 00000000..ef916c23 --- /dev/null +++ b/examples/password-reset/src/lib/format-iso-date-string.ts @@ -0,0 +1,8 @@ +export function formatIsoDateString(isoString: string): string { + const dateObject = new Date(isoString); + return dateObject.toLocaleDateString(undefined, { + year: "numeric", + month: "long", + day: "numeric", + }); +} diff --git a/examples/password-reset/src/lib/get-error-message.ts b/examples/password-reset/src/lib/get-error-message.ts new file mode 100644 index 00000000..0d88bc36 --- /dev/null +++ b/examples/password-reset/src/lib/get-error-message.ts @@ -0,0 +1,15 @@ +export function getErrorMessage(error: unknown): string { + let message: string; + + if (error instanceof Error) { + message = error.message; + } else if (error && typeof error === "object" && "message" in error) { + message = String(error.message); + } else if (typeof error === "string") { + message = error; + } else { + message = "Something went wrong."; + } + + return message; +} diff --git a/examples/password-reset/src/lib/get-store-initial-state.ts b/examples/password-reset/src/lib/get-store-initial-state.ts new file mode 100644 index 00000000..dafe837b --- /dev/null +++ b/examples/password-reset/src/lib/get-store-initial-state.ts @@ -0,0 +1,20 @@ +import { ElasticPath } from "@elasticpath/js-sdk"; +import { InitialState } from "@elasticpath/react-shopper-hooks"; +import { buildSiteNavigation } from "./build-site-navigation"; +import { getCartCookieServer } from "./cart-cookie-server"; +import { getCart } from "../services/cart"; + +export async function getStoreInitialState( + client: ElasticPath, +): Promise { + const nav = await buildSiteNavigation(client); + + const cartCookie = getCartCookieServer(); + + const cart = await getCart(cartCookie, client); + + return { + cart, + nav, + }; +} diff --git a/examples/password-reset/src/lib/is-account-member-authenticated.ts b/examples/password-reset/src/lib/is-account-member-authenticated.ts new file mode 100644 index 00000000..ef12009b --- /dev/null +++ b/examples/password-reset/src/lib/is-account-member-authenticated.ts @@ -0,0 +1,13 @@ +import type { cookies } from "next/headers"; +import { ACCOUNT_MEMBER_TOKEN_COOKIE_NAME } from "./cookie-constants"; +import { parseAccountMemberCredentialsCookieStr } from "./retrieve-account-member-credentials"; + +export function isAccountMemberAuthenticated( + cookieStore: ReturnType, +): boolean { + const cookie = cookieStore.get(ACCOUNT_MEMBER_TOKEN_COOKIE_NAME); + const parsedCredentials = + cookie && parseAccountMemberCredentialsCookieStr(cookie.value); + + return !!parsedCredentials; +} diff --git a/examples/password-reset/src/lib/is-empty-object.ts b/examples/password-reset/src/lib/is-empty-object.ts new file mode 100644 index 00000000..200e3eb9 --- /dev/null +++ b/examples/password-reset/src/lib/is-empty-object.ts @@ -0,0 +1,2 @@ +export const isEmptyObj = (obj: object): boolean => + Object.keys(obj).length === 0; diff --git a/examples/password-reset/src/lib/is-supported-extension.ts b/examples/password-reset/src/lib/is-supported-extension.ts new file mode 100644 index 00000000..a7b1adaf --- /dev/null +++ b/examples/password-reset/src/lib/is-supported-extension.ts @@ -0,0 +1,9 @@ +export function isSupportedExtension(value: unknown): boolean { + return ( + typeof value === "boolean" || + typeof value === "number" || + typeof value === "string" || + typeof value === "undefined" || + value === null + ); +} diff --git a/examples/password-reset/src/lib/middleware/apply-set-cookie.ts b/examples/password-reset/src/lib/middleware/apply-set-cookie.ts new file mode 100644 index 00000000..f6a1a400 --- /dev/null +++ b/examples/password-reset/src/lib/middleware/apply-set-cookie.ts @@ -0,0 +1,31 @@ +import { NextResponse, type NextRequest } from "next/server"; +import { + ResponseCookies, + RequestCookies, +} from "next/dist/server/web/spec-extension/cookies"; + +/** + * Copy cookies from the Set-Cookie header of the response to the Cookie header of the request, + * so that it will appear to SSR/RSC as if the user already has the new cookies. + * + * Workaround for - https://github.com/vercel/next.js/issues/49442#issuecomment-1679807704 + */ +export function applySetCookie(req: NextRequest, res: NextResponse): void { + // parse the outgoing Set-Cookie header + const setCookies = new ResponseCookies(res.headers); + // Build a new Cookie header for the request by adding the setCookies + const newReqHeaders = new Headers(req.headers); + const newReqCookies = new RequestCookies(newReqHeaders); + setCookies.getAll().forEach((cookie) => newReqCookies.set(cookie)); + // set “request header overrides” on the outgoing response + NextResponse.next({ + request: { headers: newReqHeaders }, + }).headers.forEach((value, key) => { + if ( + key === "x-middleware-override-headers" || + key.startsWith("x-middleware-request-") + ) { + res.headers.set(key, value); + } + }); +} diff --git a/examples/password-reset/src/lib/middleware/cart-cookie-middleware.ts b/examples/password-reset/src/lib/middleware/cart-cookie-middleware.ts new file mode 100644 index 00000000..f0faf431 --- /dev/null +++ b/examples/password-reset/src/lib/middleware/cart-cookie-middleware.ts @@ -0,0 +1,121 @@ +import { NextRequest, NextResponse } from "next/server"; +import { + createAuthenticationErrorUrl, + createMissingEnvironmentVariableUrl, +} from "./create-missing-environment-variable-url"; +import { epccEndpoint } from "./implicit-auth-middleware"; +import { NextResponseFlowResult } from "./middleware-runner"; +import { tokenExpired } from "../token-expired"; +import { applySetCookie } from "./apply-set-cookie"; + +const cookiePrefixKey = process.env.NEXT_PUBLIC_COOKIE_PREFIX_KEY; + +export async function cartCookieMiddleware( + req: NextRequest, + previousResponse: NextResponse, +): Promise { + if (typeof cookiePrefixKey !== "string") { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createMissingEnvironmentVariableUrl( + "NEXT_PUBLIC_COOKIE_PREFIX_KEY", + req.nextUrl.basePath, + req.url, + ), + ), + }; + } + + if (req.cookies.get(`${cookiePrefixKey}_ep_cart`)) { + return { + shouldReturn: false, + resultingResponse: previousResponse, + }; + } + + if (typeof epccEndpoint !== "string") { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createMissingEnvironmentVariableUrl( + "NEXT_PUBLIC_EPCC_ENDPOINT_URL", + req.nextUrl.basePath, + req.url, + ), + ), + }; + } + + const authToken = retrieveAuthToken(req, previousResponse); + + if (!authToken) { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createAuthenticationErrorUrl( + `Cart cookie creation failed in middleware because credentials \"${cookiePrefixKey}_ep_credentials\" cookie was missing.`, + req.nextUrl.origin, + req.url, + ), + ), + }; + } + + if (!authToken.access_token) { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createAuthenticationErrorUrl( + `Cart cookie creation failed in middleware because credentials \"access_token\" was undefined.`, + req.nextUrl.origin, + req.url, + ), + ), + }; + } + + const createdCart = await fetch(`https://${epccEndpoint}/v2/carts`, { + method: "POST", + headers: { + Authorization: `Bearer ${authToken.access_token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ data: { name: "Cart" } }), + }); + + const parsedCartJSON = await createdCart.json(); + + previousResponse.cookies.set( + `${cookiePrefixKey}_ep_cart`, + parsedCartJSON.data.id, + { + sameSite: "strict", + expires: new Date(parsedCartJSON.data.meta.timestamps.expires_at), + }, + ); + + // Apply those cookies to the request + // Workaround for - https://github.com/vercel/next.js/issues/49442#issuecomment-1679807704 + applySetCookie(req, previousResponse); + + return { + shouldReturn: false, + resultingResponse: previousResponse, + }; +} + +function retrieveAuthToken( + req: NextRequest, + resp: NextResponse, +): { access_token: string; expires: number } | undefined { + const authCookie = + req.cookies.get(`${cookiePrefixKey}_ep_credentials`) ?? + resp.cookies.get(`${cookiePrefixKey}_ep_credentials`); + + const possiblyParsedCookie = authCookie && JSON.parse(authCookie.value); + + return possiblyParsedCookie && tokenExpired(possiblyParsedCookie.expires) + ? undefined + : possiblyParsedCookie; +} diff --git a/examples/password-reset/src/lib/middleware/create-missing-environment-variable-url.ts b/examples/password-reset/src/lib/middleware/create-missing-environment-variable-url.ts new file mode 100644 index 00000000..f6f347e5 --- /dev/null +++ b/examples/password-reset/src/lib/middleware/create-missing-environment-variable-url.ts @@ -0,0 +1,36 @@ +import { NonEmptyArray } from "../types/non-empty-array"; + +export function createMissingEnvironmentVariableUrl( + name: string | NonEmptyArray, + reqUrl: string, + from?: string, +): URL { + const configErrorUrl = createBaseErrorUrl(reqUrl, from); + + (Array.isArray(name) ? name : [name]).forEach((n) => { + configErrorUrl.searchParams.append("missing-env-variable", n); + }); + + return configErrorUrl; +} + +export function createAuthenticationErrorUrl( + message: string, + reqUrl: string, + from?: string, +): URL { + const configErrorUrl = createBaseErrorUrl(reqUrl, from); + configErrorUrl.searchParams.append( + "authentication", + encodeURIComponent(message), + ); + return configErrorUrl; +} + +function createBaseErrorUrl(reqUrl: string, from?: string): URL { + const configErrorUrl = new URL("/configuration-error", reqUrl); + if (from) { + configErrorUrl.searchParams.set("from", from); + } + return configErrorUrl; +} diff --git a/examples/password-reset/src/lib/middleware/implicit-auth-middleware.ts b/examples/password-reset/src/lib/middleware/implicit-auth-middleware.ts new file mode 100644 index 00000000..22f38d5d --- /dev/null +++ b/examples/password-reset/src/lib/middleware/implicit-auth-middleware.ts @@ -0,0 +1,102 @@ +import { NextRequest, NextResponse } from "next/server"; +import { NextResponseFlowResult } from "./middleware-runner"; +import { formUrlEncodeBody } from "../form-url-encode-body"; +import { + createAuthenticationErrorUrl, + createMissingEnvironmentVariableUrl, +} from "./create-missing-environment-variable-url"; +import { tokenExpired } from "../token-expired"; +import { applySetCookie } from "./apply-set-cookie"; + +export const epccEndpoint = process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL; +const clientId = process.env.NEXT_PUBLIC_EPCC_CLIENT_ID; +const cookiePrefixKey = process.env.NEXT_PUBLIC_COOKIE_PREFIX_KEY; + +export async function implicitAuthMiddleware( + req: NextRequest, + previousResponse: NextResponse, +): Promise { + if (typeof clientId !== "string" || typeof cookiePrefixKey !== "string") { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createMissingEnvironmentVariableUrl( + ["NEXT_PUBLIC_EPCC_CLIENT_ID", "NEXT_PUBLIC_COOKIE_PREFIX_KEY"], + req.nextUrl.basePath, + req.url, + ), + ), + }; + } + + const possibleImplicitCookie = req.cookies.get( + `${cookiePrefixKey}_ep_credentials`, + ); + + if ( + possibleImplicitCookie && + !tokenExpired(JSON.parse(possibleImplicitCookie.value).expires) + ) { + return { + shouldReturn: false, + resultingResponse: previousResponse, + }; + } + + const authResponse = await getTokenImplicitToken({ + grant_type: "implicit", + client_id: clientId, + }); + + const token = await authResponse.json(); + + /** + * Check response did not fail + */ + if (token && "errors" in token) { + return { + shouldReturn: true, + resultingResponse: NextResponse.redirect( + createAuthenticationErrorUrl( + `Implicit auth middleware failed to get access token.`, + req.nextUrl.origin, + req.url, + ), + ), + }; + } + + previousResponse.cookies.set( + `${cookiePrefixKey}_ep_credentials`, + JSON.stringify({ + ...token, + client_id: clientId, + }), + { + sameSite: "strict", + expires: new Date(token.expires * 1000), + }, + ); + + // Apply those cookies to the request + // Workaround for - https://github.com/vercel/next.js/issues/49442#issuecomment-1679807704 + applySetCookie(req, previousResponse); + + return { + shouldReturn: false, + resultingResponse: previousResponse, + }; +} + +async function getTokenImplicitToken(body: { + grant_type: "implicit"; + client_id: string; +}): Promise { + return fetch(`https://${epccEndpoint}/oauth/access_token`, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: formUrlEncodeBody(body), + }); +} diff --git a/examples/password-reset/src/lib/middleware/middleware-runner.ts b/examples/password-reset/src/lib/middleware/middleware-runner.ts new file mode 100644 index 00000000..d6b8df45 --- /dev/null +++ b/examples/password-reset/src/lib/middleware/middleware-runner.ts @@ -0,0 +1,63 @@ +import { NonEmptyArray } from "../types/non-empty-array"; +import { NextRequest, NextResponse } from "next/server"; + +export interface NextResponseFlowResult { + shouldReturn: boolean; + resultingResponse: NextResponse; +} + +interface RunnableMiddlewareEntryOptions { + exclude?: NonEmptyArray; +} + +interface RunnableMiddlewareEntry { + runnable: RunnableMiddleware; + options?: RunnableMiddlewareEntryOptions; +} + +export function middlewareRunner( + ...middleware: NonEmptyArray +) { + return async (req: NextRequest): Promise => { + let lastResult: NextResponseFlowResult = { + shouldReturn: false, + resultingResponse: NextResponse.next(), + }; + + for (const m of middleware) { + const toRun: RunnableMiddlewareEntry = + "runnable" in m ? m : { runnable: m }; + + const { runnable, options } = toRun; + + if (shouldRun(req.nextUrl.pathname, options?.exclude)) { + lastResult = await runnable(req, lastResult.resultingResponse); + } + + if (lastResult.shouldReturn) { + return lastResult.resultingResponse; + } + } + return lastResult.resultingResponse; + }; +} + +function shouldRun( + pathname: string, + excluded?: NonEmptyArray, +): boolean { + if (excluded) { + for (const path of excluded) { + if (pathname.startsWith(path)) { + return false; + } + } + } + + return true; +} + +type RunnableMiddleware = ( + req: NextRequest, + previousResponse: NextResponse, +) => Promise; diff --git a/examples/password-reset/src/lib/product-context.ts b/examples/password-reset/src/lib/product-context.ts new file mode 100644 index 00000000..7be48e43 --- /dev/null +++ b/examples/password-reset/src/lib/product-context.ts @@ -0,0 +1,10 @@ +import { createContext } from "react"; +import { + ProductContextState, + ProductModalContextState, +} from "./types/product-types"; + +export const ProductContext = createContext(null); + +export const ProductModalContext = + createContext(null); diff --git a/examples/password-reset/src/lib/product-helper.test.ts b/examples/password-reset/src/lib/product-helper.test.ts new file mode 100644 index 00000000..a71ba895 --- /dev/null +++ b/examples/password-reset/src/lib/product-helper.test.ts @@ -0,0 +1,273 @@ +import type { ProductResponse, Variation } from "@elasticpath/js-sdk"; +import { describe, test, expect } from "vitest"; +import { + allVariationsHaveSelectedOption, + getOptionsFromSkuId, + getSkuIdFromOptions, + isChildProductResource, + isSimpleProductResource, + mapOptionsToVariation, +} from "./product-helper"; + +describe("product-helpers", () => { + test("isChildProductResource should return false if it's a base product", () => { + const sampleProduct = { + attributes: { + base_product: true, + }, + } as ProductResponse; + expect(isChildProductResource(sampleProduct)).toEqual(false); + }); + + test("isChildProductResource should return false if it is a simple product", () => { + const sampleProduct = { + attributes: { + base_product: false, + }, + } as ProductResponse; + expect(isChildProductResource(sampleProduct)).toEqual(false); + }); + test("isChildProductResource should return true if it is a child product", () => { + const sampleProduct = { + attributes: { + base_product: false, + base_product_id: "123", + }, + } as ProductResponse; + expect(isChildProductResource(sampleProduct)).toEqual(true); + }); + + test("isSimpleProductResource should return true if it is a simple product", () => { + const sampleProduct = { + attributes: { + base_product: false, + }, + } as ProductResponse; + expect(isSimpleProductResource(sampleProduct)).toEqual(true); + }); + + test("isSimpleProductResource should return false if it is a base product", () => { + const sampleProduct = { + attributes: { + base_product: true, + }, + } as ProductResponse; + expect(isSimpleProductResource(sampleProduct)).toEqual(false); + }); + + test("isSimpleProductResource should return false if it is a child product", () => { + const sampleProduct = { + attributes: { + base_product: true, + base_product_id: "123", + }, + } as ProductResponse; + expect(isSimpleProductResource(sampleProduct)).toEqual(false); + }); + + test("getSkuIDFromOptions should return the id of the sku for the provided options.", () => { + const variationMatrixSample = { + "4252d475-2d0e-4cd2-99d3-19fba34ef211": { + "217883ce-55f1-4c34-8e00-e86c743f4dff": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "709e6cc6-a40c-4833-9469-b4abd0e7f67f", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "c05839f5-3eac-48f2-9d36-1bc2a481a213", + }, + "37b5bcf7-0b65-4e12-ad31-3052e27c107f": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "9e07495c-caf1-4f11-93c5-16cfeb63d492", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "b9bb984a-7a6d-4433-a445-1cde0383bece", + }, + }, + "693b16b8-a3b3-4419-ad03-61007a381c56": { + "217883ce-55f1-4c34-8e00-e86c743f4dff": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "2d864c10-146f-4905-859f-86e63c18abf4", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "42aef769-c97e-48a8-a3c4-2af8ad504ebb", + }, + }, + }; + + const options = [ + "693b16b8-a3b3-4419-ad03-61007a381c56", + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89", + "217883ce-55f1-4c34-8e00-e86c743f4dff", + ]; + + expect(getSkuIdFromOptions(options, variationMatrixSample)).toEqual( + "2d864c10-146f-4905-859f-86e63c18abf4", + ); + }); + test("getSkuIDFromOptions should return undefined when proveded valid but not found options.", () => { + const variationMatrixSample = { + "4252d475-2d0e-4cd2-99d3-19fba34ef211": { + "217883ce-55f1-4c34-8e00-e86c743f4dff": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "709e6cc6-a40c-4833-9469-b4abd0e7f67f", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "c05839f5-3eac-48f2-9d36-1bc2a481a213", + }, + "37b5bcf7-0b65-4e12-ad31-3052e27c107f": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "9e07495c-caf1-4f11-93c5-16cfeb63d492", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "b9bb984a-7a6d-4433-a445-1cde0383bece", + }, + }, + "693b16b8-a3b3-4419-ad03-61007a381c56": { + "217883ce-55f1-4c34-8e00-e86c743f4dff": { + "45e2612f-6bbf-4bc9-8803-80c5cf78ed89": + "2d864c10-146f-4905-859f-86e63c18abf4", + "8b6dfc96-11e6-455d-b042-e4137df3f13a": + "42aef769-c97e-48a8-a3c4-2af8ad504ebb", + }, + }, + }; + + const options = ["4252d475-2d0e-4cd2-99d3-19fba34ef211", "456", "789"]; + + expect(getSkuIdFromOptions(options, variationMatrixSample)).toEqual( + undefined, + ); + }); + test("getSkuIDFromOptions should return undefined when proveded empty options.", () => { + const variationMatrixSample = {}; + + expect(getSkuIdFromOptions([], variationMatrixSample)).toEqual(undefined); + }); + + test("getOptionsFromSkuId should return a list of options for given sku id and matrix.", () => { + const variationMatrixSample = { + "option-1": { + "option-3": { + "option-5": "709e6cc6-a40c-4833-9469-b4abd0e7f67f", + "option-6": "c05839f5-3eac-48f2-9d36-1bc2a481a213", + }, + "option-4": { + "option-5": "9e07495c-caf1-4f11-93c5-16cfeb63d492", + "option-6": "b9bb984a-7a6d-4433-a445-1cde0383bece", + }, + }, + "option-2": { + "option-3": { + "option-5": "2d864c10-146f-4905-859f-86e63c18abf4", + "option-6": "42aef769-c97e-48a8-a3c4-2af8ad504ebb", + }, + }, + }; + + const expectedOutput = ["option-2", "option-3", "option-6"]; + + expect( + getOptionsFromSkuId( + "42aef769-c97e-48a8-a3c4-2af8ad504ebb", + variationMatrixSample, + ), + ).toEqual(expectedOutput); + }); + + test("mapOptionsToVariation should return the object mapping varitions to the selected option.", () => { + const variations: Partial[] = [ + { + id: "variation-1", + name: "Generic Sizes", + options: [ + { + id: "option-1", + description: "Small size", + name: "SM", + modifiers: [], + }, + { + id: "option-2", + description: "Medium size", + name: "MD", + modifiers: [], + }, + ], + }, + { + id: "variation-2", + name: "Simple T-Shirt Sleeve Length", + options: [ + { + id: "option-3", + description: "Simple T-Shirt with short sleeves", + name: "Short", + modifiers: [], + }, + { + id: "option-4", + description: "Simple T-Shirt with long sleeves", + name: "Long", + modifiers: [], + }, + ], + }, + ]; + + const selectedOptions = ["option-2", "option-3"]; + + const expectedOutput = { + "variation-1": "option-2", + "variation-2": "option-3", + }; + + expect( + mapOptionsToVariation(selectedOptions, variations as Variation[]), + ).toEqual(expectedOutput); + }); + + test("allVariationsHaveSelectedOption should return true if all variations keys have a defined value for their key value pair.", () => { + const variations: Partial[] = [ + { + id: "variation-1", + name: "Generic Sizes", + options: [ + { + id: "option-1", + description: "Small size", + name: "SM", + modifiers: [], + }, + { + id: "option-2", + description: "Medium size", + name: "MD", + modifiers: [], + }, + ], + }, + { + id: "variation-2", + name: "Simple T-Shirt Sleeve Length", + options: [ + { + id: "option-3", + description: "Simple T-Shirt with short sleeves", + name: "Short", + modifiers: [], + }, + { + id: "option-4", + description: "Simple T-Shirt with long sleeves", + name: "Long", + modifiers: [], + }, + ], + }, + ]; + + const optionDict = { + "variation-1": "option-2", + "variation-2": "option-3", + }; + + expect( + allVariationsHaveSelectedOption(optionDict, variations as Variation[]), + ).toEqual(true); + }); +}); diff --git a/examples/password-reset/src/lib/product-helper.ts b/examples/password-reset/src/lib/product-helper.ts new file mode 100644 index 00000000..446683f1 --- /dev/null +++ b/examples/password-reset/src/lib/product-helper.ts @@ -0,0 +1,81 @@ +import { CatalogsProductVariation, ProductResponse } from "@elasticpath/js-sdk"; +import { OptionDict } from "./types/product-types"; +import { MatrixObjectEntry, MatrixValue } from "./types/matrix-object-entry"; + +export const getSkuIdFromOptions = ( + options: string[], + matrix: MatrixObjectEntry | MatrixValue, +): string | undefined => { + if (typeof matrix === "string") { + return matrix; + } + + for (const currOption in options) { + const nestedMatrix = matrix[options[currOption]]; + if (nestedMatrix) { + return getSkuIdFromOptions(options, nestedMatrix); + } + } + + return undefined; +}; + +export const getOptionsFromSkuId = ( + skuId: string, + entry: MatrixObjectEntry | MatrixValue, + options: string[] = [], +): string[] | undefined => { + if (typeof entry === "string") { + return entry === skuId ? options : undefined; + } + + let acc: string[] | undefined; + Object.keys(entry).every((key) => { + const result = getOptionsFromSkuId(skuId, entry[key], [...options, key]); + if (result) { + acc = result; + return false; + } + return true; + }); + return acc; +}; + +// TODO refactor +export const mapOptionsToVariation = ( + options: string[], + variations: CatalogsProductVariation[], +): OptionDict => { + return variations.reduce( + (acc: OptionDict, variation: CatalogsProductVariation) => { + const x = variation.options.find((varOption) => + options.some((selectedOption) => varOption.id === selectedOption), + )?.id; + return { ...acc, [variation.id]: x ? x : "" }; + }, + {}, + ); +}; + +export function allVariationsHaveSelectedOption( + optionsDict: OptionDict, + variations: CatalogsProductVariation[], +): boolean { + return !variations.some((variation) => !optionsDict[variation.id]); +} + +export const isChildProductResource = (product: ProductResponse): boolean => + !product.attributes.base_product && !!product.attributes.base_product_id; + +export const isSimpleProductResource = (product: ProductResponse): boolean => + !product.attributes.base_product && !product.attributes.base_product_id; + +/** + * promise will resolve after 300ms. + */ +export const wait300 = new Promise((resolve) => { + const wait = setTimeout(() => { + clearTimeout(wait); + resolve(); + }, 300); +}); diff --git a/examples/password-reset/src/lib/product-util.test.ts b/examples/password-reset/src/lib/product-util.test.ts new file mode 100644 index 00000000..d4c4e4e8 --- /dev/null +++ b/examples/password-reset/src/lib/product-util.test.ts @@ -0,0 +1,315 @@ +import type { + File, + ProductResponse, + ShopperCatalogResource, + Variation, +} from "@elasticpath/js-sdk"; +import { describe, test, expect } from "vitest"; +import { + createEmptyOptionDict, + excludeChildProducts, + filterBaseProducts, + getProductMainImage, + processImageFiles, +} from "./product-util"; + +describe("product util", () => { + describe("unit tests", () => { + test("processImageFiles should return only supported images without the main image", () => { + const files: Partial[] = [ + { + type: "file", + id: "123", + mime_type: "image/jpeg", + }, + { + type: "file", + id: "456", + mime_type: "image/gif", + }, + { + type: "file", + id: "789", + mime_type: "image/jpeg", + }, + { + type: "file", + id: "101112", + mime_type: "image/png", + }, + { + type: "file", + id: "131415", + mime_type: "image/svg+xml", + }, + { + type: "file", + id: "161718", + mime_type: "image/webp", + }, + { + type: "file", + id: "192021", + mime_type: "video/mp4", + }, + { + type: "file", + id: "222324", + mime_type: "application/pdf", + }, + { + type: "file", + id: "252627", + mime_type: "application/vnd.ms-excel", + }, + { + type: "file", + id: "282930", + mime_type: "application/vnd.ms-powerpoint", + }, + { + type: "file", + id: "313233", + mime_type: "application/msword", + }, + ]; + + const expected: Partial[] = [ + { + type: "file", + id: "456", + mime_type: "image/gif", + }, + { + type: "file", + id: "789", + mime_type: "image/jpeg", + }, + { + type: "file", + id: "101112", + mime_type: "image/png", + }, + { + type: "file", + id: "131415", + mime_type: "image/svg+xml", + }, + { + type: "file", + id: "161718", + mime_type: "image/webp", + }, + ]; + expect(processImageFiles(files as File[], "123")).toEqual(expected); + }); + + test("processImageFiles should support an undefined main image id", () => { + const files: Partial[] = [ + { + type: "file", + id: "123", + mime_type: "image/jpeg", + }, + { + type: "file", + id: "456", + mime_type: "image/gif", + }, + ]; + + const expected: Partial[] = [ + { + type: "file", + id: "123", + mime_type: "image/jpeg", + }, + { + type: "file", + id: "456", + mime_type: "image/gif", + }, + ]; + expect(processImageFiles(files as File[])).toEqual(expected); + }); + + test("getProductMainImage should return a products main image file", () => { + const mainImageFile: Partial = { + type: "file", + id: "123", + mime_type: "image/jpeg", + }; + + const productResp: Partial> = { + included: { + main_images: [mainImageFile] as File[], + }, + }; + + expect(getProductMainImage(productResp.included?.main_images)).toEqual( + mainImageFile, + ); + }); + + test("getProductMainImage should return null when product does not have main image included", () => { + const productResp: Partial> = { + included: {}, + }; + + expect(getProductMainImage(productResp.included?.main_images)).toEqual( + null, + ); + }); + + test("createEmptyOptionDict should return an OptionDict with all with variation keys assigned undefined values", () => { + const variations: Partial[] = [ + { + id: "variation-1", + name: "Generic Sizes", + options: [ + { + id: "option-1", + description: "Small size", + name: "SM", + modifiers: [], + }, + { + id: "option-2", + description: "Medium size", + name: "MD", + modifiers: [], + }, + ], + }, + { + id: "variation-2", + name: "Simple T-Shirt Sleeve Length", + options: [ + { + id: "option-3", + description: "Simple T-Shirt with short sleeves", + name: "Short", + modifiers: [], + }, + { + id: "option-4", + description: "Simple T-Shirt with long sleeves", + name: "Long", + modifiers: [], + }, + ], + }, + ]; + + const optionDict = { + "variation-1": undefined, + "variation-2": undefined, + }; + + expect(createEmptyOptionDict(variations as Variation[])).toEqual( + optionDict, + ); + }); + + test("filterBaseProducts should return only the base products from a list of ProductResponse", () => { + const products: any = [ + { + id: "123", + attributes: { + base_product: false, + base_product_id: "789", + }, + relationships: { + parent: { + data: { + id: "parent-id", + type: "product", + }, + }, + }, + }, + { + id: "456", + attributes: { + base_product: false, + }, + relationships: {}, + }, + { + id: "789", + attributes: { + base_product: true, + }, + relationships: {}, + }, + ]; + + const expected = [ + { + id: "789", + attributes: { + base_product: true, + }, + relationships: {}, + }, + ]; + const actual = filterBaseProducts(products as ProductResponse[]); + expect(actual).toEqual(expected); + }); + + test("excludeChildProducts should return only the products that are not child products", () => { + const products: any = [ + { + id: "123", + attributes: { + base_product: false, + base_product_id: "789", + }, + relationships: { + parent: { + data: { + id: "parent-id", + type: "product", + }, + }, + }, + }, + { + id: "456", + attributes: { + base_product: false, + }, + relationships: {}, + }, + { + id: "789", + attributes: { + base_product: true, + }, + relationships: {}, + }, + ]; + + const expected = [ + { + id: "456", + attributes: { + base_product: false, + }, + relationships: {}, + }, + { + id: "789", + attributes: { + base_product: true, + }, + relationships: {}, + }, + ]; + + expect(excludeChildProducts(products as ProductResponse[])).toEqual( + expected, + ); + }); + }); +}); diff --git a/examples/password-reset/src/lib/product-util.ts b/examples/password-reset/src/lib/product-util.ts new file mode 100644 index 00000000..7fea4739 --- /dev/null +++ b/examples/password-reset/src/lib/product-util.ts @@ -0,0 +1,54 @@ +import type { + CatalogsProductVariation, + File, + ProductResponse, +} from "@elasticpath/js-sdk"; +import type { + IdentifiableBaseProduct, + OptionDict, +} from "./types/product-types"; + +export function processImageFiles(files: File[], mainImageId?: string) { + // filters out main image and keeps server order + const supportedMimeTypes = [ + "image/gif", + "image/jpeg", + "image/png", + "image/webp", + "image/svg+xml", + ]; + return files.filter( + (fileEntry) => + fileEntry.id !== mainImageId && + supportedMimeTypes.some((type) => fileEntry.mime_type === type), + ); +} + +export function getProductMainImage( + mainImages: File[] | undefined, +): File | null { + return mainImages?.[0] || null; +} + +// Using existance of parent relationship property to filter because only child products seem to have this property. +export const filterBaseProducts = ( + products: ProductResponse[], +): IdentifiableBaseProduct[] => + products.filter( + (product: ProductResponse): product is IdentifiableBaseProduct => + product.attributes.base_product, + ); + +// Using existance of parent relationship property to filter because only child products seem to have this property. +export const excludeChildProducts = ( + products: ProductResponse[], +): IdentifiableBaseProduct[] => + products.filter( + (product: ProductResponse): product is IdentifiableBaseProduct => + !product?.relationships?.parent, + ); + +export const createEmptyOptionDict = ( + variations: CatalogsProductVariation[], +): OptionDict => + variations.reduce((acc, c) => ({ ...acc, [c.id]: undefined }), {}); diff --git a/examples/password-reset/src/lib/resolve-cart-env.ts b/examples/password-reset/src/lib/resolve-cart-env.ts new file mode 100644 index 00000000..d4f29eba --- /dev/null +++ b/examples/password-reset/src/lib/resolve-cart-env.ts @@ -0,0 +1,11 @@ +export const COOKIE_PREFIX_KEY = cartEnv(); + +function cartEnv(): string { + const cookiePrefixKey = process.env.NEXT_PUBLIC_COOKIE_PREFIX_KEY; + if (!cookiePrefixKey) { + throw new Error( + `Failed to get cart cookie key environment variables cookiePrefixKey. \n Make sure you have set NEXT_PUBLIC_COOKIE_PREFIX_KEY`, + ); + } + return cookiePrefixKey; +} diff --git a/examples/password-reset/src/lib/resolve-ep-currency-code.ts b/examples/password-reset/src/lib/resolve-ep-currency-code.ts new file mode 100644 index 00000000..999cdaf3 --- /dev/null +++ b/examples/password-reset/src/lib/resolve-ep-currency-code.ts @@ -0,0 +1,13 @@ +import { getCookie } from "cookies-next"; +import { COOKIE_PREFIX_KEY } from "./resolve-cart-env"; + +export const EP_CURRENCY_CODE = retrieveCurrency(); + +function retrieveCurrency(): string { + const currencyInCookie = getCookie(`${COOKIE_PREFIX_KEY}_ep_currency`); + return ( + (typeof currencyInCookie === "string" + ? currencyInCookie + : process.env.NEXT_PUBLIC_DEFAULT_CURRENCY_CODE) || "USD" + ); +} diff --git a/examples/password-reset/src/lib/resolve-epcc-env.ts b/examples/password-reset/src/lib/resolve-epcc-env.ts new file mode 100644 index 00000000..7852a5c9 --- /dev/null +++ b/examples/password-reset/src/lib/resolve-epcc-env.ts @@ -0,0 +1,21 @@ +export const epccEnv = resolveEpccEnv(); + +function resolveEpccEnv(): { + client_id: string; + host?: string; + client_secret?: string; +} { + const { host, client_id, client_secret } = { + host: process.env.NEXT_PUBLIC_EPCC_ENDPOINT_URL, + client_id: process.env.NEXT_PUBLIC_EPCC_CLIENT_ID, + client_secret: process.env.EPCC_CLIENT_SECRET, + }; + + if (!client_id) { + throw new Error( + `Failed to get Elasticpath Commerce Cloud client_id environment variables client_id: \n Make sure you have set NEXT_PUBLIC_EPCC_CLIENT_ID`, + ); + } + + return { host, client_id, client_secret }; +} diff --git a/examples/password-reset/src/lib/retrieve-account-member-credentials.ts b/examples/password-reset/src/lib/retrieve-account-member-credentials.ts new file mode 100644 index 00000000..2666ad33 --- /dev/null +++ b/examples/password-reset/src/lib/retrieve-account-member-credentials.ts @@ -0,0 +1,49 @@ +import { cookies } from "next/headers"; +import { + AccountMemberCredential, + AccountMemberCredentials, + accountMemberCredentialsSchema, +} from "../app/(auth)/account-member-credentials-schema"; + +export function getSelectedAccount( + memberCredentials: AccountMemberCredentials, +): AccountMemberCredential { + const selectedAccount = + memberCredentials.accounts[memberCredentials.selected]; + if (!selectedAccount) { + throw new Error("No selected account"); + } + return selectedAccount; +} + +export function retrieveAccountMemberCredentials( + cookieStore: ReturnType, + name: string, +) { + const accountMemberCookie = cookieStore.get(name); + + // Next.js cookieStore.delete replaces a cookie with an empty string so we need to check for that here. + if (!accountMemberCookie || !accountMemberCookie.value) { + return undefined; + } + + return parseAccountMemberCredentialsCookieStr(accountMemberCookie?.value); +} + +export function parseAccountMemberCredentialsCookieStr( + str: string, +): AccountMemberCredentials | undefined { + const parsedCookie = accountMemberCredentialsSchema.safeParse( + JSON.parse(str), + ); + + if (!parsedCookie.success) { + console.error( + "Failed to parse account member cookie: ", + parsedCookie.error, + ); + return undefined; + } + + return parsedCookie.data; +} diff --git a/examples/password-reset/src/lib/sort-alphabetically.ts b/examples/password-reset/src/lib/sort-alphabetically.ts new file mode 100644 index 00000000..a69ce476 --- /dev/null +++ b/examples/password-reset/src/lib/sort-alphabetically.ts @@ -0,0 +1,4 @@ +export const sortAlphabetically = ( + a: { name: string }, + b: { name: string }, +): number => a.name.localeCompare(b.name); diff --git a/examples/password-reset/src/lib/to-base-64.ts b/examples/password-reset/src/lib/to-base-64.ts new file mode 100644 index 00000000..87b9edc2 --- /dev/null +++ b/examples/password-reset/src/lib/to-base-64.ts @@ -0,0 +1,4 @@ +export const toBase64 = (str: string): string => + typeof window === "undefined" + ? Buffer.from(str).toString("base64") + : window.btoa(str); diff --git a/examples/password-reset/src/lib/token-expired.ts b/examples/password-reset/src/lib/token-expired.ts new file mode 100644 index 00000000..694a760f --- /dev/null +++ b/examples/password-reset/src/lib/token-expired.ts @@ -0,0 +1,3 @@ +export function tokenExpired(expires: number): boolean { + return Math.floor(Date.now() / 1000) >= expires; +} diff --git a/examples/password-reset/src/lib/types/breadcrumb-lookup.ts b/examples/password-reset/src/lib/types/breadcrumb-lookup.ts new file mode 100644 index 00000000..f59ca3c9 --- /dev/null +++ b/examples/password-reset/src/lib/types/breadcrumb-lookup.ts @@ -0,0 +1,7 @@ +export interface BreadcrumbLookupEntry { + href: string; + name: string; + slug: string; +} + +export type BreadcrumbLookup = Record; diff --git a/examples/password-reset/src/lib/types/deep-partial.ts b/examples/password-reset/src/lib/types/deep-partial.ts new file mode 100644 index 00000000..e422dd51 --- /dev/null +++ b/examples/password-reset/src/lib/types/deep-partial.ts @@ -0,0 +1,3 @@ +export type DeepPartial = { + [P in keyof T]?: T[P] extends object ? DeepPartial : T[P]; +}; diff --git a/examples/password-reset/src/lib/types/matrix-object-entry.ts b/examples/password-reset/src/lib/types/matrix-object-entry.ts new file mode 100644 index 00000000..a214bbc1 --- /dev/null +++ b/examples/password-reset/src/lib/types/matrix-object-entry.ts @@ -0,0 +1,5 @@ +export type MatrixValue = string; + +export interface MatrixObjectEntry { + [key: string]: MatrixObjectEntry | MatrixValue; +} diff --git a/examples/password-reset/src/lib/types/non-empty-array.ts b/examples/password-reset/src/lib/types/non-empty-array.ts new file mode 100644 index 00000000..af797df1 --- /dev/null +++ b/examples/password-reset/src/lib/types/non-empty-array.ts @@ -0,0 +1,3 @@ +export interface NonEmptyArray extends Array { + 0: A; +} diff --git a/examples/password-reset/src/lib/types/product-types.ts b/examples/password-reset/src/lib/types/product-types.ts new file mode 100644 index 00000000..e2cc5337 --- /dev/null +++ b/examples/password-reset/src/lib/types/product-types.ts @@ -0,0 +1,31 @@ +import type { ProductResponse, File } from "@elasticpath/js-sdk"; +import type { Dispatch, SetStateAction } from "react"; + +export type IdentifiableBaseProduct = ProductResponse & { + id: string; + attributes: { slug: string; sku: string; base_product: true }; +}; + +export interface ProductContextState { + isChangingSku: boolean; + setIsChangingSku: Dispatch>; +} + +export interface ProductModalContextState { + isChangingSku: boolean; + setIsChangingSku: Dispatch>; + changedSkuId: string; + setChangedSkuId: Dispatch>; +} + +export interface OptionDict { + [key: string]: string; +} + +export interface ProductResponseWithImage extends ProductResponse { + main_image?: File; +} + +export interface ProductImageObject { + [key: string]: File; +} diff --git a/examples/password-reset/src/lib/types/read-only-non-empty-array.ts b/examples/password-reset/src/lib/types/read-only-non-empty-array.ts new file mode 100644 index 00000000..9877640a --- /dev/null +++ b/examples/password-reset/src/lib/types/read-only-non-empty-array.ts @@ -0,0 +1,7 @@ +export type ReadonlyNonEmptyArray = ReadonlyArray & { + readonly 0: A; +}; + +export const isNonEmpty = ( + as: ReadonlyArray, +): as is ReadonlyNonEmptyArray => as.length > 0; diff --git a/examples/password-reset/src/lib/types/unpacked.ts b/examples/password-reset/src/lib/types/unpacked.ts new file mode 100644 index 00000000..733a5208 --- /dev/null +++ b/examples/password-reset/src/lib/types/unpacked.ts @@ -0,0 +1,7 @@ +/** + * https://stackoverflow.com/a/52331580/4330441 + * Extract the type of array e.g. + * type Group = Item[] + * type MyItem = Unpacked + */ +export type Unpacked = T extends (infer U)[] ? U : T; diff --git a/examples/password-reset/src/lib/use-debounced.ts b/examples/password-reset/src/lib/use-debounced.ts new file mode 100644 index 00000000..9f963143 --- /dev/null +++ b/examples/password-reset/src/lib/use-debounced.ts @@ -0,0 +1,14 @@ +import { DependencyList, EffectCallback, useEffect } from "react"; + +export const useDebouncedEffect = ( + effect: EffectCallback, + delay: number, + deps?: DependencyList, +) => { + useEffect(() => { + const handler = setTimeout(() => effect(), delay); + + return () => clearTimeout(handler); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [...(deps || []), delay]); +}; diff --git a/examples/password-reset/src/middleware.ts b/examples/password-reset/src/middleware.ts new file mode 100644 index 00000000..a06a5712 --- /dev/null +++ b/examples/password-reset/src/middleware.ts @@ -0,0 +1,21 @@ +import { NextRequest } from "next/server"; +import { middlewareRunner } from "./lib/middleware/middleware-runner"; +import { implicitAuthMiddleware } from "./lib/middleware/implicit-auth-middleware"; +import { cartCookieMiddleware } from "./lib/middleware/cart-cookie-middleware"; + +export async function middleware(req: NextRequest) { + return middlewareRunner( + { + runnable: implicitAuthMiddleware, + options: { + exclude: ["/_next", "/configuration-error"], + }, + }, + { + runnable: cartCookieMiddleware, + options: { + exclude: ["/_next", "/configuration-error"], + }, + }, + )(req); +} diff --git a/examples/password-reset/src/services/cart.ts b/examples/password-reset/src/services/cart.ts new file mode 100644 index 00000000..e92757e4 --- /dev/null +++ b/examples/password-reset/src/services/cart.ts @@ -0,0 +1,9 @@ +import type {ElasticPath } from "@elasticpath/js-sdk"; +import { Cart, CartIncluded, ResourceIncluded } from "@elasticpath/js-sdk"; + +export async function getCart( + cartId: string, + client: ElasticPath, +): Promise> { + return client.Cart(cartId).With("items").Get(); +} diff --git a/examples/password-reset/src/services/hierarchy.ts b/examples/password-reset/src/services/hierarchy.ts new file mode 100644 index 00000000..6fafee61 --- /dev/null +++ b/examples/password-reset/src/services/hierarchy.ts @@ -0,0 +1,28 @@ +import type { Node, Hierarchy } from "@elasticpath/js-sdk"; +import {ElasticPath } from "@elasticpath/js-sdk"; + +export async function getHierarchies(client: ElasticPath): Promise { + const result = await client.ShopperCatalog.Hierarchies.All(); + return result.data; +} + +export async function getHierarchyChildren( + hierarchyId: string, + client: ElasticPath, +): Promise { + const result = await client.ShopperCatalog.Hierarchies.GetHierarchyChildren({ + hierarchyId, + }); + return result.data; +} + +export async function getHierarchyNodes( + hierarchyId: string, + client: ElasticPath, +): Promise { + const result = await client.ShopperCatalog.Hierarchies.GetHierarchyNodes({ + hierarchyId, + }); + + return result.data; +} diff --git a/examples/password-reset/src/services/products.ts b/examples/password-reset/src/services/products.ts new file mode 100644 index 00000000..c8f49f64 --- /dev/null +++ b/examples/password-reset/src/services/products.ts @@ -0,0 +1,68 @@ +import type { + ProductResponse, + ResourcePage, + ShopperCatalogResource, +} from "@elasticpath/js-sdk"; +import { wait300 } from "../lib/product-helper"; +import { ElasticPath } from "@elasticpath/js-sdk"; + +export async function getProductById( + productId: string, + client: ElasticPath, +): Promise> { + return client.ShopperCatalog.Products.With([ + "main_image", + "files", + "component_products", + ]).Get({ + productId, + }); +} + +export function getAllProducts(client: ElasticPath): Promise { + return _getAllProductPages(client)(); +} + +export function getProducts(client: ElasticPath, offset = 0, limit = 100) { + return client.ShopperCatalog.Products.With(["main_image"]) + .Limit(limit) + .Offset(offset) + .All(); +} + +const _getAllPages = + ( + nextPageRequestFn: ( + limit: number, + offset: number, + client?: ElasticPath, + ) => Promise>, + ) => + async ( + offset: number = 0, + limit: number = 25, + accdata: T[] = [], + ): Promise => { + const requestResp = await nextPageRequestFn(limit, offset); + const { + meta: { + page: newPage, + results: { total }, + }, + data: newData, + } = requestResp; + + const updatedOffset = offset + newPage.total; + const combinedData = [...accdata, ...newData]; + if (updatedOffset < total) { + return wait300.then(() => + _getAllPages(nextPageRequestFn)(updatedOffset, limit, combinedData), + ); + } + return Promise.resolve(combinedData); + }; + +const _getAllProductPages = (client: ElasticPath) => + _getAllPages((limit = 25, offset = 0) => + client.ShopperCatalog.Products.Limit(limit).Offset(offset).All(), + ); diff --git a/examples/password-reset/src/styles/globals.css b/examples/password-reset/src/styles/globals.css new file mode 100644 index 00000000..766ef9db --- /dev/null +++ b/examples/password-reset/src/styles/globals.css @@ -0,0 +1,27 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html, +body { + padding: 0; + margin: 0; + height: 100%; + font-family: + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Oxygen, + Ubuntu, + Cantarell, + Fira Sans, + Droid Sans, + Helvetica Neue, + sans-serif; +} + +.carousel__slide-focus-ring { + display: none !important; + outline-width: 0 !important; +} diff --git a/examples/password-reset/tailwind.config.ts b/examples/password-reset/tailwind.config.ts new file mode 100644 index 00000000..fc51cc8d --- /dev/null +++ b/examples/password-reset/tailwind.config.ts @@ -0,0 +1,78 @@ +import plugin from "tailwindcss/plugin"; +import type { Config } from "tailwindcss"; + +export default { + content: ["./src/**/*.{js,jsx,ts,tsx}"], + theme: { + extend: { + maxWidth: { + "base-max-width": "80rem", + }, + flex: { + "only-grow": "1 0 0%", + }, + colors: { + brand: { + primary: "#2BCC7E", + secondary: "#144E31", + highlight: "#56DC9B", + primaryAlt: "#EA7317", + secondaryAlt: "#ffcb47", + gray: "#666666", + }, + }, + keyframes: { + fadeIn: { + from: { opacity: "0" }, + to: { opacity: "1" }, + }, + marquee: { + "0%": { transform: "translateX(0%)" }, + "100%": { transform: "translateX(-100%)" }, + }, + blink: { + "0%": { opacity: "0.2" }, + "20%": { opacity: "1" }, + "100% ": { opacity: "0.2" }, + }, + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + fadeIn: "fadeIn .3s ease-in-out", + carousel: "marquee 60s linear infinite", + blink: "blink 1.4s both infinite", + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + clipPath: { + sidebar: "polygon(0 0, 100vmax 0, 100vmax 100%, 0 100%)", + }, + }, + }, + plugins: [ + require("@tailwindcss/forms"), + require("tailwindcss-animate"), + require("tailwind-clip-path"), + plugin(({ matchUtilities, theme }) => { + matchUtilities( + { + "animation-delay": (value) => { + return { + "animation-delay": value, + }; + }, + }, + { + values: theme("transitionDelay"), + }, + ); + }), + ], +} satisfies Config; diff --git a/examples/password-reset/tsconfig.json b/examples/password-reset/tsconfig.json new file mode 100644 index 00000000..36c7f895 --- /dev/null +++ b/examples/password-reset/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "target": "es6", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": false, + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": [ + "next-env.d.ts", + "src/**/*.ts", + "src/**/*.tsx", + ".next/types/**/*.ts", + "tailwind.config.ts" + ], + "exclude": ["node_modules"], + "types": ["global.d.ts"] +} diff --git a/examples/password-reset/vite.config.ts b/examples/password-reset/vite.config.ts new file mode 100644 index 00000000..9da935db --- /dev/null +++ b/examples/password-reset/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig, defaultExclude } from "vitest/config"; + +export default defineConfig({ + test: { + exclude: ["e2e/**/*", ...defaultExclude], + coverage: { + provider: "istanbul", + }, + }, +});