CMS providers update (#309)

* CMS providers update

* Strapi provider update

* Add channel listing update issue note to readme

* Update provider operations logs

* Update contribution guide and fields instructions

* Fix external links opening
This commit is contained in:
Dawid 2023-03-20 12:21:19 +01:00 committed by GitHub
parent b80df176e5
commit ab0dec5814
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 581 additions and 41 deletions

View file

@ -17,11 +17,11 @@ CMS Hub will:
If you want to add a provider for a new CMS, here is what you have to do:
1. Go to `/src/lib/cms/config.ts`.
1. Go to `/src/lib/cms/config/providers.ts`.
2. Update the `providersConfig` variable with basic information about your provider: `name`, `label` and `tokens`:
```ts
// src/lib/cms/config.ts
// src/lib/cms/config/providers.ts
export const providersConfig = {
contentful: {
...

View file

@ -29,6 +29,10 @@ Currently, the CMS Hub does not support mapping Saleor fields to your CMS fields
- strings fields: `saleor_id`, `name`, `product_id`, `product_name`, `product_slug`,
- JSON fileds: `channels`.
### Known issues
CMS Hub updates product variants in CMS providers on create, update or delete product variant webook events. They are triggered on product variant channel listing added or updated, but they currently don't trigger on deleting channel listing due to the [core issue #12247](https://github.com/saleor/saleor/issues/12247). To make it working on deleting channel listing, you can additionally modify other product variant field e.g. `name`, so webhook handlers receive the updated channel listings as well.
## How to use it?
1. Install the application in your Dashboard and open it.

View file

@ -7,6 +7,6 @@ DatoCMS integration requires several configuration tokens. You should enter them
Here is the list of the tokens and instructions on how to obtain them
- `baseUrl`: the optional URL to your DatoCMS project. If you leave this blank, this URL will be inferred from your API Token.
- `token`: the API token with access to Content Management API. You can find this in your DatoCMS project settings.
- `token`: the API token with access to Content Management API. You can find this in your DatoCMS project settings. More instructions of how to create it available at [DatoCMS "Authentication" documentation](https://www.datocms.com/docs/content-management-api/authentication).
- `itemTypeId`: item type ID (number). You can find this as Model ID in your DatoCMS product variant model settings, by clicking "Edit model".
- `environment`: optional environment name. If you leave this blank, default environment will be used. You can find this in your DatoCMS project settings.

View file

@ -8,3 +8,4 @@ Here is the list of the tokens and instructions on how to obtain them
- `baseUrl`: the API URL. It's the address of your Strapi API. For local Strapi development it will be: `http://localhost:XXXX`.
- `token`: the authorization token. For instructions on how to create one for CMS Hub, please go to the [Strapi "Managing API tokens" documentation](https://docs.strapi.io/user-docs/latest/settings/managing-global-settings.html#managing-api-tokens).
- `contentTypeId`: the content type id. You can find this in your Strapi project, go to Content-Type Builder > select content type > click Edit > use API ID (Plural). For more unstruction of how to get content type id, please go to [Strapi "Editing content types" documentation](https://docs.strapi.io/user-docs/content-type-builder/managing-content-types#editing-content-types).

View file

@ -29,9 +29,11 @@
"graphql-tag": "^2.12.6",
"next": "13.2",
"pino": "^8.8.0",
"pino-pretty": "^9.1.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.39.1",
"react-markdown": "^8.0.5",
"urql": "^3.0.3",
"usehooks-ts": "^2.9.1",
"uuid": "^9.0.0",

View file

@ -65,6 +65,7 @@ describe("CMS Clients Operations", () => {
name: "First provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "first-provider",
providerName: "strapi",
},
@ -72,6 +73,7 @@ describe("CMS Clients Operations", () => {
name: "Second provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "second-provider",
providerName: "strapi",
},
@ -79,6 +81,7 @@ describe("CMS Clients Operations", () => {
name: "Third provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "third-provider",
providerName: "strapi",
},
@ -134,6 +137,7 @@ describe("CMS Clients Operations", () => {
name: "First provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "first-provider",
providerName: "strapi",
},
@ -141,6 +145,7 @@ describe("CMS Clients Operations", () => {
name: "Second provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "second-provider",
providerName: "strapi",
},
@ -148,6 +153,7 @@ describe("CMS Clients Operations", () => {
name: "Third provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "third-provider",
providerName: "strapi",
},
@ -203,6 +209,7 @@ describe("CMS Clients Operations", () => {
name: "First provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "first-provider",
providerName: "strapi",
},
@ -210,6 +217,7 @@ describe("CMS Clients Operations", () => {
name: "Second provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "second-provider",
providerName: "strapi",
},
@ -217,6 +225,7 @@ describe("CMS Clients Operations", () => {
name: "Third provider",
token: "token",
baseUrl: "baseUrl",
contentTypeId: "contentTypeId",
id: "third-provider",
providerName: "strapi",
},

View file

@ -15,7 +15,6 @@ import { getCmsIdFromSaleorItemKey } from "./metadata";
type WebhookContext = Parameters<NextWebhookApiHandler>["2"];
// todo: add support for multiple providers at once
export const createCmsOperations = async ({
context,
productVariantChannels,

View file

@ -13,7 +13,7 @@ export const createCmsKeyForSaleorItem = (cmsProviderInstanceId: string) => {
};
export const getCmsIdFromSaleorItemKey = (key: string) => {
return key.split("_")[2];
return key.split("_")[1];
};
export const getCmsIdFromSaleorItem = (

View file

@ -25,40 +25,46 @@ export const providersConfig = {
icon: ContentfulIcon,
tokens: [
{
name: "baseUrl",
label: "Base URL",
helpText: "CDN API URL of your Contentful project, e.g. https://cdn.contentful.com.",
},
{
required: true,
name: "token",
label: "Token",
helpText:
"You can find this in your Contentful project, go to Settings > API keys > Content management tokens > Generate personal token.",
'You can find this in your Contentful project, go to Settings > API keys > Content management tokens > Generate personal token. More instructions at [Contentful "Authentication" documentation](https://www.contentful.com/developers/docs/references/authentication/).',
},
{
required: true,
name: "environment",
label: "Environment",
helpText:
"Environment of your content, e.g. master. You can find this in your Contentful project, go to Settings > Environments.",
},
{
required: true,
name: "spaceId",
label: "Space ID",
helpText:
"You can find this in your Contentful project, go to settings > general settings.",
},
{
required: true,
name: "contentId",
label: "Content ID",
helpText:
"You can find this in your Contentful project, go to Content model > select model > Content type id.",
},
{
required: true,
name: "locale",
label: "Locale",
helpText:
"Locale of your content, e.g. en-US. You can find this in your Contentful project, go to Settings > Locales.",
},
{
name: "baseUrl",
label: "Base URL",
helpText:
"Optional content management API URL of your Contentful project. If you leave this blank, default https://api.contentful.com will be used.",
},
],
},
strapi: {
@ -70,14 +76,21 @@ export const providersConfig = {
required: true,
name: "baseUrl",
label: "Base URL",
helpText: "API URL of your Strapi project.",
helpText: "API URL of your Strapi project. E.g. https://your-strapi-project/api.",
},
{
required: true,
name: "token",
label: "API Token (with full access)",
helpText:
"You can find this in your Strapi project settings, go to Settings > API Tokens and use full access token or create new one.",
'You can find this in your Strapi project settings, go to Settings > API Tokens and use full access token or create new one. More instructions at [Strapi "Managing API tokens" documentation](https://docs.strapi.io/user-docs/latest/settings/managing-global-settings.html#managing-api-tokens).',
},
{
required: true,
name: "contentTypeId",
label: "Content Type ID",
helpText:
'You can find this in your Strapi project, go to Content-Type Builder > select content type > click Edit > use API ID (Plural). More instructions at [Strapi "Editing content types" documentation](https://docs.strapi.io/user-docs/content-type-builder/managing-content-types#editing-content-types).',
},
],
},
@ -90,7 +103,8 @@ export const providersConfig = {
required: true,
name: "token",
label: "API Token (with access to Content Management API)",
helpText: "You can find this in your DatoCMS project settings.",
helpText:
'You can find this in your DatoCMS project settings. More instructions at [DatoCMS "Authentication" documentation](https://www.datocms.com/docs/content-management-api/authentication).',
},
{
required: true,
@ -123,24 +137,25 @@ export const strapiConfigSchema = z.object({
name: z.string().min(1),
token: z.string().min(1),
baseUrl: z.string().min(1),
contentTypeId: z.string().min(1),
});
export const contentfulConfigSchema = z.object({
name: z.string().min(1),
token: z.string(),
token: z.string().min(1),
environment: z.string().min(1),
spaceId: z.string().min(1),
locale: z.string().min(1),
contentId: z.string().min(1),
baseUrl: z.string(),
environment: z.string(),
spaceId: z.string(),
locale: z.string(),
contentId: z.string(),
});
export const datocmsConfigSchema = z.object({
name: z.string().min(1),
token: z.string().min(1),
itemTypeId: z.string().min(1),
baseUrl: z.string(),
environment: z.string(),
itemTypeId: z.string().min(1),
});
export const providerCommonSchema = z.object({

View file

@ -1,11 +1,13 @@
import { v4 as uuidv4 } from "uuid";
import { ContentfulConfig, contentfulConfigSchema } from "../config";
import { logger as pinoLogger } from "../../logger";
import { CreateOperations, CreateProductResponse, ProductInput } from "../types";
import { createProvider } from "./create";
const contentfulFetch = (endpoint: string, config: ContentfulConfig, options?: RequestInit) => {
const { baseUrl, token } = config;
const baseUrl = config.baseUrl || "https://api.contentful.com";
const token = config.token;
return fetch(`${baseUrl}${endpoint}`, {
...options,
@ -55,11 +57,8 @@ const transformInputToBody = ({
[locale]: input.productName,
},
channels: {
[locale]: JSON.stringify(input.channels),
[locale]: input.channels,
},
// image: {
// [locale]: input.image,
// },
},
};
return body;
@ -92,7 +91,9 @@ const getEntryEndpoint = ({
}): string => `/spaces/${spaceId}/environments/${environment}/entries/${resourceId}`;
const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
const { baseUrl, token, environment, spaceId, contentId, locale } = config;
const logger = pinoLogger.child({ cms: "strapi" });
const { environment, spaceId, contentId, locale } = config;
return {
createProduct: async (params) => {
@ -104,6 +105,7 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
environment,
spaceId,
});
const response = await contentfulFetch(endpoint, config, {
method: "PUT",
body: JSON.stringify(body),
@ -111,7 +113,10 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
"X-Contentful-Content-Type": contentId,
},
});
logger.debug("createProduct response", { response });
const result = await response.json();
logger.debug("createProduct result", { result });
return transformCreateProductResponse(result);
},
updateProduct: async ({ id, input }) => {
@ -121,8 +126,12 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
environment,
spaceId,
});
const getEntryResponse = await contentfulFetch(endpoint, config, { method: "GET" });
logger.debug("updateProduct getEntryResponse", { getEntryResponse });
const entry = await getEntryResponse.json();
logger.debug("updateProduct entry", { entry });
const response = await contentfulFetch(endpoint, config, {
method: "PUT",
body: JSON.stringify(body),
@ -130,12 +139,19 @@ const contentfulOperations: CreateOperations<ContentfulConfig> = (config) => {
"X-Contentful-Version": entry.sys.version,
},
});
logger.debug("updateProduct response", { response });
const result = await response.json();
logger.debug("updateProduct result", { result });
return result;
},
deleteProduct: ({ id }) => {
deleteProduct: async ({ id }) => {
const endpoint = getEntryEndpoint({ resourceId: id, environment, spaceId });
return contentfulFetch(endpoint, config, { method: "DELETE" });
const response = await contentfulFetch(endpoint, config, { method: "DELETE" });
logger.debug("deleteProduct response", { response });
return response;
},
};
};

View file

@ -1,5 +1,6 @@
import { createProvider } from "./create";
import { CreateOperations, CreateProductResponse } from "../types";
import { logger as pinoLogger } from "../../logger";
import { ApiError, buildClient, SimpleSchemaTypes } from "@datocms/cma-client-node";
import { DatocmsConfig, datocmsConfigSchema } from "../config";
@ -41,6 +42,8 @@ const transformResponseItem = (item: SimpleSchemaTypes.Item): CreateProductRespo
};
const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
const logger = pinoLogger.child({ cms: "strapi" });
return {
createProduct: async ({ input }) => {
const client = datocmsClient(config);
@ -58,6 +61,8 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
product_name: input.productName,
product_slug: input.productSlug,
});
logger.debug("createProduct response", { item });
return transformResponseItem(item);
} catch (error) {
return transformResponseError(error);
@ -66,7 +71,7 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
updateProduct: async ({ id, input }) => {
const client = datocmsClient(config);
await client.items.update(id, {
const item = await client.items.update(id, {
saleor_id: input.saleorId,
name: input.name,
channels: JSON.stringify(input.channels),
@ -74,11 +79,13 @@ const datocmsOperations: CreateOperations<DatocmsConfig> = (config) => {
product_name: input.productName,
product_slug: input.productSlug,
});
logger.debug("updateProduct response", { item });
},
deleteProduct: async ({ id }) => {
const client = datocmsClient(config);
await client.items.destroy(id);
const item = await client.items.destroy(id);
logger.debug("deleteProduct response", { item });
},
};
};

View file

@ -1,9 +1,11 @@
import { StrapiConfig, strapiConfigSchema } from "../config";
import { CmsOperations, CreateOperations, CreateProductResponse, ProductInput } from "../types";
import { createProvider } from "./create";
import { logger as pinoLogger } from "../../logger";
const strapiFetch = (endpoint: string, config: StrapiConfig, options?: RequestInit) => {
const strapiFetch = async (endpoint: string, config: StrapiConfig, options?: RequestInit) => {
const { baseUrl, token } = config;
return fetch(`${baseUrl}${endpoint}`, {
...options,
headers: {
@ -23,7 +25,7 @@ const transformInputToBody = ({ input }: { input: ProductInput }): StrapiBody =>
data: {
saleor_id: input.saleorId,
name: input.name,
channels: JSON.stringify(input.channels),
channels: input.channels,
product_id: input.productId,
product_name: input.productName,
product_slug: input.productSlug,
@ -72,24 +74,39 @@ const transformCreateProductResponse = (response: StrapiResponse): CreateProduct
type CreateStrapiOperations = CreateOperations<StrapiConfig>;
export const strapiOperations: CreateStrapiOperations = (config): CmsOperations => {
const logger = pinoLogger.child({ cms: "strapi" });
const { contentTypeId } = config;
return {
createProduct: async (params) => {
const body = transformInputToBody(params);
const response = await strapiFetch("/products", config, {
const response = await strapiFetch(`/${contentTypeId}`, config, {
method: "POST",
body: JSON.stringify(body),
});
logger.debug("createProduct response", { response });
const result = await response.json();
logger.debug("createProduct result", { result });
return transformCreateProductResponse(result);
},
updateProduct: ({ id, input }) => {
updateProduct: async ({ id, input }) => {
const body = transformInputToBody({ input });
return strapiFetch(`/products/${id}`, config, { method: "PUT", body: JSON.stringify(body) });
const response = await strapiFetch(`/${contentTypeId}/${id}`, config, {
method: "PUT",
body: JSON.stringify(body),
});
logger.debug("updateProduct response", { response });
return response;
},
deleteProduct: ({ id }) => {
return strapiFetch(`/products/${id}`, config, { method: "DELETE" });
deleteProduct: async ({ id }) => {
const response = await strapiFetch(`/${contentTypeId}/${id}`, config, { method: "DELETE" });
logger.debug("deleteProduct response", { response });
return response;
},
};
};

View file

@ -1,8 +1,9 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { Checkbox, FormControlLabel, Grid, TextField, Typography } from "@material-ui/core";
import { Grid, TextField, Typography } from "@material-ui/core";
import { Button, makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { Controller, DeepRequired, FieldErrorsImpl, Path, useForm } from "react-hook-form";
import ReactMarkdown from "react-markdown";
import { Path, useForm } from "react-hook-form";
import { z } from "zod";
import {
providersConfig,
@ -13,6 +14,7 @@ import {
ProviderInstanceSchema,
} from "../../../lib/cms/config";
import { Provider } from "../../providers/config";
import { AppMarkdownText } from "../../ui/app-markdown-text";
const useStyles = makeStyles((theme) => ({
footer: {
@ -132,7 +134,7 @@ const ProviderInstanceConfigurationForm = <TProvider extends CMSProviderSchema>(
helperText={
<>
{errors[token.name as Path<ProvidersSchema[TProvider]>]?.message ||
("helpText" in token && token.helpText)}
("helpText" in token && <AppMarkdownText>{token.helpText}</AppMarkdownText>)}
</>
}
/>

View file

@ -0,0 +1,35 @@
import { actions, useAppBridge } from "@saleor/app-sdk/app-bridge";
import ReactMarkdown from "react-markdown";
import { ReactMarkdownOptions } from "react-markdown/lib/react-markdown";
export const AppMarkdownText = ({ children, components, ...rest }: ReactMarkdownOptions) => {
const { appBridge } = useAppBridge();
const onClickHelpTextLink = (
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
href?: string
) => {
event.preventDefault();
if (href) {
appBridge?.dispatch(
actions.Redirect({
to: href,
newContext: true,
})
);
}
};
return (
<ReactMarkdown
{...rest}
components={{
...components,
a: (props) => <a {...props} onClick={(event) => onClickHelpTextLink(event, props.href)} />,
}}
>
{children}
</ReactMarkdown>
);
};

View file

@ -56,10 +56,12 @@ importers:
jsdom: ^20.0.3
next: '13.2'
pino: ^8.8.0
pino-pretty: ^9.1.1
prettier: ^2.7.1
react: 18.2.0
react-dom: 18.2.0
react-hook-form: ^7.39.1
react-markdown: ^8.0.5
typescript: '4.9'
urql: ^3.0.3
usehooks-ts: ^2.9.1
@ -82,9 +84,11 @@ importers:
graphql-tag: 2.12.6_graphql@16.6.0
next: 13.2.4_biqbaboplfbrettd7655fr4n2y
pino: 8.9.0
pino-pretty: 9.1.1
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
react-hook-form: 7.43.1_react@18.2.0
react-markdown: 8.0.5_3stiutgnnbnfnf3uowm5cip22i
urql: 3.0.3_onqnqwb3ubg5opvemcqf7c2qhy
usehooks-ts: 2.9.1_biqbaboplfbrettd7655fr4n2y
uuid: 9.0.0
@ -5703,6 +5707,12 @@ packages:
resolution: {integrity: sha512-Wtl6PUL26jEbC1NBqJi7uoyYZo1/I3EDCd9pZk9EN6ZDvKaO28M5+nIQGyYomzvkMpMHnfywpTzalhwr76/oAg==}
dev: false
/@types/hast/2.3.4:
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
dependencies:
'@types/unist': 2.0.6
dev: false
/@types/hogan.js/3.0.1:
resolution: {integrity: sha512-D03i/2OY7kGyMq9wdQ7oD8roE49z/ZCZThe/nbahtvuqCNZY9T2MfedOWyeBdbEpY2W8Gnh/dyJLdFtUCOkYbg==}
dev: false
@ -5759,6 +5769,12 @@ packages:
resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
dev: false
/@types/mdast/3.0.10:
resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==}
dependencies:
'@types/unist': 2.0.6
dev: false
/@types/minimatch/3.0.5:
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
dev: true
@ -5877,6 +5893,10 @@ packages:
resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
dev: true
/@types/unist/2.0.6:
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
dev: false
/@types/uuid/8.3.4:
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
dev: true
@ -6927,6 +6947,10 @@ packages:
- supports-color
dev: true
/bail/2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
dev: false
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@ -7283,6 +7307,10 @@ packages:
tslib: 2.5.0
dev: true
/character-entities/2.0.2:
resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
dev: false
/chardet/0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
@ -7480,6 +7508,10 @@ packages:
resolution: {integrity: sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==}
dev: false
/comma-separated-tokens/2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
dev: false
/commander/2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
dev: false
@ -7805,6 +7837,12 @@ packages:
/decimal.js/10.4.3:
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
/decode-named-character-reference/1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
dependencies:
character-entities: 2.0.2
dev: false
/decompress-response/6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
@ -7885,6 +7923,11 @@ packages:
engines: {node: '>= 0.6.0'}
dev: true
/dequal/2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
dev: false
/detect-indent/6.1.0:
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
engines: {node: '>=8'}
@ -10190,6 +10233,10 @@ packages:
dependencies:
function-bind: 1.1.1
/hast-util-whitespace/2.0.1:
resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==}
dev: false
/he/1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
@ -10445,6 +10492,10 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: false
/inline-style-parser/0.1.1:
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
dev: false
/inline-style-prefixer/6.0.4:
resolution: {integrity: sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==}
dependencies:
@ -10555,6 +10606,11 @@ packages:
call-bind: 1.0.2
has-tostringtag: 1.0.0
/is-buffer/2.0.5:
resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
engines: {node: '>=4'}
dev: false
/is-callable/1.2.7:
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
engines: {node: '>= 0.4'}
@ -10652,6 +10708,11 @@ packages:
resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
engines: {node: '>=0.10.0'}
/is-plain-obj/4.1.0:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
dev: false
/is-potential-custom-element-name/1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
@ -11504,6 +11565,52 @@ packages:
css-mediaquery: 0.1.2
dev: false
/mdast-util-definitions/5.1.2:
resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==}
dependencies:
'@types/mdast': 3.0.10
'@types/unist': 2.0.6
unist-util-visit: 4.1.2
dev: false
/mdast-util-from-markdown/1.3.0:
resolution: {integrity: sha512-HN3W1gRIuN/ZW295c7zi7g9lVBllMgZE40RxCX37wrTPWXCWtpvOZdfnuK+1WNpvZje6XuJeI3Wnb4TJEUem+g==}
dependencies:
'@types/mdast': 3.0.10
'@types/unist': 2.0.6
decode-named-character-reference: 1.0.2
mdast-util-to-string: 3.1.1
micromark: 3.1.0
micromark-util-decode-numeric-character-reference: 1.0.0
micromark-util-decode-string: 1.0.2
micromark-util-normalize-identifier: 1.0.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
unist-util-stringify-position: 3.0.3
uvu: 0.5.6
transitivePeerDependencies:
- supports-color
dev: false
/mdast-util-to-hast/12.3.0:
resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==}
dependencies:
'@types/hast': 2.3.4
'@types/mdast': 3.0.10
mdast-util-definitions: 5.1.2
micromark-util-sanitize-uri: 1.1.0
trim-lines: 3.0.1
unist-util-generated: 2.0.1
unist-util-position: 4.0.4
unist-util-visit: 4.1.2
dev: false
/mdast-util-to-string/3.1.1:
resolution: {integrity: sha512-tGvhT94e+cVnQt8JWE9/b3cUQZWS732TJxXHktvP+BYo62PpYD53Ls/6cC60rW21dW+txxiM4zMdc6abASvZKA==}
dependencies:
'@types/mdast': 3.0.10
dev: false
/mdn-data/2.0.14:
resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
dev: false
@ -11573,6 +11680,182 @@ packages:
transliteration: 2.2.0
dev: false
/micromark-core-commonmark/1.0.6:
resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==}
dependencies:
decode-named-character-reference: 1.0.2
micromark-factory-destination: 1.0.0
micromark-factory-label: 1.0.2
micromark-factory-space: 1.0.0
micromark-factory-title: 1.0.2
micromark-factory-whitespace: 1.0.0
micromark-util-character: 1.1.0
micromark-util-chunked: 1.0.0
micromark-util-classify-character: 1.0.0
micromark-util-html-tag-name: 1.1.0
micromark-util-normalize-identifier: 1.0.0
micromark-util-resolve-all: 1.0.0
micromark-util-subtokenize: 1.0.2
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
uvu: 0.5.6
dev: false
/micromark-factory-destination/1.0.0:
resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==}
dependencies:
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
dev: false
/micromark-factory-label/1.0.2:
resolution: {integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==}
dependencies:
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
uvu: 0.5.6
dev: false
/micromark-factory-space/1.0.0:
resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==}
dependencies:
micromark-util-character: 1.1.0
micromark-util-types: 1.0.2
dev: false
/micromark-factory-title/1.0.2:
resolution: {integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==}
dependencies:
micromark-factory-space: 1.0.0
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
uvu: 0.5.6
dev: false
/micromark-factory-whitespace/1.0.0:
resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==}
dependencies:
micromark-factory-space: 1.0.0
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
dev: false
/micromark-util-character/1.1.0:
resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==}
dependencies:
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
dev: false
/micromark-util-chunked/1.0.0:
resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==}
dependencies:
micromark-util-symbol: 1.0.1
dev: false
/micromark-util-classify-character/1.0.0:
resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==}
dependencies:
micromark-util-character: 1.1.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
dev: false
/micromark-util-combine-extensions/1.0.0:
resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==}
dependencies:
micromark-util-chunked: 1.0.0
micromark-util-types: 1.0.2
dev: false
/micromark-util-decode-numeric-character-reference/1.0.0:
resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==}
dependencies:
micromark-util-symbol: 1.0.1
dev: false
/micromark-util-decode-string/1.0.2:
resolution: {integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==}
dependencies:
decode-named-character-reference: 1.0.2
micromark-util-character: 1.1.0
micromark-util-decode-numeric-character-reference: 1.0.0
micromark-util-symbol: 1.0.1
dev: false
/micromark-util-encode/1.0.1:
resolution: {integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==}
dev: false
/micromark-util-html-tag-name/1.1.0:
resolution: {integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==}
dev: false
/micromark-util-normalize-identifier/1.0.0:
resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==}
dependencies:
micromark-util-symbol: 1.0.1
dev: false
/micromark-util-resolve-all/1.0.0:
resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==}
dependencies:
micromark-util-types: 1.0.2
dev: false
/micromark-util-sanitize-uri/1.1.0:
resolution: {integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==}
dependencies:
micromark-util-character: 1.1.0
micromark-util-encode: 1.0.1
micromark-util-symbol: 1.0.1
dev: false
/micromark-util-subtokenize/1.0.2:
resolution: {integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==}
dependencies:
micromark-util-chunked: 1.0.0
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
uvu: 0.5.6
dev: false
/micromark-util-symbol/1.0.1:
resolution: {integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==}
dev: false
/micromark-util-types/1.0.2:
resolution: {integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==}
dev: false
/micromark/3.1.0:
resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==}
dependencies:
'@types/debug': 4.1.7
debug: 4.3.4
decode-named-character-reference: 1.0.2
micromark-core-commonmark: 1.0.6
micromark-factory-space: 1.0.0
micromark-util-character: 1.1.0
micromark-util-chunked: 1.0.0
micromark-util-combine-extensions: 1.0.0
micromark-util-decode-numeric-character-reference: 1.0.0
micromark-util-encode: 1.0.1
micromark-util-normalize-identifier: 1.0.0
micromark-util-resolve-all: 1.0.0
micromark-util-sanitize-uri: 1.1.0
micromark-util-subtokenize: 1.0.2
micromark-util-symbol: 1.0.1
micromark-util-types: 1.0.2
uvu: 0.5.6
transitivePeerDependencies:
- supports-color
dev: false
/micromatch/4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
@ -12053,7 +12336,6 @@ packages:
/mri/1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
dev: true
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
@ -13233,6 +13515,10 @@ packages:
resolution: {integrity: sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==}
dev: false
/property-information/6.2.0:
resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==}
dev: false
/proto-list/1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
dev: false
@ -13490,6 +13776,33 @@ packages:
resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==}
dev: false
/react-markdown/8.0.5_3stiutgnnbnfnf3uowm5cip22i:
resolution: {integrity: sha512-jGJolWWmOWAvzf+xMdB9zwStViODyyFQhNB/bwCerbBKmrTmgmA599CGiOlP58OId1IMoIRsA8UdI1Lod4zb5A==}
peerDependencies:
'@types/react': '>=16'
react: '>=16'
dependencies:
'@types/hast': 2.3.4
'@types/prop-types': 15.7.5
'@types/react': 18.0.27
'@types/unist': 2.0.6
comma-separated-tokens: 2.0.3
hast-util-whitespace: 2.0.1
prop-types: 15.8.1
property-information: 6.2.0
react: 18.2.0
react-is: 18.2.0
remark-parse: 10.0.1
remark-rehype: 10.1.0
space-separated-tokens: 2.0.2
style-to-object: 0.4.1
unified: 10.1.2
unist-util-visit: 4.1.2
vfile: 5.3.7
transitivePeerDependencies:
- supports-color
dev: false
/react-modal/3.16.1_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-VStHgI3BVcGo7OXczvnJN7yT2TWHJPDXZWyI/a0ssFNhGZWsPmB8cF0z33ewDXq4VfYMO1vXgiv/g8Nj9NDyWg==}
engines: {node: '>=8'}
@ -13797,6 +14110,25 @@ packages:
- encoding
dev: true
/remark-parse/10.0.1:
resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==}
dependencies:
'@types/mdast': 3.0.10
mdast-util-from-markdown: 1.3.0
unified: 10.1.2
transitivePeerDependencies:
- supports-color
dev: false
/remark-rehype/10.1.0:
resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==}
dependencies:
'@types/hast': 2.3.4
'@types/mdast': 3.0.10
mdast-util-to-hast: 12.3.0
unified: 10.1.2
dev: false
/remedial/1.0.8:
resolution: {integrity: sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==}
dev: true
@ -13986,6 +14318,13 @@ packages:
dependencies:
tslib: 2.5.0
/sade/1.8.1:
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
engines: {node: '>=6'}
dependencies:
mri: 1.2.0
dev: false
/safe-buffer/5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
dev: false
@ -14248,6 +14587,10 @@ packages:
deprecated: Please use @jridgewell/sourcemap-codec instead
dev: false
/space-separated-tokens/2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
dev: false
/spawndamnit/2.0.0:
resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==}
dependencies:
@ -14504,6 +14847,12 @@ packages:
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
dev: false
/style-to-object/0.4.1:
resolution: {integrity: sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==}
dependencies:
inline-style-parser: 0.1.1
dev: false
/styled-jsx/5.1.1:
resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
engines: {node: '>= 12.0.0'}
@ -14744,10 +15093,18 @@ packages:
resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==}
dev: false
/trim-lines/3.0.1:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
dev: false
/trim-newlines/3.0.1:
resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
engines: {node: '>=8'}
/trough/2.1.0:
resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==}
dev: false
/ts-easing/0.2.0:
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
dev: false
@ -15019,6 +15376,55 @@ packages:
tiny-inflate: 1.0.3
dev: false
/unified/10.1.2:
resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==}
dependencies:
'@types/unist': 2.0.6
bail: 2.0.2
extend: 3.0.2
is-buffer: 2.0.5
is-plain-obj: 4.1.0
trough: 2.1.0
vfile: 5.3.7
dev: false
/unist-util-generated/2.0.1:
resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==}
dev: false
/unist-util-is/5.2.1:
resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==}
dependencies:
'@types/unist': 2.0.6
dev: false
/unist-util-position/4.0.4:
resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==}
dependencies:
'@types/unist': 2.0.6
dev: false
/unist-util-stringify-position/3.0.3:
resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==}
dependencies:
'@types/unist': 2.0.6
dev: false
/unist-util-visit-parents/5.1.3:
resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==}
dependencies:
'@types/unist': 2.0.6
unist-util-is: 5.2.1
dev: false
/unist-util-visit/4.1.2:
resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==}
dependencies:
'@types/unist': 2.0.6
unist-util-is: 5.2.1
unist-util-visit-parents: 5.1.3
dev: false
/universalify/0.1.2:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
@ -15198,6 +15604,17 @@ packages:
hasBin: true
dev: false
/uvu/0.5.6:
resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==}
engines: {node: '>=8'}
hasBin: true
dependencies:
dequal: 2.0.3
diff: 5.1.0
kleur: 4.1.5
sade: 1.8.1
dev: false
/v8-compile-cache/2.3.0:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
dev: true
@ -15236,6 +15653,22 @@ packages:
extsprintf: 1.3.0
dev: false
/vfile-message/3.1.4:
resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==}
dependencies:
'@types/unist': 2.0.6
unist-util-stringify-position: 3.0.3
dev: false
/vfile/5.3.7:
resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==}
dependencies:
'@types/unist': 2.0.6
is-buffer: 2.0.5
unist-util-stringify-position: 3.0.3
vfile-message: 3.1.4
dev: false
/vite-node/0.27.3_@types+node@18.13.0:
resolution: {integrity: sha512-eyJYOO64o5HIp8poc4bJX+ZNBwMZeI3f6/JdiUmJgW02Mt7LnoCtDMRVmLaY9S05SIsjGe339ZK4uo2wQ+bF9g==}
engines: {node: '>=v14.16.0'}