diff --git a/index.html b/index.html
index e0d1c84..8a75dc1 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
-
Vite + React + TS
+ ChatGPT Free
diff --git a/package.json b/package.json
index f829b88..6aea76c 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "chatgpt",
+ "name": "chatgpt-free-app",
"private": true,
"version": "0.0.0",
"type": "module",
@@ -9,11 +9,16 @@
"preview": "vite preview"
},
"dependencies": {
+ "dompurify": "^3.0.1",
"highlight.js": "^11.7.0",
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "react-markdown": "^8.0.5",
+ "react-scroll-to-bottom": "^4.2.0",
+ "zustand": "^4.3.5"
},
"devDependencies": {
+ "@tailwindcss/typography": "^0.5.9",
"@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10",
"@vitejs/plugin-react-swc": "^3.0.0",
diff --git a/src/App.tsx b/src/App.tsx
index 544badc..aad4b81 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,5 +1,52 @@
+import React, { useEffect } from 'react';
+import useStore from '@store/store';
+
+import Chat from './components/Chat';
+import Menu from './components/Menu';
+import ConfigMenu from './components/ConfigMenu';
+
+import useSaveToLocalStorage from '@hooks/useSaveToLocalStorage';
+import useUpdateCharts from '@hooks/useUpdateChats';
+
+import { ChatInterface } from '@type/chat';
+
function App() {
- return App
;
+ useSaveToLocalStorage();
+ useUpdateCharts();
+
+ const [setChats, setMessages, setCurrentChatIndex] = useStore((state) => [
+ state.setChats,
+ state.setMessages,
+ state.setCurrentChatIndex,
+ ]);
+
+ useEffect(() => {
+ // localStorage.removeItem('chats');
+ const storedChats = localStorage.getItem('chats');
+ if (storedChats) {
+ try {
+ const chats: ChatInterface[] = JSON.parse(storedChats);
+ setChats(chats);
+ setMessages(chats[0].messages);
+ setCurrentChatIndex(0);
+ } catch (e: unknown) {
+ setChats([]);
+ setMessages([]);
+ setCurrentChatIndex(-1);
+ console.log(e);
+ }
+ } else {
+ setChats([]);
+ }
+ }, []);
+
+ return (
+
+
+
+
+
+ );
}
export default App;
diff --git a/src/api/customApi.ts b/src/api/customApi.ts
new file mode 100644
index 0000000..a8aa777
--- /dev/null
+++ b/src/api/customApi.ts
@@ -0,0 +1,72 @@
+import { MessageInterface } from '@type/chat';
+
+export const endpoint = 'https://api.openai.com/v1/chat/completions';
+
+export const validateApiKey = async (apiKey: string) => {
+ try {
+ const response = await fetch(endpoint, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${apiKey}`,
+ },
+ });
+ const data = await response.json();
+ console.log(data);
+
+ if (response.status === 401) return false;
+ else if (response.status === 400) return true;
+ } catch (error) {
+ console.error('Error:', error);
+ return false;
+ }
+};
+
+export const getChatCompletion = async (
+ apiKey: string,
+ messages: MessageInterface[]
+) => {
+ try {
+ const response = await fetch(endpoint, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${apiKey}`,
+ },
+ body: JSON.stringify({
+ model: 'gpt-3.5-turbo',
+ messages,
+ }),
+ });
+ const data = await response.json();
+ console.log(data);
+ return data;
+ } catch (error) {
+ console.error('Error:', error);
+ }
+};
+
+export const getChatCompletionStream = async (
+ apiKey: string,
+ messages: MessageInterface[]
+) => {
+ try {
+ const response = await fetch(endpoint, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${apiKey}`,
+ },
+ body: JSON.stringify({
+ model: 'gpt-3.5-turbo',
+ messages,
+ stream: true,
+ }),
+ });
+ console.log(response);
+ const stream = response.body;
+ return stream;
+ } catch (error) {
+ console.error('Error:', error);
+ }
+};
diff --git a/src/api/freeApi.ts b/src/api/freeApi.ts
new file mode 100644
index 0000000..5378154
--- /dev/null
+++ b/src/api/freeApi.ts
@@ -0,0 +1,44 @@
+import { MessageInterface } from '@type/chat';
+
+export const endpoint = 'https://chatgpt-api.shn.hk/v1/';
+
+export const getChatCompletion = async (messages: MessageInterface[]) => {
+ try {
+ const response = await fetch(endpoint, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ model: 'gpt-3.5-turbo',
+ messages,
+ }),
+ });
+ const data = await response.json();
+ console.log(data);
+ return data;
+ } catch (error) {
+ console.error('Error:', error);
+ }
+};
+
+export const getChatCompletionStream = async (messages: MessageInterface[]) => {
+ try {
+ const response = await fetch(endpoint, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ model: 'gpt-3.5-turbo',
+ messages,
+ stream: true,
+ }),
+ });
+ console.log(response);
+ const stream = response.body;
+ return stream;
+ } catch (error) {
+ console.error('Error:', error);
+ }
+};
diff --git a/src/api/helper.ts b/src/api/helper.ts
new file mode 100644
index 0000000..298748f
--- /dev/null
+++ b/src/api/helper.ts
@@ -0,0 +1,19 @@
+import { EventSourceData } from '@type/api';
+
+export const parseEventSource = (
+ data: string
+): '[DONE]' | EventSourceData[] => {
+ const result = data
+ .split('\n\n')
+ .filter(Boolean)
+ .map((chunk) => {
+ const jsonString = chunk
+ .split('\n')
+ .map((line) => line.replace(/^data: /, ''))
+ .join('');
+ console.log(jsonString);
+ if (jsonString === '[DONE]') return jsonString;
+ else return JSON.parse(jsonString);
+ });
+ return result;
+};
diff --git a/src/assets/icons/ChatIcon.tsx b/src/assets/icons/ChatIcon.tsx
new file mode 100644
index 0000000..00a2d81
--- /dev/null
+++ b/src/assets/icons/ChatIcon.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const ChatIcon = () => {
+ return (
+
+ );
+};
+
+export default ChatIcon;
diff --git a/src/assets/icons/CopyIcon.tsx b/src/assets/icons/CopyIcon.tsx
new file mode 100644
index 0000000..a10dad8
--- /dev/null
+++ b/src/assets/icons/CopyIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const CopyIcon = () => {
+ return (
+
+ );
+};
+
+export default CopyIcon;
diff --git a/src/assets/icons/CrossIcon.tsx b/src/assets/icons/CrossIcon.tsx
new file mode 100644
index 0000000..25f1171
--- /dev/null
+++ b/src/assets/icons/CrossIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const CrossIcon = () => {
+ return (
+
+ );
+};
+
+export default CrossIcon;
diff --git a/src/assets/icons/CrossIcon2.tsx b/src/assets/icons/CrossIcon2.tsx
new file mode 100644
index 0000000..e35dd85
--- /dev/null
+++ b/src/assets/icons/CrossIcon2.tsx
@@ -0,0 +1,21 @@
+import React from 'react';
+
+const CrossIcon2 = () => {
+ return (
+
+ );
+};
+
+export default CrossIcon2;
diff --git a/src/assets/icons/DeleteIcon.tsx b/src/assets/icons/DeleteIcon.tsx
new file mode 100644
index 0000000..835fdba
--- /dev/null
+++ b/src/assets/icons/DeleteIcon.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+
+const DeleteIcon = () => {
+ return (
+
+ );
+};
+
+export default DeleteIcon;
diff --git a/src/assets/icons/DownArrow.tsx b/src/assets/icons/DownArrow.tsx
new file mode 100644
index 0000000..9603b08
--- /dev/null
+++ b/src/assets/icons/DownArrow.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const DownArrow = () => {
+ return (
+
+ );
+};
+
+export default DownArrow;
diff --git a/src/assets/icons/DownChevronArrow.tsx b/src/assets/icons/DownChevronArrow.tsx
new file mode 100644
index 0000000..931a043
--- /dev/null
+++ b/src/assets/icons/DownChevronArrow.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const DownChevronArrow = ({ className }: { className?: string }) => {
+ return (
+
+ );
+};
+
+export default DownChevronArrow;
diff --git a/src/assets/icons/EditIcon.tsx b/src/assets/icons/EditIcon.tsx
new file mode 100644
index 0000000..4b96673
--- /dev/null
+++ b/src/assets/icons/EditIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const EditIcon = () => {
+ return (
+
+ );
+};
+
+export default EditIcon;
diff --git a/src/assets/icons/EditIcon2.tsx b/src/assets/icons/EditIcon2.tsx
new file mode 100644
index 0000000..f383812
--- /dev/null
+++ b/src/assets/icons/EditIcon2.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const EditIcon2 = () => {
+ return (
+
+ );
+};
+
+export default EditIcon2;
diff --git a/src/assets/icons/HeartIcon.tsx b/src/assets/icons/HeartIcon.tsx
new file mode 100644
index 0000000..08969d3
--- /dev/null
+++ b/src/assets/icons/HeartIcon.tsx
@@ -0,0 +1,16 @@
+import React from 'react';
+
+const HeartIcon = () => {
+ return (
+
+ );
+};
+
+export default HeartIcon;
diff --git a/src/assets/icons/LinkIcon.tsx b/src/assets/icons/LinkIcon.tsx
new file mode 100644
index 0000000..4039744
--- /dev/null
+++ b/src/assets/icons/LinkIcon.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+
+const LinkIcon = () => {
+ return (
+
+ );
+};
+
+export default LinkIcon;
diff --git a/src/assets/icons/LogoutIcon.tsx b/src/assets/icons/LogoutIcon.tsx
new file mode 100644
index 0000000..91c4938
--- /dev/null
+++ b/src/assets/icons/LogoutIcon.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+
+const LogoutIcon = () => {
+ return (
+
+ );
+};
+
+export default LogoutIcon;
diff --git a/src/assets/icons/MoonIcon.tsx b/src/assets/icons/MoonIcon.tsx
new file mode 100644
index 0000000..840921c
--- /dev/null
+++ b/src/assets/icons/MoonIcon.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const MoonIcon = () => {
+ return (
+
+ );
+};
+
+export default MoonIcon;
diff --git a/src/assets/icons/PersonIcon.tsx b/src/assets/icons/PersonIcon.tsx
new file mode 100644
index 0000000..e913c91
--- /dev/null
+++ b/src/assets/icons/PersonIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const PersonIcon = () => {
+ return (
+
+ );
+};
+
+export default PersonIcon;
diff --git a/src/assets/icons/PlusIcon.tsx b/src/assets/icons/PlusIcon.tsx
new file mode 100644
index 0000000..2b2c838
--- /dev/null
+++ b/src/assets/icons/PlusIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const PlusIcon = () => {
+ return (
+
+ );
+};
+
+export default PlusIcon;
diff --git a/src/assets/icons/RefreshIcon.tsx b/src/assets/icons/RefreshIcon.tsx
new file mode 100644
index 0000000..de44047
--- /dev/null
+++ b/src/assets/icons/RefreshIcon.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+
+const RefreshIcon = () => {
+ return (
+
+ );
+};
+
+export default RefreshIcon;
diff --git a/src/assets/icons/SendIcon.tsx b/src/assets/icons/SendIcon.tsx
new file mode 100644
index 0000000..2574da2
--- /dev/null
+++ b/src/assets/icons/SendIcon.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+
+const SendIcon = () => {
+ return (
+
+ );
+};
+
+export default SendIcon;
diff --git a/src/assets/icons/SettingIcon.tsx b/src/assets/icons/SettingIcon.tsx
new file mode 100644
index 0000000..cfbf610
--- /dev/null
+++ b/src/assets/icons/SettingIcon.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+const SettingIcon = () => {
+ return (
+
+ );
+};
+
+export default SettingIcon;
diff --git a/src/assets/icons/SunIcon.tsx b/src/assets/icons/SunIcon.tsx
new file mode 100644
index 0000000..72c6de5
--- /dev/null
+++ b/src/assets/icons/SunIcon.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+
+const SunIcon = () => {
+ return (
+
+ );
+};
+
+export default SunIcon;
diff --git a/src/assets/icons/TickIcon.tsx b/src/assets/icons/TickIcon.tsx
new file mode 100644
index 0000000..6d5d58d
--- /dev/null
+++ b/src/assets/icons/TickIcon.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+
+const TickIcon = () => {
+ return (
+
+ );
+};
+
+export default TickIcon;
diff --git a/src/components/Chat/Chat.tsx b/src/components/Chat/Chat.tsx
new file mode 100644
index 0000000..f239a31
--- /dev/null
+++ b/src/components/Chat/Chat.tsx
@@ -0,0 +1,19 @@
+import React from 'react';
+
+import ChatContent from './ChatContent';
+import ChatInput from './ChatInput';
+import MobileBar from '../MobileBar';
+
+const Chat = () => {
+ return (
+
+
+
+
+ {/* */}
+
+
+ );
+};
+
+export default Chat;
diff --git a/src/components/Chat/ChatContent/ChatContent.tsx b/src/components/Chat/ChatContent/ChatContent.tsx
new file mode 100644
index 0000000..0436cf4
--- /dev/null
+++ b/src/components/Chat/ChatContent/ChatContent.tsx
@@ -0,0 +1,116 @@
+import React from 'react';
+import ScrollToBottom from 'react-scroll-to-bottom';
+import useStore from '@store/store';
+
+import ScrollToBottomButton from './ScrollToBottomButton';
+import ChatTitle from './ChatTitle';
+import Message from './Message';
+import NewMessageButton from './Message/NewMessageButton';
+
+import { getChatCompletionStream as getChatCompletionStreamFree } from '@api/freeApi';
+import { getChatCompletionStream as getChatCompletionStreamCustom } from '@api/customApi';
+import { parseEventSource } from '@api/helper';
+
+import RefreshIcon from '@icon/RefreshIcon';
+import { MessageInterface } from '@type/chat';
+
+const ChatContent = () => {
+ const [messages, inputRole, apiFree, apiKey, setMessages] = useStore(
+ (state) => [
+ state.messages,
+ state.inputRole,
+ state.apiFree,
+ state.apiKey,
+ state.setMessages,
+ ]
+ );
+
+ const handleSubmit = async () => {
+ const updatedMessages: MessageInterface[] = JSON.parse(
+ JSON.stringify(messages)
+ );
+ updatedMessages.push({ role: 'assistant', content: '' });
+ setMessages(updatedMessages);
+ let stream;
+
+ if (apiFree) {
+ stream = await getChatCompletionStreamFree(messages);
+ } else if (apiKey) {
+ stream = await getChatCompletionStreamCustom(apiKey, messages);
+ }
+
+ if (stream) {
+ const reader = stream.getReader();
+ let reading = true;
+ while (reading) {
+ const { done, value } = await reader.read();
+
+ const result = parseEventSource(new TextDecoder().decode(value));
+
+ if (result === '[DONE]' || done) {
+ reading = false;
+ } else {
+ const resultString = result.reduce((output: string, curr) => {
+ if (curr === '[DONE]') return output;
+ else {
+ const content = curr.choices[0].delta.content;
+ if (content) output += content;
+ return output;
+ }
+ }, '');
+ console.log(resultString);
+
+ const updatedMessages: MessageInterface[] = JSON.parse(
+ JSON.stringify(useStore.getState().messages)
+ );
+ updatedMessages[updatedMessages.length - 1].content += resultString;
+ setMessages(updatedMessages);
+ }
+ }
+ }
+ };
+
+ return (
+
+
+
+
+
+ {messages?.length === 0 &&
}
+ {messages?.map((message, index) => (
+ <>
+
+
+ >
+ ))}
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default ChatContent;
diff --git a/src/components/Chat/ChatContent/ChatTitle.tsx b/src/components/Chat/ChatContent/ChatTitle.tsx
new file mode 100644
index 0000000..7acab42
--- /dev/null
+++ b/src/components/Chat/ChatContent/ChatTitle.tsx
@@ -0,0 +1,11 @@
+import React from 'react';
+
+const ChatTitle = () => {
+ return (
+
+ Model: Default
+
+ );
+};
+
+export default ChatTitle;
diff --git a/src/components/Chat/ChatContent/Message/Avatar.tsx b/src/components/Chat/ChatContent/Message/Avatar.tsx
new file mode 100644
index 0000000..bf95c9f
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/Avatar.tsx
@@ -0,0 +1,62 @@
+import React from 'react';
+import { Role } from '@type/chat';
+import SettingIcon from '@icon/SettingIcon';
+import PersonIcon from '@icon/PersonIcon';
+
+const Avatar = ({ role }: { role: Role }) => {
+ return (
+
+ {role === 'user' &&
}
+ {role === 'assistant' &&
}
+ {role === 'system' &&
}
+
+ );
+};
+
+const UserAvatar = () => {
+ return (
+
+ );
+};
+
+const AssistantAvatar = () => {
+ return (
+
+ );
+};
+
+const SystemAvatar = () => {
+ return (
+
+
+
+ );
+};
+
+export default Avatar;
diff --git a/src/components/Chat/ChatContent/Message/Message.tsx b/src/components/Chat/ChatContent/Message/Message.tsx
new file mode 100644
index 0000000..a7937d9
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/Message.tsx
@@ -0,0 +1,50 @@
+import React from 'react';
+
+import Avatar from './Avatar';
+import MessageContent from './MessageContent';
+
+import { Role } from '@type/chat';
+import RoleSelector from './RoleSelector';
+
+const backgroundStyle: { [role in Role]: string } = {
+ user: 'dark:bg-gray-800',
+ assistant: 'bg-gray-50 dark:bg-[#444654]',
+ system: 'bg-gray-50 dark:bg-[#444654]',
+};
+
+const Message = ({
+ role,
+ content,
+ messageIndex,
+ sticky = false,
+}: {
+ role: Role;
+ content: string;
+ messageIndex: number;
+ sticky?: boolean;
+}) => {
+ return (
+
+ );
+};
+
+export default Message;
diff --git a/src/components/Chat/ChatContent/Message/MessageContent.tsx b/src/components/Chat/ChatContent/Message/MessageContent.tsx
new file mode 100644
index 0000000..3a2f1b5
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/MessageContent.tsx
@@ -0,0 +1,289 @@
+import React, { useState } from 'react';
+import ReactMarkdown from 'react-markdown';
+import hljs from 'highlight.js';
+import DOMPurify from 'dompurify';
+import useStore from '@store/store';
+
+import CopyIcon from '@icon/CopyIcon';
+import EditIcon2 from '@icon/EditIcon2';
+import DeleteIcon from '@icon/DeleteIcon';
+import TickIcon from '@icon/TickIcon';
+import CrossIcon from '@icon/CrossIcon';
+import DownChevronArrow from '@icon/DownChevronArrow';
+
+import { MessageInterface } from '@type/chat';
+
+const MessageContent = ({
+ content,
+ messageIndex,
+ sticky = false,
+}: {
+ content: string;
+ messageIndex: number;
+ sticky?: boolean;
+}) => {
+ const [isEdit, setIsEdit] = useState(sticky);
+
+ return (
+
+
+ {isEdit ? (
+
+ ) : (
+
+ )}
+
+ );
+};
+
+const ContentView = ({
+ content,
+ setIsEdit,
+ messageIndex,
+}: {
+ content: string;
+ setIsEdit: React.Dispatch>;
+ messageIndex: number;
+}) => {
+ const [isDelete, setIsDelete] = useState(false);
+ const [copied, setCopied] = useState(false);
+
+ const [messages, setMessages] = useStore((state) => [
+ state.messages,
+ state.setMessages,
+ ]);
+
+ const handleDelete = () => {
+ const updatedMessages = JSON.parse(JSON.stringify(messages));
+ updatedMessages.splice(messageIndex, 1);
+ setMessages(updatedMessages);
+ };
+
+ const handleMove = (direction: 'up' | 'down') => {
+ const updatedMessages = JSON.parse(JSON.stringify(messages));
+ const temp = updatedMessages[messageIndex];
+ if (direction === 'up') {
+ updatedMessages[messageIndex] = updatedMessages[messageIndex - 1];
+ updatedMessages[messageIndex - 1] = temp;
+ } else {
+ updatedMessages[messageIndex] = updatedMessages[messageIndex + 1];
+ updatedMessages[messageIndex + 1] = temp;
+ }
+ setMessages(updatedMessages);
+ };
+
+ return (
+ <>
+
+
+
+ {highlight.language}
+
+
+
+
+ );
+ },
+ }}
+ >
+ {content}
+
+
+
+ {isDelete || (
+ <>
+ {messageIndex !== 0 && (
+ handleMove('up')} />
+ )}
+ {messageIndex !== messages?.length - 1 && (
+ handleMove('down')} />
+ )}
+
+
+ >
+ )}
+ {isDelete && (
+ <>
+
+
+ >
+ )}
+
+ >
+ );
+};
+
+const MessageButton = ({
+ onClick,
+ icon,
+}: {
+ onClick: React.MouseEventHandler;
+ icon: React.ReactElement;
+}) => {
+ return (
+
+
+
+ );
+};
+
+const EditButton = ({
+ setIsEdit,
+}: {
+ setIsEdit: React.Dispatch>;
+}) => {
+ return } onClick={() => setIsEdit(true)} />;
+};
+
+const DeleteButton = ({
+ setIsDelete,
+}: {
+ setIsDelete: React.Dispatch>;
+}) => {
+ return (
+ } onClick={() => setIsDelete(true)} />
+ );
+};
+
+const DownButton = ({
+ onClick,
+}: {
+ onClick: React.MouseEventHandler;
+}) => {
+ return } onClick={onClick} />;
+};
+
+const UpButton = ({
+ onClick,
+}: {
+ onClick: React.MouseEventHandler;
+}) => {
+ return (
+ }
+ onClick={onClick}
+ />
+ );
+};
+
+const EditView = ({
+ content,
+ setIsEdit,
+ messageIndex,
+ sticky,
+}: {
+ content: string;
+ setIsEdit: React.Dispatch>;
+ messageIndex: number;
+ sticky?: boolean;
+}) => {
+ const [messages, setMessages, inputRole] = useStore((state) => [
+ state.messages,
+ state.setMessages,
+ state.inputRole,
+ ]);
+
+ const [_content, _setContent] = useState(content);
+
+ return (
+ <>
+
+
+
+ {sticky || (
+
+ )}
+
+ >
+ );
+};
+
+export default MessageContent;
diff --git a/src/components/Chat/ChatContent/Message/NewMessageButton.tsx b/src/components/Chat/ChatContent/Message/NewMessageButton.tsx
new file mode 100644
index 0000000..a6fa240
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/NewMessageButton.tsx
@@ -0,0 +1,66 @@
+import React from 'react';
+import useStore from '@store/store';
+
+import PlusIcon from '@icon/PlusIcon';
+
+import { ChatInterface, MessageInterface } from '@type/chat';
+import { defaultSystemMessage } from '@constants/chat';
+
+const NewMessageButton = ({ messageIndex }: { messageIndex: number }) => {
+ const [
+ messages,
+ chats,
+ setMessages,
+ currentChatIndex,
+ setChats,
+ setCurrentChatIndex,
+ ] = useStore((state) => [
+ state.messages,
+ state.chats,
+ state.setMessages,
+ state.currentChatIndex,
+ state.setChats,
+ state.setCurrentChatIndex,
+ ]);
+
+ const addChat = () => {
+ if (chats) {
+ const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
+ updatedChats.unshift({
+ title: `Chat ${Math.random()}`,
+ messages: [{ role: 'system', content: defaultSystemMessage }],
+ });
+ setChats(updatedChats);
+ setMessages(updatedChats[0].messages);
+ setCurrentChatIndex(0);
+ }
+ };
+
+ const addMessage = () => {
+ if (currentChatIndex === -1) {
+ addChat();
+ } else {
+ const updatedMessages: MessageInterface[] = JSON.parse(
+ JSON.stringify(messages)
+ );
+ updatedMessages.splice(messageIndex + 1, 0, {
+ content: '',
+ role: 'user',
+ });
+ setMessages(updatedMessages);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default NewMessageButton;
diff --git a/src/components/Chat/ChatContent/Message/RoleSelector.tsx b/src/components/Chat/ChatContent/Message/RoleSelector.tsx
new file mode 100644
index 0000000..ad445cd
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/RoleSelector.tsx
@@ -0,0 +1,70 @@
+import React, { useState } from 'react';
+import useStore from '@store/store';
+
+import DownChevronArrow from '@icon/DownChevronArrow';
+import { MessageInterface, Role, roles } from '@type/chat';
+
+const RoleSelector = ({
+ role,
+ messageIndex,
+ sticky,
+}: {
+ role: Role;
+ messageIndex: number;
+ sticky?: boolean;
+}) => {
+ const [messages, setMessages, setInputRole] = useStore((state) => [
+ state.messages,
+ state.setMessages,
+ state.setInputRole,
+ ]);
+
+ const [dropDown, setDropDown] = useState(false);
+
+ return (
+
+
+
+
+ {roles.map((r) => (
+ - {
+ if (!sticky) {
+ const updatedMessages: MessageInterface[] = JSON.parse(
+ JSON.stringify(messages)
+ );
+ updatedMessages[messageIndex].role = r;
+ setMessages(updatedMessages);
+ } else {
+ setInputRole(r);
+ }
+ setDropDown(false);
+ }}
+ key={r}
+ >
+ {r.charAt(0).toUpperCase() + r.slice(1)}
+
+ ))}
+
+
+
+ );
+};
+
+export default RoleSelector;
diff --git a/src/components/Chat/ChatContent/Message/index.ts b/src/components/Chat/ChatContent/Message/index.ts
new file mode 100644
index 0000000..a8132ba
--- /dev/null
+++ b/src/components/Chat/ChatContent/Message/index.ts
@@ -0,0 +1 @@
+export { default } from './Message';
diff --git a/src/components/Chat/ChatContent/ScrollToBottomButton.tsx b/src/components/Chat/ChatContent/ScrollToBottomButton.tsx
new file mode 100644
index 0000000..0318c03
--- /dev/null
+++ b/src/components/Chat/ChatContent/ScrollToBottomButton.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import { useScrollToBottom } from 'react-scroll-to-bottom';
+
+import DownArrow from '@icon/DownArrow';
+
+const ScrollToBottomButton = () => {
+ const scrollToBottom = useScrollToBottom();
+ return (
+
+ );
+};
+
+export default ScrollToBottomButton;
diff --git a/src/components/Chat/ChatContent/index.ts b/src/components/Chat/ChatContent/index.ts
new file mode 100644
index 0000000..7e8f774
--- /dev/null
+++ b/src/components/Chat/ChatContent/index.ts
@@ -0,0 +1 @@
+export { default } from './ChatContent';
diff --git a/src/components/Chat/ChatInput.tsx b/src/components/Chat/ChatInput.tsx
new file mode 100644
index 0000000..9edc276
--- /dev/null
+++ b/src/components/Chat/ChatInput.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import RefreshIcon from '@icon/RefreshIcon';
+import SendIcon from '@icon/SendIcon';
+
+const ChatInput = () => {
+ return (
+
+ );
+};
+
+const TextField = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default ChatInput;
diff --git a/src/components/Chat/index.ts b/src/components/Chat/index.ts
new file mode 100644
index 0000000..654497b
--- /dev/null
+++ b/src/components/Chat/index.ts
@@ -0,0 +1 @@
+export { default } from './Chat';
diff --git a/src/components/ConfigMenu/ConfigMenu.tsx b/src/components/ConfigMenu/ConfigMenu.tsx
new file mode 100644
index 0000000..9bd0d2f
--- /dev/null
+++ b/src/components/ConfigMenu/ConfigMenu.tsx
@@ -0,0 +1,141 @@
+import React, { useState } from 'react';
+import useStore from '@store/store';
+
+import CrossIcon2 from '@icon/CrossIcon2';
+import { validateApiKey } from '@api/customApi';
+
+const ConfigMenu = () => {
+ const [apiKey, setApiKey, apiFree, setApiFree, openConfig, setOpenConfig] =
+ useStore((state) => [
+ state.apiKey,
+ state.setApiKey,
+ state.apiFree,
+ state.setApiFree,
+ state.openConfig,
+ state.setOpenConfig,
+ ]);
+
+ const [_apiKey, _setApiKey] = useState(apiKey || '');
+ const [error, setError] = useState(false);
+
+ const handleSave = async () => {
+ if (apiFree === true) {
+ setOpenConfig(false);
+ } else {
+ const valid = await validateApiKey(_apiKey);
+
+ if (valid) {
+ setApiKey(_apiKey);
+ localStorage.setItem('apiKey', _apiKey);
+ setError(false);
+ setOpenConfig(false);
+ } else {
+ setError(true);
+ setTimeout(() => {
+ setError(false);
+ }, 3000);
+ }
+ }
+ };
+
+ const handleClose = () => {
+ setOpenConfig(false);
+ };
+
+ return openConfig ? (
+
+
+
+
+
+ Config
+
+
+
+
+
+
setApiFree(true)}
+ />
+
+
+
+
+ setApiFree(false)}
+ />
+
+
+
+ {apiFree === false && (
+ <>
+
+
+ API Key
+
+
{
+ _setApiKey(e.target.value);
+ }}
+ />
+
+ {error && (
+
+ Invalid API key!
+
+ )}
+ >
+ )}
+
+
+
+
+
+
+
+
+
+ ) : (
+ <>>
+ );
+};
+
+export default ConfigMenu;
diff --git a/src/components/ConfigMenu/index.ts b/src/components/ConfigMenu/index.ts
new file mode 100644
index 0000000..6497639
--- /dev/null
+++ b/src/components/ConfigMenu/index.ts
@@ -0,0 +1 @@
+export { default } from './ConfigMenu';
diff --git a/src/components/Menu/ChatHistoryList.tsx b/src/components/Menu/ChatHistoryList.tsx
new file mode 100644
index 0000000..1202fe5
--- /dev/null
+++ b/src/components/Menu/ChatHistoryList.tsx
@@ -0,0 +1,164 @@
+import React, { MouseEventHandler, useEffect, useState } from 'react';
+import useStore from '@store/store';
+
+import ChatIcon from '@icon/ChatIcon';
+import EditIcon from '@icon/EditIcon';
+import DeleteIcon from '@icon/DeleteIcon';
+import TickIcon from '@icon/TickIcon';
+import CrossIcon from '@icon/CrossIcon';
+
+const ChatHistoryList = () => {
+ const [chats, setCurrentChatIndex, setMessages] = useStore((state) => [
+ state.chats,
+ state.setCurrentChatIndex,
+ state.setMessages,
+ ]);
+
+ return (
+
+
+ {chats &&
+ chats.map((chat, index) => (
+ {
+ setCurrentChatIndex(index);
+ setMessages(chats[index].messages);
+ }}
+ />
+ ))}
+ {/* */}
+
+
+ );
+};
+
+const ShowMoreButton = () => {
+ return (
+
+ );
+};
+
+const ChatHistoryClass = {
+ normal:
+ 'flex py-3 px-3 items-center gap-3 relative rounded-md hover:bg-[#2A2B32] cursor-pointer break-all hover:pr-4 group',
+ active:
+ 'flex py-3 px-3 items-center gap-3 relative rounded-md cursor-pointer break-all pr-14 bg-gray-800 hover:bg-gray-800 group',
+ normalGradient:
+ 'absolute inset-y-0 right-0 w-8 z-10 bg-gradient-to-l from-gray-900 group-hover:from-[#2A2B32]',
+ activeGradient:
+ 'absolute inset-y-0 right-0 w-8 z-10 bg-gradient-to-l from-gray-800',
+};
+
+const ChatHistory = ({
+ title,
+ chatIndex,
+ onClick,
+}: {
+ title: string;
+ chatIndex: number;
+ onClick?: React.MouseEventHandler;
+}) => {
+ const [chats, setChats, currentChatIndex, setMessages, setCurrentChatIndex] =
+ useStore((state) => [
+ state.chats,
+ state.setChats,
+ state.currentChatIndex,
+ state.setMessages,
+ state.setCurrentChatIndex,
+ ]);
+
+ const [isDelete, setIsDelete] = useState(false);
+ const [isEdit, setIsEdit] = useState(false);
+ const [_title, _setTitle] = useState(title);
+
+ const active = currentChatIndex === chatIndex;
+
+ const handleTick = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ const updatedChats = JSON.parse(JSON.stringify(chats));
+ if (isEdit) {
+ updatedChats[chatIndex].title = _title;
+ setIsEdit(false);
+ } else if (isDelete) {
+ updatedChats.splice(chatIndex, 1);
+ setCurrentChatIndex(-1);
+ setMessages([]);
+ setIsDelete(false);
+ }
+ setTimeout(() => {
+ setChats(updatedChats);
+ }, 0);
+ };
+
+ const handleCross = () => {
+ setIsDelete(false);
+ setIsEdit(false);
+ };
+
+ return (
+ onClick && onClick(e)}
+ >
+
+
+ {isEdit ? (
+
{
+ _setTitle(e.target.value);
+ }}
+ />
+ ) : (
+ _title
+ )}
+
+
+
+ {active && (
+
+ {isDelete || isEdit ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+ )}
+
+ );
+};
+
+export default ChatHistoryList;
diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx
new file mode 100644
index 0000000..301cdd8
--- /dev/null
+++ b/src/components/Menu/Menu.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+
+import NewChat from './NewChat';
+import ChatHistoryList from './ChatHistoryList';
+import MenuOptions from './MenuOptions';
+import CrossIcon2 from '@icon/CrossIcon2';
+
+const Menu = () => {
+ return (
+
+ );
+};
+
+export default Menu;
diff --git a/src/components/Menu/MenuOptions/Account.tsx b/src/components/Menu/MenuOptions/Account.tsx
new file mode 100644
index 0000000..481eee4
--- /dev/null
+++ b/src/components/Menu/MenuOptions/Account.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import PersonIcon from '@icon/PersonIcon';
+
+const Account = () => {
+ return (
+
+
+ My account
+
+ );
+};
+
+export default Account;
diff --git a/src/components/Menu/MenuOptions/ClearConversation.tsx b/src/components/Menu/MenuOptions/ClearConversation.tsx
new file mode 100644
index 0000000..9c054e1
--- /dev/null
+++ b/src/components/Menu/MenuOptions/ClearConversation.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+
+import DeleteIcon from '@icon/DeleteIcon';
+
+const ClearConversation = () => {
+ return (
+
+
+ Clear conversations
+
+ );
+};
+
+export default ClearConversation;
diff --git a/src/components/Menu/MenuOptions/Config.tsx b/src/components/Menu/MenuOptions/Config.tsx
new file mode 100644
index 0000000..4dd7d3e
--- /dev/null
+++ b/src/components/Menu/MenuOptions/Config.tsx
@@ -0,0 +1,23 @@
+import React, { useState } from 'react';
+import useStore from '@store/store';
+
+import PersonIcon from '@icon/PersonIcon';
+
+const Config = () => {
+ const [apiFree, setOpenConfig] = useStore((state) => [
+ state.apiFree,
+ state.setOpenConfig,
+ ]);
+
+ return (
+ setOpenConfig(true)}
+ >
+
+ API: {apiFree ? 'Free' : 'Personal'}
+
+ );
+};
+
+export default Config;
diff --git a/src/components/Menu/MenuOptions/Logout.tsx b/src/components/Menu/MenuOptions/Logout.tsx
new file mode 100644
index 0000000..6d68408
--- /dev/null
+++ b/src/components/Menu/MenuOptions/Logout.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import LogoutIcon from '@icon/LogoutIcon';
+
+const Logout = () => {
+ return (
+
+
+ Log out
+
+ );
+};
+
+export default Logout;
diff --git a/src/components/Menu/MenuOptions/Me.tsx b/src/components/Menu/MenuOptions/Me.tsx
new file mode 100644
index 0000000..e3796d5
--- /dev/null
+++ b/src/components/Menu/MenuOptions/Me.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+
+import HeartIcon from '@icon/HeartIcon';
+
+const Me = () => {
+ return (
+
+
+ Made by Jing Hua
+
+ );
+};
+
+export default Me;
diff --git a/src/components/Menu/MenuOptions/MenuOptions.tsx b/src/components/Menu/MenuOptions/MenuOptions.tsx
new file mode 100644
index 0000000..72d83e4
--- /dev/null
+++ b/src/components/Menu/MenuOptions/MenuOptions.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+
+import Account from './Account';
+import ClearConversation from './ClearConversation';
+import Config from './Config';
+import Logout from './Logout';
+import Me from './Me';
+import ThemeSwitcher from './ThemeSwitcher';
+import Updates from './Updates';
+
+const MenuOptions = () => {
+ return (
+ <>
+ {/* */}
+
+
+ {/* */}
+
+
+ {/* */}
+ >
+ );
+};
+
+export default MenuOptions;
diff --git a/src/components/Menu/MenuOptions/ThemeSwitcher.tsx b/src/components/Menu/MenuOptions/ThemeSwitcher.tsx
new file mode 100644
index 0000000..67372d1
--- /dev/null
+++ b/src/components/Menu/MenuOptions/ThemeSwitcher.tsx
@@ -0,0 +1,38 @@
+import React, { useEffect, useState } from 'react';
+import SunIcon from '@icon/SunIcon';
+import MoonIcon from '@icon/MoonIcon';
+
+type Theme = 'light' | 'dark';
+
+const getOppositeTheme = (theme: Theme): Theme => {
+ if (theme === 'dark') {
+ return 'light';
+ } else {
+ return 'dark';
+ }
+};
+const ThemeSwitcher = () => {
+ const [theme, setTheme] = useState('dark');
+
+ const switchTheme = () => {
+ setTheme(getOppositeTheme(theme));
+ };
+
+ useEffect(() => {
+ document.documentElement.className = theme;
+ }, [theme]);
+
+ return (
+
+ {theme === 'dark' ? : }
+ {getOppositeTheme(theme).charAt(0).toUpperCase() +
+ getOppositeTheme(theme).slice(1)}{' '}
+ mode
+
+ );
+};
+
+export default ThemeSwitcher;
diff --git a/src/components/Menu/MenuOptions/Updates.tsx b/src/components/Menu/MenuOptions/Updates.tsx
new file mode 100644
index 0000000..c4e1bb6
--- /dev/null
+++ b/src/components/Menu/MenuOptions/Updates.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+import LinkIcon from '@icon/LinkIcon';
+
+const Updates = () => {
+ return (
+
+
+ Source Code
+
+ );
+};
+
+export default Updates;
diff --git a/src/components/Menu/MenuOptions/index.ts b/src/components/Menu/MenuOptions/index.ts
new file mode 100644
index 0000000..99449e8
--- /dev/null
+++ b/src/components/Menu/MenuOptions/index.ts
@@ -0,0 +1 @@
+export { default } from './MenuOptions';
diff --git a/src/components/Menu/NewChat.tsx b/src/components/Menu/NewChat.tsx
new file mode 100644
index 0000000..40774b8
--- /dev/null
+++ b/src/components/Menu/NewChat.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import useStore from '@store/store';
+
+import PlusIcon from '@icon/PlusIcon';
+
+import { ChatInterface } from '@type/chat';
+import { defaultSystemMessage } from '@constants/chat';
+
+const NewChat = () => {
+ const [chats, setChats, setCurrentChatIndex, setMessages] = useStore(
+ (state) => [
+ state.chats,
+ state.setChats,
+ state.setCurrentChatIndex,
+ state.setMessages,
+ ]
+ );
+
+ const addChat = () => {
+ if (chats) {
+ const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
+ updatedChats.unshift({
+ title: `Chat ${Math.random()}`,
+ messages: [{ role: 'system', content: defaultSystemMessage }],
+ });
+ setChats(updatedChats);
+ setMessages(updatedChats[0].messages);
+ setCurrentChatIndex(0);
+ }
+ };
+
+ return (
+
+ {' '}
+ New chat
+
+ );
+};
+
+export default NewChat;
diff --git a/src/components/Menu/index.ts b/src/components/Menu/index.ts
new file mode 100644
index 0000000..a6de24c
--- /dev/null
+++ b/src/components/Menu/index.ts
@@ -0,0 +1 @@
+export { default } from './Menu';
diff --git a/src/components/MobileBar/MobileBar.tsx b/src/components/MobileBar/MobileBar.tsx
new file mode 100644
index 0000000..d524ee1
--- /dev/null
+++ b/src/components/MobileBar/MobileBar.tsx
@@ -0,0 +1,53 @@
+import React from 'react';
+
+import useStore from '@store/store';
+
+import NewChat from '../Menu/NewChat';
+
+const MobileBar = () => {
+ const [chats, currentChatIndex] = useStore((state) => [
+ state.chats,
+ state.currentChatIndex,
+ ]);
+
+ return (
+
+
+
+ {chats && chats.length > 0
+ ? chats[currentChatIndex]?.title
+ : 'New Chat'}
+
+
+
+ );
+};
+
+export default MobileBar;
diff --git a/src/components/MobileBar/index.ts b/src/components/MobileBar/index.ts
new file mode 100644
index 0000000..73bbfef
--- /dev/null
+++ b/src/components/MobileBar/index.ts
@@ -0,0 +1 @@
+export { default } from './MobileBar';
diff --git a/src/constants/chat.ts b/src/constants/chat.ts
new file mode 100644
index 0000000..82f6570
--- /dev/null
+++ b/src/constants/chat.ts
@@ -0,0 +1,12 @@
+const date = new Date();
+const dateString =
+ date.getFullYear() +
+ '-' +
+ ('0' + (date.getMonth() + 1)).slice(-2) +
+ '-' +
+ ('0' + date.getDate()).slice(-2);
+
+// default system message obtained using the following method: https://twitter.com/DeminDimin/status/1619935545144279040
+export const defaultSystemMessage = `You are ChatGPT, a large language model trained by OpenAI.
+Knowledge cutoff: 2021-09
+Current date: ${dateString}`;
diff --git a/src/hooks/useSaveToLocalStorage.ts b/src/hooks/useSaveToLocalStorage.ts
new file mode 100644
index 0000000..ee98b41
--- /dev/null
+++ b/src/hooks/useSaveToLocalStorage.ts
@@ -0,0 +1,12 @@
+import React, { useEffect } from 'react';
+import useStore from '@store/store';
+
+const useSaveToLocalStorage = () => {
+ const chats = useStore((state) => state.chats);
+
+ useEffect(() => {
+ if (chats) localStorage.setItem('chats', JSON.stringify(chats));
+ }, [chats]);
+};
+
+export default useSaveToLocalStorage;
diff --git a/src/hooks/useUpdateChats.ts b/src/hooks/useUpdateChats.ts
new file mode 100644
index 0000000..6b9023e
--- /dev/null
+++ b/src/hooks/useUpdateChats.ts
@@ -0,0 +1,25 @@
+import React, { useEffect } from 'react';
+import useStore from '@store/store';
+import { ChatInterface, MessageInterface } from '@type/chat';
+
+const useUpdateCharts = () => {
+ const [chats, messages, setChats, currentChatIndex] = useStore((state) => [
+ state.chats,
+ state.messages,
+ state.setChats,
+ state.currentChatIndex,
+ ]);
+
+ useEffect(() => {
+ if (currentChatIndex !== -1 && chats && chats.length > 0) {
+ const updatedChats: ChatInterface[] = JSON.parse(JSON.stringify(chats));
+ const updatedMessages: MessageInterface[] = JSON.parse(
+ JSON.stringify(messages)
+ );
+ updatedChats[currentChatIndex].messages = updatedMessages;
+ setChats(updatedChats);
+ }
+ }, [messages]);
+};
+
+export default useUpdateCharts;
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index b5c61c9..0000000
--- a/src/index.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/src/main.css b/src/main.css
new file mode 100644
index 0000000..ed51e17
--- /dev/null
+++ b/src/main.css
@@ -0,0 +1,207 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ * {
+ box-sizing: border-box;
+ }
+
+ body,
+ html {
+ height: 100%;
+ }
+
+ body {
+ line-height: inherit;
+ margin: 0;
+ }
+
+ .dark body,
+ .dark html {
+ --tw-bg-opacity: 1;
+ background-color: rgba(52, 53, 65, var(--tw-bg-opacity));
+ }
+
+ #root {
+ height: 100%;
+ }
+
+ ::-webkit-scrollbar {
+ height: 1rem;
+ width: 0.5rem;
+ }
+ @media screen and (min-width: 768px) {
+ .scrollbar-trigger ::-webkit-scrollbar-thumb {
+ visibility: hidden;
+ }
+ }
+
+ .dark::-webkit-scrollbar-thumb {
+ --tw-bg-opacity: 1;
+ background-color: rgba(86, 88, 105, var(--tw-bg-opacity));
+ }
+
+ ::-webkit-scrollbar-thumb {
+ --tw-border-opacity: 1;
+ background-color: rgba(217, 217, 227, 0.8);
+ border-color: rgba(255, 255, 255, var(--tw-border-opacity));
+ border-radius: 9999px;
+ border-width: 1px;
+ }
+
+ ::-webkit-scrollbar-track {
+ background-color: transparent;
+ border-radius: 9999px;
+ }
+
+ textarea:focus {
+ outline: none;
+ }
+}
+
+@layer components {
+ .btn {
+ align-items: center;
+ border-color: transparent;
+ border-radius: 0.25rem;
+ border-width: 1px;
+ display: inline-flex;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ padding: 0.5rem 0.75rem;
+ pointer-events: auto;
+ }
+
+ .btn-neutral {
+ --tw-bg-opacity: 1;
+ --tw-text-opacity: 1;
+ background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
+ border-color: rgba(0, 0, 0, 0.1);
+ border-width: 1px;
+ color: rgba(64, 65, 79, var(--tw-text-opacity));
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ }
+
+ .btn-neutral:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgba(236, 236, 241, var(--tw-bg-opacity));
+ }
+
+ .dark .btn-neutral {
+ --tw-border-opacity: 1;
+ --tw-bg-opacity: 1;
+ --tw-text-opacity: 1;
+ background-color: rgba(52, 53, 65, var(--tw-bg-opacity));
+ border-color: rgba(86, 88, 105, var(--tw-border-opacity));
+ color: rgba(217, 217, 227, var(--tw-text-opacity));
+ }
+
+ .dark .btn-neutral:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgba(64, 65, 79, var(--tw-bg-opacity));
+ }
+
+ .btn-dark {
+ --tw-border-opacity: 1;
+ --tw-bg-opacity: 1;
+ --tw-text-opacity: 1;
+ background-color: rgba(52, 53, 65, var(--tw-bg-opacity));
+ border-color: rgba(86, 88, 105, var(--tw-border-opacity));
+ border-width: 1px;
+ color: rgba(255, 255, 255, var(--tw-text-opacity));
+ }
+
+ .btn-primary {
+ --tw-bg-opacity: 1;
+ --tw-text-opacity: 1;
+ background-color: rgba(16, 163, 127, var(--tw-bg-opacity));
+ color: rgba(255, 255, 255, var(--tw-text-opacity));
+ }
+
+ .btn-primary:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgba(26, 127, 100, var(--tw-bg-opacity));
+ }
+
+ .btn-small {
+ padding: 0.25rem 0.5rem;
+ }
+
+ button.scroll-convo {
+ display: none;
+ }
+
+ .markdown ol,
+ .markdown ul {
+ display: flex;
+ flex-direction: column;
+ padding-left: 1rem;
+ }
+
+ .markdown ol li,
+ .markdown ol li > p,
+ .markdown ol ol,
+ .markdown ol ul,
+ .markdown ul li,
+ .markdown ul li > p,
+ .markdown ul ol,
+ .markdown ul ul {
+ margin: 0;
+ }
+
+ .markdown ul li:before {
+ content: '•';
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ margin-left: -1rem;
+ position: absolute;
+ }
+}
+
+:not(pre) > code.hljs,
+:not(pre) > code[class*='language-'] {
+ border-radius: 0.3em;
+ white-space: normal;
+}
+.hljs-comment {
+ color: hsla(0, 0%, 100%, 0.5);
+}
+.hljs-meta {
+ color: hsla(0, 0%, 100%, 0.6);
+}
+.hljs-built_in,
+.hljs-class .hljs-title {
+ color: #e9950c;
+}
+.hljs-doctag,
+.hljs-formula,
+.hljs-keyword,
+.hljs-literal {
+ color: #2e95d3;
+}
+.hljs-addition,
+.hljs-attribute,
+.hljs-meta-string,
+.hljs-regexp,
+.hljs-string {
+ color: #00a67d;
+}
+.hljs-attr,
+.hljs-number,
+.hljs-selector-attr,
+.hljs-selector-class,
+.hljs-selector-pseudo,
+.hljs-template-variable,
+.hljs-type,
+.hljs-variable {
+ color: #df3079;
+}
+.hljs-bullet,
+.hljs-link,
+.hljs-selector-id,
+.hljs-symbol,
+.hljs-title {
+ color: #f22c3d;
+}
diff --git a/src/main.tsx b/src/main.tsx
index a2bf01b..f4721f7 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
-import './index.css';
+import './main.css';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
diff --git a/src/store/auth-slice.ts b/src/store/auth-slice.ts
new file mode 100644
index 0000000..994cd59
--- /dev/null
+++ b/src/store/auth-slice.ts
@@ -0,0 +1,24 @@
+import { StoreSlice } from './store';
+
+export interface AuthSlice {
+ apiKey?: string;
+ apiFree: boolean;
+ setApiKey: (apiKey: string) => void;
+ setApiFree: (apiFree: boolean) => void;
+}
+
+export const createAuthSlice: StoreSlice = (set, get) => ({
+ apiFree: true,
+ setApiKey: (apiKey: string) => {
+ set((prev: AuthSlice) => ({
+ ...prev,
+ apiKey: apiKey,
+ }));
+ },
+ setApiFree: (apiFree: boolean) => {
+ set((prev: AuthSlice) => ({
+ ...prev,
+ apiFree: apiFree,
+ }));
+ },
+});
diff --git a/src/store/chat-slice.ts b/src/store/chat-slice.ts
new file mode 100644
index 0000000..3610a4b
--- /dev/null
+++ b/src/store/chat-slice.ts
@@ -0,0 +1,34 @@
+import { StoreSlice } from './store';
+import { ChatInterface, MessageInterface } from '@type/chat';
+
+export interface ChatSlice {
+ messages: MessageInterface[];
+ chats?: ChatInterface[];
+ currentChatIndex: number;
+ setMessages: (messages: MessageInterface[]) => void;
+ setChats: (chats: ChatInterface[]) => void;
+ setCurrentChatIndex: (currentChatIndex: number) => void;
+}
+
+export const createChatSlice: StoreSlice = (set, get) => ({
+ messages: [],
+ currentChatIndex: -1,
+ setMessages: (messages: MessageInterface[]) => {
+ set((prev: ChatSlice) => ({
+ ...prev,
+ messages: messages,
+ }));
+ },
+ setChats: (chats: ChatInterface[]) => {
+ set((prev: ChatSlice) => ({
+ ...prev,
+ chats: chats,
+ }));
+ },
+ setCurrentChatIndex: (currentChatIndex: number) => {
+ set((prev: ChatSlice) => ({
+ ...prev,
+ currentChatIndex: currentChatIndex,
+ }));
+ },
+});
diff --git a/src/store/config-slice.ts b/src/store/config-slice.ts
new file mode 100644
index 0000000..4103f9e
--- /dev/null
+++ b/src/store/config-slice.ts
@@ -0,0 +1,16 @@
+import { StoreSlice } from './store';
+
+export interface ConfigSlice {
+ openConfig: boolean;
+ setOpenConfig: (openConfig: boolean) => void;
+}
+
+export const createConfigSlice: StoreSlice = (set, get) => ({
+ openConfig: false,
+ setOpenConfig: (openConfig: boolean) => {
+ set((prev: ConfigSlice) => ({
+ ...prev,
+ openConfig: openConfig,
+ }));
+ },
+});
diff --git a/src/store/input-slice.ts b/src/store/input-slice.ts
new file mode 100644
index 0000000..6741910
--- /dev/null
+++ b/src/store/input-slice.ts
@@ -0,0 +1,17 @@
+import { StoreSlice } from './store';
+import { Role } from '@type/chat';
+
+export interface InputSlice {
+ inputRole: Role;
+ setInputRole: (inputRole: Role) => void;
+}
+
+export const createInputSlice: StoreSlice = (set, get) => ({
+ inputRole: 'user',
+ setInputRole: (inputRole: Role) => {
+ set((prev: InputSlice) => ({
+ ...prev,
+ inputRole: inputRole,
+ }));
+ },
+});
diff --git a/src/store/store.ts b/src/store/store.ts
new file mode 100644
index 0000000..b816643
--- /dev/null
+++ b/src/store/store.ts
@@ -0,0 +1,21 @@
+import create, { SetState, GetState } from 'zustand';
+import { ChatSlice, createChatSlice } from './chat-slice';
+import { InputSlice, createInputSlice } from './input-slice';
+import { AuthSlice, createAuthSlice } from './auth-slice';
+import { ConfigSlice, createConfigSlice } from './config-slice';
+
+export type StoreState = ChatSlice & InputSlice & AuthSlice & ConfigSlice;
+
+export type StoreSlice = (
+ set: SetState,
+ get: GetState
+) => T;
+
+const useStore = create((set, get) => ({
+ ...createChatSlice(set, get),
+ ...createInputSlice(set, get),
+ ...createAuthSlice(set, get),
+ ...createConfigSlice(set, get),
+}));
+
+export default useStore;
diff --git a/src/types/api.ts b/src/types/api.ts
new file mode 100644
index 0000000..54fa696
--- /dev/null
+++ b/src/types/api.ts
@@ -0,0 +1,18 @@
+export interface EventSourceDataInterface {
+ choices: EventSourceDataChoices[];
+ created: number;
+ id: string;
+ model: string;
+ object: string;
+}
+
+export type EventSourceData = EventSourceDataInterface | '[DONE]';
+
+export interface EventSourceDataChoices {
+ delta: {
+ content?: string;
+ role?: string;
+ };
+ finish_reason?: string;
+ index: number;
+}
diff --git a/src/types/chat.ts b/src/types/chat.ts
new file mode 100644
index 0000000..651020e
--- /dev/null
+++ b/src/types/chat.ts
@@ -0,0 +1,12 @@
+export type Role = 'user' | 'assistant' | 'system';
+export const roles: Role[] = ['user', 'assistant', 'system'];
+
+export interface MessageInterface {
+ role: Role;
+ content: string;
+}
+
+export interface ChatInterface {
+ title: string;
+ messages: MessageInterface[];
+}
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index 62c6d9c..54bacb7 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -2,7 +2,40 @@
module.exports = {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
- extend: {},
+ fontFamily: {
+ sans: [
+ 'Söhne',
+ 'ui-sans-serif',
+ 'system-ui',
+ '-apple-system',
+ 'Segoe UI',
+ 'Roboto',
+ 'Ubuntu',
+ 'Cantarell',
+ 'Noto Sans',
+ 'sans-serif',
+ 'Helvetica Neue',
+ 'Arial',
+ 'Apple Color Emoji',
+ 'Segoe UI Emoji',
+ 'Segoe UI Symbol',
+ 'Noto Color Emoji',
+ ],
+ mono: ['Söhne Mono', 'Monaco', 'Andale Mono', 'Ubuntu Mono', 'monospace'],
+ },
+ extend: {
+ typography: {
+ DEFAULT: {
+ css: {
+ pre: { padding: 0, margin: 0 },
+ ul: {
+ 'list-style-type': 'none',
+ },
+ },
+ },
+ },
+ },
},
- plugins: [],
+ plugins: [require('@tailwindcss/typography')],
+ darkMode: 'class',
};
diff --git a/tsconfig.json b/tsconfig.json
index 3d0a51a..8e3a564 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -14,7 +14,16 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
- "jsx": "react-jsx"
+ "jsx": "react-jsx",
+ "baseUrl": ".",
+ "paths": {
+ "@icon/*": ["./src/assets/icons/*"],
+ "@type/*": ["./src/types/*"],
+ "@store/*": ["./src/store/*"],
+ "@hooks/*": ["./src/hooks/*"],
+ "@constants/*": ["./src/constants/*"],
+ "@api/*": ["./src/api/*"]
+ }
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
diff --git a/vite.config.ts b/vite.config.ts
index 861b04b..6741cd2 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,17 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react-swc'
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react-swc';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
-})
+ resolve: {
+ alias: {
+ '@icon/': new URL('./src/assets/icons/', import.meta.url).pathname,
+ '@type/': new URL('./src/types/', import.meta.url).pathname,
+ '@store/': new URL('./src/store/', import.meta.url).pathname,
+ '@hooks/': new URL('./src/hooks/', import.meta.url).pathname,
+ '@constants/': new URL('./src/constants/', import.meta.url).pathname,
+ '@api/': new URL('./src/api/', import.meta.url).pathname,
+ },
+ },
+});
diff --git a/yarn.lock b/yarn.lock
index 0133387..de2ec30 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,143 @@
# yarn lockfile v1
+"@babel/code-frame@^7.0.0":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
+ integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
+ dependencies:
+ "@babel/highlight" "^7.18.6"
+
+"@babel/helper-module-imports@^7.16.7":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
+ integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.19.4":
+ version "7.19.4"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
+ integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
+
+"@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-corejs3@^7.15.4":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz#6e4939d9d9789ff63e2dc58e88f13a3913a24eba"
+ integrity sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==
+ dependencies:
+ core-js-pure "^3.25.1"
+ regenerator-runtime "^0.13.11"
+
+"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
+ integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
+ dependencies:
+ regenerator-runtime "^0.13.11"
+
+"@babel/types@^7.18.6":
+ version "7.21.2"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.2.tgz#92246f6e00f91755893c2876ad653db70c8310d1"
+ integrity sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==
+ dependencies:
+ "@babel/helper-string-parser" "^7.19.4"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
+"@emotion/babel-plugin@^11.0.0":
+ version "11.10.6"
+ resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead"
+ integrity sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.16.7"
+ "@babel/runtime" "^7.18.3"
+ "@emotion/hash" "^0.9.0"
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/serialize" "^1.1.1"
+ babel-plugin-macros "^3.1.0"
+ convert-source-map "^1.5.0"
+ escape-string-regexp "^4.0.0"
+ find-root "^1.1.0"
+ source-map "^0.5.7"
+ stylis "4.1.3"
+
+"@emotion/cache@^11.1.3":
+ version "11.10.5"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12"
+ integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==
+ dependencies:
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/sheet" "^1.2.1"
+ "@emotion/utils" "^1.2.0"
+ "@emotion/weak-memoize" "^0.3.0"
+ stylis "4.1.3"
+
+"@emotion/css@11.1.3":
+ version "11.1.3"
+ resolved "https://registry.yarnpkg.com/@emotion/css/-/css-11.1.3.tgz#9ed44478b19e5d281ccbbd46d74d123d59be793f"
+ integrity sha512-RSQP59qtCNTf5NWD6xM08xsQdCZmVYnX/panPYvB6LQAPKQB6GL49Njf0EMbS3CyDtrlWsBcmqBtysFvfWT3rA==
+ dependencies:
+ "@emotion/babel-plugin" "^11.0.0"
+ "@emotion/cache" "^11.1.3"
+ "@emotion/serialize" "^1.0.0"
+ "@emotion/sheet" "^1.0.0"
+ "@emotion/utils" "^1.0.0"
+
+"@emotion/hash@^0.9.0":
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7"
+ integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==
+
+"@emotion/memoize@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f"
+ integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==
+
+"@emotion/serialize@^1.0.0", "@emotion/serialize@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0"
+ integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==
+ dependencies:
+ "@emotion/hash" "^0.9.0"
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/unitless" "^0.8.0"
+ "@emotion/utils" "^1.2.0"
+ csstype "^3.0.2"
+
+"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c"
+ integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==
+
+"@emotion/unitless@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db"
+ integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==
+
+"@emotion/utils@^1.0.0", "@emotion/utils@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561"
+ integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==
+
+"@emotion/weak-memoize@^0.3.0":
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb"
+ integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==
+
"@esbuild/android-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23"
@@ -199,7 +336,48 @@
"@swc/core-win32-ia32-msvc" "1.3.37"
"@swc/core-win32-x64-msvc" "1.3.37"
-"@types/prop-types@*":
+"@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/debug@^4.0.0":
+ version "4.1.7"
+ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
+ integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
+ dependencies:
+ "@types/ms" "*"
+
+"@types/hast@^2.0.0":
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
+ integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==
+ dependencies:
+ "@types/unist" "*"
+
+"@types/mdast@^3.0.0":
+ version "3.0.10"
+ resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af"
+ integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==
+ dependencies:
+ "@types/unist" "*"
+
+"@types/ms@*":
+ version "0.7.31"
+ 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"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
@@ -225,6 +403,11 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
+"@types/unist@*", "@types/unist@^2.0.0":
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
+ integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
+
"@vitejs/plugin-react-swc@^3.0.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react-swc/-/plugin-react-swc-3.2.0.tgz#7c4f6e116a296c27f680d05750f9dbf798cf7709"
@@ -251,6 +434,13 @@ acorn@^7.0.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+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"
+
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@@ -276,6 +466,20 @@ autoprefixer@^10.4.13:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
+babel-plugin-macros@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
+ integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+ cosmiconfig "^7.0.0"
+ resolve "^1.19.0"
+
+bail@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
+ integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==
+
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
@@ -298,6 +502,11 @@ browserslist@^4.21.4:
node-releases "^2.0.8"
update-browserslist-db "^1.0.10"
+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"
@@ -308,6 +517,20 @@ caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c"
integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==
+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"
+
+character-entities@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
+ integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
+
chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -323,11 +546,59 @@ chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"
+classnames@2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
+ integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
+
+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-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==
+comma-separated-tokens@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee"
+ integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==
+
+convert-source-map@^1.5.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
+ integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
+
+core-js-pure@^3.25.1:
+ version "3.29.0"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.29.0.tgz#0e1ac889214398641ea4bb1c6cf25ff0959ec1d2"
+ integrity sha512-v94gUjN5UTe1n0yN/opTihJ8QBWD2O8i19RfTZR7foONPWArnjB96QA/wk5ozu1mm6ja3udQCzOzwQXTxi3xOQ==
+
+core-js@3.18.3:
+ version "3.18.3"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.3.tgz#86a0bba2d8ec3df860fefcc07a8d119779f01509"
+ integrity sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw==
+
+cosmiconfig@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
+ integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
+ dependencies:
+ "@types/parse-json" "^4.0.0"
+ import-fresh "^3.2.1"
+ parse-json "^5.0.0"
+ path-type "^4.0.0"
+ yaml "^1.10.0"
+
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
@@ -338,11 +609,30 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
+debug@^4.0.0:
+ 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"
+
+decode-named-character-reference@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
+ integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==
+ dependencies:
+ character-entities "^2.0.0"
+
defined@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf"
integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==
+dequal@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
+ integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+
detective@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034"
@@ -357,16 +647,33 @@ didyoumean@^1.2.2:
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
+diff@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
+ integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==
+
dlv@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
+dompurify@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.1.tgz#a0933f38931b3238934dd632043b727e53004289"
+ integrity sha512-60tsgvPKwItxZZdfLmamp0MTcecCta3avOhsLgPZ0qcWt96OasFfhkeIRbJ6br5i0fQawT1/RBGB5L58/Jpwuw==
+
electron-to-chromium@^1.4.284:
version "1.4.317"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.317.tgz#9a3d38a1a37f26a417d3d95dafe198ff11ed072b"
integrity sha512-JhCRm9v30FMNzQSsjl4kXaygU+qHBD0Yh7mKxyjmF0V8VwYVB6qpBRX28GyAucrM9wDCpSUctT6FpMUQxbyKuA==
+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@^0.16.14:
version "0.16.17"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.17.tgz#fc2c3914c57ee750635fee71b89f615f25065259"
@@ -400,6 +707,21 @@ escalade@^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==
+
+extend@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+ integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+
fast-glob@^3.2.12:
version "3.2.12"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
@@ -425,6 +747,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==
+
fraction.js@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
@@ -454,6 +781,11 @@ glob-parent@^6.0.2:
dependencies:
is-glob "^4.0.3"
+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@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@@ -461,11 +793,34 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+hast-util-whitespace@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557"
+ integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==
+
highlight.js@^11.7.0:
version "11.7.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
+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"
+
+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 sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
+
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"
@@ -473,6 +828,11 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
+is-buffer@^2.0.0:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
+ integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
+
is-core-module@^2.9.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
@@ -497,28 +857,311 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-"js-tokens@^3.0.0 || ^4.0.0":
+is-plain-obj@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0"
+ integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
+
+"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==
+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==
+
+kleur@^4.0.3:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
+ integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
+
lilconfig@^2.0.5, lilconfig@^2.0.6:
version "2.1.0"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
-loose-envify@^1.1.0:
+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"
+ 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==
+
+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"
+math-random@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/math-random/-/math-random-2.0.1.tgz#5604b16c6a9a4aee63aff13937fb909b27e46b3a"
+ integrity sha512-oIEbWiVDxDpl5tIF4S6zYS9JExhh3bun3uLb3YAinHPTlRtW4g1S66LtJrJ4Npq8dgIa8CLK5iPVah5n4n0s2w==
+
+mdast-util-definitions@^5.0.0:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz#9910abb60ac5d7115d6819b57ae0bcef07a3f7a7"
+ integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ unist-util-visit "^4.0.0"
+
+mdast-util-from-markdown@^1.0.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz#0214124154f26154a2b3f9d401155509be45e894"
+ integrity sha512-HN3W1gRIuN/ZW295c7zi7g9lVBllMgZE40RxCX37wrTPWXCWtpvOZdfnuK+1WNpvZje6XuJeI3Wnb4TJEUem+g==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ decode-named-character-reference "^1.0.0"
+ mdast-util-to-string "^3.1.0"
+ micromark "^3.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-decode-string "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ unist-util-stringify-position "^3.0.0"
+ uvu "^0.5.0"
+
+mdast-util-to-hast@^12.1.0:
+ version "12.3.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz#045d2825fb04374e59970f5b3f279b5700f6fb49"
+ integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==
+ dependencies:
+ "@types/hast" "^2.0.0"
+ "@types/mdast" "^3.0.0"
+ mdast-util-definitions "^5.0.0"
+ micromark-util-sanitize-uri "^1.1.0"
+ trim-lines "^3.0.0"
+ unist-util-generated "^2.0.0"
+ unist-util-position "^4.0.0"
+ unist-util-visit "^4.0.0"
+
+mdast-util-to-string@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.1.tgz#db859050d79d48cf9896d294de06f3ede7474d16"
+ integrity sha512-tGvhT94e+cVnQt8JWE9/b3cUQZWS732TJxXHktvP+BYo62PpYD53Ls/6cC60rW21dW+txxiM4zMdc6abASvZKA==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+
merge2@^1.3.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+micromark-core-commonmark@^1.0.1:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad"
+ integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-factory-destination "^1.0.0"
+ micromark-factory-label "^1.0.0"
+ micromark-factory-space "^1.0.0"
+ micromark-factory-title "^1.0.0"
+ micromark-factory-whitespace "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-chunked "^1.0.0"
+ micromark-util-classify-character "^1.0.0"
+ micromark-util-html-tag-name "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
+micromark-factory-destination@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e"
+ integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-label@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137"
+ integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-factory-space@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633"
+ integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-title@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f"
+ integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-factory-whitespace@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c"
+ integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-character@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86"
+ integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-chunked@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06"
+ integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-classify-character@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20"
+ integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-combine-extensions@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5"
+ integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-decode-numeric-character-reference@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946"
+ integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-decode-string@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02"
+ integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-encode@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383"
+ integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==
+
+micromark-util-html-tag-name@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497"
+ integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==
+
+micromark-util-normalize-identifier@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828"
+ integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-resolve-all@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88"
+ integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==
+ dependencies:
+ micromark-util-types "^1.0.0"
+
+micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz#f12e07a85106b902645e0364feb07cf253a85aee"
+ integrity sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-encode "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-subtokenize@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105"
+ integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-util-symbol@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e"
+ integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==
+
+micromark-util-types@^1.0.0, micromark-util-types@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20"
+ integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==
+
+micromark@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.1.0.tgz#eeba0fe0ac1c9aaef675157b52c166f125e89f62"
+ integrity sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==
+ dependencies:
+ "@types/debug" "^4.0.0"
+ debug "^4.0.0"
+ decode-named-character-reference "^1.0.0"
+ micromark-core-commonmark "^1.0.1"
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.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.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-sanitize-uri "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
@@ -532,6 +1175,16 @@ minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
+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==
+
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
@@ -552,16 +1205,43 @@ normalize-range@^0.1.2:
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
+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==
+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"
@@ -608,6 +1288,14 @@ postcss-nested@6.0.0:
dependencies:
postcss-selector-parser "^6.0.10"
+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.10, postcss-selector-parser@^6.0.11:
version "6.0.11"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc"
@@ -630,6 +1318,29 @@ postcss@^8.0.9, postcss@^8.4.21:
picocolors "^1.0.0"
source-map-js "^1.0.2"
+prop-types@15.7.2:
+ version "15.7.2"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
+ integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.8.1"
+
+prop-types@^15.0.0:
+ 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"
+
+property-information@^6.0.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d"
+ integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
@@ -648,6 +1359,50 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
+react-is@^16.13.1, react-is@^16.8.1:
+ 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-is@^18.0.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
+ integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
+
+react-markdown@^8.0.5:
+ version "8.0.5"
+ resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.5.tgz#c9a70a33ca9aeeafb769c6582e7e38843b9d70ad"
+ integrity sha512-jGJolWWmOWAvzf+xMdB9zwStViODyyFQhNB/bwCerbBKmrTmgmA599CGiOlP58OId1IMoIRsA8UdI1Lod4zb5A==
+ dependencies:
+ "@types/hast" "^2.0.0"
+ "@types/prop-types" "^15.0.0"
+ "@types/unist" "^2.0.0"
+ comma-separated-tokens "^2.0.0"
+ hast-util-whitespace "^2.0.0"
+ prop-types "^15.0.0"
+ property-information "^6.0.0"
+ react-is "^18.0.0"
+ remark-parse "^10.0.0"
+ remark-rehype "^10.0.0"
+ space-separated-tokens "^2.0.0"
+ style-to-object "^0.4.0"
+ unified "^10.0.0"
+ unist-util-visit "^4.0.0"
+ vfile "^5.0.0"
+
+react-scroll-to-bottom@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/react-scroll-to-bottom/-/react-scroll-to-bottom-4.2.0.tgz#208183547f85e2b640f467c185fdbc93de2fcc64"
+ integrity sha512-1WweuumQc5JLzeAR81ykRdK/cEv9NlCPEm4vSwOGN1qS2qlpGVTyMgdI8Y7ZmaqRmzYBGV5/xPuJQtekYzQFGg==
+ dependencies:
+ "@babel/runtime-corejs3" "^7.15.4"
+ "@emotion/css" "11.1.3"
+ classnames "2.3.1"
+ core-js "3.18.3"
+ math-random "2.0.1"
+ prop-types "15.7.2"
+ simple-update-in "2.2.0"
+
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@@ -669,7 +1424,36 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
-resolve@^1.1.7, resolve@^1.22.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==
+
+remark-parse@^10.0.0:
+ version "10.0.1"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775"
+ integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ mdast-util-from-markdown "^1.0.0"
+ unified "^10.0.0"
+
+remark-rehype@^10.0.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279"
+ integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==
+ dependencies:
+ "@types/hast" "^2.0.0"
+ "@types/mdast" "^3.0.0"
+ mdast-util-to-hast "^12.1.0"
+ unified "^10.0.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.19.0, resolve@^1.22.1:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -697,6 +1481,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
+sade@^1.7.3:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
@@ -704,11 +1495,45 @@ scheduler@^0.23.0:
dependencies:
loose-envify "^1.1.0"
+simple-update-in@2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/simple-update-in/-/simple-update-in-2.2.0.tgz#86607662635ea12e59b5341044244902aa7db1c8"
+ integrity sha512-FrW41lLiOs82jKxwq39UrE1HDAHOvirKWk4Nv8tqnFFFknVbTxcHZzDS4vt02qqdU/5+KNsQHWzhKHznDBmrww==
+
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==
+source-map@^0.5.7:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+ integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
+
+space-separated-tokens@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f"
+ integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==
+
+style-to-object@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37"
+ integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==
+ dependencies:
+ inline-style-parser "0.1.1"
+
+stylis@4.1.3:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7"
+ integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==
+
+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-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"
@@ -743,6 +1568,11 @@ tailwindcss@^3.2.7:
quick-lru "^5.1.1"
resolve "^1.22.1"
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+ integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
+
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"
@@ -750,11 +1580,77 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
+trim-lines@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338"
+ integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==
+
+trough@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876"
+ integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==
+
typescript@^4.9.3:
version "4.9.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+unified@^10.0.0:
+ version "10.1.2"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
+ integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ bail "^2.0.0"
+ extend "^3.0.0"
+ is-buffer "^2.0.0"
+ is-plain-obj "^4.0.0"
+ trough "^2.0.0"
+ vfile "^5.0.0"
+
+unist-util-generated@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.1.tgz#e37c50af35d3ed185ac6ceacb6ca0afb28a85cae"
+ integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==
+
+unist-util-is@^5.0.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9"
+ integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-position@^4.0.0:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.4.tgz#93f6d8c7d6b373d9b825844645877c127455f037"
+ integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-stringify-position@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d"
+ integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-visit-parents@^5.1.1:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb"
+ integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-is "^5.0.0"
+
+unist-util-visit@^4.0.0:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2"
+ integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-is "^5.0.0"
+ unist-util-visit-parents "^5.1.1"
+
update-browserslist-db@^1.0.10:
version "1.0.10"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
@@ -763,11 +1659,44 @@ update-browserslist-db@^1.0.10:
escalade "^3.1.1"
picocolors "^1.0.0"
+use-sync-external-store@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
+ integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+
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==
+uvu@^0.5.0:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
+ integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==
+ dependencies:
+ dequal "^2.0.0"
+ diff "^5.0.0"
+ kleur "^4.0.3"
+ sade "^1.7.3"
+
+vfile-message@^3.0.0:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea"
+ integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-stringify-position "^3.0.0"
+
+vfile@^5.0.0:
+ version "5.3.7"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7"
+ integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ is-buffer "^2.0.0"
+ unist-util-stringify-position "^3.0.0"
+ vfile-message "^3.0.0"
+
vite@^4.1.0:
version "4.1.4"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.1.4.tgz#170d93bcff97e0ebc09764c053eebe130bfe6ca0"
@@ -785,7 +1714,14 @@ 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.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
+
+zustand@^4.3.5:
+ version "4.3.5"
+ resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.5.tgz#011d2997534f8a187ea7b1d75db56df31f58453d"
+ integrity sha512-2iPUzfwx+g3f0PagOMz2vDO9mZzEp2puFpNe7vrAymVPOEIEUjCPkC4/zy84eAscxIWmTU4j9g6upXYkJdzEFQ==
+ dependencies:
+ use-sync-external-store "1.2.0"