feat(frontend): start edit page

This commit is contained in:
Sam 2022-05-26 16:11:22 +02:00
parent 2ee1087eec
commit 8b31519952
15 changed files with 556 additions and 44 deletions

View File

@ -1,4 +1,4 @@
import { Routes, Route } from "react-router-dom";
import { Routes, Route, useParams } from "react-router-dom";
import "./App.css";
import Container from "./lib/Container";
import Navigation from "./lib/Navigation";
@ -15,8 +15,10 @@ function App() {
<Container>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/u/:username" element={<User />} />
<Route path="/@:username" element={<User />} />
<Route path="/@:username/:member" element={<User />} />
<Route path="/edit" element={<EditMe />} />
<Route path="/edit/:member" element={<EditMe />} />
<Route path="/login" element={<Login />} />
<Route path="/login/discord" element={<Discord />} />
</Routes>

View File

@ -0,0 +1,14 @@
import { Link } from "react-router-dom";
export type Props = {
to: string;
children?: React.ReactNode;
};
export default function BlueLink({ to, children }: Props) {
return (
<Link to={to} className="hover:underline text-sky-500 dark:text-sky-400">
{children}
</Link>
);
}

View File

@ -1,8 +1,13 @@
import React, { PropsWithChildren } from "react";
import React, { ReactNode, PropsWithChildren } from "react";
export type Props = PropsWithChildren<{ title: string; draggable?: boolean }>;
export type Props = {
children?: ReactNode | undefined;
title: string;
draggable?: boolean;
footer?: ReactNode | undefined;
};
export default function Card({ title, draggable, children }: Props) {
export default function Card({ title, draggable, children, footer }: Props) {
return (
<div className="bg-slate-100 dark:bg-slate-700 rounded-md shadow">
<h1
@ -13,6 +18,11 @@ export default function Card({ title, draggable, children }: Props) {
{title}
</h1>
<div className="flex flex-col p-2">{children}</div>
{footer && (
<div className="p-2 border-t border-zinc-200 dark:border-slate-800">
{footer}
</div>
)}
</div>
);
}

View File

@ -5,10 +5,24 @@ import {
People,
EmojiLaughing,
} from "react-bootstrap-icons";
import BlueLink from "./BlueLink";
import Card from "./Card";
import type { Field } from "./types";
function linkPronoun(input: string) {
if (input.includes(" ") || input.split("/").length !== 5)
return <span>{input}</span>;
const [sub, obj, possDet, possPro, reflexive] = input.split("/");
return (
<BlueLink to={`/pronouns/${sub}/${obj}/${possDet}/${possPro}/${reflexive}`}>
{sub}/{obj}/{possDet}
</BlueLink>
);
}
export default function FieldCard({
field,
draggable,
@ -20,7 +34,7 @@ export default function FieldCard({
<Card title={field.name} draggable={draggable}>
{field.favourite.map((entry) => (
<p className="text-lg font-bold">
<HeartFill className="inline" /> {entry}
<HeartFill className="inline" /> {linkPronoun(entry)}
</p>
))}
{field.okay.length !== 0 && (

View File

@ -0,0 +1,10 @@
import { ThreeDots } from "react-bootstrap-icons";
export default function Loading() {
return (
<div className="flex flex-col pt-32 items-center">
<ThreeDots size={64} className="animate-bounce" aria-hidden="true" />
<span className="font-bold text-xl">Loading...</span>
</div>
);
}

View File

@ -45,7 +45,7 @@ function Navigation() {
const nav = user ? (
<>
<NavItem to={`/u/${user.username}`}>@{user.username}</NavItem>
<NavItem to={`/@${user.username}`}>@{user.username}</NavItem>
<NavItem to="/settings">Settings</NavItem>
<NavItem to="/logout">Log out</NavItem>
</>

View File

@ -0,0 +1,19 @@
import { ChangeEventHandler } from "react";
export type Props = {
defaultValue?: string;
value?: string;
onChange?: ChangeEventHandler<HTMLInputElement>;
};
export default function TextInput(props: Props) {
return (
<input
type="text"
className="p-1 lg:p-2 rounded-md bg-white border-slate-300 text-black dark:bg-slate-800 dark:border-slate-900 dark:text-white"
defaultValue={props.defaultValue}
value={props.value}
onChange={props.onChange}
/>
);
}

View File

@ -33,6 +33,7 @@ export interface Field {
export interface APIError {
code: ErrorCode;
message?: string;
details?: string;
}
export enum ErrorCode {
@ -45,3 +46,9 @@ export enum ErrorCode {
UserNotFound = 2001,
}
export interface SignupRequest {
username: string;
ticket: string;
invite_code?: string;
}

View File

@ -1,38 +1,99 @@
import cloneDeep from "lodash/cloneDeep";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { ReactSortable } from "react-sortablejs";
import { useRecoilValue } from "recoil";
import {
EmojiLaughing,
HandThumbsDown,
HandThumbsUp,
Heart,
People,
Trash3,
} from "react-bootstrap-icons";
import CreatableSelect from "react-select/creatable";
import { userState } from "../lib/store";
import { Field } from "../lib/types";
import FieldCard from "../lib/FieldCard";
import Loading from "../lib/Loading";
import Card from "../lib/Card";
import TextInput from "../lib/TextInput";
interface FieldWithID extends Field {
id: number;
}
interface EditField {
id: number;
name: string;
pronouns: Record<string, PronounChoice>;
}
enum PronounChoice {
favourite,
okay,
jokingly,
friendsOnly,
avoid,
}
function fieldsEqual(arr1: EditField[], arr2: EditField[]) {
if (arr1?.length !== arr2?.length) return false;
if (!arr1.every((_, i) => arr1[i].id === arr2[i].id)) return false;
return arr1.every((_, i) =>
Object.keys(arr1[i].pronouns).every(
(val) => arr1[i].pronouns[val] === arr2[i].pronouns[val]
)
);
}
export default function EditMe() {
const navigate = useNavigate();
const meUser = useRecoilValue(userState);
useEffect(() => {
if (!meUser) {
navigate("/");
return <>Loading...</>;
}
});
if (!meUser) {
return <Loading />;
}
const [state, setState] = useState(cloneDeep(meUser));
// add an ID to every field (not returned by the API normally, but Sortable needs it)
// convert all fields to EditFields
const originalOrder = state.fields.map((f, i) => {
const fID = f as FieldWithID;
fID.id = i;
return fID;
const field: EditField = {
id: i,
name: f.name,
pronouns: {},
};
f.favourite.forEach((val) => {
field.pronouns[val] = PronounChoice.favourite;
});
f.okay.forEach((val) => {
field.pronouns[val] = PronounChoice.okay;
});
f.jokingly.forEach((val) => {
field.pronouns[val] = PronounChoice.jokingly;
});
f.friends_only.forEach((val) => {
field.pronouns[val] = PronounChoice.friendsOnly;
});
f.avoid.forEach((val) => {
field.pronouns[val] = PronounChoice.avoid;
});
return field;
});
const [fields, setFields] = useState(cloneDeep(originalOrder));
const fieldsUpdated =
fields.length !== state.fields.length ||
!fields.every((_, i) => fields[i].id === originalOrder[i].id);
const fieldsUpdated = !fieldsEqual(fields, originalOrder);
return (
<div className="container mx-auto">
@ -42,12 +103,129 @@ export default function EditMe() {
handle=".handle"
list={fields}
setList={setFields}
className="grid grid-cols-1 md:grid-cols-3 gap-4 py-2"
className="grid grid-cols-1 xl:grid-cols-2 gap-4 py-2"
>
{fields.map((field, i) => (
<FieldCard key={i} field={field} draggable></FieldCard>
<EditableCard
key={i}
field={field}
onChangeName={(e) => {
field.name = e.target.value;
setFields([...fields]);
}}
onChangeFavourite={null}
onChangeOkay={null}
onChangeJokingly={null}
onChangeFriends={null}
onChangeAvoid={null}
onClickDelete={(_) => {
const newFields = [...fields];
newFields.splice(i, 1);
setFields(newFields);
}}
/>
))}
</ReactSortable>
</div>
);
}
type EditableCardProps = {
field: EditField;
onChangeName: React.ChangeEventHandler<HTMLInputElement>;
onChangeFavourite: any;
onChangeOkay: any;
onChangeJokingly: any;
onChangeFriends: any;
onChangeAvoid: any;
onClickDelete: React.MouseEventHandler<HTMLButtonElement>;
};
function EditableCard(props: EditableCardProps) {
const footer = (
<div className="flex justify-between">
<TextInput value={props.field.name} onChange={props.onChangeName} />
<button
type="button"
onClick={props.onClickDelete}
className="bg-red-600 dark:bg-red-700 hover:bg-red-700 hover:dark:bg-red-800 p-2 rounded-md"
>
<Trash3 aria-hidden className="inline" />{" "}
<span className="font-bold">Delete</span>
</button>
</div>
);
return (
<Card title={props.field.name} draggable footer={footer}>
<ul>
{Object.keys(props.field.pronouns).map((pronoun, index) => {
const choice = props.field.pronouns[pronoun];
return (
<li className="flex justify-between my-1" key={index}>
<div>{pronoun}</div>
<div className="rounded-md">
<button
type="button"
className={`${
choice == PronounChoice.favourite
? "bg-slate-500"
: "bg-slate-600"
} hover:bg-slate-400 p-2`}
>
<Heart />
</button>
<button
type="button"
className={`${
choice == PronounChoice.okay
? "bg-slate-500"
: "bg-slate-600"
} hover:bg-slate-400 p-2`}
>
<HandThumbsUp />
</button>
<button
type="button"
className={`${
choice == PronounChoice.jokingly
? "bg-slate-500"
: "bg-slate-600"
} hover:bg-slate-400 p-2`}
>
<EmojiLaughing />
</button>
<button
type="button"
className={`${
choice == PronounChoice.friendsOnly
? "bg-slate-500"
: "bg-slate-600"
} hover:bg-slate-400 p-2`}
>
<People />
</button>
<button
type="button"
className={`${
choice == PronounChoice.avoid
? "bg-slate-500"
: "bg-slate-600"
} hover:bg-slate-400 p-2`}
>
<HandThumbsDown />
</button>
<button
type="button"
className="bg-red-600 dark:bg-red-700 hover:bg-red-700 hover:dark:bg-red-800 p-2"
>
<Trash3 />
</button>
</div>
</li>
);
})}
</ul>
</Card>
);
}

View File

@ -10,6 +10,7 @@ import FieldCard from "../lib/FieldCard";
import Card from "../lib/Card";
import { userState } from "../lib/store";
import { useRecoilValue } from "recoil";
import Loading from "../lib/Loading";
function UserPage() {
const params = useParams();
@ -21,15 +22,10 @@ function UserPage() {
fetchAPI<User>(`/users/${params.username}`).then((res) => {
setUser(res);
});
}, []);
}, [params.username]);
if (user == null) {
return (
<>
<ArrowClockwise />
<span>Loading...</span>
</>
);
return <Loading />;
}
return (
@ -57,7 +53,7 @@ function UserPage() {
{user.avatar_url && (
<img className="max-w-xs rounded-full" src={user.avatar_url} />
)}
<div className="flex flex-col lg:mx-auto">
<div className="flex flex-col">
{user.display_name && (
<h1 className="text-2xl font-bold">{user.display_name}</h1>
)}
@ -75,10 +71,11 @@ function UserPage() {
{user.bio}
</ReactMarkdown>
)}
{user.links.length !== 0 && user.fields.length === 0 && (
{user.links?.length && user.fields?.length && (
<div className="flex flex-col mx-auto lg:ml-auto">
{user.links.map((link) => (
{user.links.map((link, index) => (
<a
key={index}
href={link}
rel="nofollow noopener noreferrer me"
className="hover:underline text-sky-500 dark:text-sky-400"
@ -91,13 +88,14 @@ function UserPage() {
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 py-2">
{user.fields.map((field) => (
<FieldCard field={field}></FieldCard>
{user.fields?.map((field, index) => (
<FieldCard key={index} field={field}></FieldCard>
))}
{user.links.length !== 0 && (
{user.links?.length && (
<Card title="Links">
{user.links.map((link) => (
{user.links.map((link, index) => (
<a
key={index}
href={link}
rel="nofollow noopener noreferrer me"
className="hover:underline text-sky-500 dark:text-sky-400"

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useRecoilState } from "recoil";
import fetchAPI from "../../lib/fetch";
import Loading from "../../lib/Loading";
import { userState } from "../../lib/store";
import { MeUser } from "../../lib/types";
@ -12,6 +13,7 @@ interface CallbackResponse {
discord?: string;
ticket?: string;
require_invite?: boolean;
}
export default function Discord() {
@ -68,7 +70,7 @@ export default function Discord() {
}
if (user || state.isLoading) {
return <>Loading...</>;
return <Loading />;
}
return <>wow such login</>;

View File

@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useRecoilValue } from "recoil";
import fetchAPI from "../../lib/fetch";
import Loading from "../../lib/Loading";
import { userState } from "../../lib/store";
interface URLsResponse {
@ -38,7 +39,7 @@ export default function Login() {
}, []);
if (state.loading) {
return <>Loading...</>;
return <Loading />;
} else if (state.error) {
return <>Error: {`${state.error}`}</>;
}

View File

@ -18,6 +18,7 @@
"react-helmet": "^6.1.0",
"react-markdown": "^8.0.3",
"react-router-dom": "6",
"react-select": "^5.3.2",
"react-sortablejs": "^6.1.1",
"recoil": "^0.7.2",
"sortablejs": "^1.15.0"

11
scripts/genid/main.go Normal file
View File

@ -0,0 +1,11 @@
package main
import (
"fmt"
"github.com/rs/xid"
)
func main() {
fmt.Println(xid.New())
}

261
yarn.lock
View File

@ -10,7 +10,7 @@
"@jridgewell/gen-mapping" "^0.1.0"
"@jridgewell/trace-mapping" "^0.3.9"
"@babel/code-frame@^7.16.7":
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
@ -91,7 +91,7 @@
dependencies:
"@babel/types" "^7.16.7"
"@babel/helper-module-imports@^7.16.7":
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
@ -117,6 +117,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
"@babel/helper-plugin-utils@^7.17.12":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96"
integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==
"@babel/helper-simple-access@^7.17.7":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367"
@ -164,6 +169,13 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78"
integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ==
"@babel/plugin-syntax-jsx@^7.12.13":
version "7.17.12"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz#834035b45061983a491f60096f61a2e7c5674a47"
integrity sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog==
dependencies:
"@babel/helper-plugin-utils" "^7.17.12"
"@babel/plugin-syntax-jsx@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
@ -203,7 +215,7 @@
"@babel/plugin-syntax-jsx" "^7.16.7"
"@babel/types" "^7.17.0"
"@babel/runtime@^7.7.6":
"@babel/runtime@^7.12.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7":
version "7.17.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
@ -243,6 +255,89 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
"@emotion/babel-plugin@^11.7.1":
version "11.9.2"
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.9.2.tgz#723b6d394c89fb2ef782229d92ba95a740576e95"
integrity sha512-Pr/7HGH6H6yKgnVFNEj2MVlreu3ADqftqjqwUvDy/OJzKFgxKeTQ+eeUf20FOTuHVkDON2iNa25rAXVYtWJCjw==
dependencies:
"@babel/helper-module-imports" "^7.12.13"
"@babel/plugin-syntax-jsx" "^7.12.13"
"@babel/runtime" "^7.13.10"
"@emotion/hash" "^0.8.0"
"@emotion/memoize" "^0.7.5"
"@emotion/serialize" "^1.0.2"
babel-plugin-macros "^2.6.1"
convert-source-map "^1.5.0"
escape-string-regexp "^4.0.0"
find-root "^1.1.0"
source-map "^0.5.7"
stylis "4.0.13"
"@emotion/cache@^11.4.0", "@emotion/cache@^11.7.1":
version "11.7.1"
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==
dependencies:
"@emotion/memoize" "^0.7.4"
"@emotion/sheet" "^1.1.0"
"@emotion/utils" "^1.0.0"
"@emotion/weak-memoize" "^0.2.5"
stylis "4.0.13"
"@emotion/hash@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
"@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
"@emotion/react@^11.8.1":
version "11.9.0"
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.9.0.tgz#b6d42b1db3bd7511e7a7c4151dc8bc82e14593b8"
integrity sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ==
dependencies:
"@babel/runtime" "^7.13.10"
"@emotion/babel-plugin" "^11.7.1"
"@emotion/cache" "^11.7.1"
"@emotion/serialize" "^1.0.3"
"@emotion/utils" "^1.1.0"
"@emotion/weak-memoize" "^0.2.5"
hoist-non-react-statics "^3.3.1"
"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.3.tgz#99e2060c26c6292469fb30db41f4690e1c8fea63"
integrity sha512-2mSSvgLfyV3q+iVh3YWgNlUc2a9ZlDU7DjuP5MjK3AXRR0dYigCrP99aeFtaB2L/hjfEZdSThn5dsZ0ufqbvsA==
dependencies:
"@emotion/hash" "^0.8.0"
"@emotion/memoize" "^0.7.4"
"@emotion/unitless" "^0.7.5"
"@emotion/utils" "^1.0.0"
csstype "^3.0.2"
"@emotion/sheet@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.1.0.tgz#56d99c41f0a1cda2726a05aa6a20afd4c63e58d2"
integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==
"@emotion/unitless@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.1.0.tgz#86b0b297f3f1a0f2bdb08eeac9a2f49afd40d0cf"
integrity sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==
"@emotion/weak-memoize@^0.2.5":
version "0.2.5"
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
@ -430,6 +525,11 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/prop-types@*", "@types/prop-types@^15.0.0":
version "15.7.5"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
@ -449,6 +549,13 @@
dependencies:
"@types/react" "*"
"@types/react-transition-group@^4.4.0":
version "4.4.4"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@^18.0.0":
version "18.0.8"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.8.tgz#a051eb380a9fbcaa404550543c58e1cf5ce4ab87"
@ -551,6 +658,15 @@ axios@^0.27.2:
follow-redirects "^1.14.9"
form-data "^4.0.0"
babel-plugin-macros@^2.6.1:
version "2.8.0"
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
dependencies:
"@babel/runtime" "^7.7.2"
cosmiconfig "^6.0.0"
resolve "^1.12.0"
bail@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
@ -579,6 +695,11 @@ browserslist@^4.20.2, browserslist@^4.20.3:
node-releases "^2.0.3"
picocolors "^1.0.0"
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"
@ -657,13 +778,24 @@ comma-separated-tokens@^2.0.0:
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98"
integrity sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg==
convert-source-map@^1.7.0:
convert-source-map@^1.5.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
dependencies:
safe-buffer "~5.1.1"
cosmiconfig@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982"
integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.1.0"
parse-json "^5.0.0"
path-type "^4.0.0"
yaml "^1.7.2"
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@ -727,11 +859,26 @@ dlv@^1.1.3:
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dom-helpers@^5.0.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
electron-to-chromium@^1.4.118:
version "1.4.132"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.132.tgz#b64599eb018221e52e2e4129de103b03a413c55d"
integrity sha512-JYdZUw/1068NWN+SwXQ7w6Ue0bWYGihvSUNNQwurvcDV/SM7vSiGZ3NuFvFgoEiCs4kB8xs3cX2an3wB7d4TBw==
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"
esbuild-android-64@0.14.38:
version "0.14.38"
resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz#5b94a1306df31d55055f64a62ff6b763a47b7f64"
@ -868,6 +1015,11 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
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==
estree-walker@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
@ -903,6 +1055,11 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
follow-redirects@^1.14.9:
version "1.15.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4"
@ -985,18 +1142,31 @@ history@^5.2.0:
dependencies:
"@babel/runtime" "^7.7.6"
hoist-non-react-statics@^3.3.2:
hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
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"
import-fresh@^3.1.0:
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"
inline-style-parser@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
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"
@ -1048,6 +1218,11 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
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==
json5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
@ -1063,6 +1238,11 @@ lilconfig@^2.0.5:
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.5.tgz#19e57fd06ccc3848fd1891655b5a447092225b25"
integrity sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==
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==
lodash.castarray@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
@ -1143,6 +1323,11 @@ mdurl@^1.0.0:
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
memoize-one@^5.0.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@ -1413,11 +1598,33 @@ object-hash@^3.0.0:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
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-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"
@ -1472,7 +1679,7 @@ postcss@^8.4.12, postcss@^8.4.13:
picocolors "^1.0.0"
source-map-js "^1.0.2"
prop-types@^15.0.0, prop-types@^15.7.2:
prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -1577,6 +1784,19 @@ react-router@6.3.0:
dependencies:
history "^5.2.0"
react-select@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.3.2.tgz#ecee0d5c59ed4acb7f567f7de3c75a488d93dacb"
integrity sha512-W6Irh7U6Ha7p5uQQ2ZnemoCQ8mcfgOtHfw3wuMzG6FAu0P+CYicgofSLOq97BhjMx8jS+h+wwWdCBeVVZ9VqlQ==
dependencies:
"@babel/runtime" "^7.12.0"
"@emotion/cache" "^11.4.0"
"@emotion/react" "^11.8.1"
"@types/react-transition-group" "^4.4.0"
memoize-one "^5.0.0"
prop-types "^15.6.0"
react-transition-group "^4.3.0"
react-side-effect@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.1.tgz#66c5701c3e7560ab4822a4ee2742dee215d72eb3"
@ -1590,6 +1810,16 @@ react-sortablejs@^6.1.1:
classnames "2.3.1"
tiny-invariant "1.2.0"
react-transition-group@^4.3.0:
version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
dependencies:
"@babel/runtime" "^7.5.5"
dom-helpers "^5.0.1"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react@^18.0.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890"
@ -1635,7 +1865,12 @@ remark-rehype@^10.0.0:
mdast-util-to-hast "^12.1.0"
unified "^10.0.0"
resolve@^1.22.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.12.0, resolve@^1.22.0:
version "1.22.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
@ -1697,6 +1932,11 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
space-separated-tokens@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b"
@ -1709,6 +1949,11 @@ style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
stylis@4.0.13:
version "4.0.13"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91"
integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@ -1908,7 +2153,7 @@ xtend@^4.0.2:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
yaml@^1.10.2:
yaml@^1.10.2, yaml@^1.7.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==