From 496c1f4a70033d3cc7d1ab5cf473d10301cd2c6a Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 15:40:25 +0200 Subject: [PATCH 01/28] chore: add medusa aws host to next config --- next.config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/next.config.js b/next.config.js index 86482bb29..3c0769dd7 100644 --- a/next.config.js +++ b/next.config.js @@ -14,6 +14,11 @@ module.exports = { protocol: 'https', hostname: 'cdn.shopify.com', pathname: '/s/files/**' + }, + { + protocol: 'https', + hostname: 'medusa-public-images.s3.eu-west-1.amazonaws.com', + pathname: '/**' } ] } From 876800aad5426b80ad24f7c56ff6cd5806b3716d Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 15:41:12 +0200 Subject: [PATCH 02/28] feat: add medusa types --- lib/medusa/types.ts | 252 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 lib/medusa/types.ts diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts new file mode 100644 index 000000000..123166959 --- /dev/null +++ b/lib/medusa/types.ts @@ -0,0 +1,252 @@ +export type ProductCollection = { + id: string; + title: string; + handle: string | null; + products?: Product[]; + created_at: string; // format: date-time + updated_at: string; // format: date-time + deleted_at?: string | null; // format: date-time + metadata?: Record | null; +}; + +export type MedusaProduct = { + id: string; + title: string; + subtitle?: string | null; + description?: string | null; + handle?: string | null; + is_giftcard: boolean; + status?: 'draft' | 'proposed' | 'published' | 'rejected'; + images?: Array; + thumbnail?: string | null; + options?: Array; + variants?: Array; + categories?: Array; + profile_id?: string | null; + profile?: ShippingProfile | null; + weight?: number | null; + length?: number | null; + height?: number | null; + width?: number | null; + hs_code?: string | null; + origin_country?: string | null; + mid_code?: string | null; + metadata?: Record; + discountable?: boolean; + collection_id: string; + created_at: Date; + updated_at: Date; + deleted_at: Date | null; + type_id: string; + material?: string | null; +}; + +export type Product = MedusaProduct & { + featuredImage: { + url: string; + }; + priceRange: { + maxVariantPrice: { + amount: string; + currencyCode: string; + }; + }; +}; + +export type Image = { + id: string; + url: string; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: { [key: string]: string } | null; +}; + +export type ShippingProfile = { + id: string; + name: string; + type: 'default' | 'gift_card' | 'custom'; + products?: Product[]; + shipping_options?: ShippingOption[]; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: { [key: string]: any } | null; +}; + +export type ProductCategory = { + id: string; + name: string; + handle: string; + mpath: string | null; + is_internal?: boolean; + is_active?: boolean; + rank?: number; + category_children?: ProductCategory[]; + parent_category_id?: string | null; + parent_category?: ProductCategory | null; + products?: Product[]; + created_at: string; + updated_at: string; +}; + +export type ProductVariant = { + id: string; + title?: string; + product_id: string; + product?: Product; + prices?: MoneyAmount[]; + sku?: string; + barcode?: string | null; + ean?: string | null; + upc?: string | null; + variant_rank?: number | null; + inventory_quantity: number; + allow_backorder: boolean; + manage_inventory: boolean; + hs_code?: string | null; + origin_country?: string | null; + mid_code?: string | null; + material?: string | null; + weight?: number | null; + length?: number | null; + height?: number | null; + width?: number | null; + options?: ProductOptionValue[]; + created_at: string; + updated_at: string; + deleted_at: string | null; +}; + +type MoneyAmount = { + id: string; + currency_code: string; + currency?: Currency | null; + amount: number; + min_quantity?: number | null; + max_quantity?: number | null; + price_list_id?: string | null; + price_list?: PriceList | null; + variant_id?: string | null; + variant?: ProductVariant | null; + region_id?: string | null; + region?: Region | null; + created_at: string; + updated_at: string; + deleted_at?: string | null; +}; + +export type Currency = { + code: string; + symbol: string; + symbol_native: string; + name: string; + includes_tax?: boolean; +}; + +export type PriceList = { + id: string; + name: string; + description: string; + type?: 'sale' | 'override'; + status?: 'active' | 'draft'; + starts_at?: string | null; + ends_at?: string | null; + customer_groups?: CustomerGroup[]; + prices?: MoneyAmount[]; + includes_tax?: boolean; + created_at: string; + updated_at: string; + deleted_at?: string | null; +}; + +export type CustomerGroup = { + id: string; + name: string; +}; + +export type ProductOption = { + id: string; + title: string; + values?: ProductOptionValue[]; + product_id: string; + product?: Product | null; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type ProductOptionValue = { + id: string; + value: string; + option_id: string; + option?: ProductOption | null; + variant_id: string; + variant?: ProductVariant | null; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +type ShippingOption = { + id: string; + name: string; + region_id: string; + region?: Region | null; + profile_id: string; + profile?: ShippingProfile | null; + provider_id: string; + provider?: FulfillmentProvider | null; + price_type: 'flat_rate' | 'calculated'; + amount?: number | null; + is_return: boolean; + admin_only: boolean; + requirements?: ShippingOptionRequirement[]; + data: Record; + includes_tax: boolean; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type Region = { + id: string; + name: string; + country_code: string; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type FulfillmentProvider = { + id: string; + name: string; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type ShippingOptionRequirement = { + id: string; + requirement_id: string; + value: string; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type MedusaCart = { + id: string; + items: []; +}; + +export type Cart = Omit & { + lines: []; + totalQuantity: number; +}; From 7021789621c4b82615cdd8f63929ac50a38bc586 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 15:41:48 +0200 Subject: [PATCH 03/28] feat: add medusa endpoints and reshapers --- lib/medusa/index.ts | 180 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 lib/medusa/index.ts diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts new file mode 100644 index 000000000..cae2fc2f3 --- /dev/null +++ b/lib/medusa/index.ts @@ -0,0 +1,180 @@ +import { isShopifyError } from 'lib/type-guards'; +import { Cart, MedusaCart, MedusaProduct, Product, ProductCollection } from './types'; + +// const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; +const endpoint = `http://localhost:9000/store`; + +export default async function medusaRequest( + method: string, + path = '', + payload?: Record | undefined +) { + const options: RequestInit = { + method, + headers: { + 'Content-Type': 'application/json' + } + }; + + if (payload) { + options.body = JSON.stringify(payload); + } + + try { + const result = await fetch(`${endpoint}/${path}`, options); + + const body = await result.json(); + + if (body.errors) { + throw body.errors[0]; + } + + return { + status: result.status, + body + }; + } catch (e) { + if (isShopifyError(e)) { + throw { + status: e.status || 500, + message: e.message + }; + } + + throw { + error: e + }; + } +} + +const reshapeCart = (cart: MedusaCart): Cart => { + const lines = cart.items; + const totalQuantity = cart.items.length || 0; + + return { + ...cart, + totalQuantity, + lines + }; +}; + +const reshapeProduct = (product: MedusaProduct): Product => { + const featuredImage = { + url: product.images?.[0]?.url ?? '' + }; + const priceRange = { + maxVariantPrice: { + amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '', + currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' + } + }; + + return { + ...product, + featuredImage, + priceRange + }; +}; + +export async function createCart(): Promise { + const res = await medusaRequest('POST', '/carts', {}); + console.log('Cart created!'); + console.log(res); + return reshapeCart(res.body.cart); +} + +export async function addToCart( + cartId: string, + lineItems: { variantId: string; quantity: number }[] +): Promise { + console.log(lineItems); + // TODO: transform lines into Medusa line items + const res = await medusaRequest('POST', `/carts/${cartId}/line-items`, { + lineItems + }); + + return res.body.data.cart; +} + +export async function removeFromCart(cartId: string, lineIds: string[]): Promise { + // TODO: We only allow you to pass a single line item to delete + const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineIds[0]}`); + + return res.body.data.cart; +} + +export async function updateCart( + cartId: string, + lines: { id: string; merchandiseId: string; quantity: number }[] +): Promise { + console.log(lines); + // TODO: transform lines into Medusa line items + const res = await medusaRequest('POST', `/carts/${cartId}`, {}); + return res.body.data.cart; +} + +export async function getCart(cartId: string): Promise { + const res = await medusaRequest('GET', `/carts/${cartId}`); + + if (!res.body.cart) { + return null; + } + + return res.body.cart; +} + +export async function getCollection(handle: string): Promise { + const res = await medusaRequest('GET', `/collections?handle[]=${handle}&limit=1`); + return res.body.collections[0]; +} + +export async function getCollectionProducts(handle: string): Promise { + const collection = await getCollection(handle); + + if (!collection) { + return []; + } + + const res = await medusaRequest('GET', `/products?collection_id[]=${collection.id}`); + + if (!res.body?.products) { + return []; + } + + return res.body.products.map((product: Product) => reshapeProduct(product)); +} + +export async function getCollections(): Promise { + const collections = [ + { + handle: '', + title: 'All', + description: 'All products', + seo: { + title: 'All', + description: 'All products' + }, + path: '/search', + updatedAt: new Date().toISOString() + } + ]; + + // return collections; + return []; +} + +export async function getProduct(handle: string): Promise { + const res = await medusaRequest('get', `/products?handle=${handle}&limit=1`); + return res.body.product; +} + +export async function getProducts({ + query +}: { + query?: string; + reverse?: boolean; + sortKey?: string; +}): Promise { + const res = await medusaRequest('get', `/products?q=${query}&limit=20`); + return res.body.products; +} From 3ab0bd18d0315c70917688771a5dcfe32ec874d6 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 15:42:35 +0200 Subject: [PATCH 04/28] refactor: replace shopify imports --- app/api/cart/route.ts | 8 +++---- app/product/[handle]/page.tsx | 4 ++-- app/search/[collection]/page.tsx | 2 +- app/search/page.tsx | 2 +- app/sitemap.ts | 2 +- components/carousel.tsx | 2 +- components/cart/button.tsx | 2 +- components/cart/delete-item-button.tsx | 2 +- components/cart/edit-item-quantity-button.tsx | 2 +- components/cart/index.tsx | 2 +- components/cart/modal.tsx | 6 +++--- components/grid/three-items.tsx | 10 ++++----- components/layout/footer.tsx | 2 +- components/layout/navbar/index.tsx | 13 +++++------- components/layout/navbar/mobile-menu.tsx | 2 +- components/layout/product-grid-items.tsx | 2 +- components/layout/search/collections.tsx | 2 +- components/product/add-to-cart.tsx | 2 +- components/product/variant-selector.tsx | 2 +- lib/shopify/index.ts | 21 +++++++++++-------- 20 files changed, 45 insertions(+), 45 deletions(-) diff --git a/app/api/cart/route.ts b/app/api/cart/route.ts index 15f5fb09f..788b6b781 100644 --- a/app/api/cart/route.ts +++ b/app/api/cart/route.ts @@ -1,7 +1,7 @@ import { cookies } from 'next/headers'; import { NextRequest, NextResponse } from 'next/server'; -import { addToCart, removeFromCart, updateCart } from 'lib/shopify'; +import { addToCart, removeFromCart, updateCart } from 'lib/medusa'; import { isShopifyError } from 'lib/type-guards'; function formatErrorMessage(err: Error): string { @@ -10,13 +10,13 @@ function formatErrorMessage(err: Error): string { export async function POST(req: NextRequest): Promise { const cartId = cookies().get('cartId')?.value; - const { merchandiseId } = await req.json(); + const { variantId } = await req.json(); - if (!cartId?.length || !merchandiseId?.length) { + if (!cartId?.length || !variantId?.length) { return NextResponse.json({ error: 'Missing cartId or variantId' }, { status: 400 }); } try { - await addToCart(cartId, [{ merchandiseId, quantity: 1 }]); + await addToCart(cartId, [{ variantId, quantity: 1 }]); return NextResponse.json({ status: 204 }); } catch (e) { if (isShopifyError(e)) { diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 1b1eb4821..194b22c42 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -10,8 +10,8 @@ import { Gallery } from 'components/product/gallery'; import { VariantSelector } from 'components/product/variant-selector'; import Prose from 'components/prose'; import { HIDDEN_PRODUCT_TAG } from 'lib/constants'; -import { getProduct } from 'lib/shopify'; -import { Image } from 'lib/shopify/types'; +import { getProduct } from 'lib/medusa'; +import { Image } from 'lib/medusa/types'; export const runtime = 'edge'; diff --git a/app/search/[collection]/page.tsx b/app/search/[collection]/page.tsx index 0e1782b7d..60f73f280 100644 --- a/app/search/[collection]/page.tsx +++ b/app/search/[collection]/page.tsx @@ -1,4 +1,4 @@ -import { getCollection, getCollectionProducts } from 'lib/shopify'; +import { getCollection, getCollectionProducts } from 'lib/medusa'; import { Metadata } from 'next'; import { notFound } from 'next/navigation'; diff --git a/app/search/page.tsx b/app/search/page.tsx index 354a2022f..3b6809269 100644 --- a/app/search/page.tsx +++ b/app/search/page.tsx @@ -1,7 +1,7 @@ import Grid from 'components/grid'; import ProductGridItems from 'components/layout/product-grid-items'; import { defaultSort, sorting } from 'lib/constants'; -import { getProducts } from 'lib/shopify'; +import { getProducts } from 'lib/medusa'; export const runtime = 'edge'; diff --git a/app/sitemap.ts b/app/sitemap.ts index f4745dbc9..f2789dba2 100644 --- a/app/sitemap.ts +++ b/app/sitemap.ts @@ -1,4 +1,4 @@ -import { getCollections, getProducts } from 'lib/shopify'; +import { getCollections, getProducts } from 'lib/medusa'; import { MetadataRoute } from 'next'; const baseUrl = process.env.NEXT_PUBLIC_VERCEL_URL diff --git a/components/carousel.tsx b/components/carousel.tsx index 30b6a4733..a1ddcfda7 100644 --- a/components/carousel.tsx +++ b/components/carousel.tsx @@ -1,4 +1,4 @@ -import { getCollectionProducts } from 'lib/shopify'; +import { getCollectionProducts } from 'lib/medusa'; import Image from 'next/image'; import Link from 'next/link'; diff --git a/components/cart/button.tsx b/components/cart/button.tsx index aed87ee7a..5a3f538f7 100644 --- a/components/cart/button.tsx +++ b/components/cart/button.tsx @@ -6,7 +6,7 @@ import { useCookies } from 'react-cookie'; import CartIcon from 'components/icons/cart'; import CartModal from './modal'; -import type { Cart } from 'lib/shopify/types'; +import type { Cart } from 'lib/medusa/types'; export default function CartButton({ cart, diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index 789a87754..25f5a3b1a 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -4,7 +4,7 @@ import { useRouter } from 'next/navigation'; import { startTransition, useState } from 'react'; import clsx from 'clsx'; -import type { CartItem } from 'lib/shopify/types'; +import type { CartItem } from 'lib/medusa/types'; export default function DeleteItemButton({ item }: { item: CartItem }) { const router = useRouter(); diff --git a/components/cart/edit-item-quantity-button.tsx b/components/cart/edit-item-quantity-button.tsx index 2249bd1aa..6b8bb72fe 100644 --- a/components/cart/edit-item-quantity-button.tsx +++ b/components/cart/edit-item-quantity-button.tsx @@ -4,7 +4,7 @@ import { startTransition, useState } from 'react'; import clsx from 'clsx'; import MinusIcon from 'components/icons/minus'; import PlusIcon from 'components/icons/plus'; -import type { CartItem } from 'lib/shopify/types'; +import type { CartItem } from 'lib/medusa/types'; import LoadingDots from '../loading-dots'; export default function EditItemQuantityButton({ diff --git a/components/cart/index.tsx b/components/cart/index.tsx index 0e3ffcdc1..8d9adca32 100644 --- a/components/cart/index.tsx +++ b/components/cart/index.tsx @@ -1,4 +1,4 @@ -import { createCart, getCart } from 'lib/shopify'; +import { createCart, getCart } from 'lib/medusa'; import { cookies } from 'next/headers'; import CartButton from './button'; diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index 4220cfe94..0af119350 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -7,7 +7,7 @@ import CloseIcon from 'components/icons/close'; import ShoppingBagIcon from 'components/icons/shopping-bag'; import Price from 'components/price'; import { DEFAULT_OPTION } from 'lib/constants'; -import type { Cart } from 'lib/shopify/types'; +import type { Cart } from 'lib/medusa/types'; import { createUrl } from 'lib/utils'; import DeleteItemButton from './delete-item-button'; import EditItemQuantityButton from './edit-item-quantity-button'; @@ -70,13 +70,13 @@ export default function CartModal({ - {cart.lines.length === 0 ? ( + {cart.lines?.length === 0 ? (

Your cart is empty.

) : null} - {cart.lines.length !== 0 ? ( + {cart.lines?.length !== 0 ? (
    {cart.lines.map((item, i) => { diff --git a/components/grid/three-items.tsx b/components/grid/three-items.tsx index f4d99df80..8bbf671e6 100644 --- a/components/grid/three-items.tsx +++ b/components/grid/three-items.tsx @@ -1,6 +1,6 @@ import { GridTileImage } from 'components/grid/tile'; -import { getCollectionProducts } from 'lib/shopify'; -import type { Product } from 'lib/shopify/types'; +import { getCollectionProducts } from 'lib/medusa'; +import type { Product } from 'lib/medusa/types'; import Link from 'next/link'; function ThreeItemGridItem({ @@ -41,13 +41,13 @@ export async function ThreeItemGrid() { if (!homepageItems[0] || !homepageItems[1] || !homepageItems[2]) return null; - // const [firstProduct, secondProduct, thirdProduct] = homepageItems; + const [firstProduct, secondProduct, thirdProduct] = homepageItems; return (
    - {/* + - */} +
    ); } diff --git a/components/layout/footer.tsx b/components/layout/footer.tsx index 6d80c8fbc..d9d8afb7e 100644 --- a/components/layout/footer.tsx +++ b/components/layout/footer.tsx @@ -3,7 +3,7 @@ import Link from 'next/link'; import GitHubIcon from 'components/icons/github'; import LogoIcon from 'components/icons/logo'; import VercelIcon from 'components/icons/vercel'; -import { Menu } from 'lib/shopify/types'; +import { Menu } from 'lib/medusa/types'; const { SITE_NAME } = process.env; diff --git a/components/layout/navbar/index.tsx b/components/layout/navbar/index.tsx index 6252029d9..7efa42270 100644 --- a/components/layout/navbar/index.tsx +++ b/components/layout/navbar/index.tsx @@ -1,10 +1,7 @@ import Link from 'next/link'; -import { Suspense } from 'react'; -import Cart from 'components/cart'; -import CartIcon from 'components/icons/cart'; import LogoIcon from 'components/icons/logo'; -import { Menu } from 'lib/shopify/types'; +import { Menu } from 'lib/medusa/types'; import MobileMenu from './mobile-menu'; import Search from './search'; @@ -43,10 +40,10 @@ export default async function Navbar() {
- }> - {/* @ts-expect-error Server Component */} - - + {/* }> */} + {/* @ts-expect-error Server Component */} + {/* */} + {/* */}
); diff --git a/components/layout/navbar/mobile-menu.tsx b/components/layout/navbar/mobile-menu.tsx index c960d5218..fffff9dc7 100644 --- a/components/layout/navbar/mobile-menu.tsx +++ b/components/layout/navbar/mobile-menu.tsx @@ -8,7 +8,7 @@ import { useEffect, useState } from 'react'; import CloseIcon from 'components/icons/close'; import MenuIcon from 'components/icons/menu'; -import { Menu } from 'lib/shopify/types'; +import { Menu } from 'lib/medusa/types'; import Search from './search'; export default function MobileMenu({ menu }: { menu: Menu[] }) { diff --git a/components/layout/product-grid-items.tsx b/components/layout/product-grid-items.tsx index 0c0e907ed..380a7111a 100644 --- a/components/layout/product-grid-items.tsx +++ b/components/layout/product-grid-items.tsx @@ -1,6 +1,6 @@ import Grid from 'components/grid'; import { GridTileImage } from 'components/grid/tile'; -import { Product } from 'lib/shopify/types'; +import { Product } from 'lib/medusa/types'; import Link from 'next/link'; export default function ProductGridItems({ products }: { products: Product[] }) { diff --git a/components/layout/search/collections.tsx b/components/layout/search/collections.tsx index e4abb8d4a..5f3f8920e 100644 --- a/components/layout/search/collections.tsx +++ b/components/layout/search/collections.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; import { Suspense } from 'react'; -import { getCollections } from 'lib/shopify'; +import { getCollections } from 'lib/medusa'; import FilterList from './filter'; async function CollectionList() { diff --git a/components/product/add-to-cart.tsx b/components/product/add-to-cart.tsx index 9da11bafa..8142ba4cc 100644 --- a/components/product/add-to-cart.tsx +++ b/components/product/add-to-cart.tsx @@ -5,7 +5,7 @@ import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect, useState, useTransition } from 'react'; import LoadingDots from 'components/loading-dots'; -import { ProductVariant } from 'lib/shopify/types'; +import { ProductVariant } from 'lib/medusa/types'; export function AddToCart({ variants, diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index 520818516..2f95d06af 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -1,7 +1,7 @@ 'use client'; import clsx from 'clsx'; -import { ProductOption, ProductVariant } from 'lib/shopify/types'; +import { ProductOption, ProductVariant } from 'lib/medusa/types'; import { createUrl } from 'lib/utils'; import Link from 'next/link'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index 11f426649..75f281c7c 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -1,5 +1,6 @@ import { isShopifyError } from 'lib/type-guards'; -import { Cart, Collection, Product } from './types'; +import { ProductCollection } from '../medusa/types'; +import { Cart, Product } from './types'; // const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; const endpoint = `http://localhost:9000/store`; @@ -49,18 +50,19 @@ export default async function medusaRequest( export async function createCart(): Promise { const res = await medusaRequest('POST', '/carts', {}); + console.log('Cart created!'); + console.log(res); return res.body.cart; } export async function addToCart( cartId: string, - lines: { merchandiseId: string; quantity: number }[] + lineItems: { variantId: string; quantity: number }[] ): Promise { - console.log(lines); + console.log(lineItems); // TODO: transform lines into Medusa line items const res = await medusaRequest('POST', `/carts/${cartId}/line-items`, { - variant_id: 'something', - quantity: 1 + lineItems }); return res.body.data.cart; @@ -93,8 +95,9 @@ export async function getCart(cartId: string): Promise { return res.body.cart; } -export async function getCollection(handle: string): Promise { +export async function getCollection(handle: string): Promise { const res = await medusaRequest('get', `/collections?handle[]=${handle}&limit=1`); + console.log({ collection: res.body.collection }); return res.body.collection; } @@ -103,11 +106,11 @@ export async function getCollectionProducts(handle: string): Promise if (!res.body?.collection?.products) { return []; } - + console.log({ 'collection products': res.body.collection.products }); return res.body.collection.products; } -export async function getCollections(): Promise { +export async function getCollections(): Promise { const collections = [ { handle: '', @@ -122,7 +125,7 @@ export async function getCollections(): Promise { } ]; - return collections; + return []; } export async function getProduct(handle: string): Promise { From ff8098128df4804cbe7be77731f4b1d01a734945 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 16:14:57 +0200 Subject: [PATCH 05/28] fix: replace shopify error --- lib/medusa/index.ts | 4 ++-- lib/type-guards.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index cae2fc2f3..4b981a629 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -1,4 +1,4 @@ -import { isShopifyError } from 'lib/type-guards'; +import { isMedusaError } from 'lib/type-guards'; import { Cart, MedusaCart, MedusaProduct, Product, ProductCollection } from './types'; // const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; @@ -34,7 +34,7 @@ export default async function medusaRequest( body }; } catch (e) { - if (isShopifyError(e)) { + if (isMedusaError(e)) { throw { status: e.status || 500, message: e.message diff --git a/lib/type-guards.ts b/lib/type-guards.ts index 1b7e7af5a..e69cc22fa 100644 --- a/lib/type-guards.ts +++ b/lib/type-guards.ts @@ -1,4 +1,4 @@ -export interface ShopifyErrorLike { +export interface MedusaErrorLike { status: number; message: Error; } @@ -7,7 +7,7 @@ export const isObject = (object: unknown): object is Record => return typeof object === 'object' && object !== null && !Array.isArray(object); }; -export const isShopifyError = (error: unknown): error is ShopifyErrorLike => { +export const isMedusaError = (error: unknown): error is MedusaErrorLike => { if (!isObject(error)) return false; if (error instanceof Error) return true; From 1cd708309d0f4621e2d142a1932fd3118d473d08 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Tue, 2 May 2023 16:52:39 +0200 Subject: [PATCH 06/28] fix: type fixes --- lib/medusa/index.ts | 63 +++++++++++++++++++++++++++++++-------------- lib/medusa/types.ts | 15 +++++++++-- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 4b981a629..01deb669a 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -1,5 +1,12 @@ import { isMedusaError } from 'lib/type-guards'; -import { Cart, MedusaCart, MedusaProduct, Product, ProductCollection } from './types'; +import { + Cart, + MedusaCart, + MedusaProduct, + MedusaProductCollection, + Product, + ProductCollection +} from './types'; // const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; const endpoint = `http://localhost:9000/store`; @@ -68,11 +75,31 @@ const reshapeProduct = (product: MedusaProduct): Product => { currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' } }; + const updatedAt = product.updated_at; return { ...product, featuredImage, - priceRange + priceRange, + updatedAt + }; +}; + +const reshapeCollection = (collection: MedusaProductCollection): ProductCollection => { + const description = collection.metadata?.description?.toString() ?? ''; + const seo = { + title: collection?.metadata?.seo_title?.toString() ?? '', + description: collection?.metadata?.seo_description?.toString() ?? '' + }; + const path = `/${collection.handle}`; + const updatedAt = collection.updated_at; + + return { + ...collection, + description, + seo, + path, + updatedAt }; }; @@ -141,26 +168,21 @@ export async function getCollectionProducts(handle: string): Promise return []; } - return res.body.products.map((product: Product) => reshapeProduct(product)); + const products: Product[] = res.body.products.map((product: MedusaProduct) => + reshapeProduct(product) + ); + + return products; } export async function getCollections(): Promise { - const collections = [ - { - handle: '', - title: 'All', - description: 'All products', - seo: { - title: 'All', - description: 'All products' - }, - path: '/search', - updatedAt: new Date().toISOString() - } - ]; + const res = await medusaRequest('GET', '/collections'); - // return collections; - return []; + const collections: ProductCollection[] = res.body.collections.map( + (collection: MedusaProductCollection) => reshapeCollection(collection) + ); + + return collections; } export async function getProduct(handle: string): Promise { @@ -176,5 +198,8 @@ export async function getProducts({ sortKey?: string; }): Promise { const res = await medusaRequest('get', `/products?q=${query}&limit=20`); - return res.body.products; + const products: Product[] = res.body.products.map((product: MedusaProduct) => + reshapeProduct(product) + ); + return products; } diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 123166959..afd3d20b7 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -1,4 +1,4 @@ -export type ProductCollection = { +export type MedusaProductCollection = { id: string; title: string; handle: string | null; @@ -9,6 +9,16 @@ export type ProductCollection = { metadata?: Record | null; }; +export type ProductCollection = MedusaProductCollection & { + description?: string; + seo?: { + title?: string; + description?: string; + }; + path: string; + updatedAt: string; +}; + export type MedusaProduct = { id: string; title: string; @@ -51,6 +61,7 @@ export type Product = MedusaProduct & { currencyCode: string; }; }; + updatedAt: Date; }; export type Image = { @@ -246,7 +257,7 @@ export type MedusaCart = { items: []; }; -export type Cart = Omit & { +export type Cart = Partial & { lines: []; totalQuantity: number; }; From c4ab3aba8dcd8b36b1d2e716377637813a8c31ae Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Wed, 3 May 2023 10:55:45 +0200 Subject: [PATCH 07/28] feat: reshape products --- app/product/[handle]/page.tsx | 28 ++++++++++++++------------ lib/medusa/index.ts | 15 ++++++++++---- lib/medusa/types.ts | 38 +++++++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 194b22c42..550f398ae 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -28,8 +28,8 @@ export async function generateMetadata({ const hide = !product.tags.includes(HIDDEN_PRODUCT_TAG); return { - title: product.seo.title || product.title, - description: product.seo.description || product.description, + title: product.seo?.title || product.title, + description: product.seo?.description || product.description, robots: { index: hide, follow: hide, @@ -61,17 +61,19 @@ export default async function ProductPage({ params }: { params: { handle: string return (
-
- ({ - src: image.url, - altText: image.altText - }))} - /> -
+ {product.images && ( +
+ ({ + src: image.url, + altText: image.altText ?? '' + }))} + /> +
+ )}
{/* @ts-expect-error Server Component */} diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 01deb669a..49bdb44f2 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -66,9 +66,6 @@ const reshapeCart = (cart: MedusaCart): Cart => { }; const reshapeProduct = (product: MedusaProduct): Product => { - const featuredImage = { - url: product.images?.[0]?.url ?? '' - }; const priceRange = { maxVariantPrice: { amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '', @@ -76,12 +73,22 @@ const reshapeProduct = (product: MedusaProduct): Product => { } }; const updatedAt = product.updated_at; + const tags = product.tags?.map((tag) => tag.value) || []; + const descriptionHtml = product.description ?? ''; + const featuredImage = { + url: product.images?.[0]?.url ?? '', + altText: product.images?.[0]?.id ?? '' + }; + const availableForSale = true; return { ...product, featuredImage, priceRange, - updatedAt + updatedAt, + tags, + descriptionHtml, + availableForSale }; }; diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index afd3d20b7..c8d9b0970 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -27,10 +27,10 @@ export type MedusaProduct = { handle?: string | null; is_giftcard: boolean; status?: 'draft' | 'proposed' | 'published' | 'rejected'; - images?: Array; + images?: Array; thumbnail?: string | null; options?: Array; - variants?: Array; + variants: Array; categories?: Array; profile_id?: string | null; profile?: ShippingProfile | null; @@ -49,11 +49,14 @@ export type MedusaProduct = { deleted_at: Date | null; type_id: string; material?: string | null; + tags?: ProductTag[]; }; -export type Product = MedusaProduct & { - featuredImage: { - url: string; +export type Product = Omit & { + featuredImage: FeaturedImage; + seo?: { + title?: string; + description?: string; }; priceRange: { maxVariantPrice: { @@ -62,9 +65,28 @@ export type Product = MedusaProduct & { }; }; updatedAt: Date; + descriptionHtml: string; + tags: Array; + availableForSale: boolean; }; -export type Image = { +export type FeaturedImage = { + url: string; + width?: number; + height?: number; + altText: string; +}; + +export type ProductTag = { + id: string; + value: string; + created_at: string; + updated_at: string; + deleted_at: string | null; + metadata?: Record | null; +}; + +export type MedusaImage = { id: string; url: string; created_at: string; @@ -73,6 +95,10 @@ export type Image = { metadata?: { [key: string]: string } | null; }; +export type Image = MedusaImage & { + altText?: string; +}; + export type ShippingProfile = { id: string; name: string; From bff927e700e675eac3c499c49cd327cb72886f6f Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Wed, 3 May 2023 12:29:42 +0200 Subject: [PATCH 08/28] chore: bump compilerOptions target to es6 --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 6cd05f98a..4e93cf11a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, From e0e67f4270583b452d8b8998beb3dfe68175e1c8 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Wed, 3 May 2023 14:01:34 +0200 Subject: [PATCH 09/28] feat: product options and variants --- components/layout/navbar/index.tsx | 11 ++-- lib/medusa/index.ts | 54 +++++++++++++++++-- lib/medusa/types.ts | 85 ++++++++++++++++++++---------- 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/components/layout/navbar/index.tsx b/components/layout/navbar/index.tsx index 7efa42270..554da5180 100644 --- a/components/layout/navbar/index.tsx +++ b/components/layout/navbar/index.tsx @@ -1,7 +1,10 @@ import Link from 'next/link'; +import Cart from 'components/cart'; +import CartIcon from 'components/icons/cart'; import LogoIcon from 'components/icons/logo'; import { Menu } from 'lib/medusa/types'; +import { Suspense } from 'react'; import MobileMenu from './mobile-menu'; import Search from './search'; @@ -40,10 +43,10 @@ export default async function Navbar() {
- {/* }> */} - {/* @ts-expect-error Server Component */} - {/* */} - {/* */} + }> + {/* @ts-expect-error Server Component */} + +
); diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 49bdb44f2..c4d3cae30 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -4,8 +4,12 @@ import { MedusaCart, MedusaProduct, MedusaProductCollection, + MedusaProductOption, + MedusaProductVariant, Product, - ProductCollection + ProductCollection, + ProductOption, + ProductVariant } from './types'; // const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; @@ -80,6 +84,11 @@ const reshapeProduct = (product: MedusaProduct): Product => { altText: product.images?.[0]?.id ?? '' }; const availableForSale = true; + const variants = product.variants.map((variant) => reshapeProductVariant(variant)); + + let options; + product.options && (options = product.options.map((option) => reshapeProductOption(option))); + // console.log({ options }); return { ...product, @@ -88,7 +97,43 @@ const reshapeProduct = (product: MedusaProduct): Product => { updatedAt, tags, descriptionHtml, - availableForSale + availableForSale, + options, + variants + }; +}; + +const reshapeProductOption = (productOption: MedusaProductOption): ProductOption => { + const availableForSale = true; + const name = productOption.title; + let values = productOption.values?.map((option) => option.value) || []; + values = [...new Set(values)]; + + return { + ...productOption, + availableForSale, + name, + values + }; +}; + +const reshapeProductVariant = (productVariant: MedusaProductVariant): ProductVariant => { + console.log({ productVariant }); + const availableForSale = !!productVariant.inventory_quantity; + const selectedOptions = + productVariant.options?.map((option) => ({ + name: option.option?.title ?? '', + value: option.value + })) || []; + const price = { + amount: productVariant.prices?.[0]?.amount.toString() ?? '', + currencyCode: productVariant.prices?.[0]?.currency_code ?? '' + }; + return { + ...productVariant, + availableForSale, + selectedOptions, + price }; }; @@ -193,8 +238,9 @@ export async function getCollections(): Promise { } export async function getProduct(handle: string): Promise { - const res = await medusaRequest('get', `/products?handle=${handle}&limit=1`); - return res.body.product; + const res = await medusaRequest('GET', `/products?handle=${handle}&limit=1`); + const product = res.body.products[0]; + return reshapeProduct(product); } export async function getProducts({ diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index c8d9b0970..8640d117b 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -29,8 +29,8 @@ export type MedusaProduct = { status?: 'draft' | 'proposed' | 'published' | 'rejected'; images?: Array; thumbnail?: string | null; - options?: Array; - variants: Array; + options?: Array; + variants: Array; categories?: Array; profile_id?: string | null; profile?: ShippingProfile | null; @@ -52,7 +52,7 @@ export type MedusaProduct = { tags?: ProductTag[]; }; -export type Product = Omit & { +export type Product = Omit & { featuredImage: FeaturedImage; seo?: { title?: string; @@ -68,6 +68,8 @@ export type Product = Omit & { descriptionHtml: string; tags: Array; availableForSale: boolean; + options?: Array; + variants: Array; }; export type FeaturedImage = { @@ -127,7 +129,7 @@ export type ProductCategory = { updated_at: string; }; -export type ProductVariant = { +export type MedusaProductVariant = { id: string; title?: string; product_id: string; @@ -155,6 +157,51 @@ export type ProductVariant = { deleted_at: string | null; }; +export type ProductVariant = MedusaProductVariant & { + availableForSale: boolean; + selectedOptions: { + name: string; + value: string; + }[]; + price: Money; +}; + +export type MedusaProductOption = { + id: string; + title: string; + values?: ProductOptionValue[]; + product_id: string; + product?: Product | null; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type ProductOption = Omit & { + availableForSale: boolean; + name: string; + values: string[]; +}; + +export type ProductOptionValue = { + id: string; + value: string; + option_id: string; + option?: MedusaProductOption | null; + variant_id: string; + variant?: MedusaProductVariant | null; + created_at: string; + updated_at: string; + deleted_at?: string | null; + metadata?: Record | null; +}; + +export type Money = { + amount: string; + currencyCode: string; +}; + type MoneyAmount = { id: string; currency_code: string; @@ -202,31 +249,6 @@ export type CustomerGroup = { name: string; }; -export type ProductOption = { - id: string; - title: string; - values?: ProductOptionValue[]; - product_id: string; - product?: Product | null; - created_at: string; - updated_at: string; - deleted_at?: string | null; - metadata?: Record | null; -}; - -export type ProductOptionValue = { - id: string; - value: string; - option_id: string; - option?: ProductOption | null; - variant_id: string; - variant?: ProductVariant | null; - created_at: string; - updated_at: string; - deleted_at?: string | null; - metadata?: Record | null; -}; - type ShippingOption = { id: string; name: string; @@ -287,3 +309,8 @@ export type Cart = Partial & { lines: []; totalQuantity: number; }; + +export type Menu = { + title: string; + path: string; +}; From cfe181ac41d78cadb4df188c4558f6f2d6943fdd Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Wed, 3 May 2023 14:56:55 +0200 Subject: [PATCH 10/28] feat: variant selector --- app/[page]/page.tsx | 2 -- components/product/variant-selector.tsx | 1 + lib/medusa/index.ts | 36 ++++++++++++++++++------- lib/medusa/types.ts | 10 ++++--- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/app/[page]/page.tsx b/app/[page]/page.tsx index 37ebb0b04..00e118f37 100644 --- a/app/[page]/page.tsx +++ b/app/[page]/page.tsx @@ -12,7 +12,6 @@ export async function generateMetadata({ }: { params: { page: string }; }): Promise { - console.log(params); const page: any = null; if (!page) return notFound(); @@ -36,7 +35,6 @@ export async function generateMetadata({ } export default async function Page({ params }: { params: { page: string } }) { - console.log(params); const page: any = null; if (!page) return notFound(); diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index 2f95d06af..a555aeb7d 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -90,6 +90,7 @@ export function VariantSelector({ {option.values.map((value) => { // Base option params on selected variant params. const optionParams = new URLSearchParams(selectedVariantParams); + // Update the params using the current option to reflect how the url would change. optionParams.set(option.name.toLowerCase(), value); diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index c4d3cae30..2dcd272ab 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -9,7 +9,8 @@ import { Product, ProductCollection, ProductOption, - ProductVariant + ProductVariant, + SelectedOption } from './types'; // const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; @@ -84,11 +85,12 @@ const reshapeProduct = (product: MedusaProduct): Product => { altText: product.images?.[0]?.id ?? '' }; const availableForSale = true; - const variants = product.variants.map((variant) => reshapeProductVariant(variant)); + const variants = product.variants.map((variant) => + reshapeProductVariant(variant, product.options) + ); let options; product.options && (options = product.options.map((option) => reshapeProductOption(option))); - // console.log({ options }); return { ...product, @@ -117,14 +119,28 @@ const reshapeProductOption = (productOption: MedusaProductOption): ProductOption }; }; -const reshapeProductVariant = (productVariant: MedusaProductVariant): ProductVariant => { - console.log({ productVariant }); - const availableForSale = !!productVariant.inventory_quantity; - const selectedOptions = - productVariant.options?.map((option) => ({ - name: option.option?.title ?? '', +const mapOptionIds = (productOptions: MedusaProductOption[]) => { + const map: Record = {}; + productOptions.forEach((option) => { + map[option.id] = option.title; + }); + return map; +}; + +const reshapeProductVariant = ( + productVariant: MedusaProductVariant, + productOptions?: MedusaProductOption[] +): ProductVariant => { + let selectedOptions: SelectedOption[] = []; + if (productOptions && productVariant.options) { + const optionIdMap = mapOptionIds(productOptions); + selectedOptions = productVariant.options.map((option) => ({ + name: optionIdMap[option.option_id] ?? '', value: option.value - })) || []; + })); + } + const availableForSale = !!productVariant.inventory_quantity; + const price = { amount: productVariant.prices?.[0]?.amount.toString() ?? '', currencyCode: productVariant.prices?.[0]?.currency_code ?? '' diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 8640d117b..c282a9c31 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -159,13 +159,15 @@ export type MedusaProductVariant = { export type ProductVariant = MedusaProductVariant & { availableForSale: boolean; - selectedOptions: { - name: string; - value: string; - }[]; + selectedOptions: SelectedOption[]; price: Money; }; +export type SelectedOption = { + name: string; + value: string; +}; + export type MedusaProductOption = { id: string; title: string; From a46f39bd4c3c471fa59c8c22af5ae7c01b67a518 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Wed, 3 May 2023 18:50:58 +0200 Subject: [PATCH 11/28] feat: implemented most cart operations --- app/api/cart/route.ts | 11 +-- components/cart/delete-item-button.tsx | 9 +- components/cart/modal.tsx | 3 +- components/product/add-to-cart.tsx | 2 +- lib/medusa/index.ts | 106 +++++++++++++++++----- lib/medusa/types.ts | 117 +++++++++++++++++++++++-- lib/utils.ts | 11 +++ 7 files changed, 216 insertions(+), 43 deletions(-) diff --git a/app/api/cart/route.ts b/app/api/cart/route.ts index 788b6b781..031ff6aad 100644 --- a/app/api/cart/route.ts +++ b/app/api/cart/route.ts @@ -2,7 +2,7 @@ import { cookies } from 'next/headers'; import { NextRequest, NextResponse } from 'next/server'; import { addToCart, removeFromCart, updateCart } from 'lib/medusa'; -import { isShopifyError } from 'lib/type-guards'; +import { isMedusaError } from 'lib/type-guards'; function formatErrorMessage(err: Error): string { return JSON.stringify(err, Object.getOwnPropertyNames(err)); @@ -19,7 +19,7 @@ export async function POST(req: NextRequest): Promise { await addToCart(cartId, [{ variantId, quantity: 1 }]); return NextResponse.json({ status: 204 }); } catch (e) { - if (isShopifyError(e)) { + if (isMedusaError(e)) { return NextResponse.json({ message: formatErrorMessage(e.message) }, { status: e.status }); } @@ -47,7 +47,7 @@ export async function PUT(req: NextRequest): Promise { ]); return NextResponse.json({ status: 204 }); } catch (e) { - if (isShopifyError(e)) { + if (isMedusaError(e)) { return NextResponse.json({ message: formatErrorMessage(e.message) }, { status: e.status }); } @@ -57,7 +57,8 @@ export async function PUT(req: NextRequest): Promise { export async function DELETE(req: NextRequest): Promise { const cartId = cookies().get('cartId')?.value; - const { lineId } = await req.json(); + console.log(req.nextUrl); + const lineId = req.nextUrl.searchParams.get('lineId'); if (!cartId || !lineId) { return NextResponse.json({ error: 'Missing cartId or lineId' }, { status: 400 }); @@ -66,7 +67,7 @@ export async function DELETE(req: NextRequest): Promise { await removeFromCart(cartId, [lineId]); return NextResponse.json({ status: 204 }); } catch (e) { - if (isShopifyError(e)) { + if (isMedusaError(e)) { return NextResponse.json({ message: formatErrorMessage(e.message) }, { status: e.status }); } diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index 25f5a3b1a..b794607b1 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -13,12 +13,11 @@ export default function DeleteItemButton({ item }: { item: CartItem }) { async function handleRemove() { setRemoving(true); - const response = await fetch(`/api/cart`, { - method: 'DELETE', - body: JSON.stringify({ - lineId: item.id - }) + console.log(item.id); + const response = await fetch(`/api/cart?lineId=${item.id}`, { + method: 'DELETE' }); + const data = await response.json(); if (data.error) { diff --git a/components/cart/modal.tsx b/components/cart/modal.tsx index 0af119350..413e89337 100644 --- a/components/cart/modal.tsx +++ b/components/cart/modal.tsx @@ -107,7 +107,8 @@ export default function CartModal({ height={64} alt={ item.merchandise.product.featuredImage.altText || - item.merchandise.product.title + item.merchandise.product.title || + '' } src={item.merchandise.product.featuredImage.url} /> diff --git a/components/product/add-to-cart.tsx b/components/product/add-to-cart.tsx index 8142ba4cc..858f67b16 100644 --- a/components/product/add-to-cart.tsx +++ b/components/product/add-to-cart.tsx @@ -42,7 +42,7 @@ export function AddToCart({ const response = await fetch(`/api/cart`, { method: 'POST', body: JSON.stringify({ - merchandiseId: selectedVariantId + variantId: selectedVariantId }) }); diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 2dcd272ab..94968a667 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -1,7 +1,11 @@ import { isMedusaError } from 'lib/type-guards'; + +import { mapOptionIds } from 'lib/utils'; import { Cart, + CartItem, MedusaCart, + MedusaLineItem, MedusaProduct, MedusaProductCollection, MedusaProductOption, @@ -60,20 +64,87 @@ export default async function medusaRequest( } const reshapeCart = (cart: MedusaCart): Cart => { - const lines = cart.items; - const totalQuantity = cart.items.length || 0; + const lines = cart.items?.map((item) => reshapeLineItem(item)) || []; + const totalQuantity = lines.length; + const checkoutUrl = '/'; + const currencyCode = 'EUR'; + const cost = { + subtotalAmount: { + amount: (cart.total && cart.tax_total && cart.total - cart.tax_total)?.toString() || '0', + currencyCode + }, + totalAmount: { + amount: (cart.tax_total && cart.tax_total.toString()) || '0', + currencyCode + }, + totalTaxAmount: { + amount: (cart.tax_total && cart.tax_total.toString()) || '0', + currencyCode + } + }; return { ...cart, totalQuantity, - lines + checkoutUrl, + lines, + cost + }; +}; + +const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { + const product = { + priceRange: { + maxVariantPrice: { + amount: lineItem.variant?.prices?.[0]?.amount.toString() ?? '0', + currencyCode: lineItem.variant?.prices?.[0]?.currency_code ?? 'EUR' + } + }, + updatedAt: lineItem.updated_at, + tags: [], + descriptionHtml: lineItem.description ?? '', + featuredImage: { + url: lineItem.thumbnail ?? '', + altText: lineItem.title ?? '' + }, + availableForSale: true, + variants: [lineItem.variant && reshapeProductVariant(lineItem.variant)], + handle: lineItem.variant?.product?.handle ?? '' + }; + + const selectedOptions = + lineItem.variant?.options?.map((option) => ({ + name: option.option?.title ?? '', + value: option.value + })) || []; + + const merchandise = { + id: lineItem.variant_id || lineItem.id, + selectedOptions, + product, + title: lineItem.title + }; + + const cost = { + totalAmount: { + amount: lineItem.total.toString() ?? '0', + currencyCode: 'EUR' + } + }; + const quantity = lineItem.quantity; + + return { + ...lineItem, + merchandise, + cost, + quantity }; }; const reshapeProduct = (product: MedusaProduct): Product => { const priceRange = { maxVariantPrice: { - amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '', + amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '0', currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' } }; @@ -119,14 +190,6 @@ const reshapeProductOption = (productOption: MedusaProductOption): ProductOption }; }; -const mapOptionIds = (productOptions: MedusaProductOption[]) => { - const map: Record = {}; - productOptions.forEach((option) => { - map[option.id] = option.title; - }); - return map; -}; - const reshapeProductVariant = ( productVariant: MedusaProductVariant, productOptions?: MedusaProductOption[] @@ -142,7 +205,7 @@ const reshapeProductVariant = ( const availableForSale = !!productVariant.inventory_quantity; const price = { - amount: productVariant.prices?.[0]?.amount.toString() ?? '', + amount: productVariant.prices?.[0]?.amount.toString() ?? 'ß', currencyCode: productVariant.prices?.[0]?.currency_code ?? '' }; return { @@ -173,8 +236,6 @@ const reshapeCollection = (collection: MedusaProductCollection): ProductCollecti export async function createCart(): Promise { const res = await medusaRequest('POST', '/carts', {}); - console.log('Cart created!'); - console.log(res); return reshapeCart(res.body.cart); } @@ -185,17 +246,18 @@ export async function addToCart( console.log(lineItems); // TODO: transform lines into Medusa line items const res = await medusaRequest('POST', `/carts/${cartId}/line-items`, { - lineItems + variant_id: lineItems[0]?.variantId, + quantity: lineItems[0]?.quantity }); - - return res.body.data.cart; + console.log(res.body); + return reshapeCart(res.body.cart); } export async function removeFromCart(cartId: string, lineIds: string[]): Promise { // TODO: We only allow you to pass a single line item to delete const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineIds[0]}`); - - return res.body.data.cart; + console.log(res); + return reshapeCart(res.body.cart); } export async function updateCart( @@ -205,7 +267,7 @@ export async function updateCart( console.log(lines); // TODO: transform lines into Medusa line items const res = await medusaRequest('POST', `/carts/${cartId}`, {}); - return res.body.data.cart; + return reshapeCart(res.body.cart); } export async function getCart(cartId: string): Promise { @@ -215,7 +277,7 @@ export async function getCart(cartId: string): Promise { return null; } - return res.body.cart; + return reshapeCart(res.body.cart); } export async function getCollection(handle: string): Promise { diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index c282a9c31..001f27c82 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -52,24 +52,21 @@ export type MedusaProduct = { tags?: ProductTag[]; }; -export type Product = Omit & { +export type Product = Partial> & { featuredImage: FeaturedImage; seo?: { title?: string; description?: string; }; priceRange: { - maxVariantPrice: { - amount: string; - currencyCode: string; - }; + maxVariantPrice: Money; }; updatedAt: Date; descriptionHtml: string; tags: Array; availableForSale: boolean; options?: Array; - variants: Array; + variants: Array; }; export type FeaturedImage = { @@ -204,7 +201,7 @@ export type Money = { currencyCode: string; }; -type MoneyAmount = { +export type MoneyAmount = { id: string; currency_code: string; currency?: Currency | null; @@ -304,15 +301,117 @@ export type ShippingOptionRequirement = { export type MedusaCart = { id: string; - items: []; + email?: string; + billing_address_id: string; + // billing_address?: Address; + // shipping_address_id?: string; + // shipping_address?: Address; + items?: MedusaLineItem[]; + region_id: string; + region?: Region; + // discounts?: Discount[]; + // gift_cards?: GiftCard[]; + customer_id?: string; + // customer?: Customer; + // payment_session?: PaymentSession; + // payment_sessions?: PaymentSession[]; + payment_id?: string; + // payment?: Payment; + // shipping_methods?: ShippingMethod[]; + type: 'default' | 'swap' | 'draft_order' | 'payment_link' | 'claim'; + completed_at?: string; + payment_authorized_at?: string; + idempotency_key?: string; + context?: Record; + sales_channel_id?: string; + // sales_channel?: SalesChannel; + created_at: string; + updated_at: string; + deleted_at?: string; + metadata?: Record; + shipping_total?: number; + discount_total?: number; + raw_discount_total?: number; + item_tax_total?: number; + shipping_tax_total?: number; + tax_total?: number; + refunded_total?: number; + total?: number; }; export type Cart = Partial & { - lines: []; + lines: CartItem[]; + checkoutUrl: string; totalQuantity: number; + cost: { + subtotalAmount: Money; + totalAmount: Money; + totalTaxAmount: Money; + }; }; export type Menu = { title: string; path: string; }; + +export type MedusaLineItem = { + id: string; + cart_id?: string; + cart?: Cart; + order_id?: string; + // order?: Order; + swap_id?: string | null; + // swap?: Swap; + claim_order_id?: string | null; + // claim_order?: ClaimOrder; + // tax_lines?: LineItemTaxLine[]; + // adjustments?: LineItemAdjustment[]; + original_item_id?: string | null; + order_edit_id?: string | null; + // order_edit?: OrderEdit; + title: string; + description?: string | null; + thumbnail?: string | null; + is_return: boolean; + is_giftcard: boolean; + should_merge: boolean; + allow_discounts: boolean; + has_shipping?: boolean | null; + unit_price: number; + variant_id?: string | null; + variant?: MedusaProductVariant; + quantity: number; + fulfilled_quantity?: number | null; + returned_quantity?: number | null; + shipped_quantity?: number | null; + refundable: number; + subtotal: number; + tax_total: number; + total: number; + original_total: number; + original_tax_total: number; + discount_total: number; + raw_discount_total: number; + gift_card_total: number; + includes_tax: boolean; + created_at: Date; + updated_at: Date; + metadata?: { [key: string]: string } | null; +}; + +export type CartItem = MedusaLineItem & { + merchandise: { + id: string; + selectedOptions: SelectedOption[]; + product: Product; + title: string; + }; + cost: { + totalAmount: { + amount: string; + currencyCode: string; + }; + }; + quantity: number; +}; diff --git a/lib/utils.ts b/lib/utils.ts index e45a0df86..9c72e43a4 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,6 +1,17 @@ +import { MedusaProductOption } from './medusa/types'; + export const createUrl = (pathname: string, params: URLSearchParams) => { const paramsString = params.toString(); const queryString = `${paramsString.length ? '?' : ''}${paramsString}`; return `${pathname}${queryString}`; }; + +export const mapOptionIds = (productOptions: MedusaProductOption[]) => { + // Maps the option titles to their respective ids + const map: Record = {}; + productOptions.forEach((option) => { + map[option.id] = option.title; + }); + return map; +}; From 99d93093c7eb2dff9d0ec45400bcdab36e0e86fc Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 11:43:27 +0200 Subject: [PATCH 12/28] fix: wrap router.replace in useEffect hook --- components/product/variant-selector.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/components/product/variant-selector.tsx b/components/product/variant-selector.tsx index a555aeb7d..cb5d825cb 100644 --- a/components/product/variant-selector.tsx +++ b/components/product/variant-selector.tsx @@ -5,6 +5,7 @@ import { ProductOption, ProductVariant } from 'lib/medusa/types'; import { createUrl } from 'lib/utils'; import Link from 'next/link'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useEffect } from 'react'; type ParamsMap = { [key: string]: string; // ie. { color: 'Red', size: 'Large', ... } @@ -79,9 +80,11 @@ export function VariantSelector({ const currentUrl = createUrl(pathname, currentParams); const selectedVariantUrl = createUrl(pathname, selectedVariantParams); - if (currentUrl !== selectedVariantUrl) { - router.replace(selectedVariantUrl); - } + useEffect(() => { + if (currentUrl !== selectedVariantUrl) { + router.replace(selectedVariantUrl); + } + }, [currentUrl, router, selectedVariantUrl]); return options.map((option) => (
From 5bcf6cb5eb9865cf71393ae0058a807818bbe38d Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 11:43:59 +0200 Subject: [PATCH 13/28] fix: fix reshape function for new cart --- lib/medusa/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 94968a667..28837ec87 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -70,15 +70,15 @@ const reshapeCart = (cart: MedusaCart): Cart => { const currencyCode = 'EUR'; const cost = { subtotalAmount: { - amount: (cart.total && cart.tax_total && cart.total - cart.tax_total)?.toString() || '0', + amount: (cart?.total && cart?.tax_total && cart.total - cart.tax_total)?.toString() || '0', currencyCode }, totalAmount: { - amount: (cart.tax_total && cart.tax_total.toString()) || '0', + amount: (cart?.tax_total && cart?.tax_total.toString()) || '0', currencyCode }, totalTaxAmount: { - amount: (cart.tax_total && cart.tax_total.toString()) || '0', + amount: (cart?.tax_total && cart?.tax_total.toString()) || '0', currencyCode } }; From 4d99e73f20cd74a9ae5491c3f66470961dd6f897 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:02:46 +0200 Subject: [PATCH 14/28] fix: remove line items when 0 --- app/api/cart/route.ts | 25 +- components/cart/delete-item-button.tsx | 2 +- components/cart/edit-item-quantity-button.tsx | 19 +- lib/medusa/index.ts | 18 +- yarn.lock | 3375 +++++++++++++++++ 5 files changed, 3408 insertions(+), 31 deletions(-) create mode 100644 yarn.lock diff --git a/app/api/cart/route.ts b/app/api/cart/route.ts index 031ff6aad..03070857e 100644 --- a/app/api/cart/route.ts +++ b/app/api/cart/route.ts @@ -29,22 +29,19 @@ export async function POST(req: NextRequest): Promise { export async function PUT(req: NextRequest): Promise { const cartId = cookies().get('cartId')?.value; - const { variantId, quantity, lineId } = await req.json(); + const { lineItemId, quantity } = await req.json(); - if (!cartId || !variantId || !quantity || !lineId) { + if (!cartId || !quantity || !lineItemId) { return NextResponse.json( - { error: 'Missing cartId, variantId, lineId, or quantity' }, + { error: 'Missing cartId, variantId, lineItemId, or quantity' }, { status: 400 } ); } try { - await updateCart(cartId, [ - { - id: lineId, - merchandiseId: variantId, - quantity - } - ]); + await updateCart(cartId, { + lineItemId, + quantity + }); return NextResponse.json({ status: 204 }); } catch (e) { if (isMedusaError(e)) { @@ -58,13 +55,13 @@ export async function PUT(req: NextRequest): Promise { export async function DELETE(req: NextRequest): Promise { const cartId = cookies().get('cartId')?.value; console.log(req.nextUrl); - const lineId = req.nextUrl.searchParams.get('lineId'); + const lineItemId = req.nextUrl.searchParams.get('lineItemId'); - if (!cartId || !lineId) { - return NextResponse.json({ error: 'Missing cartId or lineId' }, { status: 400 }); + if (!cartId || !lineItemId) { + return NextResponse.json({ error: 'Missing cartId or lineItemId' }, { status: 400 }); } try { - await removeFromCart(cartId, [lineId]); + await removeFromCart(cartId, [lineItemId]); return NextResponse.json({ status: 204 }); } catch (e) { if (isMedusaError(e)) { diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index b794607b1..8124353ed 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -14,7 +14,7 @@ export default function DeleteItemButton({ item }: { item: CartItem }) { setRemoving(true); console.log(item.id); - const response = await fetch(`/api/cart?lineId=${item.id}`, { + const response = await fetch(`/api/cart?lineItemId=${item.id}`, { method: 'DELETE' }); diff --git a/components/cart/edit-item-quantity-button.tsx b/components/cart/edit-item-quantity-button.tsx index 6b8bb72fe..765cd1070 100644 --- a/components/cart/edit-item-quantity-button.tsx +++ b/components/cart/edit-item-quantity-button.tsx @@ -20,13 +20,18 @@ export default function EditItemQuantityButton({ async function handleEdit() { setEditing(true); - const response = await fetch(`/api/cart`, { - method: type === 'minus' && item.quantity - 1 === 0 ? 'DELETE' : 'PUT', - body: JSON.stringify({ - lineId: item.id, - variantId: item.merchandise.id, - quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1 - }) + const method = type === 'minus' && item.quantity - 1 === 0 ? 'DELETE' : 'PUT'; + const url = method === 'PUT' ? '/api/cart' : `/api/cart?lineItemId=${item.id}`; + + const response = await fetch(url, { + method, + body: + method === 'PUT' + ? JSON.stringify({ + lineItemId: item.id, + quantity: type === 'plus' ? item.quantity + 1 : item.quantity - 1 + }) + : null }); const data = await response.json(); diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 28837ec87..b07ae1bbe 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -253,31 +253,31 @@ export async function addToCart( return reshapeCart(res.body.cart); } -export async function removeFromCart(cartId: string, lineIds: string[]): Promise { +export async function removeFromCart(cartId: string, lineItemIds: string[]): Promise { // TODO: We only allow you to pass a single line item to delete - const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineIds[0]}`); - console.log(res); + const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineItemIds[0]}`); return reshapeCart(res.body.cart); } export async function updateCart( cartId: string, - lines: { id: string; merchandiseId: string; quantity: number }[] + { lineItemId, quantity }: { lineItemId: string; quantity: number } ): Promise { - console.log(lines); - // TODO: transform lines into Medusa line items - const res = await medusaRequest('POST', `/carts/${cartId}`, {}); + const res = await medusaRequest('POST', `/carts/${cartId}/line-items/${lineItemId}`, { + quantity + }); return reshapeCart(res.body.cart); } export async function getCart(cartId: string): Promise { const res = await medusaRequest('GET', `/carts/${cartId}`); + const cart = res.body.cart; - if (!res.body.cart) { + if (!cart) { return null; } - return reshapeCart(res.body.cart); + return reshapeCart(cart); } export async function getCollection(handle: string): Promise { diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..71ad8efe2 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3375 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@babel/code-frame@^7.0.0": + version "7.21.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/runtime@^7.20.7": + version "7.21.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" + integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== + dependencies: + regenerator-runtime "^0.13.11" + +"@emotion/is-prop-valid@^0.8.2": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz#01575e38707add677cf73ca1589abba8da899a02" + integrity sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.1" + 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" + +"@eslint/js@8.39.0": + version "8.39.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" + integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== + +"@headlessui/react@^1.7.10": + version "1.7.14" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.14.tgz#75f19552c535113640fe8a3a40e71474f49e89c9" + integrity sha512-znzdq9PG8rkwcu9oQ2FwIy0ZFtP9Z7ycS+BAqJ3R5EIqC/0bJGvhT7193rFf+45i9nnPsYvCQVW4V/bB9Xc+gA== + dependencies: + client-only "^0.0.1" + +"@humanwhocodes/config-array@^0.11.8": + version "0.11.8" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" + integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@motionone/animation@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.15.1.tgz#4a85596c31cbc5100ae8eb8b34c459fb0ccf6807" + integrity sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ== + dependencies: + "@motionone/easing" "^10.15.1" + "@motionone/types" "^10.15.1" + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/dom@^10.15.3": + version "10.15.5" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.15.5.tgz#4af18f8136d85c2fc997cac98121c969f6731802" + integrity sha512-Xc5avlgyh3xukU9tydh9+8mB8+2zAq+WlLsC3eEIp7Ax7DnXgY7Bj/iv0a4X2R9z9ZFZiaXK3BO0xMYHKbAAdA== + dependencies: + "@motionone/animation" "^10.15.1" + "@motionone/generators" "^10.15.1" + "@motionone/types" "^10.15.1" + "@motionone/utils" "^10.15.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.15.1.tgz#95cf3adaef34da6deebb83940d8143ede3deb693" + integrity sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw== + dependencies: + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/generators@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.15.1.tgz#dc6abb11139d1bafe758a41c134d4c753a9b871c" + integrity sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ== + dependencies: + "@motionone/types" "^10.15.1" + "@motionone/utils" "^10.15.1" + tslib "^2.3.1" + +"@motionone/types@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.15.1.tgz#89441b54285012795cbba8612cbaa0fa420db3eb" + integrity sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA== + +"@motionone/utils@^10.15.1": + version "10.15.1" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.15.1.tgz#6b5f51bde75be88b5411e084310299050368a438" + integrity sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw== + dependencies: + "@motionone/types" "^10.15.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@next/env@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.3.1.tgz#589707043065f6b71d411ed9b8f1ffd057c0fd4a" + integrity sha512-EDtCoedIZC7JlUQ3uaQpSc4aVmyhbLHmQVALg7pFfQgOTjgSnn7mKtA0DiCMkYvvsx6aFb5octGMtWrOtGXW9A== + +"@next/eslint-plugin-next@13.3.4": + version "13.3.4" + resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-13.3.4.tgz#0f1092d89b0801dbe99fc7e712f9bf1d835431a3" + integrity sha512-mvS+HafOPy31oJbAi920WJXMdjbyb4v5FAMr9PeGZfRIdEcsLkA3mU/ZvmwzovJgP3nAWw2e2yM8iIFW8VpvIA== + dependencies: + glob "7.1.7" + +"@next/swc-darwin-arm64@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.1.tgz#2c9719dd10a9cdf63bf50a7576b05dcf78999fe8" + integrity sha512-UXPtriEc/pBP8luSLSCZBcbzPeVv+SSjs9cH/KygTbhmACye8/OOXRZO13Z2Wq1G0gLmEAIHQAOuF+vafPd2lw== + +"@next/swc-darwin-x64@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.1.tgz#0be90342c89e53a390ccd9bece15f7f5cd480049" + integrity sha512-lT36yYxosCfLtplFzJWgo0hrPu6/do8+msgM7oQkPeohDNdhjtjFUgOOwdSnPublLR6Mo2Ym4P/wl5OANuD2bw== + +"@next/swc-linux-arm64-gnu@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.1.tgz#a7353265839f8b8569a346a444dc3ab3770d297e" + integrity sha512-wRb76nLWJhonH8s3kxC/1tFguEkeOPayIwe9mkaz1G/yeS3OrjeyKMJsb4+Kdg0zbTo53bNCOl59NNtDM7yyyw== + +"@next/swc-linux-arm64-musl@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.1.tgz#24552e6102c350e372f83f505a1d93c880551a50" + integrity sha512-qz3BzjJRZ16Iq/jrp+pjiYOc0jTjHlfmxQmZk9x/+5uhRP6/eWQSTAPVJ33BMo6oK5O5N4644OgTAbzXzorecg== + +"@next/swc-linux-x64-gnu@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.1.tgz#5f335a683b6eafa52307b12af97782993b6c45ff" + integrity sha512-6mgkLmwlyWlomQmpl21I3hxgqE5INoW4owTlcLpNsd1V4wP+J46BlI/5zV5KWWbzjfncIqzXoeGs5Eg+1GHODA== + +"@next/swc-linux-x64-musl@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.1.tgz#58e5aad6f97203a0788783f66324456c8f9cdb50" + integrity sha512-uqm5sielhQmKJM+qayIhgZv1KlS5pqTdQ99b+Z7hMWryXS96qE0DftTmMZowBcUL6x7s2vSXyH5wPtO1ON7LBg== + +"@next/swc-win32-arm64-msvc@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.1.tgz#f8ed1badab57ed4503969758754e6fb0cf326753" + integrity sha512-WomIiTj/v3LevltlibNQKmvrOymNRYL+a0dp5R73IwPWN5FvXWwSELN/kiNALig/+T3luc4qHNTyvMCp9L6U5Q== + +"@next/swc-win32-ia32-msvc@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.1.tgz#7f599c8975b09ee5527cc49b9e5a4d13be50635a" + integrity sha512-M+PoH+0+q658wRUbs285RIaSTYnGBSTdweH/0CdzDgA6Q4rBM0sQs4DHmO3BPP0ltCO/vViIoyG7ks66XmCA5g== + +"@next/swc-win32-x64-msvc@13.3.1": + version "13.3.1" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.1.tgz#192d43ab44ebb98bd4f5865d0e1d7ce62703182f" + integrity sha512-Sl1F4Vp5Z1rNXWZYqJwMuWRRol4bqOB6+/d7KqkgQ4AcafKPN1PZmpkCoxv4UFHtFNIB7EotnuIhtXu3zScicQ== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgr/utils@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03" + integrity sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw== + dependencies: + cross-spawn "^7.0.3" + is-glob "^4.0.3" + open "^8.4.0" + picocolors "^1.0.0" + tiny-glob "^0.2.9" + tslib "^2.4.0" + +"@playwright/test@^1.31.2": + version "1.33.0" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.33.0.tgz#669ef859efb81b143dfc624eef99d1dd92a81b67" + integrity sha512-YunBa2mE7Hq4CfPkGzQRK916a4tuZoVx/EpLjeWlTVOnD4S2+fdaQZE0LJkbfhN5FTSKNLdcl7MoT5XB37bTkg== + dependencies: + "@types/node" "*" + playwright-core "1.33.0" + optionalDependencies: + fsevents "2.3.2" + +"@resvg/resvg-wasm@2.0.0-alpha.4": + version "2.0.0-alpha.4" + resolved "https://registry.yarnpkg.com/@resvg/resvg-wasm/-/resvg-wasm-2.0.0-alpha.4.tgz#fc2f86186a9641df030d8f9f3f9d995899cd1ecb" + integrity sha512-pWIG9a/x1ky8gXKRhPH1OPKpHFoMN1ISLbJ+O+gPXQHIAKhNd5I28RlWf7q576hAOQA9JZTlo3p/M2uyLzJmmw== + +"@rushstack/eslint-patch@^1.1.3": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728" + integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== + +"@shuding/opentype.js@1.4.0-beta.0": + version "1.4.0-beta.0" + resolved "https://registry.yarnpkg.com/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz#5d1e7e9e056f546aad41df1c5043f8f85d39e24b" + integrity sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA== + dependencies: + fflate "^0.7.3" + string.prototype.codepointat "^0.2.1" + +"@swc/helpers@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.0.tgz#bf1d807b60f7290d0ec763feea7ccdeda06e85f1" + integrity sha512-SjY/p4MmECVVEWspzSRpQEM3sjR17sP8PbGxELWrT+YZMBfiUyt1MRUNjMV23zohwlG2HYtCQOsCwsTHguXkyg== + dependencies: + tslib "^2.4.0" + +"@tailwindcss/typography@^0.5.9": + version "0.5.9" + resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.9.tgz#027e4b0674929daaf7c921c900beee80dbad93e8" + integrity sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg== + dependencies: + lodash.castarray "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + postcss-selector-parser "6.0.10" + +"@types/cookie@^0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803" + integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow== + +"@types/hoist-non-react-statics@^3.0.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/node@*": + version "18.16.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.3.tgz#6bda7819aae6ea0b386ebc5b24bdf602f1b42b01" + integrity sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q== + +"@types/node@18.13.0": + version "18.13.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850" + integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg== + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/react-dom@18.0.10": + version "18.0.10" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.10.tgz#3b66dec56aa0f16a6cc26da9e9ca96c35c0b4352" + integrity sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "18.2.0" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.0.tgz#15cda145354accfc09a18d2f2305f9fc099ada21" + integrity sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react@18.0.27": + version "18.0.27" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.27.tgz#d9425abe187a00f8a5ec182b010d4fd9da703b71" + integrity sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@typescript-eslint/parser@^5.42.0": + version "5.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.1.tgz#73c2c12127c5c1182d2e5b71a8fa2a85d215cbb4" + integrity sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g== + dependencies: + "@typescript-eslint/scope-manager" "5.59.1" + "@typescript-eslint/types" "5.59.1" + "@typescript-eslint/typescript-estree" "5.59.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.59.1": + version "5.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz#8a20222719cebc5198618a5d44113705b51fd7fe" + integrity sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA== + dependencies: + "@typescript-eslint/types" "5.59.1" + "@typescript-eslint/visitor-keys" "5.59.1" + +"@typescript-eslint/types@5.59.1": + version "5.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.1.tgz#03f3fedd1c044cb336ebc34cc7855f121991f41d" + integrity sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg== + +"@typescript-eslint/typescript-estree@5.59.1": + version "5.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz#4aa546d27fd0d477c618f0ca00b483f0ec84c43c" + integrity sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA== + dependencies: + "@typescript-eslint/types" "5.59.1" + "@typescript-eslint/visitor-keys" "5.59.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@5.59.1": + version "5.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz#0d96c36efb6560d7fb8eb85de10442c10d8f6058" + integrity sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA== + dependencies: + "@typescript-eslint/types" "5.59.1" + eslint-visitor-keys "^3.3.0" + +"@vercel/git-hooks@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@vercel/git-hooks/-/git-hooks-1.0.0.tgz#40ed416e532b868eb0ef77dd7566cd5059dc0fc3" + integrity sha512-OxDFAAdyiJ/H0b8zR9rFCu3BIb78LekBXOphOYG3snV4ULhKFX387pBPpqZ9HLiRTejBWBxYEahkw79tuIgdAA== + +"@vercel/og@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@vercel/og/-/og-0.1.0.tgz#dd0574bca4acef7cf69576142d9b158fb74fda08" + integrity sha512-0M7YT3TKd1bsJ/At46B5EMtxgZBixfTQV5VRnkdd8bTiKAGnzw/li+uORU4pvOyyPLoVQJpzuU0Xx+bbAKu2bQ== + dependencies: + "@resvg/resvg-wasm" "2.0.0-alpha.4" + satori "0.2.2" + yoga-wasm-web "0.3.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.8.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + 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" + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-includes@^3.1.5, array-includes@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.flat@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" + integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.1.3" + +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +autoprefixer@^10.4.13: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axe-core@^4.6.2: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== + +axobject-query@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + dependencies: + deep-equal "^2.0.5" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.21.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +busboy@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + +caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: + version "1.0.30001481" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz#f58a717afe92f9e69d0e35ff64df596bfad93912" + integrity sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ== + +chalk@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + 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" + optionalDependencies: + fsevents "~2.3.2" + +ci-info@^3.6.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clean-regexp/-/clean-regexp-1.0.0.tgz#8df7c7aae51fd36874e8f8d05b9180bc11a3fed7" + integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== + dependencies: + escape-string-regexp "^1.0.5" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + +client-only@0.0.1, client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + +clsx@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cookie@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" + integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-background-parser@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/css-background-parser/-/css-background-parser-0.1.0.tgz#48a17f7fe6d4d4f1bca3177ddf16c5617950741b" + integrity sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA== + +css-box-shadow@1.0.0-3: + version "1.0.0-3" + resolved "https://registry.yarnpkg.com/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz#9eaeb7140947bf5d649fc49a19e4bbaa5f602713" + integrity sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg== + +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== + +css-to-react-native@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-equal@^2.0.5: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.1.tgz#c72ab22f3a7d3503a4ca87dde976fe9978816739" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" + 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.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +electron-to-chromium@^1.4.284: + version "1.4.377" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.377.tgz#7f326a0b2c1b96eca6bb65907addc505d0d15989" + integrity sha512-H3BYG6DW5Z+l0xcfXaicJGxrpA4kMlCxnN71+iNX+dBLkRMOdVJqFJiAmbNZZKA1zISpRg17JR03qGifXNsJtw== + +emoji-regex@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.2.1.tgz#a41c330d957191efd3d9dfe6e1e8e1e9ab048b3f" + integrity sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +enhanced-resolve@^5.12.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz#26d1ecc448c02de997133217b5c1053f34a0a275" + integrity sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.21.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" + integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + dependencies: + array-buffer-byte-length "^1.0.0" + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.2.0" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.10" + is-weakref "^1.0.2" + object-inspect "^1.12.3" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.7" + string.prototype.trimend "^1.0.6" + string.prototype.trimstart "^1.0.6" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.9" + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + 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" + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-next@^13.3.1: + version "13.3.4" + resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-13.3.4.tgz#3243b19e48e76b5388917f27c9cd3f793ef381d6" + integrity sha512-TknEcP+EdTqLvJ2zMY1KnWqcx8ZHl1C2Tjjbq3qmtWcHRU5oxe1PAsz3vrKG3NOzonSaPcB2SpCSfYqcgj6nfA== + dependencies: + "@next/eslint-plugin-next" "13.3.4" + "@rushstack/eslint-patch" "^1.1.3" + "@typescript-eslint/parser" "^5.42.0" + eslint-import-resolver-node "^0.3.6" + eslint-import-resolver-typescript "^3.5.2" + eslint-plugin-import "^2.26.0" + eslint-plugin-jsx-a11y "^6.5.1" + eslint-plugin-react "^7.31.7" + eslint-plugin-react-hooks "^4.5.0" + +eslint-config-prettier@^8.6.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + +eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.7: + version "0.3.7" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== + dependencies: + debug "^3.2.7" + is-core-module "^2.11.0" + resolve "^1.22.1" + +eslint-import-resolver-typescript@^3.5.2: + version "3.5.5" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" + integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + get-tsconfig "^4.5.0" + globby "^13.1.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + synckit "^0.8.5" + +eslint-module-utils@^2.7.4: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@^2.26.0: + version "2.27.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + array.prototype.flatmap "^1.3.1" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.7" + eslint-module-utils "^2.7.4" + has "^1.0.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.6" + resolve "^1.22.1" + semver "^6.3.0" + tsconfig-paths "^3.14.1" + +eslint-plugin-jsx-a11y@^6.5.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== + dependencies: + "@babel/runtime" "^7.20.7" + aria-query "^5.1.3" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + ast-types-flow "^0.0.7" + axe-core "^4.6.2" + axobject-query "^3.1.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + has "^1.0.3" + jsx-ast-utils "^3.3.3" + language-tags "=1.0.5" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + semver "^6.3.0" + +eslint-plugin-react-hooks@^4.5.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react@^7.31.7: + version "7.32.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" + integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.0" + string.prototype.matchall "^4.0.8" + +eslint-plugin-unicorn@^45.0.2: + version "45.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz#d6ba704793a6909fe5dfe013900d2b05b715284c" + integrity sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw== + dependencies: + "@babel/helper-validator-identifier" "^7.19.1" + "@eslint-community/eslint-utils" "^4.1.2" + ci-info "^3.6.1" + clean-regexp "^1.0.0" + esquery "^1.4.0" + indent-string "^4.0.0" + is-builtin-module "^3.2.0" + jsesc "^3.0.2" + lodash "^4.17.21" + pluralize "^8.0.0" + read-pkg-up "^7.0.1" + regexp-tree "^0.1.24" + regjsparser "^0.9.1" + safe-regex "^2.1.1" + semver "^7.3.8" + strip-indent "^3.0.0" + +eslint-scope@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" + integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== + +eslint@^8.35.0: + version "8.39.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" + integrity sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.2" + "@eslint/js" "8.39.0" + "@humanwhocodes/config-array" "^0.11.8" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + 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.0" + eslint-visitor-keys "^3.4.0" + espree "^9.5.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" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" + 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.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" + integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.0" + +esquery@^1.4.0, esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + 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" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: + version "3.2.12" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + 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" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fflate@^0.7.3: + version "0.7.4" + resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.4.tgz#61587e5d958fdabb5a9368a302c25363f4f69f50" + integrity sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw== + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +framer-motion@^8.4.0: + version "8.5.5" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-8.5.5.tgz#e30e9087bfc9b3367459f83b4d9fe7efd5acade6" + integrity sha512-5IDx5bxkjWHWUF3CVJoSyUVOtrbAxtzYBBowRE2uYI/6VYhkEBD+rbTHEGuUmbGHRj6YqqSfoG7Aa1cLyWCrBA== + dependencies: + "@motionone/dom" "^10.15.3" + hey-listen "^1.0.8" + tslib "^2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@2.3.2, fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2, functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-tsconfig@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" + integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globalyzer@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" + integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + 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" + +globby@^13.1.3: + version "13.1.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" + integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + +globrex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" + integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.2.4: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + +hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + +is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-builtin-module@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.9.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" + integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-empty-iterable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-empty-iterable/-/is-empty-iterable-3.0.0.tgz#647e56cbe5a205296d5ef6d036bfa4f699646bcf" + integrity sha512-ZXVNGZrRvda9spnGVME3nTYTyDNjCTrmRy3DfDjBaMQ7aftcPsy/vkJoLL47IwcAbgioIfGvjQJWdit8GiggPg== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.9: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jiti@^1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" + integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== + +js-sdsl@^4.1.4: + version "4.4.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" + integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + +language-subtag-registry@~0.3.2: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@=1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== + dependencies: + language-subtag-registry "~0.3.2" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@2.1.0, lilconfig@^2.0.5, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lint-staged@^13.1.1: + version "13.2.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.2.2.tgz#5e711d3139c234f73402177be2f8dd312e6508ca" + integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== + dependencies: + chalk "5.2.0" + cli-truncate "^3.1.0" + commander "^10.0.0" + debug "^4.3.4" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-inspect "^1.12.3" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.2.2" + +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.19" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.8.0" + through "^2.3.8" + wrap-ansi "^7.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115" + integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.4, nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +next@13.3.1: + version "13.3.1" + resolved "https://registry.yarnpkg.com/next/-/next-13.3.1.tgz#17625f7423db2e059d71b41bd9031756cf2b33bc" + integrity sha512-eByWRxPzKHs2oQz1yE41LX35umhz86ZSZ+mYyXBqn2IBi2hyUqxBA88avywdr4uyH+hCJczegGsDGWbzQA5Rqw== + dependencies: + "@next/env" "13.3.1" + "@swc/helpers" "0.5.0" + busboy "1.6.0" + caniuse-lite "^1.0.30001406" + postcss "8.4.14" + styled-jsx "5.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "13.3.1" + "@next/swc-darwin-x64" "13.3.1" + "@next/swc-linux-arm64-gnu" "13.3.1" + "@next/swc-linux-arm64-musl" "13.3.1" + "@next/swc-linux-x64-gnu" "13.3.1" + "@next/swc-linux-x64-musl" "13.3.1" + "@next/swc-win32-arm64-msvc" "13.3.1" + "@next/swc-win32-ia32-msvc" "13.3.1" + "@next/swc-win32-x64-msvc" "13.3.1" + +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.12.3, object-inspect@^1.9.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.3, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.fromentries@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.hasown@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== + dependencies: + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.values@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^8.4.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + 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.3" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + 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" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pirates@^4.0.1: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +playwright-core@1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.33.0.tgz#269efe29a927cd6d144d05f3c2d2f72bd72447a1" + integrity sha512-aizyPE1Cj62vAECdph1iaMILpT0WUDCq3E6rW6I+dleSbBoGbktvJtzS6VHkZ4DKNEOG9qJpiom/ZxO+S15LAw== + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== + dependencies: + lilconfig "^2.0.5" + yaml "^2.1.1" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-selector-parser@6.0.10: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.11: + version "6.0.12" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz#2efae5ffab3c8bfb2b7fbf0c426e3bca616c4abb" + integrity sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.14: + version "8.4.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" + integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.4.21, postcss@^8.4.23: + version "8.4.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" + integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-plugin-tailwindcss@^0.2.2: + version "0.2.8" + resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.8.tgz#e9c0356680331f909a86fefe8fc2b247c21e23a2" + integrity sha512-KgPcEnJeIijlMjsA6WwYgRs5rh3/q76oInqtMXBA/EMcamrcYJpyhtRhyX1ayT9hnHlHTuO8sIifHF10WuSDKg== + +prettier@^2.8.4: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-cookie@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/react-cookie/-/react-cookie-4.1.1.tgz#832e134ad720e0de3e03deaceaab179c4061a19d" + integrity sha512-ffn7Y7G4bXiFbnE+dKhHhbP+b8I34mH9jqnm8Llhj89zF4nPxPutxHT1suUqMeCEhLDBI7InYwf1tpaSoK5w8A== + dependencies: + "@types/hoist-non-react-statics" "^3.0.1" + hoist-non-react-statics "^3.0.0" + universal-cookie "^4.0.0" + +react-dom@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react@18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regexp-tree@^0.1.24, regexp-tree@~0.1.1: + version "0.1.27" + resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd" + integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== + +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" + integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + functions-have-names "^1.2.3" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +safe-regex@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-2.1.1.tgz#f7128f00d056e2fe5c11e81a1324dd974aadced2" + integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== + dependencies: + regexp-tree "~0.1.1" + +satori@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/satori/-/satori-0.2.2.tgz#5a2661052a91aa75c55fdd4adbe686f0fe737877" + integrity sha512-/9A9cMdrkSqFPavObgQAn9737hMnBeKSgf/L5zWm2a6UzwMR2jl5xjrH4LURlJLEXdx/ijOjH0/Q6PUn2Fgpdg== + dependencies: + "@shuding/opentype.js" "1.4.0-beta.0" + css-background-parser "^0.1.0" + css-box-shadow "1.0.0-3" + css-to-react-native "^3.0.0" + emoji-regex "^10.2.1" + postcss-value-parser "^4.2.0" + yoga-wasm-web "^0.3.0" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +"semver@2 || 3 || 4 || 5": + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.7, semver@^7.3.8: + version "7.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +string-argv@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string.prototype.codepointat@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc" + integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg== + +string.prototype.matchall@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.4.3" + side-channel "^1.0.4" + +string.prototype.trim@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" + integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimend@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +string.prototype.trimstart@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +styled-jsx@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" + integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== + dependencies: + client-only "0.0.1" + +sucrase@^3.32.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" + integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + +tailwindcss@^3.2.6: + version "3.3.2" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" + integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.2.12" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.18.2" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + postcss-value-parser "^4.2.0" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +tiny-glob@^0.2.9: + version "0.2.9" + resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" + integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== + dependencies: + globalyzer "0.1.0" + globrex "^0.1.2" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +tsconfig-paths@^3.14.1: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typescript@4.9.5: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +universal-cookie@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/universal-cookie/-/universal-cookie-4.0.4.tgz#06e8b3625bf9af049569ef97109b4bb226ad798d" + integrity sha512-lbRVHoOMtItjWbM7TwDLdl8wug7izB0tq3/YVKhT/ahB4VDvWMyvnADfnJI8y6fSvsjh51Ix7lTGC6Tn4rMPhw== + dependencies: + "@types/cookie" "^0.3.3" + cookie "^0.4.0" + +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^2.1.1, yaml@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" + integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoga-wasm-web@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.0.tgz#b14493f35dccda41701524de80ff089fcda0b4ae" + integrity sha512-rD3L4jyMlO1m+RWU60lNwZQK5zmzglCV5fI1gTRikmpv3YzmNIZQbjyfE6cMNb9Xaly/C1SwemYGbsiOekMvnQ== + +yoga-wasm-web@^0.3.0: + version "0.3.3" + resolved "https://registry.yarnpkg.com/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz#eb8e9fcb18e5e651994732f19a220cb885d932ba" + integrity sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA== From 8d0f25f501ff8bade15377142a5e318d53a232de Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:37:48 +0200 Subject: [PATCH 15/28] fix: cart total amounts --- lib/medusa/index.ts | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index b07ae1bbe..199ab5f64 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -70,16 +70,19 @@ const reshapeCart = (cart: MedusaCart): Cart => { const currencyCode = 'EUR'; const cost = { subtotalAmount: { - amount: (cart?.total && cart?.tax_total && cart.total - cart.tax_total)?.toString() || '0', - currencyCode + amount: + (cart?.tax_total && cart?.total && (cart?.total - cart?.tax_total).toString()) || + cart?.total?.toString() || + '0', + currencyCode: currencyCode }, totalAmount: { - amount: (cart?.tax_total && cart?.tax_total.toString()) || '0', - currencyCode + amount: (cart?.total && cart?.total.toString()) || '0', + currencyCode: currencyCode }, totalTaxAmount: { amount: (cart?.tax_total && cart?.tax_total.toString()) || '0', - currencyCode + currencyCode: currencyCode } }; @@ -142,12 +145,16 @@ const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { }; const reshapeProduct = (product: MedusaProduct): Product => { + console.log({ + amount: product.variants?.[0]?.prices?.[0]?.amount + }); const priceRange = { maxVariantPrice: { amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '0', currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' } }; + console.log({ priceRange }); const updatedAt = product.updated_at; const tags = product.tags?.map((tag) => tag.value) || []; const descriptionHtml = product.description ?? ''; @@ -241,21 +248,17 @@ export async function createCart(): Promise { export async function addToCart( cartId: string, - lineItems: { variantId: string; quantity: number }[] + lineItem: { variantId: string; quantity: number } ): Promise { - console.log(lineItems); - // TODO: transform lines into Medusa line items const res = await medusaRequest('POST', `/carts/${cartId}/line-items`, { - variant_id: lineItems[0]?.variantId, - quantity: lineItems[0]?.quantity + variant_id: lineItem?.variantId, + quantity: lineItem?.quantity }); - console.log(res.body); return reshapeCart(res.body.cart); } -export async function removeFromCart(cartId: string, lineItemIds: string[]): Promise { - // TODO: We only allow you to pass a single line item to delete - const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineItemIds[0]}`); +export async function removeFromCart(cartId: string, lineItemId: string): Promise { + const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineItemId}`); return reshapeCart(res.body.cart); } From f8747bd506039ab5ea887fa1522c0dcfad1d887b Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:38:03 +0200 Subject: [PATCH 16/28] refactor: small cleanup --- components/cart/delete-item-button.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/cart/delete-item-button.tsx b/components/cart/delete-item-button.tsx index 8124353ed..397514198 100644 --- a/components/cart/delete-item-button.tsx +++ b/components/cart/delete-item-button.tsx @@ -13,7 +13,6 @@ export default function DeleteItemButton({ item }: { item: CartItem }) { async function handleRemove() { setRemoving(true); - console.log(item.id); const response = await fetch(`/api/cart?lineItemId=${item.id}`, { method: 'DELETE' }); From 1971f1a7d1cad70d79566a2dbee6b0a907ca910a Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:39:19 +0200 Subject: [PATCH 17/28] fix: empty cart error --- lib/medusa/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 199ab5f64..ecf61c8f7 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -64,7 +64,7 @@ export default async function medusaRequest( } const reshapeCart = (cart: MedusaCart): Cart => { - const lines = cart.items?.map((item) => reshapeLineItem(item)) || []; + const lines = cart?.items?.map((item) => reshapeLineItem(item)) || []; const totalQuantity = lines.length; const checkoutUrl = '/'; const currencyCode = 'EUR'; From e453e401fbd28def6e06504e05536f01e7740ad2 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:43:20 +0200 Subject: [PATCH 18/28] fix: add to cart route --- app/api/cart/route.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/api/cart/route.ts b/app/api/cart/route.ts index 03070857e..87b46d184 100644 --- a/app/api/cart/route.ts +++ b/app/api/cart/route.ts @@ -16,7 +16,7 @@ export async function POST(req: NextRequest): Promise { return NextResponse.json({ error: 'Missing cartId or variantId' }, { status: 400 }); } try { - await addToCart(cartId, [{ variantId, quantity: 1 }]); + await addToCart(cartId, { variantId, quantity: 1 }); return NextResponse.json({ status: 204 }); } catch (e) { if (isMedusaError(e)) { @@ -54,14 +54,13 @@ export async function PUT(req: NextRequest): Promise { export async function DELETE(req: NextRequest): Promise { const cartId = cookies().get('cartId')?.value; - console.log(req.nextUrl); const lineItemId = req.nextUrl.searchParams.get('lineItemId'); if (!cartId || !lineItemId) { return NextResponse.json({ error: 'Missing cartId or lineItemId' }, { status: 400 }); } try { - await removeFromCart(cartId, [lineItemId]); + await removeFromCart(cartId, lineItemId); return NextResponse.json({ status: 204 }); } catch (e) { if (isMedusaError(e)) { From f4a71fa67d5e64b3d4aaa61b8fa8cb8743cbca71 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 13:57:32 +0200 Subject: [PATCH 19/28] fix: some TS issues --- lib/medusa/index.ts | 3 ++- lib/medusa/types.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index ecf61c8f7..dfca4d1a2 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -97,6 +97,7 @@ const reshapeCart = (cart: MedusaCart): Cart => { const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { const product = { + title: lineItem.title, priceRange: { maxVariantPrice: { amount: lineItem.variant?.prices?.[0]?.amount.toString() ?? '0', @@ -318,7 +319,7 @@ export async function getCollections(): Promise { return collections; } -export async function getProduct(handle: string): Promise { +export async function getProduct(handle: string): Promise { const res = await medusaRequest('GET', `/products?handle=${handle}&limit=1`); const product = res.body.products[0]; return reshapeProduct(product); diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 001f27c82..0ac747db1 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -53,6 +53,7 @@ export type MedusaProduct = { }; export type Product = Partial> & { + title: string; featuredImage: FeaturedImage; seo?: { title?: string; @@ -66,7 +67,7 @@ export type Product = Partial; availableForSale: boolean; options?: Array; - variants: Array; + variants: Array; }; export type FeaturedImage = { @@ -380,7 +381,7 @@ export type MedusaLineItem = { has_shipping?: boolean | null; unit_price: number; variant_id?: string | null; - variant?: MedusaProductVariant; + variant: MedusaProductVariant; quantity: number; fulfilled_quantity?: number | null; returned_quantity?: number | null; From 3c091ce5f60c95270b76401720efbbc6a40d1038 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 14:03:43 +0200 Subject: [PATCH 20/28] fix: hide hidden colections --- lib/medusa/index.ts | 5 ++++- lib/medusa/types.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index dfca4d1a2..8f511006e 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -316,7 +316,10 @@ export async function getCollections(): Promise { (collection: MedusaProductCollection) => reshapeCollection(collection) ); - return collections; + // Hide collections starting with 'hidden' + const filtered = collections.filter((collection) => !collection.handle.startsWith('hidden')); + + return filtered; } export async function getProduct(handle: string): Promise { diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 0ac747db1..315c970db 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -1,7 +1,7 @@ export type MedusaProductCollection = { id: string; title: string; - handle: string | null; + handle: string; products?: Product[]; created_at: string; // format: date-time updated_at: string; // format: date-time From 692ef9d8df757ca3cde53596edd937775266d69e Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 14:04:59 +0200 Subject: [PATCH 21/28] refactor: remove shopify folder --- lib/shopify/fragments/cart.ts | 53 ------ lib/shopify/fragments/image.ts | 10 -- lib/shopify/fragments/product.ts | 64 -------- lib/shopify/fragments/seo.ts | 8 - lib/shopify/index.ts | 145 ---------------- lib/shopify/mutations/cart.ts | 45 ----- lib/shopify/queries/cart.ts | 10 -- lib/shopify/queries/collection.ts | 52 ------ lib/shopify/queries/menu.ts | 10 -- lib/shopify/queries/page.ts | 41 ----- lib/shopify/queries/product.ts | 32 ---- lib/shopify/types.ts | 263 ------------------------------ 12 files changed, 733 deletions(-) delete mode 100644 lib/shopify/fragments/cart.ts delete mode 100644 lib/shopify/fragments/image.ts delete mode 100644 lib/shopify/fragments/product.ts delete mode 100644 lib/shopify/fragments/seo.ts delete mode 100644 lib/shopify/index.ts delete mode 100644 lib/shopify/mutations/cart.ts delete mode 100644 lib/shopify/queries/cart.ts delete mode 100644 lib/shopify/queries/collection.ts delete mode 100644 lib/shopify/queries/menu.ts delete mode 100644 lib/shopify/queries/page.ts delete mode 100644 lib/shopify/queries/product.ts delete mode 100644 lib/shopify/types.ts diff --git a/lib/shopify/fragments/cart.ts b/lib/shopify/fragments/cart.ts deleted file mode 100644 index fc5c838dd..000000000 --- a/lib/shopify/fragments/cart.ts +++ /dev/null @@ -1,53 +0,0 @@ -import productFragment from './product'; - -const cartFragment = /* GraphQL */ ` - fragment cart on Cart { - id - checkoutUrl - cost { - subtotalAmount { - amount - currencyCode - } - totalAmount { - amount - currencyCode - } - totalTaxAmount { - amount - currencyCode - } - } - lines(first: 100) { - edges { - node { - id - quantity - cost { - totalAmount { - amount - currencyCode - } - } - merchandise { - ... on ProductVariant { - id - title - selectedOptions { - name - value - } - product { - ...product - } - } - } - } - } - } - totalQuantity - } - ${productFragment} -`; - -export default cartFragment; diff --git a/lib/shopify/fragments/image.ts b/lib/shopify/fragments/image.ts deleted file mode 100644 index 5d002f175..000000000 --- a/lib/shopify/fragments/image.ts +++ /dev/null @@ -1,10 +0,0 @@ -const imageFragment = /* GraphQL */ ` - fragment image on Image { - url - altText - width - height - } -`; - -export default imageFragment; diff --git a/lib/shopify/fragments/product.ts b/lib/shopify/fragments/product.ts deleted file mode 100644 index be14dedca..000000000 --- a/lib/shopify/fragments/product.ts +++ /dev/null @@ -1,64 +0,0 @@ -import imageFragment from './image'; -import seoFragment from './seo'; - -const productFragment = /* GraphQL */ ` - fragment product on Product { - id - handle - availableForSale - title - description - descriptionHtml - options { - id - name - values - } - priceRange { - maxVariantPrice { - amount - currencyCode - } - minVariantPrice { - amount - currencyCode - } - } - variants(first: 250) { - edges { - node { - id - title - availableForSale - selectedOptions { - name - value - } - price { - amount - currencyCode - } - } - } - } - featuredImage { - ...image - } - images(first: 20) { - edges { - node { - ...image - } - } - } - seo { - ...seo - } - tags - updatedAt - } - ${imageFragment} - ${seoFragment} -`; - -export default productFragment; diff --git a/lib/shopify/fragments/seo.ts b/lib/shopify/fragments/seo.ts deleted file mode 100644 index 2d4786c4f..000000000 --- a/lib/shopify/fragments/seo.ts +++ /dev/null @@ -1,8 +0,0 @@ -const seoFragment = /* GraphQL */ ` - fragment seo on SEO { - description - title - } -`; - -export default seoFragment; diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts deleted file mode 100644 index 75f281c7c..000000000 --- a/lib/shopify/index.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { isShopifyError } from 'lib/type-guards'; -import { ProductCollection } from '../medusa/types'; -import { Cart, Product } from './types'; - -// const endpoint = `${process.env.MEDUSA_BACKEND_API!}`; -const endpoint = `http://localhost:9000/store`; - -export default async function medusaRequest( - method: string, - path = '', - payload?: Record | undefined -) { - const options: RequestInit = { - method, - headers: { - 'Content-Type': 'application/json' - } - }; - - if (payload) { - options.body = JSON.stringify(payload); - } - - try { - const result = await fetch(`${endpoint}/${path}`, options); - - const body = await result.json(); - - if (body.errors) { - throw body.errors[0]; - } - - return { - status: result.status, - body - }; - } catch (e) { - if (isShopifyError(e)) { - throw { - status: e.status || 500, - message: e.message - }; - } - - throw { - error: e - }; - } -} - -export async function createCart(): Promise { - const res = await medusaRequest('POST', '/carts', {}); - console.log('Cart created!'); - console.log(res); - return res.body.cart; -} - -export async function addToCart( - cartId: string, - lineItems: { variantId: string; quantity: number }[] -): Promise { - console.log(lineItems); - // TODO: transform lines into Medusa line items - const res = await medusaRequest('POST', `/carts/${cartId}/line-items`, { - lineItems - }); - - return res.body.data.cart; -} - -export async function removeFromCart(cartId: string, lineIds: string[]): Promise { - // TODO: We only allow you to pass a single line item to delete - const res = await medusaRequest('DELETE', `/carts/${cartId}/line-items/${lineIds[0]}`); - - return res.body.data.cart; -} - -export async function updateCart( - cartId: string, - lines: { id: string; merchandiseId: string; quantity: number }[] -): Promise { - console.log(lines); - // TODO: transform lines into Medusa line items - const res = await medusaRequest('POST', `/carts/${cartId}`, {}); - return res.body.data.cart; -} - -export async function getCart(cartId: string): Promise { - const res = await medusaRequest('GET', `/carts/${cartId}`); - - if (!res.body.cart) { - return null; - } - - return res.body.cart; -} - -export async function getCollection(handle: string): Promise { - const res = await medusaRequest('get', `/collections?handle[]=${handle}&limit=1`); - console.log({ collection: res.body.collection }); - return res.body.collection; -} - -export async function getCollectionProducts(handle: string): Promise { - const res = await medusaRequest('get', `/collections?handle[]=${handle}&expand=products`); - if (!res.body?.collection?.products) { - return []; - } - console.log({ 'collection products': res.body.collection.products }); - return res.body.collection.products; -} - -export async function getCollections(): Promise { - const collections = [ - { - handle: '', - title: 'All', - description: 'All products', - seo: { - title: 'All', - description: 'All products' - }, - path: '/search', - updatedAt: new Date().toISOString() - } - ]; - - return []; -} - -export async function getProduct(handle: string): Promise { - const res = await medusaRequest('get', `/products?handle=${handle}&limit=1`); - return res.body.product; -} - -export async function getProducts({ - query -}: { - query?: string; - reverse?: boolean; - sortKey?: string; -}): Promise { - const res = await medusaRequest('get', `/products?q=${query}&limit=20`); - return res.body.products; -} diff --git a/lib/shopify/mutations/cart.ts b/lib/shopify/mutations/cart.ts deleted file mode 100644 index 4cc1b5ac6..000000000 --- a/lib/shopify/mutations/cart.ts +++ /dev/null @@ -1,45 +0,0 @@ -import cartFragment from '../fragments/cart'; - -export const addToCartMutation = /* GraphQL */ ` - mutation addToCart($cartId: ID!, $lines: [CartLineInput!]!) { - cartLinesAdd(cartId: $cartId, lines: $lines) { - cart { - ...cart - } - } - } - ${cartFragment} -`; - -export const createCartMutation = /* GraphQL */ ` - mutation createCart($lineItems: [CartLineInput!]) { - cartCreate(input: { lines: $lineItems }) { - cart { - ...cart - } - } - } - ${cartFragment} -`; - -export const editCartItemsMutation = /* GraphQL */ ` - mutation editCartItems($cartId: ID!, $lines: [CartLineUpdateInput!]!) { - cartLinesUpdate(cartId: $cartId, lines: $lines) { - cart { - ...cart - } - } - } - ${cartFragment} -`; - -export const removeFromCartMutation = /* GraphQL */ ` - mutation removeFromCart($cartId: ID!, $lineIds: [ID!]!) { - cartLinesRemove(cartId: $cartId, lineIds: $lineIds) { - cart { - ...cart - } - } - } - ${cartFragment} -`; diff --git a/lib/shopify/queries/cart.ts b/lib/shopify/queries/cart.ts deleted file mode 100644 index 044e47f66..000000000 --- a/lib/shopify/queries/cart.ts +++ /dev/null @@ -1,10 +0,0 @@ -import cartFragment from '../fragments/cart'; - -export const getCartQuery = /* GraphQL */ ` - query getCart($cartId: ID!) { - cart(id: $cartId) { - ...cart - } - } - ${cartFragment} -`; diff --git a/lib/shopify/queries/collection.ts b/lib/shopify/queries/collection.ts deleted file mode 100644 index ac3fb4dd9..000000000 --- a/lib/shopify/queries/collection.ts +++ /dev/null @@ -1,52 +0,0 @@ -import productFragment from '../fragments/product'; -import seoFragment from '../fragments/seo'; - -const collectionFragment = /* GraphQL */ ` - fragment collection on Collection { - handle - title - description - seo { - ...seo - } - updatedAt - } - ${seoFragment} -`; - -export const getCollectionQuery = /* GraphQL */ ` - query getCollection($handle: String!) { - collection(handle: $handle) { - ...collection - } - } - ${collectionFragment} -`; - -export const getCollectionsQuery = /* GraphQL */ ` - query getCollections { - collections(first: 100, sortKey: TITLE) { - edges { - node { - ...collection - } - } - } - } - ${collectionFragment} -`; - -export const getCollectionProductsQuery = /* GraphQL */ ` - query getCollectionProducts($handle: String!) { - collection(handle: $handle) { - products(first: 100) { - edges { - node { - ...product - } - } - } - } - } - ${productFragment} -`; diff --git a/lib/shopify/queries/menu.ts b/lib/shopify/queries/menu.ts deleted file mode 100644 index d05b09949..000000000 --- a/lib/shopify/queries/menu.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const getMenuQuery = /* GraphQL */ ` - query getMenu($handle: String!) { - menu(handle: $handle) { - items { - title - url - } - } - } -`; diff --git a/lib/shopify/queries/page.ts b/lib/shopify/queries/page.ts deleted file mode 100644 index ac6f6f986..000000000 --- a/lib/shopify/queries/page.ts +++ /dev/null @@ -1,41 +0,0 @@ -import seoFragment from '../fragments/seo'; - -const pageFragment = /* GraphQL */ ` - fragment page on Page { - ... on Page { - id - title - handle - body - bodySummary - seo { - ...seo - } - createdAt - updatedAt - } - } - ${seoFragment} -`; - -export const getPageQuery = /* GraphQL */ ` - query getPage($handle: String!) { - pageByHandle(handle: $handle) { - ...page - } - } - ${pageFragment} -`; - -export const getPagesQuery = /* GraphQL */ ` - query getPages { - pages(first: 100) { - edges { - node { - ...page - } - } - } - } - ${pageFragment} -`; diff --git a/lib/shopify/queries/product.ts b/lib/shopify/queries/product.ts deleted file mode 100644 index d3f12bd0f..000000000 --- a/lib/shopify/queries/product.ts +++ /dev/null @@ -1,32 +0,0 @@ -import productFragment from '../fragments/product'; - -export const getProductQuery = /* GraphQL */ ` - query getProduct($handle: String!) { - product(handle: $handle) { - ...product - } - } - ${productFragment} -`; - -export const getProductsQuery = /* GraphQL */ ` - query getProducts($sortKey: ProductSortKeys, $reverse: Boolean, $query: String) { - products(sortKey: $sortKey, reverse: $reverse, query: $query, first: 100) { - edges { - node { - ...product - } - } - } - } - ${productFragment} -`; - -export const getProductRecommendationsQuery = /* GraphQL */ ` - query getProductRecommendations($productId: ID!) { - productRecommendations(productId: $productId) { - ...product - } - } - ${productFragment} -`; diff --git a/lib/shopify/types.ts b/lib/shopify/types.ts deleted file mode 100644 index b18ed3b63..000000000 --- a/lib/shopify/types.ts +++ /dev/null @@ -1,263 +0,0 @@ -export type Maybe = T | null; - -export type Connection = { - edges: Array>; -}; - -export type Edge = { - node: T; -}; - -export type Cart = Omit & { - lines: CartItem[]; -}; - -export type CartItem = { - id: string; - quantity: number; - cost: { - totalAmount: Money; - }; - merchandise: { - id: string; - title: string; - selectedOptions: { - name: string; - value: string; - }[]; - product: Product; - }; -}; - -export type Collection = ShopifyCollection & { - path: string; -}; - -export type Image = { - url: string; - altText: string; - width: number; - height: number; -}; - -export type Menu = { - title: string; - path: string; -}; - -export type Money = { - amount: string; - currencyCode: string; -}; - -export type Page = { - id: string; - title: string; - handle: string; - body: string; - bodySummary: string; - seo?: SEO; - createdAt: string; - updatedAt: string; -}; - -export type Product = Omit & { - variants: ProductVariant[]; - images: Image[]; -}; - -export type ProductOption = { - id: string; - name: string; - values: string[]; -}; - -export type ProductVariant = { - id: string; - title: string; - availableForSale: boolean; - selectedOptions: { - name: string; - value: string; - }[]; - price: Money; -}; - -export type SEO = { - title: string; - description: string; -}; - -export type ShopifyCart = { - id: string; - checkoutUrl: string; - cost: { - subtotalAmount: Money; - totalAmount: Money; - totalTaxAmount: Money; - }; - lines: Connection; - totalQuantity: number; -}; - -export type ShopifyCollection = { - handle: string; - title: string; - description: string; - seo: SEO; - updatedAt: string; -}; - -export type ShopifyProduct = { - id: string; - handle: string; - availableForSale: boolean; - title: string; - description: string; - descriptionHtml: string; - options: ProductOption[]; - priceRange: { - maxVariantPrice: Money; - minVariantPrice: Money; - }; - variants: Connection; - featuredImage: Image; - images: Connection; - seo: SEO; - tags: string[]; - updatedAt: string; -}; - -export type ShopifyCartOperation = { - data: { - cart: ShopifyCart; - }; - variables: { - cartId: string; - }; -}; - -export type ShopifyCreateCartOperation = { - data: { cartCreate: { cart: ShopifyCart } }; -}; - -export type ShopifyAddToCartOperation = { - data: { - cartLinesAdd: { - cart: ShopifyCart; - }; - }; - variables: { - cartId: string; - lines: { - merchandiseId: string; - quantity: number; - }[]; - }; -}; - -export type ShopifyRemoveFromCartOperation = { - data: { - cartLinesRemove: { - cart: ShopifyCart; - }; - }; - variables: { - cartId: string; - lineIds: string[]; - }; -}; - -export type ShopifyUpdateCartOperation = { - data: { - cartLinesUpdate: { - cart: ShopifyCart; - }; - }; - variables: { - cartId: string; - lines: { - id: string; - merchandiseId: string; - quantity: number; - }[]; - }; -}; - -export type ShopifyCollectionOperation = { - data: { - collection: ShopifyCollection; - }; - variables: { - handle: string; - }; -}; - -export type ShopifyCollectionProductsOperation = { - data: { - collection: { - products: Connection; - }; - }; - variables: { - handle: string; - }; -}; - -export type ShopifyCollectionsOperation = { - data: { - collections: Connection; - }; -}; - -export type ShopifyMenuOperation = { - data: { - menu?: { - items: { - title: string; - url: string; - }[]; - }; - }; - variables: { - handle: string; - }; -}; - -export type ShopifyPageOperation = { - data: { pageByHandle: Page }; - variables: { handle: string }; -}; - -export type ShopifyPagesOperation = { - data: { - pages: Connection; - }; -}; - -export type ShopifyProductOperation = { - data: { product: ShopifyProduct }; - variables: { - handle: string; - }; -}; - -export type ShopifyProductRecommendationsOperation = { - data: { - productRecommendations: ShopifyProduct[]; - }; - variables: { - productId: string; - }; -}; - -export type ShopifyProductsOperation = { - data: { - products: Connection; - }; - variables: { - query?: string; - reverse?: boolean; - sortKey?: string; - }; -}; From 18ce43d0a4eca1ac6171cf656436aac1f6cf4b6f Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 14:17:43 +0200 Subject: [PATCH 22/28] refactor: getCollections --- lib/medusa/index.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 8f511006e..186bd825c 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -312,14 +312,12 @@ export async function getCollectionProducts(handle: string): Promise export async function getCollections(): Promise { const res = await medusaRequest('GET', '/collections'); - const collections: ProductCollection[] = res.body.collections.map( - (collection: MedusaProductCollection) => reshapeCollection(collection) - ); + // Reshape collections and hide collections starting with 'hidden' + const collections = res.body.collections + .map((collection: MedusaProductCollection) => reshapeCollection(collection)) + .filter((collection: MedusaProductCollection) => !collection.handle.startsWith('hidden')); - // Hide collections starting with 'hidden' - const filtered = collections.filter((collection) => !collection.handle.startsWith('hidden')); - - return filtered; + return collections; } export async function getProduct(handle: string): Promise { From 28c0fe95ed4345afad15cdaa6b537cb81a695315 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 14:19:46 +0200 Subject: [PATCH 23/28] refactor: remove console.logs --- app/product/[handle]/page.tsx | 1 - lib/medusa/index.ts | 4 ---- 2 files changed, 5 deletions(-) diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 550f398ae..1af2be940 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -99,7 +99,6 @@ export default async function ProductPage({ params }: { params: { handle: string } async function RelatedProducts({ id }: { id: string }) { - console.log(id); // const relatedProducts = await getProductRecommendations(id); const relatedProducts: any[] = []; diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 186bd825c..f97b789b5 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -146,16 +146,12 @@ const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { }; const reshapeProduct = (product: MedusaProduct): Product => { - console.log({ - amount: product.variants?.[0]?.prices?.[0]?.amount - }); const priceRange = { maxVariantPrice: { amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '0', currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' } }; - console.log({ priceRange }); const updatedAt = product.updated_at; const tags = product.tags?.map((tag) => tag.value) || []; const descriptionHtml = product.description ?? ''; From 10381c01105ed3e5398f27b7446fdfb695f7d5cd Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 15:00:40 +0200 Subject: [PATCH 24/28] fix: remove seo attributes from pdp --- app/product/[handle]/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/product/[handle]/page.tsx b/app/product/[handle]/page.tsx index 1af2be940..ce924f09e 100644 --- a/app/product/[handle]/page.tsx +++ b/app/product/[handle]/page.tsx @@ -28,8 +28,8 @@ export async function generateMetadata({ const hide = !product.tags.includes(HIDDEN_PRODUCT_TAG); return { - title: product.seo?.title || product.title, - description: product.seo?.description || product.description, + title: product.title, + description: product.description, robots: { index: hide, follow: hide, From 575c3a3d0b676665a789b5a8ea859b29b7e99f82 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Thu, 4 May 2023 15:09:38 +0200 Subject: [PATCH 25/28] refactor: use cart.subtotal --- lib/medusa/index.ts | 5 +---- lib/medusa/types.ts | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index f97b789b5..007898710 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -70,10 +70,7 @@ const reshapeCart = (cart: MedusaCart): Cart => { const currencyCode = 'EUR'; const cost = { subtotalAmount: { - amount: - (cart?.tax_total && cart?.total && (cart?.total - cart?.tax_total).toString()) || - cart?.total?.toString() || - '0', + amount: cart?.subtotal?.toString() || '0', currencyCode: currencyCode }, totalAmount: { diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 315c970db..697fc6a37 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -338,6 +338,7 @@ export type MedusaCart = { tax_total?: number; refunded_total?: number; total?: number; + subtotal?: number; }; export type Cart = Partial & { From cce421c418e03ec08abd3a42437a2bd6e4de8a7d Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Fri, 5 May 2023 12:28:12 +0200 Subject: [PATCH 26/28] feat: price formatting --- lib/medusa/helpers.ts | 43 ++++++++++++++++++++++++++++++++ lib/medusa/index.ts | 57 ++++++++++++++++++++++++++++++------------- lib/medusa/types.ts | 12 +++++++++ lib/utils.ts | 13 ++++++++++ 4 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 lib/medusa/helpers.ts diff --git a/lib/medusa/helpers.ts b/lib/medusa/helpers.ts new file mode 100644 index 000000000..203d4f927 --- /dev/null +++ b/lib/medusa/helpers.ts @@ -0,0 +1,43 @@ +import { isEmpty } from '../utils'; +import { MedusaProductVariant, RegionInfo } from './types'; + +type ComputeAmountParams = { + amount: number; + region: RegionInfo; + includeTaxes?: boolean; +}; + +/** + * Takes an amount, a region, and returns the amount as a decimal including or excluding taxes + */ +export const computeAmount = ({ amount, region, includeTaxes = true }: ComputeAmountParams) => { + const toDecimal = convertToDecimal(amount, region.currency_code); + + const taxRate = includeTaxes ? getTaxRate(region) : 0; + + const amountWithTaxes = toDecimal * (1 + taxRate); + + return amountWithTaxes; +}; + +export const calculateVariantAmount = (variant: MedusaProductVariant) => { + const currencyCode = variant.prices?.[0]?.currency_code ?? 'USD'; + const amount = convertToDecimal(variant.prices?.[0]?.amount || 0, currencyCode).toString(); + return { + amount, + currencyCode + }; +}; + +// we should probably add a more extensive list +const noDivisionCurrencies = ['krw', 'jpy', 'vnd']; + +export const convertToDecimal = (amount: number, currencyCode = 'USD') => { + const divisor = noDivisionCurrencies.includes(currencyCode.toLowerCase()) ? 1 : 100; + + return Math.floor(amount) / divisor; +}; + +const getTaxRate = (region?: RegionInfo) => { + return region && !isEmpty(region) ? region?.tax_rate / 100 : 0; +}; diff --git a/lib/medusa/index.ts b/lib/medusa/index.ts index 007898710..11407b50a 100644 --- a/lib/medusa/index.ts +++ b/lib/medusa/index.ts @@ -1,6 +1,7 @@ import { isMedusaError } from 'lib/type-guards'; import { mapOptionIds } from 'lib/utils'; +import { calculateVariantAmount, computeAmount, convertToDecimal } from './helpers'; import { Cart, CartItem, @@ -67,18 +68,34 @@ const reshapeCart = (cart: MedusaCart): Cart => { const lines = cart?.items?.map((item) => reshapeLineItem(item)) || []; const totalQuantity = lines.length; const checkoutUrl = '/'; - const currencyCode = 'EUR'; + const currencyCode = cart.region?.currency_code || 'USD'; + + let subtotalAmount = '0'; + if (cart.subtotal && cart.region) { + subtotalAmount = computeAmount({ amount: cart.subtotal, region: cart.region }).toString(); + } + + let totalAmount = '0'; + if (cart.total && cart.region) { + totalAmount = computeAmount({ amount: cart.total, region: cart.region }).toString(); + } + + let totalTaxAmount = '0'; + if (cart.tax_total && cart.region) { + totalTaxAmount = computeAmount({ amount: cart.tax_total, region: cart.region }).toString(); + } + const cost = { subtotalAmount: { - amount: cart?.subtotal?.toString() || '0', + amount: subtotalAmount, currencyCode: currencyCode }, totalAmount: { - amount: (cart?.total && cart?.total.toString()) || '0', + amount: totalAmount, currencyCode: currencyCode }, totalTaxAmount: { - amount: (cart?.tax_total && cart?.tax_total.toString()) || '0', + amount: totalTaxAmount, currencyCode: currencyCode } }; @@ -96,10 +113,7 @@ const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { const product = { title: lineItem.title, priceRange: { - maxVariantPrice: { - amount: lineItem.variant?.prices?.[0]?.amount.toString() ?? '0', - currencyCode: lineItem.variant?.prices?.[0]?.currency_code ?? 'EUR' - } + maxVariantPrice: calculateVariantAmount(lineItem.variant) }, updatedAt: lineItem.updated_at, tags: [], @@ -128,7 +142,10 @@ const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { const cost = { totalAmount: { - amount: lineItem.total.toString() ?? '0', + amount: convertToDecimal( + lineItem.total, + lineItem.variant.prices?.[0]?.currency_code + ).toString(), currencyCode: 'EUR' } }; @@ -143,9 +160,18 @@ const reshapeLineItem = (lineItem: MedusaLineItem): CartItem => { }; const reshapeProduct = (product: MedusaProduct): Product => { + const variant = product.variants?.[0]; + + let amount = '0'; + let currencyCode = 'USD'; + if (variant && variant.prices?.[0]?.amount) { + currencyCode = variant.prices?.[0]?.currency_code ?? 'USD'; + amount = convertToDecimal(variant.prices[0].amount, currencyCode).toString(); + } + const priceRange = { maxVariantPrice: { - amount: product.variants?.[0]?.prices?.[0]?.amount.toString() ?? '0', + amount, currencyCode: product.variants?.[0]?.prices?.[0]?.currency_code ?? '' } }; @@ -156,7 +182,7 @@ const reshapeProduct = (product: MedusaProduct): Product => { url: product.images?.[0]?.url ?? '', altText: product.images?.[0]?.id ?? '' }; - const availableForSale = true; + const availableForSale = product.variants?.[0]?.purchasable || true; const variants = product.variants.map((variant) => reshapeProductVariant(variant, product.options) ); @@ -178,7 +204,7 @@ const reshapeProduct = (product: MedusaProduct): Product => { }; const reshapeProductOption = (productOption: MedusaProductOption): ProductOption => { - const availableForSale = true; + const availableForSale = productOption.product?.variants?.[0]?.purchasable || true; const name = productOption.title; let values = productOption.values?.map((option) => option.value) || []; values = [...new Set(values)]; @@ -203,12 +229,9 @@ const reshapeProductVariant = ( value: option.value })); } - const availableForSale = !!productVariant.inventory_quantity; + const availableForSale = productVariant.purchasable || true; + const price = calculateVariantAmount(productVariant); - const price = { - amount: productVariant.prices?.[0]?.amount.toString() ?? 'ß', - currencyCode: productVariant.prices?.[0]?.currency_code ?? '' - }; return { ...productVariant, availableForSale, diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 697fc6a37..67f2fcce8 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -153,6 +153,7 @@ export type MedusaProductVariant = { created_at: string; updated_at: string; deleted_at: string | null; + purchasable?: boolean; }; export type ProductVariant = MedusaProductVariant & { @@ -279,6 +280,9 @@ export type Region = { updated_at: string; deleted_at?: string | null; metadata?: Record | null; + currency_code: string; + tax_code: string; + tax_rate: number; }; export type FulfillmentProvider = { @@ -417,3 +421,11 @@ export type CartItem = MedusaLineItem & { }; quantity: number; }; + +export type RegionInfo = Pick; +export type ProductVariantEntity = ConvertDateToString>; +export type ProductVariantInfo = Pick; + +type ConvertDateToString = { + [P in keyof T]: T[P] extends Date ? Date | string : T[P]; +}; diff --git a/lib/utils.ts b/lib/utils.ts index 9c72e43a4..21f627c58 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -15,3 +15,16 @@ export const mapOptionIds = (productOptions: MedusaProductOption[]) => { }); return map; }; + +export const isObject = (input: any) => input instanceof Object; +export const isArray = (input: any) => Array.isArray(input); + +export const isEmpty = (input: any) => { + return ( + input === null || + input === undefined || + (isObject(input) && Object.keys(input).length === 0) || + (isArray(input) && (input as any[]).length === 0) || + (typeof input === 'string' && input.trim().length === 0) + ); +}; From 2e1ca6eabc2ef322059b56cbdd9e55ad906e73de Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Fri, 5 May 2023 12:57:50 +0200 Subject: [PATCH 27/28] fix: some minor fixes --- lib/medusa/helpers.ts | 7 +++++-- lib/medusa/types.ts | 5 +---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/medusa/helpers.ts b/lib/medusa/helpers.ts index 203d4f927..b17d57569 100644 --- a/lib/medusa/helpers.ts +++ b/lib/medusa/helpers.ts @@ -1,5 +1,5 @@ import { isEmpty } from '../utils'; -import { MedusaProductVariant, RegionInfo } from './types'; +import { MedusaProductVariant, Money, RegionInfo } from './types'; type ComputeAmountParams = { amount: number; @@ -20,7 +20,10 @@ export const computeAmount = ({ amount, region, includeTaxes = true }: ComputeAm return amountWithTaxes; }; -export const calculateVariantAmount = (variant: MedusaProductVariant) => { +/** + * Takes a product variant, and returns the amount as a decimal including or excluding taxes and the currency code + */ +export const calculateVariantAmount = (variant: MedusaProductVariant): Money => { const currencyCode = variant.prices?.[0]?.currency_code ?? 'USD'; const amount = convertToDecimal(variant.prices?.[0]?.amount || 0, currencyCode).toString(); return { diff --git a/lib/medusa/types.ts b/lib/medusa/types.ts index 67f2fcce8..b16b0ccfc 100644 --- a/lib/medusa/types.ts +++ b/lib/medusa/types.ts @@ -414,10 +414,7 @@ export type CartItem = MedusaLineItem & { title: string; }; cost: { - totalAmount: { - amount: string; - currencyCode: string; - }; + totalAmount: Money; }; quantity: number; }; From c114974faae053fca5dd16f251d550962cde7533 Mon Sep 17 00:00:00 2001 From: Victor Gerbrands Date: Fri, 5 May 2023 15:22:33 +0200 Subject: [PATCH 28/28] feat: medusify readme --- README.md | 197 +++++++++--------------------------------------------- 1 file changed, 31 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index e7ec645ad..722ecc50f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fcommerce&project-name=commerce&repo-name=commerce&demo-title=Next.js%20Commerce&demo-url=https%3A%2F%2Fdemo.vercel.store&demo-image=https%3A%2F%2Fbigcommerce-demo-asset-ksvtgfvnd.vercel.app%2Fbigcommerce.png&env=SHOPIFY_STOREFRONT_ACCESS_TOKEN,SHOPIFY_STORE_DOMAIN,SITE_NAME,TWITTER_CREATOR,TWITTER_SITE) -# Next.js Commerce +_Todo: update deploy url_ + +# Next.js Commerce x Medusa > Note: Looking for Next.js Commerce v1? View the [code](https://github.com/vercel/commerce/tree/v1), [demo](https://commerce-v1.vercel.store), and [release notes](https://github.com/vercel/commerce/releases/tag/v1) -A Next.js 13 and App Router-ready ecommerce template, built with Shopify, featuring: +A Next.js 13 and App Router-ready ecommerce template, built with [Medusa](https://github.com/medusajs/medusa), featuring: - Next.js App Router - Optimized for SEO using Next.js's Metadata @@ -14,9 +16,14 @@ A Next.js 13 and App Router-ready ecommerce template, built with Shopify, featur - New fetching and caching paradigms - Dynamic OG images - Styling with Tailwind CSS -- Checkout and payments with Shopify - Automatic light/dark mode based on system settings +## What is Medusa? + +Medusa is a set of commerce modules and tools that allow you to build rich, reliable, and performant commerce applications without reinventing core commerce logic. The modules can be customized and used to build advanced ecommerce stores, marketplaces, or any product that needs foundational commerce primitives. All modules are open-source and freely available on npm. + +Learn more about [Medusa’s architecture](https://docs.medusajs.com/development/fundamentals/architecture-overview) and [commerce modules](https://docs.medusajs.com/modules/overview) in the Docs. + ## Running locally You will need to use the environment variables [defined in `.env.example`](.env.example) to run Next.js Commerce. It's recommended you use [Vercel Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables) for this, but a `.env` file is all that is necessary. @@ -34,179 +41,37 @@ pnpm dev Your app should now be running on [localhost:3000](http://localhost:3000/). -## How to configure your Shopify store for Next.js Commerce +## How to configure your Medusa server for Next.js Commerce -Next.js Commerce requires a [paid Shopify plan](https://www.shopify.com/pricing). It will not work with a Shopify Starter plan. +Next.js Commerce x Medusa requires a running [Medusa](https://github.com/medusajs/medusa) server. -### Add Shopify domain to an environment variable +### Create a Medusa Backend[​](https://docs.medusajs.com/development/backend/install#create-a-medusa-backend 'Direct link to Create a Medusa Backend') -Create a `SHOPIFY_STORE_DOMAIN` environment variable and use your Shopify domain as the the value (ie. `SHOPIFY_STORE_SUBDOMAIN.myshopify.com`). +It is recommended to use [Yarn](https://yarnpkg.com/getting-started/install) for the installation process as it's much faster than using NPM. -> Note: Do not include the `https://`. +#### 1. Install Medusa CLI[​](https://docs.medusajs.com/development/backend/install#1-install-medusa-cli 'Direct link to 1. Install Medusa CLI') -### Accessing the Shopify Storefront API +- npm +- Yarn -Next.js Commerce utilizes [Shopify's Storefront API](https://shopify.dev/docs/api/storefront) to create unique customer experiences. The API offers a full range of commerce options making it possible for customers to control products, collections, menus, pages, cart, checkout, and more. +``` +yarn global add @medusajs/medusa-cli +``` -In order to use the Shopify's Storefront API, you need to install the [Headless app](https://apps.shopify.com/headless) in your Shopify store. +If you run into any errors while installing the CLI tool, check out the [troubleshooting guide](https://docs.medusajs.com/troubleshooting/cli-installation-errors). -Once installed, you'll need to create a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` environment variable and use the public access token as the value +#### 2. Create a new Medusa project[​](https://docs.medusajs.com/development/backend/install#2-create-a-new-medusa-project 'Direct link to 2. Create a new Medusa project') -> Note: Shopify does offer a Node.js Storefront API SDK. We use the Storefront API via GraphQL directly instead of the Node.js SDK so we have more control over fetching and caching. +``` +medusa new my-medusa-store --seed +``` -
- Expand to view detailed walkthrough +#### 3. Start your Medusa backend[​](https://docs.medusajs.com/development/backend/install#3-start-your-medusa-backend 'Direct link to 3. Start your Medusa backend') -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/apps`. -1. Click the green `Shopify App Store` button. - ![Shopify App Store](https://user-images.githubusercontent.com/446260/233220545-cb4c1461-ebc5-424e-a421-bf0d32044027.jpg) -1. Search for `Headless` and click on the `Headless` app. - ![Headless](https://user-images.githubusercontent.com/446260/233220547-6d93b5ef-16c7-45db-99e7-13ae7e18eb39.jpg) -1. Click the black `Add app` button. - ![Add app](https://user-images.githubusercontent.com/446260/233220550-a34c8bda-75a8-437a-9673-125f3794ff35.jpg) -1. Click the green `Add sales channel` button. - ![Add sales channel](https://user-images.githubusercontent.com/446260/233220553-42d94a74-421d-4f8a-99ab-a95936b707a3.jpg) -1. Click the green `Create storefront` button. - ![Create storefront](https://user-images.githubusercontent.com/446260/233220556-1eee15c4-a45d-446e-9f73-2e7c9f56b29c.jpg) -1. Copy and paste the public access token and assign it to a `SHOPIFY_STOREFRONT_ACCESS_TOKEN` environment variable. - ![Pubic access token](https://user-images.githubusercontent.com/446260/233220558-5db04ff9-b894-40fe-bfba-0e92f26b8e1f.jpg) -1. If you ever need to reference the public access token again, you can navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/headless_storefronts`. -
+``` +cd my-medusa-store medusa develop +``` -### Install a headless theme +#### 4. Add Medusa backend domain to an environment variable -When using a headless Shopify setup, you normally don't want customers to access any of the theme pages except for checkout. However, you can't totally disable the theme and a lot of links will still point to the theme (e.g. links in emails, order details, plugins, checkout, etc.). - -To enable a seamless flow between your headless site and Shopify, you can install the [Shopify Headless Theme](https://github.com/instantcommerce/shopify-headless-theme). - -Follow the installation instructions and configure the theme with your headless site's values. - -
- Expand to view detailed walkthrough - -1. Download [Shopify Headless Theme](https://github.com/instantcommerce/shopify-headless-theme). - ![Download Shoify Headless Theme](https://user-images.githubusercontent.com/446260/233220560-9f3f5ab0-ffb4-4305-b4ee-2c9d33eea90f.jpg) -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/themes`. -1. Click `Add theme`, then `Upload zip file`. - ![Upload zip file](https://user-images.githubusercontent.com/446260/233220561-7a53809e-0d95-45eb-b52f-3a52e3663a9c.jpg) -1. Select the downloaded zip file from above, and click the green `Upload file` button. - ![Select and upload file](https://user-images.githubusercontent.com/446260/233220563-135fb9f7-2921-4189-8f17-3b1cc15c0ea6.jpg) -1. Click `Customize`. - ![Customize theme](https://user-images.githubusercontent.com/446260/233220565-24b9c954-c18a-46f1-9db5-3d2a00040e48.jpg) -1. Click `Theme settings` (ie. the paintbrush icon), expand the `STOREFRONT` section, enter your headless store domain, click the gray `Publish` button. - ![Set headless domain in theme settings](https://user-images.githubusercontent.com/446260/233220566-acaee14d-03f8-400d-a2a2-28e85eb5ecdc.jpg) -1. Confirm the theme change by clicking the green `Save and publish` button. - ![Confirm save and publish](https://user-images.githubusercontent.com/446260/233220567-504d5bde-cfb9-426d-a264-f9a12d02af13.jpg) -1. The headless theme should now be your current active theme. -![Headless theme is current and active](https://user-images.githubusercontent.com/446260/233220569-63cab2b4-241b-4bf1-9b5b-451daaeceb91.jpg) -
- -### Branding & Design - -Since you're creating a headless Shopify store, you'll be in full control of your brand and design. However, there are still a few aspects we're leaving within Shopify's control. - -- Checkout -- Emails -- Order status -- Order history -- Favicon (for any Shopify controlled pages) - -You can use Shopify's admin to customize these pages to match your brand and design. - -
- Expand to view detailed walkthrough - -#### Checkout, order status, and order history - -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/checkout`. -1. Click the green `Customize` button. - ![Customize](https://user-images.githubusercontent.com/446260/233220530-9beda4b4-5008-440a-b923-9d196b722539.jpg) -1. Click `Branding` (ie. the paintbrush icon) and customize your brand. Please note, there are three steps / pages to the checkout flow. Use the dropdown to change pages and adjust branding as needed on each page. Click `Save` when you are done. - ![Branding](https://user-images.githubusercontent.com/446260/233220534-e884d9fd-1a39-4f4d-9d09-163dde47c2e8.jpg) -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/branding`. -1. Customize settings to match your brand. - ![Branding](https://user-images.githubusercontent.com/446260/233220536-452b8802-9a1e-40f0-9a12-52b3dace84a5.jpg) - -#### Emails - -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/settings/email_settings`. -1. Customize settings to match your brand. - ![Branding](https://user-images.githubusercontent.com/446260/233220538-13c83a9e-55f8-41e6-9b34-a39ee0848a8a.jpg) - -#### Favicon - -1. Navigate to `https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/themes`. -1. Click the green `Customize` button. - ![Customize theme](https://user-images.githubusercontent.com/446260/233220539-4869a6cd-f59f-4de6-8091-95ed81d2302d.jpg) -1. Click `Theme settings` (ie. the paintbrush icon), expand the `FAVICON` section, upload favicon, then click the `Save` button. - ![Favicon](https://user-images.githubusercontent.com/446260/233220542-ac81b674-d86e-4172-ab38-c79d1ad1ff36.jpg) - -
- -### Configure webhooks for on-demand incremental static regeneration (ISR) - -Coming soon. - -### Using Shopify as a CMS - -Next.js Commerce is fully powered by Shopify in a truly headless and data driven way. - -#### Products - -`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/products` - -Only `Active` products are shown. `Draft` products will not be shown until they are marked as `Active`. - -`Active` products can still be hidden and not seen by navigating the site, by adding a `nextjs-frontend-hidden` tag on the product. This tag will also tell search engines to not index or crawl the product. The product is still directly accessible via url. This feature is great for "secret" products you only want to people you share the url with. - -Product options and option combinations are driven from Shopify options and variants. When selecting options on the product detail page, other option and variant combinations will be visually validated and verified for availability, like Amazon does. - -Products that are active and "out of stock" are still shown on the site, but the ability to add the product to the cart is disabled. - -#### Collections - -`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/collections` - -Create whatever collections you want and configure them however you want. All available collections will show on the search page as filters on the left, with one exception... - -Any collection names that start with the word "hidden" will not show up on the headless front end. The Next.js Commerce theme comes pre-configured to look for two hidden collections. Collections were chosen for this over tags so that order of products could be controlled (collections allow for manual ordering). - -Create the following collections: - -- `Hidden: Homepage Featured Items` -- Products in this collection are displayed in the three featured blocks on the homepage. -- `Hidden: Homepage Carousel` -- Products in this collection are displayed in the auto-scrolling carousel section on the homepage. - -![Shopify collections](https://user-images.githubusercontent.com/446260/233220543-81896a2b-7085-4abc-a4f1-ce321e08b953.jpg) - -![Shopify collection detail](https://user-images.githubusercontent.com/446260/233220544-ecd4c069-49fc-4a0b-8378-aa5e1b4b5257.jpg) - -#### Pages - -`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/pages` - -Next.js Commerce contains a dynamic `[page]` route. It will use the value to look for a corresponding page in Shopify. If a page is found, it will display its rich content using Tailwind's prose. If a page is not found, a 404 page is displayed. - -![Shopify pages](https://user-images.githubusercontent.com/446260/233221142-4dc3fa56-5256-4d84-b0a3-331ffb7d79b2.jpg) - -![Shopify page detail](https://user-images.githubusercontent.com/446260/233247700-cbeaf917-fb67-49e9-b9b9-5ee8cb188639.jpg) - -#### Navigation menus - -`https://SHOPIFY_STORE_SUBDOMAIN.myshopify.com/admin/menus` - -Next.js Commerce's header and footer navigation is pre-configured to be controlled by Shopify navigation menus. This means you have full control over what links go here. They can be to collections, pages, external links, and more. - -Create the following navigation menus: - -- `Next.js Frontend Header Menu` -- Menu items to be shown in the headless frontend header. -- `Next.js Frontend Footer Menu` -- Menu items to be shown in the headless frontend footer. - -![Shopify navigation menus](https://user-images.githubusercontent.com/446260/233220571-33f9d5a8-1206-4ab4-ad79-83b4ca954331.jpg) - -![Shopify navigation menu detail](https://user-images.githubusercontent.com/446260/233220573-5f03a51f-4100-461f-a696-f085856e391b.jpg) - -#### SEO - -Shopify's products, collections, pages, etc. allow you to create custom SEO titles and descriptions. Next.js Commerce is pre-configured to display these custom values, but also comes with sensible default fallbacks if they are not provided. - -![Shopify SEO](https://user-images.githubusercontent.com/446260/233247701-0ff2a560-7949-4e6c-b3a8-8168ed6341f8.jpg) +Create a `MEDUSA_BACKEND_API` environment variable in you Next.js Commerce project and use your Medusa backend domain as the the value (default: `http://localhost:9000`).