diff --git a/README.md b/README.md index a6288798..3b6308be 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,9 @@ One-Click to deploy well-designed ChatGPT web UI on Vercel. ## Roadmap - [x] System Prompt: pin a user defined prompt as system prompt [#138](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/138) -- [ ] User Prompt: user can edit and save custom prompts to prompt list +- [x] User Prompt: user can edit and save custom prompts to prompt list +- [ ] Prompt Template: create a new chat with pre-defined in-context prompts +- [ ] Share as image, share to ShareGPT - [ ] Desktop App with tauri - [ ] Self-host Model: support llama, alpaca, ChatGLM, BELLE etc. - [ ] Plugins: support network search, caculator, any other apis etc. [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) @@ -59,7 +61,9 @@ One-Click to deploy well-designed ChatGPT web UI on Vercel. ## 开发计划 - [x] 为每个对话设置系统 Prompt [#138](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/138) -- [ ] 允许用户自行编辑内置 Prompt 列表 +- [x] 允许用户自行编辑内置 Prompt 列表 +- [ ] 提示词模板:使用预制上下文快速定制新对话 +- [ ] 分享为图片,分享到 ShareGPT - [ ] 使用 tauri 打包桌面应用 - [ ] 支持自部署的大语言模型 - [ ] 插件机制,支持联网搜索、计算器、调用其他平台 api [#165](https://github.com/Yidadaa/ChatGPT-Next-Web/issues/165) @@ -221,6 +225,9 @@ bash <(curl -s https://raw.githubusercontent.com/Yidadaa/ChatGPT-Next-Web/main/s [@chazzhou](https://github.com/chazzhou) [@hauy](https://github.com/hauy) [@Corwin006](https://github.com/Corwin006) +[@yankunsong](https://github.com/yankunsong) +[@ypwhs](https://github.com/ypwhs) +[@fxxxchao](https://github.com/fxxxchao) ### Contributor diff --git a/app/api/openai/route.ts b/app/api/openai/route.ts index 261c20a8..0ac94bdd 100644 --- a/app/api/openai/route.ts +++ b/app/api/openai/route.ts @@ -17,7 +17,7 @@ async function makeRequest(req: NextRequest) { }, { status: 500, - }, + } ); } } @@ -29,3 +29,7 @@ export async function POST(req: NextRequest) { export async function GET(req: NextRequest) { return makeRequest(req); } + +export const config = { + runtime: "edge", +}; diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 991ef312..3c66627f 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -570,10 +570,9 @@ export function Chat(props: { if (userIndex === null) return; setIsLoading(true); - chatStore - .onUserInput(session.messages[userIndex].content) - .then(() => setIsLoading(false)); + const content = session.messages[userIndex].content; deleteMessage(userIndex); + chatStore.onUserInput(content).then(() => setIsLoading(false)); inputRef.current?.focus(); }; diff --git a/app/components/settings.module.scss b/app/components/settings.module.scss index 830e1bae..b7f09558 100644 --- a/app/components/settings.module.scss +++ b/app/components/settings.module.scss @@ -32,3 +32,63 @@ min-width: 80%; } } + +.user-prompt-modal { + min-height: 40vh; + + .user-prompt-search { + width: 100%; + max-width: 100%; + margin-bottom: 10px; + background-color: var(--gray); + } + + .user-prompt-list { + padding: 10px 0; + + .user-prompt-item { + margin-bottom: 10px; + widows: 100%; + + .user-prompt-header { + display: flex; + widows: 100%; + margin-bottom: 5px; + + .user-prompt-title { + flex-grow: 1; + max-width: 100%; + margin-right: 5px; + padding: 5px; + font-size: 12px; + text-align: left; + } + + .user-prompt-buttons { + display: flex; + align-items: center; + + .user-prompt-button { + height: 100%; + + &:not(:last-child) { + margin-right: 5px; + } + } + } + } + + .user-prompt-content { + width: 100%; + box-sizing: border-box; + padding: 5px; + margin-right: 10px; + font-size: 12px; + flex-grow: 1; + } + } + } + + .user-prompt-actions { + } +} diff --git a/app/components/settings.tsx b/app/components/settings.tsx index e418d484..d81b5b35 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo, HTMLProps } from "react"; +import { useState, useEffect, useMemo, HTMLProps, useRef } from "react"; import EmojiPicker, { Theme as EmojiTheme } from "emoji-picker-react"; @@ -6,12 +6,13 @@ import styles from "./settings.module.scss"; import ResetIcon from "../icons/reload.svg"; import CloseIcon from "../icons/close.svg"; +import CopyIcon from "../icons/copy.svg"; import ClearIcon from "../icons/clear.svg"; import EditIcon from "../icons/edit.svg"; import EyeIcon from "../icons/eye.svg"; import EyeOffIcon from "../icons/eye-off.svg"; -import { List, ListItem, Popover, showToast } from "./ui-lib"; +import { Input, List, ListItem, Modal, Popover } from "./ui-lib"; import { IconButton } from "./button"; import { @@ -26,14 +27,114 @@ import { import { Avatar } from "./chat"; import Locale, { AllLangs, changeLang, getLang } from "../locales"; -import { getEmojiUrl } from "../utils"; +import { copyToClipboard, getEmojiUrl } from "../utils"; import Link from "next/link"; import { UPDATE_URL } from "../constant"; -import { SearchService, usePromptStore } from "../store/prompt"; -import { requestUsage } from "../requests"; +import { Prompt, SearchService, usePromptStore } from "../store/prompt"; import { ErrorBoundary } from "./error"; import { InputRange } from "./input-range"; +function UserPromptModal(props: { onClose?: () => void }) { + const promptStore = usePromptStore(); + const userPrompts = promptStore.getUserPrompts(); + const builtinPrompts = SearchService.builtinPrompts; + const allPrompts = userPrompts.concat(builtinPrompts); + const [searchInput, setSearchInput] = useState(""); + const [searchPrompts, setSearchPrompts] = useState([]); + const prompts = searchInput.length > 0 ? searchPrompts : allPrompts; + + useEffect(() => { + if (searchInput.length > 0) { + const searchResult = SearchService.search(searchInput); + setSearchPrompts(searchResult); + } else { + setSearchPrompts([]); + } + }, [searchInput]); + + return ( +
+ props.onClose?.()} + actions={[ + promptStore.add({ title: "", content: "" })} + icon={} + bordered + text={Locale.Settings.Prompt.Modal.Add} + />, + ]} + > +
+ setSearchInput(e.currentTarget.value)} + > + +
+ {prompts.map((v, _) => ( +
+
+ { + if (v.isUser) { + promptStore.updateUserPrompts( + v.id!, + (prompt) => (prompt.title = e.currentTarget.value), + ); + } + }} + > + +
+ {v.isUser && ( + } + bordered + className={styles["user-prompt-button"]} + onClick={() => promptStore.remove(v.id!)} + /> + )} + } + bordered + className={styles["user-prompt-button"]} + onClick={() => copyToClipboard(v.content)} + /> +
+
+ { + if (v.isUser) { + promptStore.updateUserPrompts( + v.id!, + (prompt) => (prompt.content = e.currentTarget.value), + ); + } + }} + /> +
+ ))} +
+
+
+
+ ); +} + function SettingItem(props: { title: string; subTitle?: string; @@ -99,18 +200,16 @@ export function Settings(props: { closeSettings: () => void }) { }); } - const [usage, setUsage] = useState<{ - used?: number; - subscription?: number; - }>(); + const usage = { + used: updateStore.used, + subscription: updateStore.subscription, + }; const [loadingUsage, setLoadingUsage] = useState(false); function checkUsage() { setLoadingUsage(true); - requestUsage() - .then((res) => setUsage(res)) - .finally(() => { - setLoadingUsage(false); - }); + updateStore.updateUsage().finally(() => { + setLoadingUsage(false); + }); } const accessStore = useAccessStore(); @@ -122,10 +221,12 @@ export function Settings(props: { closeSettings: () => void }) { const promptStore = usePromptStore(); const builtinCount = SearchService.count.builtin; - const customCount = promptStore.prompts.size ?? 0; + const customCount = promptStore.getUserPrompts().length ?? 0; + const [shouldShowPromptModal, setShowPromptModal] = useState(false); const showUsage = accessStore.isAuthorized(); useEffect(() => { + // checks per minutes checkUpdate(); showUsage && checkUsage(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -469,7 +570,7 @@ export function Settings(props: { closeSettings: () => void }) { } text={Locale.Settings.Prompt.Edit} - onClick={() => showToast(Locale.WIP)} + onClick={() => setShowPromptModal(true)} /> @@ -555,6 +656,10 @@ export function Settings(props: { closeSettings: () => void }) { > + + {shouldShowPromptModal && ( + setShowPromptModal(false)} /> + )} ); diff --git a/app/components/ui-lib.module.scss b/app/components/ui-lib.module.scss index 457c5504..8965c06a 100644 --- a/app/components/ui-lib.module.scss +++ b/app/components/ui-lib.module.scss @@ -53,7 +53,7 @@ box-shadow: var(--card-shadow); background-color: var(--white); border-radius: 12px; - width: 50vw; + width: 60vw; animation: slide-in ease 0.3s; --modal-padding: 20px; diff --git a/app/locales/cn.ts b/app/locales/cn.ts index 391ade2a..d0ab27ca 100644 --- a/app/locales/cn.ts +++ b/app/locales/cn.ts @@ -59,10 +59,10 @@ const cn = { ResetAll: "重置所有选项", Close: "关闭", ConfirmResetAll: { - Confirm: "Are you sure you want to reset all configurations?", + Confirm: "确认清除所有配置?", }, ConfirmClearAll: { - Confirm: "Are you sure you want to reset all chat?", + Confirm: "确认清除所有聊天记录?", }, }, Lang: { @@ -105,6 +105,11 @@ const cn = { ListCount: (builtin: number, custom: number) => `内置 ${builtin} 条,用户定义 ${custom} 条`, Edit: "编辑", + Modal: { + Title: "提示词列表", + Add: "增加一条", + Search: "搜尋提示詞", + }, }, HistoryCount: { Title: "附带历史消息数", diff --git a/app/locales/de.ts b/app/locales/de.ts index d373cba5..e71abfaf 100644 --- a/app/locales/de.ts +++ b/app/locales/de.ts @@ -107,6 +107,11 @@ const de: LocaleType = { ListCount: (builtin: number, custom: number) => `${builtin} integriert, ${custom} benutzerdefiniert`, Edit: "Bearbeiten", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, }, HistoryCount: { Title: "Anzahl der angehängten Nachrichten", diff --git a/app/locales/en.ts b/app/locales/en.ts index 213b02d3..20e56960 100644 --- a/app/locales/en.ts +++ b/app/locales/en.ts @@ -107,6 +107,11 @@ const en: LocaleType = { ListCount: (builtin: number, custom: number) => `${builtin} built-in, ${custom} user-defined`, Edit: "Edit", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, }, HistoryCount: { Title: "Attached Messages Count", @@ -128,7 +133,7 @@ const en: LocaleType = { return `Used this month $${used}, subscription $${total}`; }, IsChecking: "Checking...", - Check: "Check Again", + Check: "Check", NoAccess: "Enter API Key to check balance", }, AccessCode: { diff --git a/app/locales/es.ts b/app/locales/es.ts index 5d6eca17..e2a9eb21 100644 --- a/app/locales/es.ts +++ b/app/locales/es.ts @@ -107,6 +107,11 @@ const es: LocaleType = { ListCount: (builtin: number, custom: number) => `${builtin} incorporado, ${custom} definido por el usuario`, Edit: "Editar", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, }, HistoryCount: { Title: "Cantidad de mensajes adjuntos", diff --git a/app/locales/it.ts b/app/locales/it.ts index 22523888..f0453b5c 100644 --- a/app/locales/it.ts +++ b/app/locales/it.ts @@ -107,6 +107,11 @@ const it: LocaleType = { ListCount: (builtin: number, custom: number) => `${builtin} built-in, ${custom} user-defined`, Edit: "Modifica", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, }, HistoryCount: { Title: "Conteggio dei messaggi allegati", diff --git a/app/locales/jp.ts b/app/locales/jp.ts index f4ad741c..a793b5fe 100644 --- a/app/locales/jp.ts +++ b/app/locales/jp.ts @@ -108,6 +108,11 @@ const jp = { ListCount: (builtin: number, custom: number) => `組み込み ${builtin} 件、ユーザー定義 ${custom} 件`, Edit: "編集", + Modal: { + Title: "提示词列表", + Add: "增加一条", + Search: "搜尋提示詞", + }, }, HistoryCount: { Title: "履歴メッセージ数を添付", diff --git a/app/locales/tr.ts b/app/locales/tr.ts index a7ede192..04a84624 100644 --- a/app/locales/tr.ts +++ b/app/locales/tr.ts @@ -107,6 +107,11 @@ const tr: LocaleType = { ListCount: (builtin: number, custom: number) => `${builtin} yerleşik, ${custom} kullanıcı tanımlı`, Edit: "Düzenle", + Modal: { + Title: "Prompt List", + Add: "Add One", + Search: "Search Prompts", + }, }, HistoryCount: { Title: "Ekli Mesaj Sayısı", diff --git a/app/locales/tw.ts b/app/locales/tw.ts index 1397bb09..2fbb2e47 100644 --- a/app/locales/tw.ts +++ b/app/locales/tw.ts @@ -105,6 +105,11 @@ const tw: LocaleType = { ListCount: (builtin: number, custom: number) => `內置 ${builtin} 條,用戶定義 ${custom} 條`, Edit: "編輯", + Modal: { + Title: "提示詞列表", + Add: "增加一條", + Search: "搜索提示词", + }, }, HistoryCount: { Title: "附帶歷史訊息數", diff --git a/app/requests.ts b/app/requests.ts index db91f6fc..3cb838e6 100644 --- a/app/requests.ts +++ b/app/requests.ts @@ -114,6 +114,10 @@ export async function requestUsage() { response.total_usage = Math.round(response.total_usage) / 100; } + if (total.hard_limit_usd) { + total.hard_limit_usd = Math.round(total.hard_limit_usd * 100) / 100; + } + return { used: response.total_usage, subscription: total.hard_limit_usd, diff --git a/app/store/prompt.ts b/app/store/prompt.ts index 648b3814..8d754ff5 100644 --- a/app/store/prompt.ts +++ b/app/store/prompt.ts @@ -5,62 +5,74 @@ import { getLang } from "../locales"; export interface Prompt { id?: number; + isUser?: boolean; title: string; content: string; } export interface PromptStore { + counter: number; latestId: number; - prompts: Map; + prompts: Record; add: (prompt: Prompt) => number; remove: (id: number) => void; search: (text: string) => Prompt[]; + + getUserPrompts: () => Prompt[]; + updateUserPrompts: (id: number, updater: (prompt: Prompt) => void) => void; } export const PROMPT_KEY = "prompt-store"; export const SearchService = { ready: false, - engine: new Fuse([], { keys: ["title"] }), + builtinEngine: new Fuse([], { keys: ["title"] }), + userEngine: new Fuse([], { keys: ["title"] }), count: { builtin: 0, }, - allBuiltInPrompts: [] as Prompt[], + allPrompts: [] as Prompt[], + builtinPrompts: [] as Prompt[], - init(prompts: Prompt[]) { + init(builtinPrompts: Prompt[], userPrompts: Prompt[]) { if (this.ready) { return; } - this.allBuiltInPrompts = prompts; - this.engine.setCollection(prompts); + this.allPrompts = userPrompts.concat(builtinPrompts); + this.builtinPrompts = builtinPrompts.slice(); + this.builtinEngine.setCollection(builtinPrompts); + this.userEngine.setCollection(userPrompts); this.ready = true; }, remove(id: number) { - this.engine.remove((doc) => doc.id === id); + this.userEngine.remove((doc) => doc.id === id); }, add(prompt: Prompt) { - this.engine.add(prompt); + this.userEngine.add(prompt); }, search(text: string) { - const results = this.engine.search(text); - return results.map((v) => v.item); + const userResults = this.userEngine.search(text); + const builtinResults = this.builtinEngine.search(text); + return userResults.concat(builtinResults).map((v) => v.item); }, }; export const usePromptStore = create()( persist( (set, get) => ({ + counter: 0, latestId: 0, - prompts: new Map(), + prompts: {}, add(prompt) { const prompts = get().prompts; prompt.id = get().latestId + 1; - prompts.set(prompt.id, prompt); + prompt.isUser = true; + prompts[prompt.id] = prompt; set(() => ({ latestId: prompt.id!, @@ -72,19 +84,40 @@ export const usePromptStore = create()( remove(id) { const prompts = get().prompts; - prompts.delete(id); + delete prompts[id]; SearchService.remove(id); set(() => ({ prompts, + counter: get().counter + 1, })); }, + getUserPrompts() { + const userPrompts = Object.values(get().prompts ?? {}); + userPrompts.sort((a, b) => (b.id && a.id ? b.id - a.id : 0)); + return userPrompts; + }, + + updateUserPrompts(id: number, updater) { + const prompt = get().prompts[id] ?? { + title: "", + content: "", + id, + }; + + SearchService.remove(id); + updater(prompt); + const prompts = get().prompts; + prompts[id] = prompt; + set(() => ({ prompts })); + SearchService.add(prompt); + }, + search(text) { if (text.length === 0) { - // return all prompts - const userPrompts = get().prompts?.values?.() ?? []; - return SearchService.allBuiltInPrompts.concat([...userPrompts]); + // return all rompts + return SearchService.allPrompts.concat([...get().getUserPrompts()]); } return SearchService.search(text) as Prompt[]; }, @@ -104,23 +137,27 @@ export const usePromptStore = create()( if (getLang() === "cn") { fetchPrompts = fetchPrompts.reverse(); } - const builtinPrompts = fetchPrompts - .map((promptList: PromptList) => { + const builtinPrompts = fetchPrompts.map( + (promptList: PromptList) => { return promptList.map( ([title, content]) => ({ + id: Math.random(), title, content, } as Prompt), ); - }) - .concat([...(state?.prompts?.values() ?? [])]); + }, + ); + + const userPrompts = + usePromptStore.getState().getUserPrompts() ?? []; const allPromptsForSearch = builtinPrompts .reduce((pre, cur) => pre.concat(cur), []) .filter((v) => !!v.title && !!v.content); SearchService.count.builtin = res.en.length + res.cn.length; - SearchService.init(allPromptsForSearch); + SearchService.init(allPromptsForSearch, userPrompts); }); }, }, diff --git a/app/store/update.ts b/app/store/update.ts index efcdc8a7..47b190b8 100644 --- a/app/store/update.ts +++ b/app/store/update.ts @@ -1,13 +1,19 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; import { FETCH_COMMIT_URL, FETCH_TAG_URL } from "../constant"; +import { requestUsage } from "../requests"; export interface UpdateStore { lastUpdate: number; remoteVersion: string; + used?: number; + subscription?: number; + lastUpdateUsage: number; + version: string; - getLatestVersion: (force: boolean) => Promise; + getLatestVersion: (force?: boolean) => Promise; + updateUsage: (force?: boolean) => Promise; } export const UPDATE_KEY = "chat-update"; @@ -26,22 +32,27 @@ function queryMeta(key: string, defaultValue?: string): string { return ret; } +const ONE_MINUTE = 60 * 1000; + export const useUpdateStore = create()( persist( (set, get) => ({ lastUpdate: 0, remoteVersion: "", + lastUpdateUsage: 0, + version: "unknown", async getLatestVersion(force = false) { - set(() => ({ version: queryMeta("version") })); + set(() => ({ version: queryMeta("version") ?? "unknown" })); - const overTenMins = Date.now() - get().lastUpdate > 10 * 60 * 1000; - const shouldFetch = force || overTenMins; - if (!shouldFetch) { - return get().version ?? "unknown"; - } + const overTenMins = Date.now() - get().lastUpdate > 10 * ONE_MINUTE; + if (!force && !overTenMins) return; + + set(() => ({ + lastUpdate: Date.now(), + })); try { // const data = await (await fetch(FETCH_TAG_URL)).json(); @@ -49,14 +60,26 @@ export const useUpdateStore = create()( const data = await (await fetch(FETCH_COMMIT_URL)).json(); const remoteId = (data[0].sha as string).substring(0, 7); set(() => ({ - lastUpdate: Date.now(), remoteVersion: remoteId, })); console.log("[Got Upstream] ", remoteId); - return remoteId; } catch (error) { console.error("[Fetch Upstream Commit Id]", error); - return get().version ?? ""; + } + }, + + async updateUsage(force = false) { + const overOneMinute = Date.now() - get().lastUpdateUsage >= ONE_MINUTE; + if (!overOneMinute && !force) return; + + set(() => ({ + lastUpdateUsage: Date.now(), + })); + + const usage = await requestUsage(); + + if (usage) { + set(() => usage); } }, }), diff --git a/app/styles/globals.scss b/app/styles/globals.scss index cf36ee92..37c66228 100644 --- a/app/styles/globals.scss +++ b/app/styles/globals.scss @@ -140,6 +140,7 @@ label { input { text-align: center; + font-family: inherit; } input[type="checkbox"] { @@ -224,6 +225,7 @@ input[type="password"] { color: var(--black); padding: 0 10px; max-width: 50%; + font-family: inherit; } div.math { diff --git a/package.json b/package.json index acca33ce..19047ad1 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "emoji-picker-react": "^4.4.7", "eventsource-parser": "^0.1.0", "fuse.js": "^6.6.2", - "next": "^13.3.0", + "next": "^13.3.1-canary.8", "node-fetch": "^3.3.1", "openai": "^3.2.1", "react": "^18.2.0", diff --git a/yarn.lock b/yarn.lock index f1f5bf2f..342ea4a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1099,10 +1099,10 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" -"@next/env@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/env/-/env-13.3.0.tgz#cc2e49f03060a4684ce7ec7fd617a21bc5b9edba" - integrity sha512-AjppRV4uG3No7L1plinoTQETH+j2F10TEnrMfzbTUYwze5sBUPveeeBAPZPm8OkJZ1epq9OyYKhZrvbD6/9HCQ== +"@next/env@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.3.1-canary.8.tgz#9f5cf57999e4f4b59ef6407924803a247cc4e451" + integrity sha512-xZfNu7yq3OfiC4rkGuGMcqb25se+ZHRqajSdny8dp+nZzkNSK1SHuNT3W8faI+KGk6dqzO/zAdHR9YrqnQlCAg== "@next/eslint-plugin-next@13.2.3": version "13.2.3" @@ -1111,50 +1111,50 @@ dependencies: glob "7.1.7" -"@next/swc-darwin-arm64@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.0.tgz#38f18e0639cd4c7edc6a38d4b83fe00f38eea4f2" - integrity sha512-DmIQCNq6JtccLPPBzf0dgh2vzMWt5wjxbP71pCi5EWpWYE3MsP6FcRXi4MlAmFNDQOfcFXR2r7kBeG1LpZUh1w== +"@next/swc-darwin-arm64@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.1-canary.8.tgz#66786ba76d37c210c184739624c6f84eaf2dc52b" + integrity sha512-BLbvhcaSzwuXbREOmJiqAdXVD7Jl9830hDY5ZTTNg7hXqEZgoMg2LxAEmtaaBMVZRfDQjd5bH3QPBV8fbG4UKg== -"@next/swc-darwin-x64@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.0.tgz#b670ed1fd1d231aa21279173ec52e3ad56dc6aeb" - integrity sha512-oQoqFa88OGgwnYlnAGHVct618FRI/749se0N3S8t9Bzdv5CRbscnO0RcX901+YnNK4Q6yeiizfgO3b7kogtsZg== +"@next/swc-darwin-x64@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.1-canary.8.tgz#289296bd3cc55db7fef42037eb89ce4a6260ba31" + integrity sha512-n4tJKPIvFTZshS1TVWrsqaW7h9VW+BmguO/AlZ3Q3NJ9hWxC5L4lxn2T6CTQ4M30Gf+t5u+dPzYLQ5IDtJFnFQ== -"@next/swc-linux-arm64-gnu@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.0.tgz#b114935f6b4c94c123f6cac55a4823d483209ba5" - integrity sha512-Wzz2p/WqAJUqTVoLo6H18WMeAXo3i+9DkPDae4oQG8LMloJ3if4NEZTnOnTUlro6cq+S/W4pTGa97nWTrOjbGw== +"@next/swc-linux-arm64-gnu@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.1-canary.8.tgz#dc79e8005849b6482241b460abdce9334665c766" + integrity sha512-AxnsgZ56whwVAeejyEZMk8xc8Vapwzb3Zn0YdZzPCR42WKfkcSkM+AWfq33zUOZnjvCmQBDyfHIo4CURVweR6g== -"@next/swc-linux-arm64-musl@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.0.tgz#67a57309f8761c7d00d629d6785d56ed0567a0d2" - integrity sha512-xPVrIQOQo9WXJYgmoTlMnAD/HlR/1e1ZIWGbwIzEirXBVBqMARUulBEIKdC19zuvoJ477qZJgBDCKtKEykCpyQ== +"@next/swc-linux-arm64-musl@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.1-canary.8.tgz#f70873add4aad7ced36f760d1640adc008b7dc03" + integrity sha512-zc7rzhtrHMWZ/phvjCNplHGo+ZLembjtluI5J8Xl4iwQQCyZwAtnmQhs37/zkdi6dHZou+wcFBZWRz14awRDBw== -"@next/swc-linux-x64-gnu@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.0.tgz#11bd2bea7c00b40be111c0dd16e71171f3792086" - integrity sha512-jOFlpGuPD7W2tuXVJP4wt9a3cpNxWAPcloq5EfMJRiXsBBOjLVFZA7boXYxEBzSVgUiVVr1V9T0HFM7pULJ1qA== +"@next/swc-linux-x64-gnu@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.1-canary.8.tgz#fe81b8033628c6cf74e154f2db8c8c7f1593008f" + integrity sha512-vNbFDiuZ9fWmcznlilDbflZLb04evWPUQlyDT7Tqjd964PlSIaaX3tr64pdYjJOljDaqTr2Kbx0YW74mWF/PEw== -"@next/swc-linux-x64-musl@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.0.tgz#d57e99f85890799b78719c3ea32a4624de8d701b" - integrity sha512-2OwKlzaBgmuet9XYHc3KwsEilzb04F540rlRXkAcjMHL7eCxB7uZIGtsVvKOnQLvC/elrUegwSw1+5f7WmfyOw== +"@next/swc-linux-x64-musl@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.1-canary.8.tgz#ada4585046a7937f96f2d39fc4aaca12826dde5f" + integrity sha512-/FVBPJEBDZYCNraocRWtd5ObAgNi9VFnzJYGYDYIj4jKkFRWWm/CaWu9A7toQACC/JDy262uPyDPathXT9BAqQ== -"@next/swc-win32-arm64-msvc@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.0.tgz#0c209aa35d1c88b01e78259a89cd68f4139b5093" - integrity sha512-OeHiA6YEvndxT46g+rzFK/MQTfftKxJmzslERMu9LDdC6Kez0bdrgEYed5eXFK2Z1viKZJCGRlhd06rBusyztA== +"@next/swc-win32-arm64-msvc@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.1-canary.8.tgz#21b4f6c4be61845759753df9313bd9bcbb241969" + integrity sha512-8jMwRCeI26yVZLPwG0AjOi4b1yqSeqYmbHA7r+dqiV0OgFdYjnbyHU1FmiKDaC5SnnJN6LWV2Qjer9GDD0Kcuw== -"@next/swc-win32-ia32-msvc@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.0.tgz#52ae74da1dd6d840c3743923367d27ed013803dd" - integrity sha512-4aB7K9mcVK1lYEzpOpqWrXHEZympU3oK65fnNcY1Qc4HLJFLJj8AViuqQd4jjjPNuV4sl8jAwTz3gN5VNGWB7w== +"@next/swc-win32-ia32-msvc@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.1-canary.8.tgz#e23192e1d1b1a32b0eb805363b02360c5b523a77" + integrity sha512-kcYB9iSEikFhv0I9uQDdgQ2lm8i3O8LA+GhnED9e5VtURBwOSwED7c6ZpaRQBYSPgnEA9/xiJVChICE/I7Ig1g== -"@next/swc-win32-x64-msvc@13.3.0": - version "13.3.0" - resolved "https://registry.npmmirror.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.0.tgz#db7b55fee834dc8c2c484c696469e65bae2ee770" - integrity sha512-Reer6rkLLcoOvB0dd66+Y7WrWVFH7sEEkF/4bJCIfsSKnTStTYaHtwIJAwbqnt9I392Tqvku0KkoqZOryWV9LQ== +"@next/swc-win32-x64-msvc@13.3.1-canary.8": + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.1-canary.8.tgz#a3f29404955cba2193de5e74fd5d9fcfdcb0ab51" + integrity sha512-UKrGHonKVWBNg+HI4J8pXE6Jjjl8GwjhygFau71s8M0+jSy99y5Y+nGH9EmMNWKNvrObukyYvrs6OsAusKdCqw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -3924,27 +3924,27 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -next@^13.3.0: - version "13.3.0" - resolved "https://registry.npmmirror.com/next/-/next-13.3.0.tgz#40632d303d74fc8521faa0a5bf4a033a392749b1" - integrity sha512-OVTw8MpIPa12+DCUkPqRGPS3thlJPcwae2ZL4xti3iBff27goH024xy4q2lhlsdoYiKOi8Kz6uJoLW/GXwgfOA== +next@^13.3.1-canary.8: + version "13.3.1-canary.8" + resolved "https://registry.yarnpkg.com/next/-/next-13.3.1-canary.8.tgz#f0846e5eada1491884326786a0749d5adc04c24d" + integrity sha512-z4QUgyAN+hSWSEqb4pvGvC3iRktE6NH2DVLU4AvfqNYpzP+prePiJC8HN/cJpFhGW9YbhyRLi5FliDC631OOag== dependencies: - "@next/env" "13.3.0" + "@next/env" "13.3.1-canary.8" "@swc/helpers" "0.4.14" busboy "1.6.0" caniuse-lite "^1.0.30001406" postcss "8.4.14" styled-jsx "5.1.1" optionalDependencies: - "@next/swc-darwin-arm64" "13.3.0" - "@next/swc-darwin-x64" "13.3.0" - "@next/swc-linux-arm64-gnu" "13.3.0" - "@next/swc-linux-arm64-musl" "13.3.0" - "@next/swc-linux-x64-gnu" "13.3.0" - "@next/swc-linux-x64-musl" "13.3.0" - "@next/swc-win32-arm64-msvc" "13.3.0" - "@next/swc-win32-ia32-msvc" "13.3.0" - "@next/swc-win32-x64-msvc" "13.3.0" + "@next/swc-darwin-arm64" "13.3.1-canary.8" + "@next/swc-darwin-x64" "13.3.1-canary.8" + "@next/swc-linux-arm64-gnu" "13.3.1-canary.8" + "@next/swc-linux-arm64-musl" "13.3.1-canary.8" + "@next/swc-linux-x64-gnu" "13.3.1-canary.8" + "@next/swc-linux-x64-musl" "13.3.1-canary.8" + "@next/swc-win32-arm64-msvc" "13.3.1-canary.8" + "@next/swc-win32-ia32-msvc" "13.3.1-canary.8" + "@next/swc-win32-x64-msvc" "13.3.1-canary.8" node-domexception@^1.0.0: version "1.0.0"