feat: Added react-syntax-highlighter for code highlighting and copy functionality for programming tool UI

This commit is contained in:
zaidmukaddam 2024-08-13 09:58:59 +05:30
parent fd6581245c
commit 095c430ab9
6 changed files with 220 additions and 35 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -18,7 +18,8 @@ import { toast } from 'sonner';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import Image from 'next/image'; import Image from 'next/image';
import { suggestQuestions, Message } from './actions'; import { suggestQuestions, Message } from './actions';
import { copyToClipboard } from '@/lib/utils' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { import {
SearchIcon, SearchIcon,
ChevronDown, ChevronDown,
@ -126,6 +127,46 @@ export default function Home() {
}, },
}); });
const copyToClipboard = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
toast.success("Copied to clipboard");
return true;
} catch (error) {
console.error('Failed to copy:', error);
toast.error("Failed to copy");
return false;
}
};
const CopyButton = ({ text }: { text: string }) => {
const [isCopied, setIsCopied] = useState(false);
const handleCopy = async () => {
const success = await copyToClipboard(text);
if (success) {
setIsCopied(true);
setTimeout(() => setIsCopied(false), 2000);
}
};
return (
<Button
variant="ghost"
size="sm"
onClick={handleCopy}
className="h-8 px-2 text-xs"
>
{isCopied ? (
<Check className="h-3 w-3 mr-1" />
) : (
<Copy className="h-3 w-3 mr-1" />
)}
{isCopied ? "Copied" : "Copy"}
</Button>
);
};
const models = [ const models = [
{ name: 'Speed', description: 'High speed, but lower quality.', details: '(OpenAI/GPT-4o-mini)', icon: FastForward }, { name: 'Speed', description: 'High speed, but lower quality.', details: '(OpenAI/GPT-4o-mini)', icon: FastForward },
{ name: 'Quality (GPT)', description: 'Speed and quality, balanced.', details: '(OpenAI/GPT | Optimized)', icon: Sparkles }, { name: 'Quality (GPT)', description: 'Speed and quality, balanced.', details: '(OpenAI/GPT | Optimized)', icon: Sparkles },
@ -420,20 +461,42 @@ export default function Home() {
<AccordionContent className="pt-4 pb-2 space-y-4"> <AccordionContent className="pt-4 pb-2 space-y-4">
{args?.code && ( {args?.code && (
<div> <div>
<h3 className="text-sm font-medium mb-2">Code</h3> <div className="flex items-center justify-between mb-2">
<pre className="bg-muted p-3 rounded-md overflow-x-auto text-sm"> <h3 className="text-sm font-medium">Code</h3>
<code className='font-mono'>{args.code}</code> <CopyButton text={args.code} />
</pre> </div>
<div className="relative">
<SyntaxHighlighter
language="python"
style={oneLight}
customStyle={{
margin: 0,
padding: '1rem',
borderRadius: '0.5rem',
fontSize: '0.875rem',
}}
>
{args.code}
</SyntaxHighlighter>
<div className="absolute top-2 right-2">
<Badge variant="outline" className="text-xs">
Python
</Badge>
</div>
</div>
</div> </div>
)} )}
<div> <div>
<h3 className="text-sm font-medium mb-2">Result</h3> <div className="flex items-center justify-between mb-2">
<h3 className="text-sm font-medium">Result</h3>
{result && <CopyButton text={result} />}
</div>
{result ? ( {result ? (
<pre className="bg-muted p-3 rounded-md overflow-x-auto text-sm"> <pre className="bg-neutral-50 p-3 rounded-md overflow-x-auto text-sm">
<code>{result}</code> <code>{result}</code>
</pre> </pre>
) : ( ) : (
<div className="flex items-center justify-between w-full bg-muted p-3 rounded-md"> <div className="flex items-center justify-between w-full !bg-neutral-100 p-3 rounded-md">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Loader2 className="h-5 w-5 text-muted-foreground animate-spin" /> <Loader2 className="h-5 w-5 text-muted-foreground animate-spin" />
<span className="text-muted-foreground text-sm">Executing code...</span> <span className="text-muted-foreground text-sm">Executing code...</span>
@ -855,26 +918,7 @@ export default function Home() {
<Sparkles className="size-5 text-primary" /> <Sparkles className="size-5 text-primary" />
<h2 className="text-base font-semibold">Answer</h2> <h2 className="text-base font-semibold">Answer</h2>
</div> </div>
<Button <CopyButton text={message.content} />
variant="ghost"
size="sm"
className={`flex items-center gap-2 ${isLoading ? 'hidden' : ''}`}
onClick={() => {
copyToClipboard(message.content)
.then(() => {
toast.success("Copied to clipboard");
})
.catch((error) => {
console.error('Failed to copy:', error);
toast.error("Failed to copy", {
description: "There was an error copying the answer to your clipboard.",
});
});
}}
>
<Copy className="h-4 w-4" />
<span className="sr-only">Copy Answer</span>
</Button>
</div> </div>
<div> <div>
<MarkdownRenderer content={message.content} /> <MarkdownRenderer content={message.content} />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

@ -4,10 +4,3 @@ import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
} }
export async function copyToClipboard(text: string): Promise<void> {
if (!navigator.clipboard) {
throw new Error('Clipboard API not available');
}
await navigator.clipboard.writeText(text);
}

View File

@ -33,6 +33,7 @@
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
"react-markdown": "^9.0.1", "react-markdown": "^9.0.1",
"react-syntax-highlighter": "^15.5.0",
"recharts": "^2.12.7", "recharts": "^2.12.7",
"remark-gfm": "^4.0.0", "remark-gfm": "^4.0.0",
"sonner": "^1.5.0", "sonner": "^1.5.0",
@ -44,6 +45,7 @@
"@types/node": "^20", "@types/node": "^20",
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"@types/react-syntax-highlighter": "^15.5.13",
"eslint": "^8", "eslint": "^8",
"eslint-config-next": "14.2.5", "eslint-config-next": "14.2.5",
"postcss": "^8", "postcss": "^8",

View File

@ -77,6 +77,9 @@ dependencies:
react-markdown: react-markdown:
specifier: ^9.0.1 specifier: ^9.0.1
version: 9.0.1(@types/react@18.3.3)(react@18.3.1) version: 9.0.1(@types/react@18.3.3)(react@18.3.1)
react-syntax-highlighter:
specifier: ^15.5.0
version: 15.5.0(react@18.3.1)
recharts: recharts:
specifier: ^2.12.7 specifier: ^2.12.7
version: 2.12.7(react-dom@18.3.1)(react@18.3.1) version: 2.12.7(react-dom@18.3.1)(react@18.3.1)
@ -106,6 +109,9 @@ devDependencies:
'@types/react-dom': '@types/react-dom':
specifier: ^18 specifier: ^18
version: 18.3.0 version: 18.3.0
'@types/react-syntax-highlighter':
specifier: ^15.5.13
version: 15.5.13
eslint: eslint:
specifier: ^8 specifier: ^8
version: 8.57.0 version: 8.57.0
@ -1338,6 +1344,12 @@ packages:
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
dev: false dev: false
/@types/hast@2.3.10:
resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==}
dependencies:
'@types/unist': 2.0.10
dev: false
/@types/hast@3.0.4: /@types/hast@3.0.4:
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
dependencies: dependencies:
@ -1372,6 +1384,12 @@ packages:
dependencies: dependencies:
'@types/react': 18.3.3 '@types/react': 18.3.3
/@types/react-syntax-highlighter@15.5.13:
resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==}
dependencies:
'@types/react': 18.3.3
dev: true
/@types/react@18.3.3: /@types/react@18.3.3:
resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==}
dependencies: dependencies:
@ -1882,14 +1900,26 @@ packages:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
dev: false dev: false
/character-entities-legacy@1.1.4:
resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
dev: false
/character-entities-legacy@3.0.0: /character-entities-legacy@3.0.0:
resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
dev: false dev: false
/character-entities@1.2.4:
resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
dev: false
/character-entities@2.0.2: /character-entities@2.0.2:
resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
dev: false dev: false
/character-reference-invalid@1.1.4:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: false
/character-reference-invalid@2.0.1: /character-reference-invalid@2.0.1:
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
dev: false dev: false
@ -1947,6 +1977,10 @@ packages:
/color-name@1.1.4: /color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
/comma-separated-tokens@1.0.8:
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
dev: false
/comma-separated-tokens@2.0.3: /comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
dev: false dev: false
@ -2732,6 +2766,12 @@ packages:
dependencies: dependencies:
reusify: 1.0.4 reusify: 1.0.4
/fault@1.0.4:
resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
dependencies:
format: 0.2.2
dev: false
/file-entry-cache@6.0.1: /file-entry-cache@6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -2779,6 +2819,11 @@ packages:
cross-spawn: 7.0.3 cross-spawn: 7.0.3
signal-exit: 4.1.0 signal-exit: 4.1.0
/format@0.2.2:
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
engines: {node: '>=0.4.x'}
dev: false
/framer-motion@11.3.20(react-dom@18.3.1)(react@18.3.1): /framer-motion@11.3.20(react-dom@18.3.1)(react@18.3.1):
resolution: {integrity: sha512-xRPHtcrSjCdQ7gIttxcnSXOPq+P0AiU7tU82fWE3Tco7EmQQmu5AIgwkdcI6ebZolm+rz9ehSzECVSdZONSj+Q==} resolution: {integrity: sha512-xRPHtcrSjCdQ7gIttxcnSXOPq+P0AiU7tU82fWE3Tco7EmQQmu5AIgwkdcI6ebZolm+rz9ehSzECVSdZONSj+Q==}
peerDependencies: peerDependencies:
@ -2982,6 +3027,10 @@ packages:
dependencies: dependencies:
function-bind: 1.1.2 function-bind: 1.1.2
/hast-util-parse-selector@2.2.5:
resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
dev: false
/hast-util-to-jsx-runtime@2.3.0: /hast-util-to-jsx-runtime@2.3.0:
resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==}
dependencies: dependencies:
@ -3010,6 +3059,20 @@ packages:
'@types/hast': 3.0.4 '@types/hast': 3.0.4
dev: false dev: false
/hastscript@6.0.0:
resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==}
dependencies:
'@types/hast': 2.3.10
comma-separated-tokens: 1.0.8
hast-util-parse-selector: 2.2.5
property-information: 5.6.0
space-separated-tokens: 1.1.5
dev: false
/highlight.js@10.7.3:
resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
dev: false
/html-url-attributes@3.0.0: /html-url-attributes@3.0.0:
resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==} resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==}
dev: false dev: false
@ -3068,10 +3131,21 @@ packages:
loose-envify: 1.4.0 loose-envify: 1.4.0
dev: false dev: false
/is-alphabetical@1.0.4:
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
dev: false
/is-alphabetical@2.0.1: /is-alphabetical@2.0.1:
resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
dev: false dev: false
/is-alphanumerical@1.0.4:
resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
dependencies:
is-alphabetical: 1.0.4
is-decimal: 1.0.4
dev: false
/is-alphanumerical@2.0.1: /is-alphanumerical@2.0.1:
resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
dependencies: dependencies:
@ -3147,6 +3221,10 @@ packages:
has-tostringtag: 1.0.2 has-tostringtag: 1.0.2
dev: true dev: true
/is-decimal@1.0.4:
resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
dev: false
/is-decimal@2.0.1: /is-decimal@2.0.1:
resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
dev: false dev: false
@ -3178,6 +3256,10 @@ packages:
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
/is-hexadecimal@1.0.4:
resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
dev: false
/is-hexadecimal@2.0.1: /is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
dev: false dev: false
@ -3449,6 +3531,13 @@ packages:
dependencies: dependencies:
js-tokens: 4.0.0 js-tokens: 4.0.0
/lowlight@1.20.0:
resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
dependencies:
fault: 1.0.4
highlight.js: 10.7.3
dev: false
/lru-cache@10.4.3: /lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@ -4142,6 +4231,17 @@ packages:
callsites: 3.1.0 callsites: 3.1.0
dev: true dev: true
/parse-entities@2.0.0:
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
dependencies:
character-entities: 1.2.4
character-entities-legacy: 1.1.4
character-reference-invalid: 1.1.4
is-alphanumerical: 1.0.4
is-decimal: 1.0.4
is-hexadecimal: 1.0.4
dev: false
/parse-entities@4.0.1: /parse-entities@4.0.1:
resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
dependencies: dependencies:
@ -4305,6 +4405,16 @@ packages:
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
dev: true dev: true
/prismjs@1.27.0:
resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
engines: {node: '>=6'}
dev: false
/prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
dev: false
/prop-types@15.8.1: /prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
dependencies: dependencies:
@ -4312,6 +4422,12 @@ packages:
object-assign: 4.1.1 object-assign: 4.1.1
react-is: 16.13.1 react-is: 16.13.1
/property-information@5.6.0:
resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
dependencies:
xtend: 4.0.2
dev: false
/property-information@6.5.0: /property-information@6.5.0:
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
dev: false dev: false
@ -4424,6 +4540,19 @@ packages:
tslib: 2.6.3 tslib: 2.6.3
dev: false dev: false
/react-syntax-highlighter@15.5.0(react@18.3.1):
resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==}
peerDependencies:
react: '>= 0.14.0'
dependencies:
'@babel/runtime': 7.25.0
highlight.js: 10.7.3
lowlight: 1.20.0
prismjs: 1.29.0
react: 18.3.1
refractor: 3.6.0
dev: false
/react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1): /react-transition-group@4.4.5(react-dom@18.3.1)(react@18.3.1):
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies: peerDependencies:
@ -4494,6 +4623,14 @@ packages:
which-builtin-type: 1.1.4 which-builtin-type: 1.1.4
dev: true dev: true
/refractor@3.6.0:
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
dependencies:
hastscript: 6.0.0
parse-entities: 2.0.0
prismjs: 1.27.0
dev: false
/regenerator-runtime@0.14.1: /regenerator-runtime@0.14.1:
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
dev: false dev: false
@ -4702,6 +4839,10 @@ packages:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
/space-separated-tokens@1.1.5:
resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
dev: false
/space-separated-tokens@2.0.2: /space-separated-tokens@2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
dev: false dev: false
@ -5359,6 +5500,11 @@ packages:
utf-8-validate: 6.0.4 utf-8-validate: 6.0.4
dev: false dev: false
/xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
dev: false
/yaml@2.5.0: /yaml@2.5.0:
resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==}
engines: {node: '>= 14'} engines: {node: '>= 14'}