mirror of
https://github.com/NovaOSS/nova-betterchat.git
synced 2024-11-25 20:43:58 +01:00
parent
df82b62e38
commit
ac7ea965ec
|
@ -11,6 +11,8 @@
|
|||
"dependencies": {
|
||||
"dompurify": "^3.0.1",
|
||||
"highlight.js": "^11.7.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jspdf": "^2.5.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-markdown": "^8.0.5",
|
||||
|
|
17
src/assets/icons/ImageIcon.tsx
Normal file
17
src/assets/icons/ImageIcon.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
|
||||
const ImageIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
viewBox='0 0 1024 1024'
|
||||
fill='currentColor'
|
||||
height='1em'
|
||||
width='1em'
|
||||
{...props}
|
||||
>
|
||||
<path d='M553.1 509.1l-77.8 99.2-41.1-52.4a8 8 0 00-12.6 0l-99.8 127.2a7.98 7.98 0 006.3 12.9H696c6.7 0 10.4-7.7 6.3-12.9l-136.5-174a8.1 8.1 0 00-12.7 0zM360 442a40 40 0 1080 0 40 40 0 10-80 0zm494.6-153.4L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z' />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageIcon;
|
17
src/assets/icons/MarkdownIcon.tsx
Normal file
17
src/assets/icons/MarkdownIcon.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
|
||||
const MarkdownIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
viewBox='0 0 1024 1024'
|
||||
fill='currentColor'
|
||||
height='1em'
|
||||
width='1em'
|
||||
{...props}
|
||||
>
|
||||
<path d='M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494zM429 481.2c-1.9-4.4-6.2-7.2-11-7.2h-35c-6.6 0-12 5.4-12 12v272c0 6.6 5.4 12 12 12h27.1c6.6 0 12-5.4 12-12V582.1l66.8 150.2a12 12 0 0011 7.1H524c4.7 0 9-2.8 11-7.1l66.8-150.6V758c0 6.6 5.4 12 12 12H641c6.6 0 12-5.4 12-12V486c0-6.6-5.4-12-12-12h-34.7c-4.8 0-9.1 2.8-11 7.2l-83.1 191-83.2-191z' />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarkdownIcon;
|
17
src/assets/icons/PdfIcon.tsx
Normal file
17
src/assets/icons/PdfIcon.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
|
||||
const PdfIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||
return (
|
||||
<svg
|
||||
viewBox='0 0 1024 1024'
|
||||
fill='currentColor'
|
||||
height='1em'
|
||||
width='1em'
|
||||
{...props}
|
||||
>
|
||||
<path d='M531.3 574.4l.3-1.4c5.8-23.9 13.1-53.7 7.4-80.7-3.8-21.3-19.5-29.6-32.9-30.2-15.8-.7-29.9 8.3-33.4 21.4-6.6 24-.7 56.8 10.1 98.6-13.6 32.4-35.3 79.5-51.2 107.5-29.6 15.3-69.3 38.9-75.2 68.7-1.2 5.5.2 12.5 3.5 18.8 3.7 7 9.6 12.4 16.5 15 3 1.1 6.6 2 10.8 2 17.6 0 46.1-14.2 84.1-79.4 5.8-1.9 11.8-3.9 17.6-5.9 27.2-9.2 55.4-18.8 80.9-23.1 28.2 15.1 60.3 24.8 82.1 24.8 21.6 0 30.1-12.8 33.3-20.5 5.6-13.5 2.9-30.5-6.2-39.6-13.2-13-45.3-16.4-95.3-10.2-24.6-15-40.7-35.4-52.4-65.8zM421.6 726.3c-13.9 20.2-24.4 30.3-30.1 34.7 6.7-12.3 19.8-25.3 30.1-34.7zm87.6-235.5c5.2 8.9 4.5 35.8.5 49.4-4.9-19.9-5.6-48.1-2.7-51.4.8.1 1.5.7 2.2 2zm-1.6 120.5c10.7 18.5 24.2 34.4 39.1 46.2-21.6 4.9-41.3 13-58.9 20.2-4.2 1.7-8.3 3.4-12.3 5 13.3-24.1 24.4-51.4 32.1-71.4zm155.6 65.5c.1.2.2.5-.4.9h-.2l-.2.3c-.8.5-9 5.3-44.3-8.6 40.6-1.9 45 7.3 45.1 7.4zm191.4-388.2L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0042 42h216v494z' />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default PdfIcon;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import ScrollToBottom from 'react-scroll-to-bottom';
|
||||
import useStore from '@store/store';
|
||||
|
||||
|
@ -9,6 +9,7 @@ import NewMessageButton from './Message/NewMessageButton';
|
|||
import CrossIcon from '@icon/CrossIcon';
|
||||
|
||||
import useSubmit from '@hooks/useSubmit';
|
||||
import DownloadChat from './DownloadChat';
|
||||
|
||||
const ChatContent = () => {
|
||||
const inputRole = useStore((state) => state.inputRole);
|
||||
|
@ -31,6 +32,8 @@ const ChatContent = () => {
|
|||
);
|
||||
const generating = useStore.getState().generating;
|
||||
|
||||
const saveRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// clear error at the start of generating new messages
|
||||
useEffect(() => {
|
||||
if (generating) {
|
||||
|
@ -48,25 +51,30 @@ const ChatContent = () => {
|
|||
>
|
||||
<ScrollToBottomButton />
|
||||
<div className='flex flex-col items-center text-sm dark:bg-gray-800'>
|
||||
<ChatTitle />
|
||||
{messages?.length === 0 && <NewMessageButton messageIndex={-1} />}
|
||||
{messages?.map((message, index) => (
|
||||
<>
|
||||
<Message
|
||||
role={message.role}
|
||||
content={message.content}
|
||||
messageIndex={index}
|
||||
/>
|
||||
<NewMessageButton messageIndex={index} />
|
||||
</>
|
||||
))}
|
||||
<div
|
||||
className='flex flex-col items-center text-sm dark:bg-gray-800 w-full'
|
||||
ref={saveRef}
|
||||
>
|
||||
<ChatTitle />
|
||||
{messages?.length === 0 && <NewMessageButton messageIndex={-1} />}
|
||||
{messages?.map((message, index) => (
|
||||
<>
|
||||
<Message
|
||||
role={message.role}
|
||||
content={message.content}
|
||||
messageIndex={index}
|
||||
/>
|
||||
<NewMessageButton messageIndex={index} />
|
||||
</>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Message
|
||||
role={inputRole}
|
||||
content=''
|
||||
messageIndex={stickyIndex}
|
||||
sticky
|
||||
/>
|
||||
|
||||
{error !== '' && (
|
||||
<div className='relative py-2 px-3 w-3/5 mt-3 max-md:w-11/12 border rounded-md border-red-500 bg-red-500/10'>
|
||||
<div className='text-gray-600 dark:text-gray-100 text-sm whitespace-pre-wrap'>
|
||||
|
@ -82,7 +90,9 @@ const ChatContent = () => {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='mt-4'>
|
||||
<DownloadChat saveRef={saveRef} />
|
||||
</div>
|
||||
<div className='w-full h-36'></div>
|
||||
</div>
|
||||
</ScrollToBottom>
|
||||
|
|
112
src/components/Chat/ChatContent/DownloadChat.tsx
Normal file
112
src/components/Chat/ChatContent/DownloadChat.tsx
Normal file
|
@ -0,0 +1,112 @@
|
|||
import React, { useState } from 'react';
|
||||
import useStore from '@store/store';
|
||||
import PopupModal from '@components/PopupModal';
|
||||
import {
|
||||
chatToMarkdown,
|
||||
downloadImg,
|
||||
downloadMarkdown,
|
||||
downloadPDF,
|
||||
htmlToImg,
|
||||
} from '@utils/chat';
|
||||
import ImageIcon from '@icon/ImageIcon';
|
||||
import PdfIcon from '@icon/PdfIcon';
|
||||
import MarkdownIcon from '@icon/MarkdownIcon';
|
||||
|
||||
const DownloadChat = ({
|
||||
saveRef,
|
||||
}: {
|
||||
saveRef: React.RefObject<HTMLDivElement>;
|
||||
}) => {
|
||||
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className='btn btn-neutral'
|
||||
onClick={() => {
|
||||
setIsModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Download Chat
|
||||
</button>
|
||||
{isModalOpen && (
|
||||
<PopupModal
|
||||
setIsModalOpen={setIsModalOpen}
|
||||
title='Download Chat'
|
||||
cancelButton={false}
|
||||
>
|
||||
<div className='p-6 border-b border-gray-200 dark:border-gray-600 flex gap-4'>
|
||||
<button
|
||||
className='btn btn-neutral gap-2'
|
||||
onClick={async () => {
|
||||
if (saveRef && saveRef.current) {
|
||||
const imgData = await htmlToImg(saveRef.current);
|
||||
downloadImg(
|
||||
imgData,
|
||||
`${
|
||||
useStore
|
||||
.getState()
|
||||
.chats?.[
|
||||
useStore.getState().currentChatIndex
|
||||
].title.trim() ?? 'download'
|
||||
}.png`
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ImageIcon />
|
||||
Image
|
||||
</button>
|
||||
<button
|
||||
className='btn btn-neutral gap-2'
|
||||
onClick={async () => {
|
||||
if (saveRef && saveRef.current) {
|
||||
const imgData = await htmlToImg(saveRef.current);
|
||||
downloadPDF(
|
||||
imgData,
|
||||
useStore.getState().theme,
|
||||
`${
|
||||
useStore
|
||||
.getState()
|
||||
.chats?.[
|
||||
useStore.getState().currentChatIndex
|
||||
].title.trim() ?? 'download'
|
||||
}.pdf`
|
||||
);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<PdfIcon />
|
||||
PDF
|
||||
</button>
|
||||
<button
|
||||
className='btn btn-neutral gap-2'
|
||||
onClick={async () => {
|
||||
if (saveRef && saveRef.current) {
|
||||
const chats = useStore.getState().chats;
|
||||
if (chats) {
|
||||
const markdown = chatToMarkdown(
|
||||
chats[useStore.getState().currentChatIndex]
|
||||
);
|
||||
downloadMarkdown(
|
||||
markdown,
|
||||
`${
|
||||
chats[
|
||||
useStore.getState().currentChatIndex
|
||||
].title.trim() ?? 'download'
|
||||
}.md`
|
||||
);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<MarkdownIcon />
|
||||
Markdown
|
||||
</button>
|
||||
</div>
|
||||
</PopupModal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DownloadChat;
|
|
@ -27,6 +27,10 @@
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
@apply inline-block;
|
||||
}
|
||||
|
||||
input[type='range']::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
@apply w-4;
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import html2canvas from 'html2canvas';
|
||||
import useStore from '@store/store';
|
||||
import jsPDF from 'jspdf';
|
||||
import { ChatInterface } from '@type/chat';
|
||||
import { roles } from '@type/chat';
|
||||
import { Theme } from '@type/theme';
|
||||
|
||||
export const isChats = (chats: any): chats is ChatInterface[] => {
|
||||
if (!Array.isArray(chats)) return false;
|
||||
|
@ -22,3 +26,73 @@ export const isChats = (chats: any): chats is ChatInterface[] => {
|
|||
|
||||
return true;
|
||||
};
|
||||
|
||||
export const htmlToImg = async (html: HTMLDivElement) => {
|
||||
const initialWidth = html.style.width;
|
||||
html.style.width = '1023px';
|
||||
const canvas = await html2canvas(html);
|
||||
html.style.width = initialWidth;
|
||||
const dataURL = canvas.toDataURL('image/png');
|
||||
return dataURL;
|
||||
};
|
||||
|
||||
export const downloadImg = (imgData: string, fileName: string) => {
|
||||
const link = document.createElement('a');
|
||||
link.href = imgData;
|
||||
link.download = fileName;
|
||||
link.click();
|
||||
link.remove();
|
||||
};
|
||||
|
||||
export const downloadPDF = (
|
||||
imageData: string,
|
||||
theme: Theme,
|
||||
fileName: string
|
||||
) => {
|
||||
const pdf = new jsPDF('p', 'mm');
|
||||
const imageProps = pdf.getImageProperties(imageData);
|
||||
const pageHeight = pdf.internal.pageSize.getHeight();
|
||||
const pageWidth = pdf.internal.pageSize.getWidth();
|
||||
const imgHeight = (imageProps.height * pageWidth) / imageProps.width;
|
||||
let heightLeft = imgHeight;
|
||||
let position = 0;
|
||||
|
||||
pdf.addImage(imageData, 'PNG', 0, position, pageWidth, imgHeight);
|
||||
heightLeft -= pageHeight;
|
||||
|
||||
while (heightLeft >= 0) {
|
||||
position -= pageHeight;
|
||||
heightLeft -= pageHeight;
|
||||
pdf.addPage();
|
||||
pdf.addImage(imageData, 'PNG', 0, position, pageWidth, imgHeight);
|
||||
}
|
||||
|
||||
if (heightLeft < 0) {
|
||||
heightLeft = -heightLeft;
|
||||
if (theme === 'dark') {
|
||||
pdf.setFillColor(52, 53, 65);
|
||||
} else {
|
||||
pdf.setFillColor(255, 255, 255);
|
||||
}
|
||||
pdf.rect(0, pageHeight - heightLeft - 3, pageWidth, heightLeft + 3, 'F');
|
||||
}
|
||||
|
||||
pdf.save(fileName);
|
||||
};
|
||||
|
||||
export const chatToMarkdown = (chat: ChatInterface) => {
|
||||
let markdown = `# ${chat.title}\n\n`;
|
||||
chat.messages.forEach((message) => {
|
||||
markdown += `### **${message.role}**:\n\n${message.content}\n\n---\n\n`;
|
||||
});
|
||||
return markdown;
|
||||
};
|
||||
|
||||
export const downloadMarkdown = (markdown: string, fileName: string) => {
|
||||
const link = document.createElement('a');
|
||||
const markdownFile = new Blob([markdown], { type: 'text/markdown' });
|
||||
link.href = URL.createObjectURL(markdownFile);
|
||||
link.download = fileName;
|
||||
link.click();
|
||||
link.remove();
|
||||
};
|
||||
|
|
124
yarn.lock
124
yarn.lock
|
@ -43,7 +43,7 @@
|
|||
core-js-pure "^3.25.1"
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3":
|
||||
"@babel/runtime@^7.12.5", "@babel/runtime@^7.14.0", "@babel/runtime@^7.18.3":
|
||||
version "7.21.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
|
||||
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
|
||||
|
@ -394,6 +394,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
|
||||
"@types/raf@^3.4.0":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2"
|
||||
integrity sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==
|
||||
|
||||
"@types/react-dom@^18.0.10":
|
||||
version "18.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33"
|
||||
|
@ -478,6 +483,11 @@ arg@^5.0.2:
|
|||
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
|
||||
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
|
||||
|
||||
atob@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
autoprefixer@^10.4.13:
|
||||
version "10.4.13"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.13.tgz#b5136b59930209a321e9fa3dca2e7c4d223e83a8"
|
||||
|
@ -504,6 +514,11 @@ bail@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
|
||||
integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==
|
||||
|
||||
base64-arraybuffer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#1c37589a7c4b0746e34bd1feb951da2df01c1bdc"
|
||||
integrity sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
|
@ -526,6 +541,11 @@ browserslist@^4.21.4:
|
|||
node-releases "^2.0.8"
|
||||
update-browserslist-db "^1.0.10"
|
||||
|
||||
btoa@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
|
||||
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
|
@ -541,6 +561,20 @@ caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449:
|
|||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz#871e35866b4654a7d25eccca86864f411825540c"
|
||||
integrity sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==
|
||||
|
||||
canvg@^3.0.6:
|
||||
version "3.0.10"
|
||||
resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.10.tgz#8e52a2d088b6ffa23ac78970b2a9eebfae0ef4b3"
|
||||
integrity sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
"@types/raf" "^3.4.0"
|
||||
core-js "^3.8.3"
|
||||
raf "^3.4.1"
|
||||
regenerator-runtime "^0.13.7"
|
||||
rgbcolor "^1.0.1"
|
||||
stackblur-canvas "^2.0.0"
|
||||
svg-pathdata "^6.0.3"
|
||||
|
||||
ccount@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5"
|
||||
|
@ -622,6 +656,11 @@ core-js@3.18.3:
|
|||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.3.tgz#86a0bba2d8ec3df860fefcc07a8d119779f01509"
|
||||
integrity sha512-tReEhtMReZaPFVw7dajMx0vlsz3oOb8ajgPoHVYGxr8ErnZ6PcYEvvmjGmXlfpnxpkYSdOQttjB+MvVbCGfvLw==
|
||||
|
||||
core-js@^3.6.0, core-js@^3.8.3:
|
||||
version "3.29.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.29.0.tgz#0273e142b67761058bcde5615c503c7406b572d6"
|
||||
integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg==
|
||||
|
||||
cosmiconfig@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
|
||||
|
@ -633,6 +672,13 @@ cosmiconfig@^7.0.0:
|
|||
path-type "^4.0.0"
|
||||
yaml "^1.10.0"
|
||||
|
||||
css-line-break@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.1.0.tgz#bfef660dfa6f5397ea54116bb3cb4873edbc4fa0"
|
||||
integrity sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
|
@ -691,6 +737,11 @@ dlv@^1.1.3:
|
|||
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
|
||||
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
|
||||
|
||||
dompurify@^2.2.0:
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.5.tgz#0e89a27601f0bad978f9a924e7a05d5d2cccdd87"
|
||||
integrity sha512-jggCCd+8Iqp4Tsz0nIvpcb22InKEBrGz5dw3EQJMs8HPJDsKbFIO3STYtAvCfDx26Muevn1MHVI0XxjgFfmiSA==
|
||||
|
||||
dompurify@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.1.tgz#a0933f38931b3238934dd632043b727e53004289"
|
||||
|
@ -779,6 +830,11 @@ fastq@^1.6.0:
|
|||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
fflate@^0.4.8:
|
||||
version "0.4.8"
|
||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
|
||||
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
|
@ -891,6 +947,14 @@ highlight.js@^11.7.0:
|
|||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.7.0.tgz#3ff0165bc843f8c9bce1fd89e2fda9143d24b11e"
|
||||
integrity sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==
|
||||
|
||||
html2canvas@^1.0.0-rc.5, html2canvas@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.1.tgz#7cef1888311b5011d507794a066041b14669a543"
|
||||
integrity sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==
|
||||
dependencies:
|
||||
css-line-break "^2.1.0"
|
||||
text-segmentation "^1.0.3"
|
||||
|
||||
import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -960,6 +1024,21 @@ json-parse-even-better-errors@^2.3.0:
|
|||
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
|
||||
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
|
||||
|
||||
jspdf@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jspdf/-/jspdf-2.5.1.tgz#00c85250abf5447a05f3b32ab9935ab4a56592cc"
|
||||
integrity sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.14.0"
|
||||
atob "^2.1.2"
|
||||
btoa "^1.2.1"
|
||||
fflate "^0.4.8"
|
||||
optionalDependencies:
|
||||
canvg "^3.0.6"
|
||||
core-js "^3.6.0"
|
||||
dompurify "^2.2.0"
|
||||
html2canvas "^1.0.0-rc.5"
|
||||
|
||||
katex@^0.13.0:
|
||||
version "0.13.24"
|
||||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.13.24.tgz#fe55455eb455698cb24b911a353d16a3c855d905"
|
||||
|
@ -1551,6 +1630,11 @@ path-type@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||
|
||||
performance-now@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
||||
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
|
@ -1660,6 +1744,13 @@ quick-lru@^5.1.1:
|
|||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
|
||||
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
|
||||
|
||||
raf@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
|
||||
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
|
||||
dependencies:
|
||||
performance-now "^2.1.0"
|
||||
|
||||
react-dom@^18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
|
@ -1733,7 +1824,7 @@ readdirp@~3.6.0:
|
|||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
regenerator-runtime@^0.13.11:
|
||||
regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.7:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
|
@ -1820,6 +1911,11 @@ reusify@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||
|
||||
rgbcolor@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d"
|
||||
integrity sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==
|
||||
|
||||
rollup@^3.10.0:
|
||||
version "3.18.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.18.0.tgz#2354ba63ba66d6a09c652c3ea0dbcd9dad72bbde"
|
||||
|
@ -1868,6 +1964,11 @@ space-separated-tokens@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f"
|
||||
integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==
|
||||
|
||||
stackblur-canvas@^2.0.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz#aa87bbed1560fdcd3138fff344fc6a1c413ebac4"
|
||||
integrity sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==
|
||||
|
||||
style-to-object@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37"
|
||||
|
@ -1892,6 +1993,11 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
svg-pathdata@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/svg-pathdata/-/svg-pathdata-6.0.3.tgz#80b0e0283b652ccbafb69ad4f8f73e8d3fbf2cac"
|
||||
integrity sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==
|
||||
|
||||
tailwindcss@^3.2.7:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.7.tgz#5936dd08c250b05180f0944500c01dce19188c07"
|
||||
|
@ -1921,6 +2027,13 @@ tailwindcss@^3.2.7:
|
|||
quick-lru "^5.1.1"
|
||||
resolve "^1.22.1"
|
||||
|
||||
text-segmentation@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.3.tgz#52a388159efffe746b24a63ba311b6ac9f2d7943"
|
||||
integrity sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==
|
||||
dependencies:
|
||||
utrie "^1.0.2"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
|
@ -2038,6 +2151,13 @@ util-deprecate@^1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
utrie@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.2.tgz#d42fe44de9bc0119c25de7f564a6ed1b2c87a645"
|
||||
integrity sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==
|
||||
dependencies:
|
||||
base64-arraybuffer "^1.0.2"
|
||||
|
||||
uvu@^0.5.0:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
|
||||
|
|
Loading…
Reference in a new issue