forked from XiaoMo/ChatGPT-Next-Web
feat: add dark theme support
This commit is contained in:
parent
a9940cb05e
commit
14d50f1167
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all .3s ease;
|
transition: all 0.3s ease;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@ -29,6 +29,16 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
div:not(:global(.no-dark)) > .icon-button-icon {
|
||||||
|
filter: invert(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button:hover {
|
||||||
|
filter: brightness(1.2) hue-rotate(0.01turn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.icon-button-text {
|
.icon-button-text {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
@ -1,6 +1,6 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import styles from "./button.module.css";
|
import styles from "./button.module.scss";
|
||||||
|
|
||||||
export function IconButton(props: {
|
export function IconButton(props: {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
@ -8,6 +8,7 @@ export function IconButton(props: {
|
|||||||
text?: string;
|
text?: string;
|
||||||
bordered?: boolean;
|
bordered?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
title?: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -16,6 +17,7 @@ export function IconButton(props: {
|
|||||||
` ${props.bordered && styles.border} ${props.className ?? ""}`
|
` ${props.bordered && styles.border} ${props.className ?? ""}`
|
||||||
}
|
}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
|
title={props.title}
|
||||||
>
|
>
|
||||||
<div className={styles["icon-button-icon"]}>{props.icon}</div>
|
<div className={styles["icon-button-icon"]}>{props.icon}</div>
|
||||||
{props.text && (
|
{props.text && (
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
border: var(--border-in-light);
|
border: var(--border-in-light);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
|
color: var(--black);
|
||||||
|
background-color: var(--white);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -177,11 +179,11 @@
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-actions {
|
.window-actions {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-action-button {
|
.window-action-button {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,13 +239,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-item {
|
.chat-message-item {
|
||||||
margin-top: 5px;
|
margin-top: 10px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
user-select: text;
|
user-select: text;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
border: var(--border-in-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-message-user > .chat-message-container > .chat-message-item {
|
.chat-message-user > .chat-message-container > .chat-message-item {
|
||||||
@ -289,11 +292,12 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: var(--border-in-light);
|
border: var(--border-in-light);
|
||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--black);
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
padding: 10px 14px;
|
padding: 10px 14px;
|
||||||
resize: none;
|
resize: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
color: #333;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-input:focus {
|
.chat-input:focus {
|
@ -6,10 +6,10 @@ import "katex/dist/katex.min.css";
|
|||||||
import RemarkMath from "remark-math";
|
import RemarkMath from "remark-math";
|
||||||
import RehypeKatex from "rehype-katex";
|
import RehypeKatex from "rehype-katex";
|
||||||
|
|
||||||
import EmojiPicker, { Emoji, EmojiClickData } from "emoji-picker-react";
|
import EmojiPicker, { Emoji, Theme as EmojiTheme } from "emoji-picker-react";
|
||||||
|
|
||||||
import { IconButton } from "./button";
|
import { IconButton } from "./button";
|
||||||
import styles from "./home.module.css";
|
import styles from "./home.module.scss";
|
||||||
|
|
||||||
import SettingsIcon from "../icons/settings.svg";
|
import SettingsIcon from "../icons/settings.svg";
|
||||||
import GithubIcon from "../icons/github.svg";
|
import GithubIcon from "../icons/github.svg";
|
||||||
@ -21,8 +21,9 @@ import BotIcon from "../icons/bot.svg";
|
|||||||
import AddIcon from "../icons/add.svg";
|
import AddIcon from "../icons/add.svg";
|
||||||
import DeleteIcon from "../icons/delete.svg";
|
import DeleteIcon from "../icons/delete.svg";
|
||||||
import LoadingIcon from "../icons/three-dots.svg";
|
import LoadingIcon from "../icons/three-dots.svg";
|
||||||
|
import ResetIcon from "../icons/reload.svg";
|
||||||
|
|
||||||
import { Message, SubmitKey, useChatStore } from "../store";
|
import { Message, SubmitKey, useChatStore, Theme } from "../store";
|
||||||
import { Card, List, ListItem, Popover } from "./ui-lib";
|
import { Card, List, ListItem, Popover } from "./ui-lib";
|
||||||
|
|
||||||
export function Markdown(props: { content: string }) {
|
export function Markdown(props: { content: string }) {
|
||||||
@ -101,12 +102,34 @@ export function ChatList() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useSubmitHandler() {
|
||||||
|
const config = useChatStore((state) => state.config);
|
||||||
|
const submitKey = config.submitKey;
|
||||||
|
|
||||||
|
const shouldSubmit = (e: KeyboardEvent) => {
|
||||||
|
if (e.key !== "Enter") return false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
(config.submitKey === SubmitKey.AltEnter && e.altKey) ||
|
||||||
|
(config.submitKey === SubmitKey.CtrlEnter && e.ctrlKey) ||
|
||||||
|
(config.submitKey === SubmitKey.ShiftEnter && e.shiftKey) ||
|
||||||
|
config.submitKey === SubmitKey.Enter
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
submitKey,
|
||||||
|
shouldSubmit,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function Chat() {
|
export function Chat() {
|
||||||
type RenderMessage = Message & { preview?: boolean };
|
type RenderMessage = Message & { preview?: boolean };
|
||||||
|
|
||||||
const session = useChatStore((state) => state.currentSession());
|
const session = useChatStore((state) => state.currentSession());
|
||||||
const [userInput, setUserInput] = useState("");
|
const [userInput, setUserInput] = useState("");
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const { submitKey, shouldSubmit } = useSubmitHandler();
|
||||||
|
|
||||||
const onUserInput = useChatStore((state) => state.onUserInput);
|
const onUserInput = useChatStore((state) => state.onUserInput);
|
||||||
const onUserSubmit = () => {
|
const onUserSubmit = () => {
|
||||||
@ -116,7 +139,7 @@ export function Chat() {
|
|||||||
setUserInput("");
|
setUserInput("");
|
||||||
};
|
};
|
||||||
const onInputKeyDown = (e: KeyboardEvent) => {
|
const onInputKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.key === "Enter" && (e.shiftKey || e.ctrlKey || e.metaKey)) {
|
if (shouldSubmit(e)) {
|
||||||
onUserSubmit();
|
onUserSubmit();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
@ -165,12 +188,20 @@ export function Chat() {
|
|||||||
与 ChatGPT 的 {session.messages.length} 条对话
|
与 ChatGPT 的 {session.messages.length} 条对话
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["chat-actions"]}>
|
<div className={styles["window-actions"]}>
|
||||||
<div className={styles["chat-action-button"]}>
|
<div className={styles["window-action-button"]}>
|
||||||
<IconButton icon={<BrainIcon />} bordered />
|
<IconButton
|
||||||
|
icon={<BrainIcon />}
|
||||||
|
bordered
|
||||||
|
title="查看压缩后的历史 Prompt(开发中)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["chat-action-button"]}>
|
<div className={styles["window-action-button"]}>
|
||||||
<IconButton icon={<ExportIcon />} bordered />
|
<IconButton
|
||||||
|
icon={<ExportIcon />}
|
||||||
|
bordered
|
||||||
|
title="导出聊天记录为 Markdown(开发中)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -223,7 +254,7 @@ export function Chat() {
|
|||||||
<div className={styles["chat-input-panel-inner"]}>
|
<div className={styles["chat-input-panel-inner"]}>
|
||||||
<textarea
|
<textarea
|
||||||
className={styles["chat-input"]}
|
className={styles["chat-input"]}
|
||||||
placeholder="输入消息,Ctrl + Enter 发送"
|
placeholder={`输入消息,${submitKey} 发送`}
|
||||||
rows={3}
|
rows={3}
|
||||||
onInput={(e) => setUserInput(e.currentTarget.value)}
|
onInput={(e) => setUserInput(e.currentTarget.value)}
|
||||||
value={userInput}
|
value={userInput}
|
||||||
@ -232,7 +263,7 @@ export function Chat() {
|
|||||||
<IconButton
|
<IconButton
|
||||||
icon={<SendWhiteIcon />}
|
icon={<SendWhiteIcon />}
|
||||||
text={"发送"}
|
text={"发送"}
|
||||||
className={styles["chat-input-send"]}
|
className={styles["chat-input-send"] + " no-dark"}
|
||||||
onClick={onUserSubmit}
|
onClick={onUserSubmit}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -241,12 +272,28 @@ export function Chat() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function useSwitchTheme() {
|
||||||
|
const config = useChatStore((state) => state.config);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.body.classList.remove("light");
|
||||||
|
document.body.classList.remove("dark");
|
||||||
|
if (config.theme === "dark") {
|
||||||
|
document.body.classList.add("dark");
|
||||||
|
} else if (config.theme === "light") {
|
||||||
|
document.body.classList.add("light");
|
||||||
|
}
|
||||||
|
}, [config.theme]);
|
||||||
|
}
|
||||||
|
|
||||||
export function Home() {
|
export function Home() {
|
||||||
const [createNewSession] = useChatStore((state) => [state.newSession]);
|
const [createNewSession] = useChatStore((state) => [state.newSession]);
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
const [openSettings, setOpenSettings] = useState(false);
|
const [openSettings, setOpenSettings] = useState(false);
|
||||||
|
|
||||||
|
useSwitchTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.sidebar}>
|
<div className={styles.sidebar}>
|
||||||
@ -260,7 +307,10 @@ export function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles["sidebar-body"]}>
|
<div
|
||||||
|
className={styles["sidebar-body"]}
|
||||||
|
onClick={() => setOpenSettings(false)}
|
||||||
|
>
|
||||||
<ChatList />
|
<ChatList />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -295,13 +345,6 @@ export function Home() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EmojiPickerModal(props: {
|
|
||||||
show: boolean;
|
|
||||||
onClose: (_: boolean) => void;
|
|
||||||
}) {
|
|
||||||
return <div className=""></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Settings() {
|
export function Settings() {
|
||||||
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
||||||
const [config, updateConfig] = useChatStore((state) => [
|
const [config, updateConfig] = useChatStore((state) => [
|
||||||
@ -316,6 +359,11 @@ export function Settings() {
|
|||||||
<div className={styles["window-header-title"]}>设置</div>
|
<div className={styles["window-header-title"]}>设置</div>
|
||||||
<div className={styles["window-header-sub-title"]}>设置选项</div>
|
<div className={styles["window-header-sub-title"]}>设置选项</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={styles["window-actions"]}>
|
||||||
|
<div className={styles["window-action-button"]}>
|
||||||
|
<IconButton icon={<ResetIcon />} bordered title="重置所有选项" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["settings"]}>
|
<div className={styles["settings"]}>
|
||||||
<List>
|
<List>
|
||||||
@ -326,6 +374,7 @@ export function Settings() {
|
|||||||
content={
|
content={
|
||||||
<EmojiPicker
|
<EmojiPicker
|
||||||
lazyLoadEmojis
|
lazyLoadEmojis
|
||||||
|
theme={EmojiTheme.AUTO}
|
||||||
onEmojiClick={(e) => {
|
onEmojiClick={(e) => {
|
||||||
updateConfig((config) => (config.avatar = e.unified));
|
updateConfig((config) => (config.avatar = e.unified));
|
||||||
setShowEmojiPicker(false);
|
setShowEmojiPicker(false);
|
||||||
@ -355,8 +404,28 @@ export function Settings() {
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.entries(SubmitKey).map(([k, v]) => (
|
{Object.values(SubmitKey).map((v) => (
|
||||||
<option value={k} key={v}>
|
<option value={v} key={v}>
|
||||||
|
{v}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem>
|
||||||
|
<div className={styles["settings-title"]}>主题</div>
|
||||||
|
<div className="">
|
||||||
|
<select
|
||||||
|
value={config.theme}
|
||||||
|
onChange={(e) => {
|
||||||
|
updateConfig(
|
||||||
|
(config) => (config.theme = e.target.value as any as Theme)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Object.values(Theme).map((v) => (
|
||||||
|
<option value={v} key={v}>
|
||||||
{v}
|
{v}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
@ -366,13 +435,36 @@ export function Settings() {
|
|||||||
</List>
|
</List>
|
||||||
<List>
|
<List>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<div className={styles["settings-title"]}>最大记忆历史消息数</div>
|
<div className={styles["settings-title"]}>最大上下文消息数</div>
|
||||||
<div className="">{config.historyMessageCount}</div>
|
<input
|
||||||
|
type="range"
|
||||||
|
title={config.historyMessageCount.toString()}
|
||||||
|
value={config.historyMessageCount}
|
||||||
|
min="5"
|
||||||
|
max="20"
|
||||||
|
step="5"
|
||||||
|
onChange={(e) =>
|
||||||
|
updateConfig(
|
||||||
|
(config) =>
|
||||||
|
(config.historyMessageCount = e.target.valueAsNumber)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
></input>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<div className={styles["settings-title"]}>发送机器人回复消息</div>
|
<div className={styles["settings-title"]}>
|
||||||
<div className="">{config.sendBotMessages ? "是" : "否"}</div>
|
上下文中包含机器人消息
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={config.sendBotMessages}
|
||||||
|
onChange={(e) =>
|
||||||
|
updateConfig(
|
||||||
|
(config) => (config.sendBotMessages = e.currentTarget.checked)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
></input>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
border-bottom: var(--border-in-light);
|
border-bottom: var(--border-in-light);
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
|
animation: slide-in ease 0.6s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list {
|
.list {
|
||||||
@ -49,6 +50,7 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
animation: slide-in ease 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list .list-item:last-child {
|
.list .list-item:last-child {
|
@ -1,4 +1,4 @@
|
|||||||
import styles from "./ui-lib.module.css";
|
import styles from "./ui-lib.module.scss";
|
||||||
|
|
||||||
export function Popover(props: {
|
export function Popover(props: {
|
||||||
children: JSX.Element;
|
children: JSX.Element;
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
:root {
|
|
||||||
/* color */
|
|
||||||
--white: white;
|
|
||||||
--black: --black;
|
|
||||||
--gray: rgb(250, 250, 250);
|
|
||||||
--primary: rgb(29, 147, 171);
|
|
||||||
--second: rgb(231, 248, 255);
|
|
||||||
--hover-color: #f3f3f3;
|
|
||||||
|
|
||||||
/* shadow */
|
|
||||||
--shadow: 50px 50px 100px 10px rgb(0, 0, 0, 0.1);
|
|
||||||
--card-shadow: 0px 2px 4px 0px rgb(0, 0, 0, 0.05);
|
|
||||||
|
|
||||||
/* stroke */
|
|
||||||
--border-in-light: 1px solid rgb(222, 222, 222);
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: var(--gray);
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
|
||||||
border-radius: 20px;
|
|
||||||
border: 6px solid transparent;
|
|
||||||
background-clip: content-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
border: var(--border-in-light);
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
141
app/globals.scss
Normal file
141
app/globals.scss
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
@mixin light {
|
||||||
|
/* color */
|
||||||
|
--white: white;
|
||||||
|
--black: rgb(48, 48, 48);
|
||||||
|
--gray: rgb(250, 250, 250);
|
||||||
|
--primary: rgb(29, 147, 171);
|
||||||
|
--second: rgb(231, 248, 255);
|
||||||
|
--hover-color: #f3f3f3;
|
||||||
|
|
||||||
|
/* shadow */
|
||||||
|
--shadow: 50px 50px 100px 10px rgb(0, 0, 0, 0.1);
|
||||||
|
--card-shadow: 0px 2px 4px 0px rgb(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
/* stroke */
|
||||||
|
--border-in-light: 1px solid rgb(222, 222, 222);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin dark {
|
||||||
|
/* color */
|
||||||
|
--white: rgb(30, 30, 30);
|
||||||
|
--black: rgb(187, 187, 187);
|
||||||
|
--gray: rgb(21, 21, 21);
|
||||||
|
--primary: rgb(29, 147, 171);
|
||||||
|
--second: rgb(27 38 42);
|
||||||
|
--hover-color: #323232;
|
||||||
|
|
||||||
|
--border-in-light: 1px solid rgba(255, 255, 255, 0.192);
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
@include light;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
@include dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
filter: invert(0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
@include light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
@include dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--gray);
|
||||||
|
color: var(--black);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 6px solid transparent;
|
||||||
|
background-clip: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
border: var(--border-in-light);
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--black);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--black);
|
||||||
|
appearance: none;
|
||||||
|
border: var(--border-in-light);
|
||||||
|
border-radius: 5px;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:checked::after {
|
||||||
|
display: block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
content: " ";
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"] {
|
||||||
|
appearance: none;
|
||||||
|
border: var(--border-in-light);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 5px 15px 5px 10px;
|
||||||
|
background-color: var(--white);
|
||||||
|
color: var(--black);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: attr(value);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
|
appearance: none;
|
||||||
|
height: 8px;
|
||||||
|
width: 20px;
|
||||||
|
background-color: var(--primary);
|
||||||
|
border-radius: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all ease 0.3s;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="range"]::-webkit-slider-thumb:hover {
|
||||||
|
transform: scaleY(1.2);
|
||||||
|
width: 24px;
|
||||||
|
}
|
24
app/icons/reload.svg
Normal file
24
app/icons/reload.svg
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16"
|
||||||
|
height="16" viewBox="0 0 16 16" fill="none">
|
||||||
|
<defs>
|
||||||
|
<rect id="path_0" x="0" y="0" width="16" height="16" />
|
||||||
|
</defs>
|
||||||
|
<g opacity="1" transform="translate(0 0) rotate(0 8 8)">
|
||||||
|
<mask id="bg-mask-0" fill="white">
|
||||||
|
<use xlink:href="#path_0"></use>
|
||||||
|
</mask>
|
||||||
|
<g mask="url(#bg-mask-0)">
|
||||||
|
<path id="路径 1"
|
||||||
|
style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0"
|
||||||
|
transform="translate(14 2.6666666666666665) rotate(0 0 2.6666666666666665)"
|
||||||
|
d="M0,0L0,5.33 " />
|
||||||
|
<path id="路径 2"
|
||||||
|
style="stroke:#333333; stroke-width:1.3333333333333333; stroke-opacity:1; stroke-dasharray:0 0"
|
||||||
|
transform="translate(2 8) rotate(0 0 2.6666666666666665)" d="M0,0L0,5.33 " />
|
||||||
|
<path id="分组 1"
|
||||||
|
style="stroke:#333333; stroke-width:1.333; stroke-opacity:1; stroke-dasharray:0 0"
|
||||||
|
transform="translate(2.000000057161194 2) rotate(0 6.001349925994873 6)"
|
||||||
|
d="M12.0027 6C12.0027 2.69 9.3127 0 6.0027 0C4.3027 0 2.7727 0.7 1.6827 1.83 M-5.71612e-08 6C-5.71612e-08 9.31 2.69 12 6 12C7.62 12 9.09 11.36 10.17 10.32 " />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,4 +1,4 @@
|
|||||||
import "./globals.css";
|
import "./globals.scss";
|
||||||
import "./markdown.css";
|
import "./markdown.css";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
|
11
app/store.ts
11
app/store.ts
@ -17,12 +17,19 @@ export enum SubmitKey {
|
|||||||
AltEnter = "Alt + Enter",
|
AltEnter = "Alt + Enter",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum Theme {
|
||||||
|
Auto = "auto",
|
||||||
|
Dark = "dark",
|
||||||
|
Light = "light",
|
||||||
|
}
|
||||||
|
|
||||||
interface ChatConfig {
|
interface ChatConfig {
|
||||||
maxToken?: number;
|
maxToken?: number;
|
||||||
historyMessageCount: number; // -1 means all
|
historyMessageCount: number; // -1 means all
|
||||||
sendBotMessages: boolean; // send bot's message or not
|
sendBotMessages: boolean; // send bot's message or not
|
||||||
submitKey: SubmitKey;
|
submitKey: SubmitKey;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
|
theme: Theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChatStat {
|
interface ChatStat {
|
||||||
@ -98,8 +105,9 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
config: {
|
config: {
|
||||||
historyMessageCount: 5,
|
historyMessageCount: 5,
|
||||||
sendBotMessages: false as boolean,
|
sendBotMessages: false as boolean,
|
||||||
submitKey: SubmitKey.CtrlEnter,
|
submitKey: SubmitKey.CtrlEnter as SubmitKey,
|
||||||
avatar: "1fae0",
|
avatar: "1fae0",
|
||||||
|
theme: Theme.Auto as Theme,
|
||||||
},
|
},
|
||||||
|
|
||||||
getConfig() {
|
getConfig() {
|
||||||
@ -224,7 +232,6 @@ export const useChatStore = create<ChatStore>()(
|
|||||||
const sessions = get().sessions;
|
const sessions = get().sessions;
|
||||||
const session = sessions.at(sessionIndex);
|
const session = sessions.at(sessionIndex);
|
||||||
const messages = session?.messages;
|
const messages = session?.messages;
|
||||||
console.log(sessions, messages?.length, messages?.at(messageIndex));
|
|
||||||
updater(messages?.at(messageIndex));
|
updater(messages?.at(messageIndex));
|
||||||
set(() => ({ sessions }));
|
set(() => ({ sessions }));
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
|
||||||
|
const withLess = require("next-with-less");
|
||||||
|
|
||||||
|
const nextConfig = withLess({
|
||||||
experimental: {
|
experimental: {
|
||||||
appDir: true,
|
appDir: true,
|
||||||
},
|
},
|
||||||
@ -11,6 +14,6 @@ const nextConfig = {
|
|||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
|
|
||||||
module.exports = nextConfig;
|
module.exports = nextConfig;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"react-markdown": "^8.0.5",
|
"react-markdown": "^8.0.5",
|
||||||
"rehype-katex": "^6.0.2",
|
"rehype-katex": "^6.0.2",
|
||||||
"remark-math": "^5.1.1",
|
"remark-math": "^5.1.1",
|
||||||
|
"sass": "^1.59.2",
|
||||||
"typescript": "4.9.5",
|
"typescript": "4.9.5",
|
||||||
"zustand": "^4.3.6"
|
"zustand": "^4.3.6"
|
||||||
}
|
}
|
||||||
|
76
yarn.lock
76
yarn.lock
@ -1473,6 +1473,14 @@ ansi-styles@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^2.0.1"
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
anymatch@~3.1.2:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
|
||||||
|
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
|
||||||
|
dependencies:
|
||||||
|
normalize-path "^3.0.0"
|
||||||
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
argparse@^2.0.1:
|
argparse@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
resolved "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||||
@ -1600,6 +1608,11 @@ balanced-match@^1.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
binary-extensions@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||||
|
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||||
|
|
||||||
boolbase@^1.0.0:
|
boolbase@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
resolved "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||||
@ -1613,7 +1626,7 @@ brace-expansion@^1.1.7:
|
|||||||
balanced-match "^1.0.0"
|
balanced-match "^1.0.0"
|
||||||
concat-map "0.0.1"
|
concat-map "0.0.1"
|
||||||
|
|
||||||
braces@^3.0.2:
|
braces@^3.0.2, braces@~3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
resolved "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||||
@ -1680,6 +1693,21 @@ character-entities@^2.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
|
resolved "https://registry.npmmirror.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
|
||||||
integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
|
integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
|
||||||
|
|
||||||
|
"chokidar@>=3.0.0 <4.0.0":
|
||||||
|
version "3.5.3"
|
||||||
|
resolved "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||||
|
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||||
|
dependencies:
|
||||||
|
anymatch "~3.1.2"
|
||||||
|
braces "~3.0.2"
|
||||||
|
glob-parent "~5.1.2"
|
||||||
|
is-binary-path "~2.1.0"
|
||||||
|
is-glob "~4.0.1"
|
||||||
|
normalize-path "~3.0.0"
|
||||||
|
readdirp "~3.6.0"
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents "~2.3.2"
|
||||||
|
|
||||||
client-only@0.0.1:
|
client-only@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
resolved "https://registry.npmmirror.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||||
@ -2404,6 +2432,11 @@ fs.realpath@^1.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||||
|
|
||||||
|
fsevents@~2.3.2:
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||||
|
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||||
|
|
||||||
function-bind@^1.1.1:
|
function-bind@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
@ -2451,7 +2484,7 @@ get-tsconfig@^4.2.0:
|
|||||||
resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5"
|
resolved "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.4.0.tgz#64eee64596668a81b8fce18403f94f245ee0d4e5"
|
||||||
integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==
|
integrity sha512-0Gdjo/9+FzsYhXCEFueo2aY1z1tpXrxWZzP7k8ul9qt1U5o8rYJwTJYmaeHdrVosYIVYkOy2iwCJ9FdpocJhPQ==
|
||||||
|
|
||||||
glob-parent@^5.1.2:
|
glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||||
@ -2663,6 +2696,11 @@ ignore@^5.2.0:
|
|||||||
resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
|
resolved "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
|
||||||
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
|
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
|
||||||
|
|
||||||
|
immutable@^4.0.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.npmmirror.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be"
|
||||||
|
integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==
|
||||||
|
|
||||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
||||||
version "3.3.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||||
@ -2732,6 +2770,13 @@ is-bigint@^1.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-bigints "^1.0.1"
|
has-bigints "^1.0.1"
|
||||||
|
|
||||||
|
is-binary-path@~2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||||
|
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||||
|
dependencies:
|
||||||
|
binary-extensions "^2.0.0"
|
||||||
|
|
||||||
is-boolean-object@^1.1.0:
|
is-boolean-object@^1.1.0:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
resolved "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
||||||
@ -2774,7 +2819,7 @@ is-extglob@^2.1.1:
|
|||||||
resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||||
|
|
||||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
|
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
resolved "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||||
@ -3428,6 +3473,11 @@ node-releases@^2.0.8:
|
|||||||
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f"
|
resolved "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f"
|
||||||
integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==
|
integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==
|
||||||
|
|
||||||
|
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||||
|
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||||
|
|
||||||
nth-check@^2.0.1:
|
nth-check@^2.0.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
|
resolved "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
|
||||||
@ -3605,7 +3655,7 @@ picocolors@^1.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||||
|
|
||||||
picomatch@^2.3.1:
|
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
resolved "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||||
@ -3694,6 +3744,13 @@ react@^18.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
|
|
||||||
|
readdirp@~3.6.0:
|
||||||
|
version "3.6.0"
|
||||||
|
resolved "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||||
|
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||||
|
dependencies:
|
||||||
|
picomatch "^2.2.1"
|
||||||
|
|
||||||
regenerate-unicode-properties@^10.1.0:
|
regenerate-unicode-properties@^10.1.0:
|
||||||
version "10.1.0"
|
version "10.1.0"
|
||||||
resolved "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
|
resolved "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
|
||||||
@ -3862,6 +3919,15 @@ safe-regex-test@^1.0.0:
|
|||||||
get-intrinsic "^1.1.3"
|
get-intrinsic "^1.1.3"
|
||||||
is-regex "^1.1.4"
|
is-regex "^1.1.4"
|
||||||
|
|
||||||
|
sass@^1.59.2:
|
||||||
|
version "1.59.2"
|
||||||
|
resolved "https://registry.npmmirror.com/sass/-/sass-1.59.2.tgz#537f6d11614d4f20f97696f23ad358ee398b1937"
|
||||||
|
integrity sha512-jJyO6SmbzkJexF8MUorHx5tAilcgabioYxT/BHbY4+OvoqmbHxsYlrjZ8Adhqcgl6Zqwie0TgMXLCAmPFxXOuw==
|
||||||
|
dependencies:
|
||||||
|
chokidar ">=3.0.0 <4.0.0"
|
||||||
|
immutable "^4.0.0"
|
||||||
|
source-map-js ">=0.6.2 <2.0.0"
|
||||||
|
|
||||||
scheduler@^0.23.0:
|
scheduler@^0.23.0:
|
||||||
version "0.23.0"
|
version "0.23.0"
|
||||||
resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
|
resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
|
||||||
@ -3912,7 +3978,7 @@ slash@^4.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
|
resolved "https://registry.npmmirror.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
|
||||||
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
|
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
|
||||||
|
|
||||||
source-map-js@^1.0.2:
|
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||||
|
Loading…
Reference in New Issue
Block a user