59 Commits

Author SHA1 Message Date
5fa6d4182a fix args copy 2023-07-08 15:14:46 +08:00
feecd6582d esgimate token length after editing 2023-07-08 14:45:21 +08:00
4ce23bb1eb move dev buttons to down 2023-07-08 14:40:26 +08:00
1cac4a77c0 calculate response token in stream mode 2023-07-08 14:35:10 +08:00
f2129f6a67 fix edit message z-index 10 2023-07-08 14:24:32 +08:00
86699511df edit message token 2023-07-08 14:23:56 +08:00
e2f78987a3 setShowRetry(false) on success 2023-07-08 14:17:30 +08:00
8fb17ba3f8 fix bug on completion with empty history 2023-07-08 14:16:51 +08:00
1b8eeb0c86 fix calculate user token in hide state 2023-07-08 14:03:45 +08:00
9d34189c96 regenerate and complte function 2023-07-08 10:07:10 +08:00
22b4d59b1c v1.4.0 warning 2023-07-08 09:56:41 +08:00
c0566f3105 better way to edit message content 2023-07-07 19:11:01 +08:00
1c14e413bb fix develop mode style 2023-07-07 18:57:54 +08:00
1da4d38799 1.4.0 dev mode support more ops and args 2023-07-07 18:20:14 +08:00
ecfa32f75e chatgpt.ts support more args 2023-07-07 11:06:30 +08:00
7553cf41cf update packages 2023-07-03 10:17:59 +08:00
66ab8d4978 handle partial chunk 2023-06-19 20:33:18 +08:00
da31f32fcb Update chatbox.tsx handle "data:{xxxx}" 2023-06-19 20:11:09 +08:00
280545c224 accumulated cost 2023-06-14 13:14:28 +08:00
7ded1c8522 change default system message to "follow my instructions carefully" 2023-06-14 12:47:53 +08:00
e76f087776 fix generating message style 2023-06-14 12:45:11 +08:00
67e12e6933 change default model to gpt-3.5-turbo-0613 2023-06-14 12:16:22 +08:00
4860c6dff3 inherit chatStore.model 2023-06-14 12:14:57 +08:00
e03160d04d openai model update 2023-06-14 12:10:18 +08:00
b46b550a70 recognize text/event-stream, charset=utf-8 2023-04-19 16:21:05 +08:00
8f1a327ea0 fix total token in stream mode 2023-04-04 00:39:58 +08:00
8c049c9ee9 handle response error 2023-04-03 17:46:07 +08:00
528eb0a300 永远显示提示<p> 2023-04-03 17:46:07 +08:00
d5d077f39c Update README.md 2023-04-02 13:01:38 +08:00
b4244d3900 现在我觉得它不灵车了 2023-04-01 19:57:59 +08:00
8f3d69d2a2 fix todo: estimate user's token 2023-04-01 12:35:26 +08:00
11d9b09e36 prevent undefined on new models 2023-03-31 15:00:57 +08:00
464e417537 switch model with token 2023-03-31 05:14:44 +08:00
5a328db87d cost in stream mode 2023-03-31 05:09:25 +08:00
3b09abaf66 header 2023-03-31 05:00:52 +08:00
05f57f29e5 show cost 2023-03-31 04:50:49 +08:00
11afa12b09 fix show version warning 2023-03-31 04:41:08 +08:00
26f9632f41 record each message's token and hide status, calc postBeginIndex based on token 2023-03-31 04:16:23 +08:00
bdfe03699f support import chat store 2023-03-30 14:33:54 +08:00
fecfc24519 support export as json 2023-03-30 13:56:03 +08:00
07885c681c show response model name 2023-03-30 13:39:19 +08:00
faac2303df gpt-4 内测提示 2023-03-30 13:01:28 +08:00
fc17d6ba15 fix copy max_token from chaStore to client 2023-03-29 16:42:57 +08:00
3de689a796 use gpt-3.5-turbo as default new ChatStore 2023-03-29 15:51:04 +08:00
35ee9cab0e highlight status bar 2023-03-29 15:48:49 +08:00
5fc2c62b4f select chat index after fetch 2023-03-29 15:37:36 +08:00
c31c6cd84a set maxToken based on model 2023-03-29 13:02:48 +08:00
6406993e83 handle create new chatstore on diff model 2023-03-29 12:51:31 +08:00
2d7edeb5b0 support gpt-4 2023-03-29 12:45:59 +08:00
1158fdca38 update stream mode based on response 2023-03-28 21:18:30 +08:00
7c34379ecb calculate token and forget some message 2023-03-28 21:12:34 +08:00
26a66d112b create chatStore if not equal params 2023-03-27 13:43:06 +08:00
e791367d2d break all text 2023-03-27 13:18:30 +08:00
30abf3ed15 auto create new chatStore if there any params in URL 2023-03-27 13:15:23 +08:00
146f34a22d 更好的提示 2023-03-26 21:00:28 +08:00
d5a8799fde issue caused by height: 100vh 2023-03-26 19:30:03 +08:00
241a93b151 更改默认 system message 2023-03-26 18:36:51 +08:00
a4b762586c 更好的文档和提示 2023-03-26 14:04:53 +08:00
700c424d64 更好的提示 2023-03-26 00:11:11 +08:00
12 changed files with 1199 additions and 393 deletions

View File

@@ -1,9 +1,11 @@
> 前排提示:滥用 API 或在不支持的地区调用 API 有被封号的风险 <https://github.com/zhayujie/chatgpt-on-wechat/issues/423> > 前排提示:滥用 API 或在不支持的地区调用 API 有被封号的风险 <https://github.com/zhayujie/chatgpt-on-wechat/issues/423>
>
> 建议自行搭建代理中转 API 请求,然后更改对话设置中的 API Endpoint 参数使用中转
>
> 具体反向代理搭建教程请参阅此 [>>Wiki页面<<](https://github.com/heimoshuiyu/chatgpt-api-web/wiki)
# ChatGPT API WEB # ChatGPT API WEB
> 灵车东西,做着玩儿的
一个简单的网页,调用 OPENAI ChatGPT 进行对话。 一个简单的网页,调用 OPENAI ChatGPT 进行对话。
![build status](https://github.com/heimoshuiyu/chatgpt-api-web/actions/workflows/pages.yml/badge.svg) ![build status](https://github.com/heimoshuiyu/chatgpt-api-web/actions/workflows/pages.yml/badge.svg)
@@ -13,7 +15,14 @@
- API 调用速度更快更稳定 - API 调用速度更快更稳定
- 对话记录、API 密钥等使用浏览器的 localStorage 保存在本地 - 对话记录、API 密钥等使用浏览器的 localStorage 保存在本地
- 可删除对话消息 - 可删除对话消息
- 可以设置 system message (如:"你是一个猫娘" 或 "你是一个有用的助理" 或 "将我的话翻译成英语",参见官方 [API 文档](https://platform.openai.com/docs/guides/chat)) - 可以导入/导出整个历史对话记录
- 可以设置 system message (参见官方 [API 文档](https://platform.openai.com/docs/guides/chat)) 例如:
- > 你是一个有用的有用的人工智能助理
- > You are a helpful assistant
- > 你是一个专业英语翻译,把我说的话翻译成英语,为了保持通顺连贯可以适当修改内容。
- > 根据我的描述给出适用于 Stable Diffusion 的 prompt 和 negative prompt用英文回答要求尽量长一些。
- > 根据我的要求撰写并修改商业文案
- > ~~你是一个猫娘,你要用猫娘的语气说话~~
- 可以为不同对话设置不同 APIKEY - 可以为不同对话设置不同 APIKEY
- 小(整个网页 30k 左右) - 小(整个网页 30k 左右)
- 可以设置不同的 API Endpoint方便墙内人士使用反向代理转发 API 请求) - 可以设置不同的 API Endpoint方便墙内人士使用反向代理转发 API 请求)
@@ -30,6 +39,12 @@
- 从 [release](https://github.com/heimoshuiyu/chatgpt-api-web/releases) 下载网页文件,或在 [github pages](https://heimoshuiyu.github.io/chatgpt-api-web/) 按 `ctrl+s` 保存网页,然后双击打开 - 从 [release](https://github.com/heimoshuiyu/chatgpt-api-web/releases) 下载网页文件,或在 [github pages](https://heimoshuiyu.github.io/chatgpt-api-web/) 按 `ctrl+s` 保存网页,然后双击打开
- 自行编译构建网页 - 自行编译构建网页
### 默认参数继承
新建会话将会使用 URL 中设置的默认参数。
如果 URL 没有设置该参数,则使用 **目前选中的会话** 的参数
### 更改默认参数 ### 更改默认参数
- `key`: OPENAI API KEY 默认为空 - `key`: OPENAI API KEY 默认为空

View File

@@ -10,15 +10,14 @@
}, },
"dependencies": { "dependencies": {
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"postcss": "^8.4.21", "postcss": "^8.4.24",
"preact": "^10.11.3", "preact": "^10.15.1",
"preact-markdown": "^2.1.0",
"sakura.css": "^1.4.1", "sakura.css": "^1.4.1",
"tailwindcss": "^3.2.7" "tailwindcss": "^3.3.2"
}, },
"devDependencies": { "devDependencies": {
"@preact/preset-vite": "^2.5.0", "@preact/preset-vite": "^2.5.0",
"typescript": "^4.9.3", "typescript": "^5.1.6",
"vite": "^4.1.0" "vite": "^4.3.9"
} }
} }

View File

@@ -0,0 +1,3 @@
const CHATGPT_API_WEB_VERSION = "v1.4.0";
export default CHATGPT_API_WEB_VERSION;

View File

@@ -1,13 +1,22 @@
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import "./global.css"; import "./global.css";
import { Message } from "./chatgpt"; import { calculate_token_length, Message } from "./chatgpt";
import getDefaultParams from "./getDefaultParam"; import getDefaultParams from "./getDefaultParam";
import ChatBOX from "./chatbox"; import ChatBOX from "./chatbox";
import models from "./models";
import CHATGPT_API_WEB_VERSION from "./CHATGPT_API_WEB_VERSION";
export interface ChatStoreMessage extends Message {
hide: boolean;
token: number;
}
export interface ChatStore { export interface ChatStore {
chatgpt_api_web_version: string;
systemMessageContent: string; systemMessageContent: string;
history: Message[]; history: ChatStoreMessage[];
postBeginIndex: number; postBeginIndex: number;
tokenMargin: number; tokenMargin: number;
totalTokens: number; totalTokens: number;
@@ -15,31 +24,69 @@ export interface ChatStore {
apiKey: string; apiKey: string;
apiEndpoint: string; apiEndpoint: string;
streamMode: boolean; streamMode: boolean;
model: string;
responseModelName: string;
cost: number;
temperature: number;
top_p: number;
presence_penalty: number;
frequency_penalty: number;
develop_mode: boolean;
} }
const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions"; const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions";
const newChatStore = ( const newChatStore = (
apiKey = "", apiKey = "",
systemMessageContent = "你是一个有用的人工智能助理", systemMessageContent = "Follow my instructions carefully",
apiEndpoint = _defaultAPIEndpoint, apiEndpoint = _defaultAPIEndpoint,
streamMode = true streamMode = true,
model = "gpt-3.5-turbo-0613",
temperature = 1.0,
dev = false
): ChatStore => { ): ChatStore => {
return { return {
chatgpt_api_web_version: CHATGPT_API_WEB_VERSION,
systemMessageContent: getDefaultParams("sys", systemMessageContent), systemMessageContent: getDefaultParams("sys", systemMessageContent),
history: [], history: [],
postBeginIndex: 0, postBeginIndex: 0,
tokenMargin: 1024, tokenMargin: 1024,
totalTokens: 0, totalTokens: 0,
maxTokens: 4096, maxTokens: models[getDefaultParams("model", model)]?.maxToken ?? 4096,
apiKey: getDefaultParams("key", apiKey), apiKey: getDefaultParams("key", apiKey),
apiEndpoint: getDefaultParams("api", apiEndpoint), apiEndpoint: getDefaultParams("api", apiEndpoint),
streamMode: getDefaultParams("mode", streamMode), streamMode: getDefaultParams("mode", streamMode),
model: getDefaultParams("model", model),
responseModelName: "",
cost: 0,
temperature: getDefaultParams("temp", temperature),
top_p: 1,
presence_penalty: 0,
frequency_penalty: 0,
develop_mode: getDefaultParams("dev", dev),
}; };
}; };
const STORAGE_NAME = "chatgpt-api-web"; const STORAGE_NAME = "chatgpt-api-web";
const STORAGE_NAME_SELECTED = `${STORAGE_NAME}-selected`; const STORAGE_NAME_SELECTED = `${STORAGE_NAME}-selected`;
const STORAGE_NAME_INDEXES = `${STORAGE_NAME}-indexes`; const STORAGE_NAME_INDEXES = `${STORAGE_NAME}-indexes`;
const STORAGE_NAME_TOTALCOST = `${STORAGE_NAME}-totalcost`;
export function addTotalCost(cost: number) {
let totalCost = getTotalCost();
totalCost += cost;
localStorage.setItem(STORAGE_NAME_TOTALCOST, `${totalCost}`);
}
export function getTotalCost(): number {
let totalCost = parseFloat(
localStorage.getItem(STORAGE_NAME_TOTALCOST) ?? "0"
);
return totalCost;
}
export function clearTotalCost() {
localStorage.setItem(STORAGE_NAME_TOTALCOST, `0`);
}
export function App() { export function App() {
// init indexes // init indexes
@@ -71,31 +118,57 @@ export function App() {
const key = `${STORAGE_NAME}-${index}`; const key = `${STORAGE_NAME}-${index}`;
const val = localStorage.getItem(key); const val = localStorage.getItem(key);
if (val === null) return newChatStore(); if (val === null) return newChatStore();
return JSON.parse(val) as ChatStore; const ret = JSON.parse(val) as ChatStore;
// handle read from old version chatstore
if (ret.model === undefined) ret.model = "gpt-3.5-turbo";
if (ret.responseModelName === undefined) ret.responseModelName = "";
if (ret.chatgpt_api_web_version === undefined)
// this is from old version becasue it is undefined,
// so no higher than v1.3.0
ret.chatgpt_api_web_version = "v1.2.2";
for (const message of ret.history) {
if (message.hide === undefined) message.hide = false;
if (message.token === undefined)
message.token = calculate_token_length(message.content);
}
if (ret.cost === undefined) ret.cost = 0;
return ret;
}; };
const [chatStore, _setChatStore] = useState( const [chatStore, _setChatStore] = useState(
getChatStoreByIndex(selectedChatIndex) getChatStoreByIndex(selectedChatIndex)
); );
const setChatStore = (cs: ChatStore) => { const setChatStore = (chatStore: ChatStore) => {
console.log("saved chat", selectedChatIndex, chatStore); console.log("saved chat", selectedChatIndex, chatStore);
localStorage.setItem( localStorage.setItem(
`${STORAGE_NAME}-${selectedChatIndex}`, `${STORAGE_NAME}-${selectedChatIndex}`,
JSON.stringify(cs) JSON.stringify(chatStore)
); );
_setChatStore(cs);
console.log("recalculate postBeginIndex");
const max = chatStore.maxTokens - chatStore.tokenMargin;
let sum = 0;
chatStore.postBeginIndex = chatStore.history.filter(
({ hide }) => !hide
).length;
for (const msg of chatStore.history
.filter(({ hide }) => !hide)
.slice()
.reverse()) {
if (sum + msg.token > max) break;
sum += msg.token;
chatStore.postBeginIndex -= 1;
}
chatStore.postBeginIndex =
chatStore.postBeginIndex < 0 ? 0 : chatStore.postBeginIndex;
_setChatStore(chatStore);
}; };
useEffect(() => { useEffect(() => {
_setChatStore(getChatStoreByIndex(selectedChatIndex)); _setChatStore(getChatStoreByIndex(selectedChatIndex));
}, [selectedChatIndex]); }, [selectedChatIndex]);
return ( const handleNewChatStore = () => {
<div className="flex text-sm h-screen bg-slate-200 dark:bg-slate-800 dark:text-white">
<div className="flex flex-col h-full p-2 border-r-indigo-500 border-2 dark:border-slate-800 dark:border-r-indigo-500 dark:text-black">
<div className="grow overflow-scroll">
<button
className="bg-violet-300 p-1 rounded hover:bg-violet-400"
onClick={() => {
const max = Math.max(...allChatStoreIndexes); const max = Math.max(...allChatStoreIndexes);
const next = max + 1; const next = max + 1;
console.log("save next chat", next); console.log("save next chat", next);
@@ -106,14 +179,43 @@ export function App() {
chatStore.apiKey, chatStore.apiKey,
chatStore.systemMessageContent, chatStore.systemMessageContent,
chatStore.apiEndpoint, chatStore.apiEndpoint,
chatStore.streamMode chatStore.streamMode,
chatStore.model
) )
) )
); );
allChatStoreIndexes.push(next); allChatStoreIndexes.push(next);
setAllChatStoreIndexes([...allChatStoreIndexes]); setAllChatStoreIndexes([...allChatStoreIndexes]);
setSelectedChatIndex(next); setSelectedChatIndex(next);
}} };
// if there are any params in URL, create a new chatStore
useEffect(() => {
const api = getDefaultParams("api", "");
const key = getDefaultParams("key", "");
const sys = getDefaultParams("sys", "");
const mode = getDefaultParams("mode", "");
const model = getDefaultParams("model", "");
// only create new chatStore if the params in URL are NOT
// equal to the current selected chatStore
if (
(api && api !== chatStore.apiEndpoint) ||
(key && key !== chatStore.apiKey) ||
(sys && sys !== chatStore.systemMessageContent) ||
(mode && mode !== (chatStore.streamMode ? "stream" : "fetch")) ||
(model && model !== chatStore.model)
) {
handleNewChatStore();
}
}, []);
return (
<div className="flex text-sm h-full bg-slate-200 dark:bg-slate-800 dark:text-white">
<div className="flex flex-col h-full p-2 border-r-indigo-500 border-2 dark:border-slate-800 dark:border-r-indigo-500 dark:text-black">
<div className="grow overflow-scroll">
<button
className="bg-violet-300 p-1 rounded hover:bg-violet-400"
onClick={handleNewChatStore}
> >
NEW NEW
</button> </button>
@@ -126,7 +228,7 @@ export function App() {
return ( return (
<li> <li>
<button <button
className={`w-full my-1 p-1 rounded hover:bg-blue-300 ${ className={`w-full my-1 p-1 rounded hover:bg-blue-500 ${
i === selectedChatIndex ? "bg-blue-500" : "bg-blue-200" i === selectedChatIndex ? "bg-blue-500" : "bg-blue-200"
}`} }`}
onClick={() => { onClick={() => {
@@ -158,7 +260,8 @@ export function App() {
chatStore.apiKey, chatStore.apiKey,
chatStore.systemMessageContent, chatStore.systemMessageContent,
chatStore.apiEndpoint, chatStore.apiEndpoint,
chatStore.streamMode chatStore.streamMode,
chatStore.model
) )
); );
} }
@@ -175,7 +278,12 @@ export function App() {
DEL DEL
</button> </button>
</div> </div>
<ChatBOX chatStore={chatStore} setChatStore={setChatStore} /> <ChatBOX
chatStore={chatStore}
setChatStore={setChatStore}
selectedChatIndex={selectedChatIndex}
setSelectedChatIndex={setSelectedChatIndex}
/>
</div> </div>
); );
} }

View File

@@ -1,13 +1,20 @@
import { createRef } from "preact"; import { createRef } from "preact";
import { useEffect, useState } from "preact/hooks"; import { StateUpdater, useEffect, useState } from "preact/hooks";
import type { ChatStore } from "./app"; import { ChatStore, addTotalCost } from "./app";
import ChatGPT, { ChunkMessage, FetchResponse } from "./chatgpt"; import ChatGPT, {
calculate_token_length,
ChunkMessage,
FetchResponse,
} from "./chatgpt";
import Message from "./message"; import Message from "./message";
import models from "./models";
import Settings from "./settings"; import Settings from "./settings";
export default function ChatBOX(props: { export default function ChatBOX(props: {
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
selectedChatIndex: number;
setSelectedChatIndex: StateUpdater<number>;
}) { }) {
const { chatStore, setChatStore } = props; const { chatStore, setChatStore } = props;
// prevent error // prevent error
@@ -25,20 +32,36 @@ export default function ChatBOX(props: {
const client = new ChatGPT(chatStore.apiKey); const client = new ChatGPT(chatStore.apiKey);
const update_total_tokens = () => {
// manually estimate token
client.total_tokens = calculate_token_length(
chatStore.systemMessageContent
);
for (const msg of chatStore.history
.filter(({ hide }) => !hide)
.slice(chatStore.postBeginIndex)) {
client.total_tokens += msg.token;
}
chatStore.totalTokens = client.total_tokens;
};
const _completeWithStreamMode = async (response: Response) => { const _completeWithStreamMode = async (response: Response) => {
let responseTokenCount = 0;
chatStore.streamMode = true;
// call api, return reponse text // call api, return reponse text
console.log("response", response); console.log("response", response);
const reader = response.body?.getReader(); const reader = response.body?.getReader();
const allChunkMessage: string[] = []; const allChunkMessage: string[] = [];
new ReadableStream({ new ReadableStream({
async start() { async start() {
let lastText = "";
while (true) { while (true) {
let responseDone = false; let responseDone = false;
let state = await reader?.read(); let state = await reader?.read();
let done = state?.done; let done = state?.done;
let value = state?.value; let value = state?.value;
if (done) break; if (done) break;
let text = new TextDecoder().decode(value); let text = lastText + new TextDecoder().decode(value);
// console.log("text:", text); // console.log("text:", text);
const lines = text const lines = text
.trim() .trim()
@@ -46,19 +69,32 @@ export default function ChatBOX(props: {
.map((line) => line.trim()) .map((line) => line.trim())
.filter((i) => { .filter((i) => {
if (!i) return false; if (!i) return false;
if (i === "data: [DONE]") { if (i === "data: [DONE]" || i === "data:[DONE]") {
responseDone = true; responseDone = true;
responseTokenCount += 1;
return false; return false;
} }
return true; return true;
}); });
responseTokenCount += lines.length;
console.log("lines", lines); console.log("lines", lines);
const jsons: ChunkMessage[] = lines const jsons: ChunkMessage[] = lines
.map((line) => { .map((line) => {
return JSON.parse(line.trim().slice("data: ".length)); try {
const ret = JSON.parse(line.trim().slice("data:".length));
lastText = "";
return ret;
} catch (e) {
console.log(`Chunk parse error at: ${line}`);
lastText = line;
return null;
}
}) })
.filter((i) => i); .filter((i) => i);
// console.log("jsons", jsons); console.log("jsons", jsons);
for (const { model } of jsons) {
if (model) chatStore.responseModelName = model;
}
const chunkText = jsons const chunkText = jsons
.map((j) => j.choices[0].delta.content ?? "") .map((j) => j.choices[0].delta.content ?? "")
.join(""); .join("");
@@ -71,17 +107,36 @@ export default function ChatBOX(props: {
setShowGenerating(false); setShowGenerating(false);
// console.log("push to history", allChunkMessage); // console.log("push to history", allChunkMessage);
const content = allChunkMessage.join("");
// estimate cost
let cost = 0;
if (chatStore.responseModelName) {
cost +=
responseTokenCount *
(models[chatStore.responseModelName]?.price?.completion ?? 0);
let sum = 0;
for (const msg of chatStore.history
.filter(({ hide }) => !hide)
.slice(chatStore.postBeginIndex)) {
sum += msg.token;
}
cost +=
sum * (models[chatStore.responseModelName]?.price?.prompt ?? 0);
}
chatStore.cost += cost;
addTotalCost(cost);
chatStore.history.push({ chatStore.history.push({
role: "assistant", role: "assistant",
content: allChunkMessage.join(""), content,
hide: false,
token: responseTokenCount,
}); });
// manually copy status from client to chatStore // manually copy status from client to chatStore
chatStore.maxTokens = client.max_tokens; chatStore.maxTokens = client.max_tokens;
chatStore.tokenMargin = client.tokens_margin; chatStore.tokenMargin = client.tokens_margin;
chatStore.totalTokens = update_total_tokens();
client.total_tokens +
39 +
client.calculate_token_length(allChunkMessage.join(""));
setChatStore({ ...chatStore }); setChatStore({ ...chatStore });
setGeneratingMessage(""); setGeneratingMessage("");
setShowGenerating(false); setShowGenerating(false);
@@ -90,9 +145,44 @@ export default function ChatBOX(props: {
}; };
const _completeWithFetchMode = async (response: Response) => { const _completeWithFetchMode = async (response: Response) => {
chatStore.streamMode = false;
const data = (await response.json()) as FetchResponse; const data = (await response.json()) as FetchResponse;
chatStore.responseModelName = data.model ?? "";
if (data.model) {
let cost = 0;
cost +=
(data.usage.prompt_tokens ?? 0) *
(models[data.model]?.price?.prompt ?? 0);
cost +=
(data.usage.completion_tokens ?? 0) *
(models[data.model]?.price?.completion ?? 0);
chatStore.cost += cost;
addTotalCost(cost);
}
const content = client.processFetchResponse(data); const content = client.processFetchResponse(data);
chatStore.history.push({ role: "assistant", content });
// estimate user's input message token
let aboveToken = 0;
for (const msg of chatStore.history
.filter(({ hide }) => !hide)
.slice(chatStore.postBeginIndex, -1)) {
aboveToken += msg.token;
}
if (data.usage.prompt_tokens) {
const userMessageToken = data.usage.prompt_tokens - aboveToken;
console.log("set user message token");
if (chatStore.history.filter((msg) => !msg.hide).length > 0) {
chatStore.history.filter((msg) => !msg.hide).slice(-1)[0].token =
userMessageToken;
}
}
chatStore.history.push({
role: "assistant",
content,
hide: false,
token: data.usage.completion_tokens ?? calculate_token_length(content),
});
setShowGenerating(false); setShowGenerating(false);
}; };
@@ -101,12 +191,30 @@ export default function ChatBOX(props: {
// manually copy status from chatStore to client // manually copy status from chatStore to client
client.apiEndpoint = chatStore.apiEndpoint; client.apiEndpoint = chatStore.apiEndpoint;
client.sysMessageContent = chatStore.systemMessageContent; client.sysMessageContent = chatStore.systemMessageContent;
client.messages = chatStore.history.slice(chatStore.postBeginIndex); client.tokens_margin = chatStore.tokenMargin;
client.temperature = chatStore.temperature;
client.top_p = chatStore.top_p;
client.frequency_penalty = chatStore.frequency_penalty;
client.presence_penalty = chatStore.presence_penalty;
client.messages = chatStore.history
// only copy non hidden message
.filter(({ hide }) => !hide)
.slice(chatStore.postBeginIndex)
// only copy content and role attribute to client for posting
.map(({ content, role }) => {
return {
content,
role,
};
});
client.model = chatStore.model;
client.max_tokens = chatStore.maxTokens;
try { try {
setShowGenerating(true); setShowGenerating(true);
const response = await client._fetch(chatStore.streamMode); const response = await client._fetch(chatStore.streamMode);
const contentType = response.headers.get("content-type"); const contentType = response.headers.get("content-type");
if (contentType === "text/event-stream") { if (contentType?.startsWith("text/event-stream")) {
await _completeWithStreamMode(response); await _completeWithStreamMode(response);
} else if (contentType === "application/json") { } else if (contentType === "application/json") {
await _completeWithFetchMode(response); await _completeWithFetchMode(response);
@@ -117,18 +225,16 @@ export default function ChatBOX(props: {
chatStore.maxTokens = client.max_tokens; chatStore.maxTokens = client.max_tokens;
chatStore.tokenMargin = client.tokens_margin; chatStore.tokenMargin = client.tokens_margin;
chatStore.totalTokens = client.total_tokens; chatStore.totalTokens = client.total_tokens;
// when total token > max token - margin token:
// ChatGPT will "forgot" some historical message
// so client.message.length will be less than chatStore.history.length
chatStore.postBeginIndex =
chatStore.history.length - client.messages.length;
console.log("postBeginIndex", chatStore.postBeginIndex); console.log("postBeginIndex", chatStore.postBeginIndex);
setShowRetry(false);
setChatStore({ ...chatStore }); setChatStore({ ...chatStore });
} catch (error) { } catch (error) {
setShowRetry(true); setShowRetry(true);
alert(error); alert(error);
} finally { } finally {
setShowGenerating(false); setShowGenerating(false);
props.setSelectedChatIndex(props.selectedChatIndex);
} }
}; };
@@ -139,7 +245,16 @@ export default function ChatBOX(props: {
console.log("empty message"); console.log("empty message");
return; return;
} }
chatStore.history.push({ role: "user", content: inputMsg.trim() }); chatStore.responseModelName = "";
chatStore.history.push({
role: "user",
content: inputMsg.trim(),
hide: false,
token: calculate_token_length(inputMsg.trim()),
});
// manually calculate token length
chatStore.totalTokens += client.calculate_token_length(inputMsg.trim());
client.total_tokens += client.calculate_token_length(inputMsg.trim());
setChatStore({ ...chatStore }); setChatStore({ ...chatStore });
setInputMsg(""); setInputMsg("");
await complete(); await complete();
@@ -148,14 +263,16 @@ export default function ChatBOX(props: {
const [showSettings, setShowSettings] = useState(false); const [showSettings, setShowSettings] = useState(false);
return ( return (
<div className="grow flex flex-col p-2 dark:text-black"> <div className="grow flex flex-col p-2 dark:text-black">
{showSettings && (
<Settings <Settings
chatStore={chatStore} chatStore={chatStore}
setChatStore={setChatStore} setChatStore={setChatStore}
show={showSettings}
setShow={setShowSettings} setShow={setShowSettings}
selectedChatStoreIndex={props.selectedChatIndex}
/> />
)}
<p <p
className="cursor-pointer dark:text-white" className="cursor-pointer rounded bg-cyan-300 dark:text-white p-1 dark:bg-cyan-800"
onClick={() => setShowSettings(true)} onClick={() => setShowSettings(true)}
> >
<div> <div>
@@ -169,11 +286,24 @@ export default function ChatBOX(props: {
</button> </button>
</div> </div>
<div className="text-xs"> <div className="text-xs">
<span>Total: {chatStore.totalTokens}</span>{" "} <span className="underline">{chatStore.model}</span>{" "}
<span>Max: {chatStore.maxTokens}</span>{" "} <span>
<span>Margin: {chatStore.tokenMargin}</span>{" "} Tokens:{" "}
<span>Message: {chatStore.history.length}</span>{" "} <span className="underline">
<span>Cut: {chatStore.postBeginIndex}</span> {chatStore.totalTokens}/{chatStore.maxTokens}
</span>
</span>{" "}
<span>
Cut:{" "}
<span className="underline">
{chatStore.postBeginIndex}/
{chatStore.history.filter(({ hide }) => !hide).length}
</span>{" "}
</span>{" "}
<span>
Cost:{" "}
<span className="underline">${chatStore.cost.toFixed(4)}</span>
</span>
</div> </div>
</p> </p>
<div className="grow overflow-scroll"> <div className="grow overflow-scroll">
@@ -188,8 +318,33 @@ export default function ChatBOX(props: {
</p> </p>
)} )}
{chatStore.history.length === 0 && ( {chatStore.history.length === 0 && (
<p className="opacity-60 p-6 rounded bg-white my-3 text-left dark:text-black"> <p className="break-all opacity-60 p-6 rounded bg-white my-3 text-left dark:text-black">
<br />
Model: {chatStore.model}
<br />
Key: {chatStore.apiKey}
<br />
Endpoint: {chatStore.apiEndpoint}
<br />
<br />
NEW
<br />
使 ChatGPT API
API
<br />
<br />
:{" "}
<a
className="underline"
href="https://github.com/heimoshuiyu/chatgpt-api-web"
target="_blank"
>
github.com/heimoshuiyu/chatgpt-api-web
</a>
</p> </p>
)} )}
{chatStore.history.map((_, messageIndex) => ( {chatStore.history.map((_, messageIndex) => (
@@ -197,16 +352,75 @@ export default function ChatBOX(props: {
chatStore={chatStore} chatStore={chatStore}
setChatStore={setChatStore} setChatStore={setChatStore}
messageIndex={messageIndex} messageIndex={messageIndex}
update_total_tokens={update_total_tokens}
/> />
))} ))}
{showGenerating && ( {showGenerating && (
<p className="p-2 my-2 animate-pulse dark:text-white"> <p className="p-2 my-2 animate-pulse dark:text-white message-content">
{generatingMessage {generatingMessage || "生成中,最长可能需要一分钟,请保持网络稳定"}
? generatingMessage.split("\n").map((line) => <p>{line}</p>)
: "生成中,请保持网络稳定"}
... ...
</p> </p>
)} )}
{chatStore.develop_mode && (
<p className="text-center rounded">
<button
className="p-2 m-2 bg-teal-500 rounded"
onClick={async () => {
const messageIndex = chatStore.history.length - 1;
chatStore.history[messageIndex].hide = true;
//chatStore.totalTokens =
update_total_tokens();
setChatStore({ ...chatStore });
await complete();
}}
>
Re-Generate
</button>
<button
className="p-2 m-2 bg-yellow-500 rounded"
onClick={async () => {
await complete();
}}
>
Completion
</button>
</p>
)}
<p className="p-2 my-2 text-center opacity-50 dark:text-white">
{chatStore.responseModelName && (
<>Generated by {chatStore.responseModelName}</>
)}
{chatStore.postBeginIndex !== 0 && (
<>
<br />
{chatStore.postBeginIndex}
</>
)}
</p>
{chatStore.chatgpt_api_web_version < "v1.3.0" && (
<p className="p-2 my-2 text-center dark:text-white">
<br />
{chatStore.chatgpt_api_web_version}
<br />
v1.3.0
使
<br />
</p>
)}
{chatStore.chatgpt_api_web_version < "v1.4.0" && (
<p className="p-2 my-2 text-center dark:text-white">
<br />
{chatStore.chatgpt_api_web_version} {"< v1.4.0"}
<br />
v1.4.0 使
<br />
</p>
)}
{showRetry && ( {showRetry && (
<p className="text-right p-2 my-2 dark:text-white"> <p className="text-right p-2 my-2 dark:text-white">
<button <button
@@ -248,6 +462,42 @@ export default function ChatBOX(props: {
> >
Send Send
</button> </button>
{chatStore.develop_mode && (
<button
className="disabled:line-through disabled:bg-slate-500 rounded m-1 p-1 border-2 bg-cyan-400 hover:bg-cyan-600"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
chatStore.history.push({
role: "assistant",
content: inputMsg,
token: calculate_token_length(inputMsg),
hide: false,
});
update_total_tokens();
setChatStore({ ...chatStore });
}}
>
Assistant
</button>
)}
{chatStore.develop_mode && (
<button
className="disabled:line-through disabled:bg-slate-500 rounded m-1 p-1 border-2 bg-cyan-400 hover:bg-cyan-600"
disabled={showGenerating || !chatStore.apiKey}
onClick={() => {
chatStore.history.push({
role: "user",
content: inputMsg,
token: calculate_token_length(inputMsg),
hide: false,
});
update_total_tokens();
setChatStore({ ...chatStore });
}}
>
User
</button>
)}
</div> </div>
</div> </div>
); );

View File

@@ -1,15 +1,17 @@
export interface Message { export interface Message {
role: "system" | "user" | "assistant"; role: "system" | "user" | "assistant" | "function";
content: string; content: string;
} }
export interface ChunkMessage { export interface ChunkMessage {
model: string;
choices: { choices: {
delta: { role: "assitant" | undefined; content: string | undefined }; delta: { role: "assitant" | undefined; content: string | undefined };
}[]; }[];
} }
export interface FetchResponse { export interface FetchResponse {
error?: any;
id: string; id: string;
object: string; object: string;
created: number; created: number;
@@ -25,6 +27,14 @@ export interface FetchResponse {
index: number | undefined; index: number | undefined;
}[]; }[];
} }
// https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them
export function calculate_token_length(content: string): number {
const totalCount = content.length;
const chineseCount = content.match(/[\u00ff-\uffff]|\S+/g)?.length ?? 0;
const englishCount = totalCount - chineseCount;
const tokenLength = englishCount / 4 + (chineseCount * 4) / 3;
return ~~tokenLength;
}
class Chat { class Chat {
OPENAI_API_KEY: string; OPENAI_API_KEY: string;
@@ -34,6 +44,11 @@ class Chat {
max_tokens: number; max_tokens: number;
tokens_margin: number; tokens_margin: number;
apiEndpoint: string; apiEndpoint: string;
model: string;
temperature: number;
top_p: number;
presence_penalty: number;
frequency_penalty: number;
constructor( constructor(
OPENAI_API_KEY: string | undefined, OPENAI_API_KEY: string | undefined,
@@ -42,6 +57,11 @@ class Chat {
max_tokens = 4096, max_tokens = 4096,
tokens_margin = 1024, tokens_margin = 1024,
apiEndPoint = "https://api.openai.com/v1/chat/completions", apiEndPoint = "https://api.openai.com/v1/chat/completions",
model = "gpt-3.5-turbo",
temperature = 1.0,
top_p = 1,
presence_penalty = 0,
frequency_penalty = 0,
} = {} } = {}
) { ) {
if (OPENAI_API_KEY === undefined) { if (OPENAI_API_KEY === undefined) {
@@ -54,6 +74,11 @@ class Chat {
this.tokens_margin = tokens_margin; this.tokens_margin = tokens_margin;
this.sysMessageContent = systemMessage; this.sysMessageContent = systemMessage;
this.apiEndpoint = apiEndPoint; this.apiEndpoint = apiEndPoint;
this.model = model;
this.temperature = temperature;
this.top_p = top_p;
this.presence_penalty = presence_penalty;
this.frequency_penalty = frequency_penalty;
} }
_fetch(stream = false) { _fetch(stream = false) {
@@ -64,19 +89,27 @@ class Chat {
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
body: JSON.stringify({ body: JSON.stringify({
model: "gpt-3.5-turbo", model: this.model,
messages: [ messages: [
{ role: "system", content: this.sysMessageContent }, { role: "system", content: this.sysMessageContent },
...this.messages, ...this.messages,
], ],
stream, stream,
temperature: this.temperature,
top_p: this.top_p,
presence_penalty: this.presence_penalty,
frequency_penalty: this.frequency_penalty,
}), }),
}); });
} }
async fetch(): Promise<FetchResponse> { async fetch(): Promise<FetchResponse> {
const resp = await this._fetch(); const resp = await this._fetch();
return await resp.json(); const j = await resp.json();
if (j.error !== undefined) {
throw JSON.stringify(j.error);
}
return j;
} }
async say(content: string): Promise<string> { async say(content: string): Promise<string> {
@@ -86,6 +119,9 @@ class Chat {
} }
processFetchResponse(resp: FetchResponse): string { processFetchResponse(resp: FetchResponse): string {
if (resp.error !== undefined) {
throw JSON.stringify(resp.error);
}
this.total_tokens = resp?.usage?.total_tokens ?? 0; this.total_tokens = resp?.usage?.total_tokens ?? 0;
if (resp?.choices[0]?.message) { if (resp?.choices[0]?.message) {
this.messages.push(resp?.choices[0]?.message); this.messages.push(resp?.choices[0]?.message);
@@ -114,13 +150,8 @@ class Chat {
return this._fetch(true); return this._fetch(true);
} }
// https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them
calculate_token_length(content: string): number { calculate_token_length(content: string): number {
const totalCount = content.length; return calculate_token_length(content);
const chineseCount = content.match(/[\u00ff-\uffff]|\S+/g)?.length ?? 0;
const englishCount = totalCount - chineseCount;
const tokenLength = englishCount / 4 + (chineseCount * 4) / 3;
return ~~tokenLength;
} }
user(...messages: string[]) { user(...messages: string[]) {

View File

@@ -7,10 +7,12 @@ function getDefaultParams(param: any, val: any) {
if (typeof val === "string") { if (typeof val === "string") {
return get ?? val; return get ?? val;
} else if (typeof val === "number") { } else if (typeof val === "number") {
return parseInt(get ?? `${val}`); return parseFloat(get ?? `${val}`);
} else if (typeof val === "boolean") { } else if (typeof val === "boolean") {
if (get === "stream") return true; if (get === "stream") return true;
if (get === "fetch") return false; if (get === "fetch") return false;
if (get === "true") return true;
if (get === "false") return false;
return val; return val;
} }
} }

View File

@@ -2,6 +2,12 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
html,
body,
#app {
height: 100%;
}
/* Hide scrollbar for webkit based browsers */ /* Hide scrollbar for webkit based browsers */
::-webkit-scrollbar { ::-webkit-scrollbar {
display: none; display: none;

View File

@@ -1,72 +1,138 @@
import Markdown from "preact-markdown"; import { useState } from "preact/hooks";
import { ChatStore } from "./app"; import { ChatStore } from "./app";
import { calculate_token_length } from "./chatgpt";
const Pre: React.FC<any> = ({ children, props }) => (
<div class="rounded p-1 bg-black text-white" {...props}>{children}</div>
);
const Code: React.FC<any> = ({ children }) => <code className="overflow-scroll break-keep">{children}</code>;
interface Props { interface Props {
messageIndex: number; messageIndex: number;
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
update_total_tokens: () => void;
} }
export default function Message(props: Props) { export default function Message(props: Props) {
const { chatStore, messageIndex, setChatStore } = props; const { chatStore, messageIndex, setChatStore } = props;
const chat = chatStore.history[messageIndex]; const chat = chatStore.history[messageIndex];
const [showEdit, setShowEdit] = useState(false);
const DeleteIcon = () => ( const DeleteIcon = () => (
<button <button
className={`absolute bottom-0 ${ className={`absolute bottom-0 ${
chat.role === "user" ? "left-0" : "right-0" chat.role === "user" ? "left-0" : "right-0"
}`} }`}
onClick={() => { onClick={() => {
if ( chatStore.history[messageIndex].hide =
confirm( !chatStore.history[messageIndex].hide;
`Are you sure to delete this message?\n${chat.content.slice(
0, //chatStore.totalTokens =
39 chatStore.totalTokens = 0;
)}...` for (const i of chatStore.history
) .filter(({ hide }) => !hide)
) { .slice(chatStore.postBeginIndex)
chatStore.history.splice(messageIndex, 1); .map(({ token }) => token)) {
chatStore.postBeginIndex = Math.max(chatStore.postBeginIndex - 1, 0); chatStore.totalTokens += i;
setChatStore({ ...chatStore });
} }
setChatStore({ ...chatStore });
}} }}
> >
🗑 🗑
</button> </button>
); );
const codeMatches = chat.content.match(/(```([\s\S]*?)```$)/);
const AnyMarkdown = Markdown as any;
console.log("codeMatches", codeMatches);
if (codeMatches) console.log("matches", codeMatches[0]);
return ( return (
<>
{chatStore.postBeginIndex !== 0 &&
!chatStore.history[messageIndex].hide &&
chatStore.postBeginIndex ===
chatStore.history.slice(0, messageIndex).filter(({ hide }) => !hide)
.length && (
<div className="flex items-center relative justify-center">
<hr className="w-full h-px my-4 border-0 bg-slate-800 dark:bg-white" />
<span className="absolute px-3 bg-slate-800 text-white rounded p-1 dark:bg-white dark:text-black">
Above messages are "forgotten"
</span>
</div>
)}
<div <div
className={`flex ${ className={`flex ${
chat.role === "assistant" ? "justify-start" : "justify-end" chat.role === "assistant" ? "justify-start" : "justify-end"
}`} }`}
> >
<div>
<div <div
className={`relative w-fit p-2 rounded my-2 ${ className={`relative w-fit p-2 rounded my-2 ${
chat.role === "assistant" chat.role === "assistant"
? "bg-white dark:bg-gray-700 dark:text-white" ? "bg-white dark:bg-gray-700 dark:text-white"
: "bg-green-400" : "bg-green-400"
}`} } ${chat.hide ? "opacity-50" : ""}`}
> >
<p className="message-content"> <p className="message-content">
<AnyMarkdown {chat.hide
markdown={chat.content} ? chat.content.split("\n")[0].slice(0, 16) + "... (deleted)"
markupOpts={{ : chat.content}
components: {
code: Code,
pre: Pre,
},
}}
/>
</p> </p>
<DeleteIcon /> <DeleteIcon />
</div> </div>
{chatStore.develop_mode && (
<div>
token{" "}
<input
value={chat.token}
className="w-20"
onChange={(event: any) => {
chat.token = parseInt(event.target.value);
props.update_total_tokens();
setChatStore({ ...chatStore });
}}
/>
<button
onClick={() => {
chatStore.history.splice(messageIndex, 1);
chatStore.postBeginIndex = Math.max(
chatStore.postBeginIndex - 1,
0
);
//chatStore.totalTokens =
chatStore.totalTokens = 0;
for (const i of chatStore.history
.filter(({ hide }) => !hide)
.slice(chatStore.postBeginIndex)
.map(({ token }) => token)) {
chatStore.totalTokens += i;
}
setChatStore({ ...chatStore });
}}
>
</button>
<button onClick={() => setShowEdit(true)}>🖋</button>
{showEdit && (
<div
className={
"absolute bg-black bg-opacity-50 w-full h-full top-0 left-0 pt-5 px-5 pb-20 rounded z-10"
}
>
<textarea
className={"relative w-full h-full"}
value={chat.content}
onChange={(event: any) => {
chat.content = event.target.value;
chat.token = calculate_token_length(chat.content);
setChatStore({ ...chatStore });
}}
></textarea>
<div className={"w-full flex justify-center"}>
<button
className={"m-2 p-1 rounded bg-green-500"}
onClick={() => {
setShowEdit(false);
}}
>
Close
</button>
</div> </div>
</div>
)}
</div>
)}
</div>
</div>
</>
); );
} }

56
src/models.ts Normal file
View File

@@ -0,0 +1,56 @@
interface Model {
maxToken: number;
price: {
prompt: number;
completion: number;
};
}
const models: Record<string, Model> = {
"gpt-3.5-turbo": {
maxToken: 4096,
price: { prompt: 0.0015 / 1000, completion: 0.002 / 1000 },
},
"gpt-3.5-turbo-16k": {
maxToken: 16384,
price: { prompt: 0.0003 / 1000, completion: 0.004 / 1000 },
},
"gpt-3.5-turbo-0613": {
maxToken: 4096,
price: { prompt: 0.0015 / 1000, completion: 0.002 / 1000 },
},
"gpt-3.5-turbo-16k-0613": {
maxToken: 16384,
price: { prompt: 0.0003 / 1000, completion: 0.004 / 1000 },
},
"gpt-3.5-turbo-0301": {
maxToken: 4096,
price: { prompt: 0.0015 / 1000, completion: 0.002 / 1000 },
},
"gpt-4": {
maxToken: 8192,
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
},
"gpt-4-0613": {
maxToken: 8192,
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
},
"gpt-4-32k": {
maxToken: 8192,
price: { prompt: 0.06 / 1000, completion: 0.12 / 1000 },
},
"gpt-4-32k-0613": {
maxToken: 8192,
price: { prompt: 0.06 / 1000, completion: 0.12 / 1000 },
},
"gpt-4-0314": {
maxToken: 8192,
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
},
"gpt-4-32k-0314": {
maxToken: 8192,
price: { prompt: 0.06 / 1000, completion: 0.12 / 1000 },
},
};
export default models;

View File

@@ -1,5 +1,7 @@
import { StateUpdater } from "preact/hooks"; import { createRef } from "preact";
import { ChatStore } from "./app"; import { StateUpdater, useState } from "preact/hooks";
import { ChatStore, clearTotalCost, getTotalCost } from "./app";
import models from "./models";
const Help = (props: { children: any; help: string }) => { const Help = (props: { children: any; help: string }) => {
return ( return (
@@ -17,10 +19,56 @@ const Help = (props: { children: any; help: string }) => {
); );
}; };
const SelectModel = (props: {
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
help: string;
}) => {
return (
<Help help={props.help}>
<label className="m-2 p-2">Model</label>
<select
className="m-2 p-2"
value={props.chatStore.model}
onChange={(event: any) => {
const model = event.target.value as string;
props.chatStore.model = model;
props.chatStore.maxTokens = models[model].maxToken;
props.setChatStore({ ...props.chatStore });
}}
>
{Object.keys(models).map((opt) => (
<option value={opt}>{opt}</option>
))}
</select>
</Help>
);
};
const LongInput = (props: {
chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void;
field: "systemMessageContent";
help: string;
}) => {
return (
<Help help={props.help}>
<textarea
className="m-2 p-2 border rounded focus w-full"
value={props.chatStore[props.field]}
onChange={(event: any) => {
props.chatStore[props.field] = event.target.value;
props.setChatStore({ ...props.chatStore });
}}
></textarea>
</Help>
);
};
const Input = (props: { const Input = (props: {
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
field: "apiKey" | "systemMessageContent" | "apiEndpoint"; field: "apiKey" | "apiEndpoint";
help: string; help: string;
}) => { }) => {
return ( return (
@@ -40,7 +88,15 @@ const Input = (props: {
const Number = (props: { const Number = (props: {
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
field: "totalTokens" | "maxTokens" | "tokenMargin" | "postBeginIndex"; field:
| "totalTokens"
| "maxTokens"
| "tokenMargin"
| "postBeginIndex"
| "temperature"
| "top_p"
| "presence_penalty"
| "frequency_penalty";
readOnly: boolean; readOnly: boolean;
help: string; help: string;
}) => { }) => {
@@ -54,7 +110,7 @@ const Number = (props: {
value={props.chatStore[props.field]} value={props.chatStore[props.field]}
onChange={(event: any) => { onChange={(event: any) => {
console.log("type", typeof event.target.value); console.log("type", typeof event.target.value);
let newNumber = parseInt(event.target.value); let newNumber = parseFloat(event.target.value);
if (newNumber < 0) newNumber = 0; if (newNumber < 0) newNumber = 0;
props.chatStore[props.field] = newNumber; props.chatStore[props.field] = newNumber;
props.setChatStore({ ...props.chatStore }); props.setChatStore({ ...props.chatStore });
@@ -66,7 +122,7 @@ const Number = (props: {
const Choice = (props: { const Choice = (props: {
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
field: "streamMode"; field: "streamMode" | "develop_mode";
help: string; help: string;
}) => { }) => {
return ( return (
@@ -88,11 +144,10 @@ const Choice = (props: {
export default (props: { export default (props: {
chatStore: ChatStore; chatStore: ChatStore;
setChatStore: (cs: ChatStore) => void; setChatStore: (cs: ChatStore) => void;
show: boolean;
setShow: StateUpdater<boolean>; setShow: StateUpdater<boolean>;
selectedChatStoreIndex: number;
}) => { }) => {
if (!props.show) return <div></div>; let link =
const link =
location.protocol + location.protocol +
"//" + "//" +
location.host + location.host +
@@ -101,14 +156,39 @@ export default (props: {
props.chatStore.apiKey props.chatStore.apiKey
)}&api=${encodeURIComponent(props.chatStore.apiEndpoint)}&mode=${ )}&api=${encodeURIComponent(props.chatStore.apiEndpoint)}&mode=${
props.chatStore.streamMode ? "stream" : "fetch" props.chatStore.streamMode ? "stream" : "fetch"
}&sys=${encodeURIComponent(props.chatStore.systemMessageContent)}`; }&model=${props.chatStore.model}&sys=${encodeURIComponent(
props.chatStore.systemMessageContent
)}`;
if (props.chatStore.develop_mode) {
link = link + `&dev=true`;
}
const importFileRef = createRef();
const [totalCost, setTotalCost] = useState(getTotalCost());
return ( return (
<div className="left-0 top-0 overflow-scroll flex justify-center absolute w-screen h-screen bg-black bg-opacity-50 z-10"> <div className="left-0 top-0 overflow-scroll flex justify-center absolute w-screen h-full bg-black bg-opacity-50 z-10">
<div className="m-2 p-2 bg-white rounded-lg h-fit"> <div className="m-2 p-2 bg-white rounded-lg h-fit">
<h3 className="text-xl">Settings</h3> <h3 className="text-xl">Settings</h3>
<hr /> <hr />
<div className="flex justify-between">
<p className="m-2 p-2">
Accumulated cost in all sessions ${totalCost.toFixed(4)}
</p>
<button
className="p-2 m-2 rounded bg-emerald-500"
onClick={() => {
clearTotalCost();
setTotalCost(getTotalCost());
}}
>
Reset
</button>
</div>
<p className="m-2 p-2">
Total cost in this session ${props.chatStore.cost.toFixed(4)}
</p>
<div className="box"> <div className="box">
<Input <LongInput
field="systemMessageContent" field="systemMessageContent"
help="系统消息用于指示ChatGPT的角色和一些前置条件例如“你是一个有帮助的人工智能助理”或者“你是一个专业英语翻译把我的话全部翻译成英语”详情参考 OPEAN AI API 文档" help="系统消息用于指示ChatGPT的角色和一些前置条件例如“你是一个有帮助的人工智能助理”或者“你是一个专业英语翻译把我的话全部翻译成英语”详情参考 OPEAN AI API 文档"
{...props} {...props}
@@ -128,9 +208,18 @@ export default (props: {
help="流模式,使用 stream mode 将可以动态看到生成内容,但无法准确计算 token 数量,在 token 数量过多时可能会裁切过多或过少历史消息" help="流模式,使用 stream mode 将可以动态看到生成内容,但无法准确计算 token 数量,在 token 数量过多时可能会裁切过多或过少历史消息"
{...props} {...props}
/> />
<Choice
field="develop_mode"
help="开发者模式,拥有更多选项及功能"
{...props}
/>
<SelectModel
help="模型,默认 3.5。不同模型性能和定价也不同,请参考 API 文档。GPT-4 模型处于内测阶段,需要向 OPENAI 申请, 请确保您有访问权限)"
{...props}
/>
<Number <Number
field="maxTokens" field="maxTokens"
help="最大 token 数量,这个详情参考 OPENAI API 文档" help="最大 token 数量。如果使用非gpt-3.5模型请手动修改上限。gpt-4 & gpt-4-0314: 8192。gpt-4-32k & gpt-4-32k-0314: 32768"
readOnly={false} readOnly={false}
{...props} {...props}
/> />
@@ -152,6 +241,95 @@ export default (props: {
readOnly={true} readOnly={true}
{...props} {...props}
/> />
<Number field="temperature" help="温度" readOnly={false} {...props} />
<Number field="top_p" help="top_p" readOnly={false} {...props} />
<Number
field="presence_penalty"
help="presence_penalty"
readOnly={false}
{...props}
/>
<Number
field="frequency_penalty"
help="frequency_penalty"
readOnly={false}
{...props}
/>
<p className="flex justify-evenly">
<button
className="p-2 m-2 rounded bg-amber-500"
onClick={() => {
let dataStr =
"data:text/json;charset=utf-8," +
encodeURIComponent(
JSON.stringify(props.chatStore, null, "\t")
);
let downloadAnchorNode = document.createElement("a");
downloadAnchorNode.setAttribute("href", dataStr);
downloadAnchorNode.setAttribute(
"download",
`chatgpt-api-web-${props.selectedChatStoreIndex}.json`
);
document.body.appendChild(downloadAnchorNode); // required for firefox
downloadAnchorNode.click();
downloadAnchorNode.remove();
}}
>
Export
</button>
<button
className="p-2 m-2 rounded bg-amber-500"
onClick={() => {
if (
!confirm(
"This will OVERWRITE the current chat history! Continue?"
)
)
return;
console.log("importFileRef", importFileRef);
importFileRef.current.click();
}}
>
Import
</button>
<input
className="hidden"
ref={importFileRef}
type="file"
onChange={() => {
const file = importFileRef.current.files[0];
console.log("file to import", file);
if (!file || file.type !== "application/json") {
alert("Please select a json file");
return;
}
const reader = new FileReader();
reader.onload = () => {
console.log("import content", reader.result);
if (!reader) {
alert("Empty file");
return;
}
try {
const newChatStore: ChatStore = JSON.parse(
reader.result as string
);
if (!newChatStore.chatgpt_api_web_version) {
throw "This is not an exported chatgpt-api-web chatstore file. The key 'chatgpt_api_web_version' is missing!";
}
props.setChatStore({ ...newChatStore });
} catch (e) {
alert(`Import error on parsing json: ${e}`);
}
};
reader.readAsText(file);
}}
/>
</p>
<p className="text-center m-2 p-2">
chatgpt-api-web ChatStore Version{" "}
{props.chatStore.chatgpt_api_web_version}
</p>
</div> </div>
<hr /> <hr />
<div className="flex justify-between"> <div className="flex justify-between">

586
yarn.lock
View File

@@ -2,6 +2,11 @@
# yarn lockfile v1 # yarn lockfile v1
"@alloc/quick-lru@^5.2.0":
version "5.2.0"
resolved "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
"@ampproject/remapping@^2.2.0": "@ampproject/remapping@^2.2.0":
version "2.2.0" version "2.2.0"
resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
@@ -228,115 +233,115 @@
"@babel/helper-validator-identifier" "^7.19.1" "@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@esbuild/android-arm64@0.16.17": "@esbuild/android-arm64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23" resolved "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd"
integrity sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg== integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==
"@esbuild/android-arm@0.16.17": "@esbuild/android-arm@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz#025b6246d3f68b7bbaa97069144fb5fb70f2fff2" resolved "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d"
integrity sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw== integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==
"@esbuild/android-x64@0.16.17": "@esbuild/android-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz#c820e0fef982f99a85c4b8bfdd582835f04cd96e" resolved "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1"
integrity sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ== integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==
"@esbuild/darwin-arm64@0.16.17": "@esbuild/darwin-arm64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz#edef4487af6b21afabba7be5132c26d22379b220" resolved "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276"
integrity sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w== integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==
"@esbuild/darwin-x64@0.16.17": "@esbuild/darwin-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz#42829168730071c41ef0d028d8319eea0e2904b4" resolved "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb"
integrity sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg== integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==
"@esbuild/freebsd-arm64@0.16.17": "@esbuild/freebsd-arm64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz#1f4af488bfc7e9ced04207034d398e793b570a27" resolved "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2"
integrity sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw== integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==
"@esbuild/freebsd-x64@0.16.17": "@esbuild/freebsd-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz#636306f19e9bc981e06aa1d777302dad8fddaf72" resolved "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4"
integrity sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug== integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==
"@esbuild/linux-arm64@0.16.17": "@esbuild/linux-arm64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz#a003f7ff237c501e095d4f3a09e58fc7b25a4aca" resolved "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb"
integrity sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g== integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==
"@esbuild/linux-arm@0.16.17": "@esbuild/linux-arm@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz#b591e6a59d9c4fe0eeadd4874b157ab78cf5f196" resolved "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a"
integrity sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ== integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==
"@esbuild/linux-ia32@0.16.17": "@esbuild/linux-ia32@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz#24333a11027ef46a18f57019450a5188918e2a54" resolved "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a"
integrity sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg== integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==
"@esbuild/linux-loong64@0.16.17": "@esbuild/linux-loong64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz#d5ad459d41ed42bbd4d005256b31882ec52227d8" resolved "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72"
integrity sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ== integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==
"@esbuild/linux-mips64el@0.16.17": "@esbuild/linux-mips64el@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz#4e5967a665c38360b0a8205594377d4dcf9c3726" resolved "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289"
integrity sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw== integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==
"@esbuild/linux-ppc64@0.16.17": "@esbuild/linux-ppc64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz#206443a02eb568f9fdf0b438fbd47d26e735afc8" resolved "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7"
integrity sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g== integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==
"@esbuild/linux-riscv64@0.16.17": "@esbuild/linux-riscv64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz#c351e433d009bf256e798ad048152c8d76da2fc9" resolved "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09"
integrity sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw== integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==
"@esbuild/linux-s390x@0.16.17": "@esbuild/linux-s390x@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz#661f271e5d59615b84b6801d1c2123ad13d9bd87" resolved "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829"
integrity sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w== integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==
"@esbuild/linux-x64@0.16.17": "@esbuild/linux-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz#e4ba18e8b149a89c982351443a377c723762b85f" resolved "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4"
integrity sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw== integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==
"@esbuild/netbsd-x64@0.16.17": "@esbuild/netbsd-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz#7d4f4041e30c5c07dd24ffa295c73f06038ec775" resolved "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462"
integrity sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA== integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==
"@esbuild/openbsd-x64@0.16.17": "@esbuild/openbsd-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz#970fa7f8470681f3e6b1db0cc421a4af8060ec35" resolved "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691"
integrity sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg== integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==
"@esbuild/sunos-x64@0.16.17": "@esbuild/sunos-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz#abc60e7c4abf8b89fb7a4fe69a1484132238022c" resolved "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273"
integrity sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw== integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==
"@esbuild/win32-arm64@0.16.17": "@esbuild/win32-arm64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz#7b0ff9e8c3265537a7a7b1fd9a24e7bd39fcd87a" resolved "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f"
integrity sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw== integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==
"@esbuild/win32-ia32@0.16.17": "@esbuild/win32-ia32@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz#e90fe5267d71a7b7567afdc403dfd198c292eb09" resolved "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03"
integrity sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig== integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==
"@esbuild/win32-x64@0.16.17": "@esbuild/win32-x64@0.17.19":
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091" resolved "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061"
integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q== integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==
"@jridgewell/gen-mapping@^0.1.0": "@jridgewell/gen-mapping@^0.1.0":
version "0.1.1" version "0.1.1"
@@ -447,25 +452,6 @@
estree-walker "^2.0.1" estree-walker "^2.0.1"
picomatch "^2.2.2" picomatch "^2.2.2"
acorn-node@^1.8.2:
version "1.8.2"
resolved "https://registry.npmmirror.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8"
integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==
dependencies:
acorn "^7.0.0"
acorn-walk "^7.0.0"
xtend "^4.0.2"
acorn-walk@^7.0.0:
version "7.2.0"
resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn@^7.0.0:
version "7.4.1"
resolved "https://registry.npmmirror.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
ansi-styles@^3.2.1: ansi-styles@^3.2.1:
version "3.2.1" version "3.2.1"
resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -473,6 +459,11 @@ ansi-styles@^3.2.1:
dependencies: dependencies:
color-convert "^1.9.0" color-convert "^1.9.0"
any-promise@^1.0.0:
version "1.3.0"
resolved "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
anymatch@~3.1.2: anymatch@~3.1.2:
version "3.1.3" version "3.1.3"
resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" resolved "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@@ -503,11 +494,24 @@ babel-plugin-transform-hook-names@^1.0.2:
resolved "https://registry.npmmirror.com/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz#0d75c2d78e8bbcdb258241131562b9cf07f010f3" resolved "https://registry.npmmirror.com/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz#0d75c2d78e8bbcdb258241131562b9cf07f010f3"
integrity sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw== integrity sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" resolved "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
braces@^3.0.2, 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"
@@ -571,10 +575,15 @@ color-name@1.1.3:
resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@^1.1.4: commander@^4.0.0:
version "1.1.4" version "4.1.1"
resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" resolved "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
convert-source-map@^1.7.0: convert-source-map@^1.7.0:
version "1.9.0" version "1.9.0"
@@ -593,20 +602,6 @@ debug@^4.1.0, debug@^4.3.1:
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
defined@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/defined/-/defined-1.0.1.tgz#c0b9db27bfaffd95d6f61399419b893df0f91ebf"
integrity sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==
detective@^5.2.1:
version "5.2.1"
resolved "https://registry.npmmirror.com/detective/-/detective-5.2.1.tgz#6af01eeda11015acb0e73f933242b70f24f91034"
integrity sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==
dependencies:
acorn-node "^1.8.2"
defined "^1.0.0"
minimist "^1.2.6"
didyoumean@^1.2.2: didyoumean@^1.2.2:
version "1.2.2" version "1.2.2"
resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@@ -622,33 +617,33 @@ electron-to-chromium@^1.4.284:
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.328.tgz#b4565ffa502542b561cea16086d6d9b916c7095a" resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.328.tgz#b4565ffa502542b561cea16086d6d9b916c7095a"
integrity sha512-DE9tTy2PNmy1v55AZAO542ui+MLC2cvINMK4P2LXGsJdput/ThVG9t+QGecPuAZZSgC8XoI+Jh9M1OG9IoNSCw== integrity sha512-DE9tTy2PNmy1v55AZAO542ui+MLC2cvINMK4P2LXGsJdput/ThVG9t+QGecPuAZZSgC8XoI+Jh9M1OG9IoNSCw==
esbuild@^0.16.14: esbuild@^0.17.5:
version "0.16.17" version "0.17.19"
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.16.17.tgz#fc2c3914c57ee750635fee71b89f615f25065259" resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955"
integrity sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg== integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==
optionalDependencies: optionalDependencies:
"@esbuild/android-arm" "0.16.17" "@esbuild/android-arm" "0.17.19"
"@esbuild/android-arm64" "0.16.17" "@esbuild/android-arm64" "0.17.19"
"@esbuild/android-x64" "0.16.17" "@esbuild/android-x64" "0.17.19"
"@esbuild/darwin-arm64" "0.16.17" "@esbuild/darwin-arm64" "0.17.19"
"@esbuild/darwin-x64" "0.16.17" "@esbuild/darwin-x64" "0.17.19"
"@esbuild/freebsd-arm64" "0.16.17" "@esbuild/freebsd-arm64" "0.17.19"
"@esbuild/freebsd-x64" "0.16.17" "@esbuild/freebsd-x64" "0.17.19"
"@esbuild/linux-arm" "0.16.17" "@esbuild/linux-arm" "0.17.19"
"@esbuild/linux-arm64" "0.16.17" "@esbuild/linux-arm64" "0.17.19"
"@esbuild/linux-ia32" "0.16.17" "@esbuild/linux-ia32" "0.17.19"
"@esbuild/linux-loong64" "0.16.17" "@esbuild/linux-loong64" "0.17.19"
"@esbuild/linux-mips64el" "0.16.17" "@esbuild/linux-mips64el" "0.17.19"
"@esbuild/linux-ppc64" "0.16.17" "@esbuild/linux-ppc64" "0.17.19"
"@esbuild/linux-riscv64" "0.16.17" "@esbuild/linux-riscv64" "0.17.19"
"@esbuild/linux-s390x" "0.16.17" "@esbuild/linux-s390x" "0.17.19"
"@esbuild/linux-x64" "0.16.17" "@esbuild/linux-x64" "0.17.19"
"@esbuild/netbsd-x64" "0.16.17" "@esbuild/netbsd-x64" "0.17.19"
"@esbuild/openbsd-x64" "0.16.17" "@esbuild/openbsd-x64" "0.17.19"
"@esbuild/sunos-x64" "0.16.17" "@esbuild/sunos-x64" "0.17.19"
"@esbuild/win32-arm64" "0.16.17" "@esbuild/win32-arm64" "0.17.19"
"@esbuild/win32-ia32" "0.16.17" "@esbuild/win32-ia32" "0.17.19"
"@esbuild/win32-x64" "0.16.17" "@esbuild/win32-x64" "0.17.19"
escalade@^3.1.1: escalade@^3.1.1:
version "3.1.1" version "3.1.1"
@@ -695,6 +690,11 @@ fraction.js@^4.2.0:
resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@~2.3.2: fsevents@~2.3.2:
version "2.3.2" version "2.3.2"
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
@@ -724,6 +724,18 @@ glob-parent@^6.0.2:
dependencies: dependencies:
is-glob "^4.0.3" is-glob "^4.0.3"
glob@7.1.6:
version "7.1.6"
resolved "https://registry.npmmirror.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^11.1.0: globals@^11.1.0:
version "11.12.0" version "11.12.0"
resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" resolved "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@@ -741,6 +753,19 @@ has@^1.0.3:
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.1"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.4"
resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-binary-path@~2.1.0: is-binary-path@~2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@@ -748,6 +773,13 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-core-module@^2.11.0:
version "2.12.1"
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd"
integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==
dependencies:
has "^1.0.3"
is-core-module@^2.9.0: is-core-module@^2.9.0:
version "2.11.0" version "2.11.0"
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
@@ -772,6 +804,11 @@ is-number@^7.0.0:
resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
jiti@^1.18.2:
version "1.18.2"
resolved "https://registry.npmmirror.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd"
integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==
js-tokens@^4.0.0: js-tokens@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -792,11 +829,16 @@ kolorist@^1.2.10:
resolved "https://registry.npmmirror.com/kolorist/-/kolorist-1.7.0.tgz#8e22bc470ea2d2743dbd461808f8b5246b19f5f4" resolved "https://registry.npmmirror.com/kolorist/-/kolorist-1.7.0.tgz#8e22bc470ea2d2743dbd461808f8b5246b19f5f4"
integrity sha512-ymToLHqL02udwVdbkowNpzjFd6UzozMtshPQKVi5k1EjKRqKqBrOnE9QbLEb0/pV76SAiIT13hdL8R6suc+f3g== integrity sha512-ymToLHqL02udwVdbkowNpzjFd6UzozMtshPQKVi5k1EjKRqKqBrOnE9QbLEb0/pV76SAiIT13hdL8R6suc+f3g==
lilconfig@^2.0.5, lilconfig@^2.0.6: lilconfig@^2.0.5, lilconfig@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" resolved "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
lru-cache@^5.1.1: lru-cache@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
@@ -804,11 +846,6 @@ lru-cache@^5.1.1:
dependencies: dependencies:
yallist "^3.0.2" yallist "^3.0.2"
marked@^4.0.10:
version "4.3.0"
resolved "https://registry.npmmirror.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3"
integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==
merge2@^1.3.0: merge2@^1.3.0:
version "1.4.1" version "1.4.1"
resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@@ -822,20 +859,31 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2" braces "^3.0.2"
picomatch "^2.3.1" picomatch "^2.3.1"
minimist@^1.2.6: minimatch@^3.0.4:
version "1.2.8" version "3.1.2"
resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
ms@2.1.2: ms@2.1.2:
version "2.1.2" version "2.1.2"
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nanoid@^3.3.4: mz@^2.7.0:
version "3.3.4" version "2.7.0"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" resolved "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"
nanoid@^3.3.6:
version "3.3.6"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
node-releases@^2.0.8: node-releases@^2.0.8:
version "2.0.10" version "2.0.10"
@@ -852,11 +900,28 @@ normalize-range@^0.1.2:
resolved "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" resolved "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-hash@^3.0.0: object-hash@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" resolved "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-parse@^1.0.7: path-parse@^1.0.7:
version "1.0.7" version "1.0.7"
resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
@@ -877,38 +942,43 @@ pify@^2.3.0:
resolved "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" resolved "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
postcss-import@^14.1.0: pirates@^4.0.1:
version "14.1.0" version "4.0.6"
resolved "https://registry.npmmirror.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" resolved "https://registry.npmmirror.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
postcss-import@^15.1.0:
version "15.1.0"
resolved "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70"
integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==
dependencies: dependencies:
postcss-value-parser "^4.0.0" postcss-value-parser "^4.0.0"
read-cache "^1.0.0" read-cache "^1.0.0"
resolve "^1.1.7" resolve "^1.1.7"
postcss-js@^4.0.0: postcss-js@^4.0.1:
version "4.0.1" version "4.0.1"
resolved "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" resolved "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
dependencies: dependencies:
camelcase-css "^2.0.1" camelcase-css "^2.0.1"
postcss-load-config@^3.1.4: postcss-load-config@^4.0.1:
version "3.1.4" version "4.0.1"
resolved "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-3.1.4.tgz#1ab2571faf84bb078877e1d07905eabe9ebda855" resolved "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd"
integrity sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg== integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==
dependencies: dependencies:
lilconfig "^2.0.5" lilconfig "^2.0.5"
yaml "^1.10.2" yaml "^2.1.1"
postcss-nested@6.0.0: postcss-nested@^6.0.1:
version "6.0.0" version "6.0.1"
resolved "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.0.0.tgz#1572f1984736578f360cffc7eb7dca69e30d1735" resolved "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c"
integrity sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w== integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==
dependencies: dependencies:
postcss-selector-parser "^6.0.10" postcss-selector-parser "^6.0.11"
postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11: postcss-selector-parser@^6.0.11:
version "6.0.11" version "6.0.11"
resolved "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" resolved "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc"
integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==
@@ -921,43 +991,25 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0:
resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.0.9, postcss@^8.4.21: postcss@^8.4.23, postcss@^8.4.24:
version "8.4.21" version "8.4.24"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df"
integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==
dependencies: dependencies:
nanoid "^3.3.4" nanoid "^3.3.6"
picocolors "^1.0.0" picocolors "^1.0.0"
source-map-js "^1.0.2" source-map-js "^1.0.2"
preact-markdown@^2.1.0: preact@^10.15.1:
version "2.1.0" version "10.15.1"
resolved "https://registry.npmmirror.com/preact-markdown/-/preact-markdown-2.1.0.tgz#c271cdd084b8854778f7d8e3640bbe9a7ea6ba4d" resolved "https://registry.npmmirror.com/preact/-/preact-10.15.1.tgz#a1de60c9fc0c79a522d969c65dcaddc5d994eede"
integrity sha512-6c2hfarjLFkVDNa1hUKytXID6wl6yilZnGb2y83xKXnfk5SpXYAwhJc+JENgffAcNALWggqvX/ezlk8/8qJsuA== integrity sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==
dependencies:
marked "^4.0.10"
preact-markup "^2.1.1"
preact-markup@^2.1.1:
version "2.1.1"
resolved "https://registry.npmmirror.com/preact-markup/-/preact-markup-2.1.1.tgz#0451e7eed1dac732d7194c34a7f16ff45a2cfdd7"
integrity sha512-8JL2p36mzK8XkspOyhBxUSPjYwMxDM0L5BWBZWxsZMVW8WsGQrYQDgVuDKkRspt2hwrle+Cxr/053hpc9BJwfw==
preact@^10.11.3:
version "10.13.1"
resolved "https://registry.npmmirror.com/preact/-/preact-10.13.1.tgz#d220bd8771b8fa197680d4917f3cefc5eed88720"
integrity sha512-KyoXVDU5OqTpG9LXlB3+y639JAGzl8JSBXLn1J9HTSB3gbKcuInga7bZnXLlxmK94ntTs1EFeZp0lrja2AuBYQ==
queue-microtask@^1.2.2: queue-microtask@^1.2.2:
version "1.2.3" version "1.2.3"
resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
quick-lru@^5.1.1:
version "5.1.1"
resolved "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
read-cache@^1.0.0: read-cache@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" resolved "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
@@ -972,7 +1024,7 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1: resolve@^1.1.7, resolve@^1.20.0:
version "1.22.1" version "1.22.1"
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -981,15 +1033,24 @@ resolve@^1.1.7, resolve@^1.20.0, resolve@^1.22.1:
path-parse "^1.0.7" path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0" supports-preserve-symlinks-flag "^1.0.0"
resolve@^1.22.2:
version "1.22.2"
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
dependencies:
is-core-module "^2.11.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
reusify@^1.0.4: reusify@^1.0.4:
version "1.0.4" version "1.0.4"
resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rollup@^3.10.0: rollup@^3.21.0:
version "3.19.1" version "3.26.0"
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.19.1.tgz#2b3a31ac1ff9f3afab2e523fa687fef5b0ee20fc" resolved "https://registry.npmmirror.com/rollup/-/rollup-3.26.0.tgz#9f2e0316a4ca641911cefd8515c562a9124e6130"
integrity sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg== integrity sha512-YzJH0eunH2hr3knvF3i6IkLO/jTjAEwU4HoMUbQl4//Tnl3ou0e7P5SjxdDr8HQJdeUJShlbEHXrrnEHy1l7Yg==
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
@@ -1015,6 +1076,19 @@ source-map-js@^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==
sucrase@^3.32.0:
version "3.32.0"
resolved "https://registry.npmmirror.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7"
integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
commander "^4.0.0"
glob "7.1.6"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
supports-color@^5.3.0: supports-color@^5.3.0:
version "5.5.0" version "5.5.0"
resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@@ -1027,34 +1101,48 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
tailwindcss@^3.2.7: tailwindcss@^3.3.2:
version "3.2.7" version "3.3.2"
resolved "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.2.7.tgz#5936dd08c250b05180f0944500c01dce19188c07" resolved "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3"
integrity sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ== integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==
dependencies: dependencies:
"@alloc/quick-lru" "^5.2.0"
arg "^5.0.2" arg "^5.0.2"
chokidar "^3.5.3" chokidar "^3.5.3"
color-name "^1.1.4"
detective "^5.2.1"
didyoumean "^1.2.2" didyoumean "^1.2.2"
dlv "^1.1.3" dlv "^1.1.3"
fast-glob "^3.2.12" fast-glob "^3.2.12"
glob-parent "^6.0.2" glob-parent "^6.0.2"
is-glob "^4.0.3" is-glob "^4.0.3"
lilconfig "^2.0.6" jiti "^1.18.2"
lilconfig "^2.1.0"
micromatch "^4.0.5" micromatch "^4.0.5"
normalize-path "^3.0.0" normalize-path "^3.0.0"
object-hash "^3.0.0" object-hash "^3.0.0"
picocolors "^1.0.0" picocolors "^1.0.0"
postcss "^8.0.9" postcss "^8.4.23"
postcss-import "^14.1.0" postcss-import "^15.1.0"
postcss-js "^4.0.0" postcss-js "^4.0.1"
postcss-load-config "^3.1.4" postcss-load-config "^4.0.1"
postcss-nested "6.0.0" postcss-nested "^6.0.1"
postcss-selector-parser "^6.0.11" postcss-selector-parser "^6.0.11"
postcss-value-parser "^4.2.0" postcss-value-parser "^4.2.0"
quick-lru "^5.1.1" resolve "^1.22.2"
resolve "^1.22.1" sucrase "^3.32.0"
thenify-all@^1.0.0:
version "1.6.0"
resolved "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
dependencies:
thenify ">= 3.1.0 < 4"
"thenify@>= 3.1.0 < 4":
version "3.3.1"
resolved "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
to-fast-properties@^2.0.0: to-fast-properties@^2.0.0:
version "2.0.0" version "2.0.0"
@@ -1068,10 +1156,15 @@ to-regex-range@^5.0.1:
dependencies: dependencies:
is-number "^7.0.0" is-number "^7.0.0"
typescript@^4.9.3: ts-interface-checker@^0.1.9:
version "4.9.5" version "0.1.13"
resolved "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" resolved "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
typescript@^5.1.6:
version "5.1.6"
resolved "https://registry.npmmirror.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
update-browserslist-db@^1.0.10: update-browserslist-db@^1.0.10:
version "1.0.10" version "1.0.10"
@@ -1086,29 +1179,28 @@ util-deprecate@^1.0.2:
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
vite@^4.1.0: vite@^4.3.9:
version "4.1.4" version "4.3.9"
resolved "https://registry.npmmirror.com/vite/-/vite-4.1.4.tgz#170d93bcff97e0ebc09764c053eebe130bfe6ca0" resolved "https://registry.npmmirror.com/vite/-/vite-4.3.9.tgz#db896200c0b1aa13b37cdc35c9e99ee2fdd5f96d"
integrity sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg== integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==
dependencies: dependencies:
esbuild "^0.16.14" esbuild "^0.17.5"
postcss "^8.4.21" postcss "^8.4.23"
resolve "^1.22.1" rollup "^3.21.0"
rollup "^3.10.0"
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
xtend@^4.0.2: wrappy@1:
version "4.0.2" version "1.0.2"
resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
yallist@^3.0.2: yallist@^3.0.2:
version "3.1.1" version "3.1.1"
resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yaml@^1.10.2: yaml@^2.1.1:
version "1.10.2" version "2.3.1"
resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" resolved "https://registry.npmmirror.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==