Merge branch 'pdf-pptx-layout' of https://github.com/presenton/presenton into pdf-pptx-layout
merge
This commit is contained in:
commit
2facff5280
12 changed files with 263 additions and 120 deletions
Binary file not shown.
|
|
@ -1,9 +1,14 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Save, X, Eye, Code } from "lucide-react";
|
||||
import { Save, X, Code } from "lucide-react";
|
||||
import { ProcessedSlide } from "../../types";
|
||||
import Editor from 'react-simple-code-editor';
|
||||
import { highlight, languages } from 'prismjs';
|
||||
import 'prismjs/components/prism-clike';
|
||||
import 'prismjs/components/prism-javascript';
|
||||
import 'prismjs/components/prism-markup';
|
||||
import 'prismjs/components/prism-jsx';
|
||||
|
||||
interface HtmlEditorProps {
|
||||
slide: ProcessedSlide;
|
||||
|
|
@ -19,7 +24,6 @@ export const HtmlEditor: React.FC<HtmlEditorProps> = ({
|
|||
onCancel,
|
||||
}) => {
|
||||
const [htmlContent, setHtmlContent] = useState(slide.html || "");
|
||||
const [isPreviewMode, setIsPreviewMode] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setHtmlContent(slide.html || "");
|
||||
|
|
@ -45,15 +49,7 @@ export const HtmlEditor: React.FC<HtmlEditorProps> = ({
|
|||
<span className="text-purple-800">HTML Editor</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant={isPreviewMode ? "default" : "outline"}
|
||||
size="sm"
|
||||
onClick={() => setIsPreviewMode(!isPreviewMode)}
|
||||
className="flex items-center gap-1"
|
||||
>
|
||||
<Eye size={14} />
|
||||
{isPreviewMode ? "Code" : "Preview"}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
|
|
@ -73,30 +69,29 @@ export const HtmlEditor: React.FC<HtmlEditorProps> = ({
|
|||
</div>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{isPreviewMode ? (
|
||||
<div className="border rounded-lg p-4 bg-white">
|
||||
<div
|
||||
className="prose max-w-none"
|
||||
dangerouslySetInnerHTML={{ __html: htmlContent }}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-gray-700">
|
||||
Edit HTML Content:
|
||||
</label>
|
||||
<Textarea
|
||||
defaultValue={htmlContent}
|
||||
onBlur={(e) => setHtmlContent(e.target.value)}
|
||||
className="font-mono text-sm h-96 resize-none"
|
||||
placeholder="Enter HTML content here..."
|
||||
/>
|
||||
<div className="text-xs text-gray-500">
|
||||
Tip: You can edit the HTML directly. Make sure to maintain proper HTML structure.
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<CardContent className="space-y-4 ">
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: htmlContent,
|
||||
}}
|
||||
/>
|
||||
<p className="text-base text-gray-800">Edit the HTML code to customize the slide layout.</p>
|
||||
{/* Render code editor */}
|
||||
<div className="container__content_area">
|
||||
|
||||
<Editor
|
||||
value={htmlContent}
|
||||
onValueChange={htmlContent => setHtmlContent(htmlContent)}
|
||||
highlight={htmlContent => highlight(htmlContent, languages.jsx!,'jsx')}
|
||||
padding={10}
|
||||
id="html-editor"
|
||||
name="html-editor"
|
||||
|
||||
className="container__editor"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import React from "react";
|
|||
|
||||
import SlideContent from "../SlideContent";
|
||||
import { SlideContentDisplayProps } from "../../types";
|
||||
import { Repeat2 } from "lucide-react";
|
||||
|
||||
export const SlideContentDisplay: React.FC<SlideContentDisplayProps> = ({
|
||||
slide,
|
||||
|
|
@ -103,7 +104,10 @@ export const SlideContentDisplay: React.FC<SlideContentDisplayProps> = ({
|
|||
slide.error
|
||||
)}
|
||||
</div>
|
||||
<button onClick={() => retrySlide(slide.slide_number)}>Retry</button>
|
||||
<div className="flex justify-center">
|
||||
|
||||
<button className="bg-red-50 flex gap-2 items-center rounded border border-red-200 px-4 py-2 " onClick={() => retrySlide(slide.slide_number)}><Repeat2 className="w-4 h-4" />Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,56 @@ export const useLayoutSaving = (
|
|||
setIsModalOpen(false);
|
||||
}, []);
|
||||
|
||||
const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
const convertSlideToReact = async (slide: ProcessedSlide, presentationId: string, FontUrls: string[]) => {
|
||||
const maxRetries = 3;
|
||||
let retryCount = 0;
|
||||
|
||||
while (retryCount < maxRetries) {
|
||||
try {
|
||||
const response = await fetch("/api/v1/ppt/html-to-react/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
html: slide.html,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await ApiResponseHandler.handleResponse(
|
||||
response,
|
||||
`Failed to convert slide ${slide.slide_number} to React`
|
||||
);
|
||||
|
||||
return {
|
||||
presentation_id: presentationId,
|
||||
layout_id: `${slide.slide_number}`,
|
||||
layout_name: `Slide${slide.slide_number}`,
|
||||
layout_code: data.react_component || data.component_code,
|
||||
fonts: FontUrls,
|
||||
};
|
||||
} catch (error) {
|
||||
retryCount++;
|
||||
console.error(`Error converting slide ${slide.slide_number} (attempt ${retryCount}):`, error);
|
||||
|
||||
if (retryCount < maxRetries) {
|
||||
toast.error(`Failed to convert slide ${slide.slide_number}. Retrying in 2 minutes...`, {
|
||||
description: `Attempt ${retryCount}/${maxRetries}. Error: ${error instanceof Error ? error.message : "An unexpected error occurred"}`,
|
||||
});
|
||||
|
||||
// Wait for 2 minutes before retrying
|
||||
await delay(2 * 60 * 1000);
|
||||
|
||||
toast.info(`Retrying conversion for slide ${slide.slide_number}...`);
|
||||
} else {
|
||||
throw new Error(`Failed to convert slide ${slide.slide_number} after ${maxRetries} attempts: ${error instanceof Error ? error.message : "An unexpected error occurred"}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const saveLayout = useCallback(async (layoutName: string, description: string) => {
|
||||
if (!slides.length) {
|
||||
toast.error("No slides to save");
|
||||
|
|
@ -46,41 +96,23 @@ export const useLayoutSaving = (
|
|||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/v1/ppt/html-to-react/", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
html: slide.html,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await ApiResponseHandler.handleResponse(
|
||||
response,
|
||||
`Failed to convert slide ${slide.slide_number} to React`
|
||||
);
|
||||
|
||||
reactComponents.push({
|
||||
presentation_id: presentationId,
|
||||
layout_id: `${slide.slide_number}`,
|
||||
layout_name: `Slide${slide.slide_number}`,
|
||||
layout_code: data.react_component || data.component_code,
|
||||
fonts: FontUrls,
|
||||
});
|
||||
const reactComponent = await convertSlideToReact(slide, presentationId, FontUrls);
|
||||
reactComponents.push(reactComponent);
|
||||
|
||||
// Update progress
|
||||
toast.info(
|
||||
toast.success(
|
||||
`Converted slide ${slide.slide_number} to React component`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error converting slide ${slide.slide_number}:`, error);
|
||||
toast.error(`Failed to convert slide ${slide.slide_number}`, {
|
||||
toast.error(`Failed to convert slide ${slide.slide_number} after all retries`, {
|
||||
description:
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: "An unexpected error occurred",
|
||||
});
|
||||
// Continue with other slides even if one fails
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -173,20 +173,7 @@ export const useSlideEdit = (
|
|||
processing: false,
|
||||
error: undefined,
|
||||
};
|
||||
// download screenshot
|
||||
const screenshot = slideOnly.toDataURL("image/png");
|
||||
const link = document.createElement("a");
|
||||
link.href = screenshot;
|
||||
link.download = `slide-${slide.slide_number}-current.png`;
|
||||
link.click();
|
||||
// second screenshot
|
||||
if (sketchImageBlob && slideWithCanvas) {
|
||||
const screenshot2 = slideWithCanvas.toDataURL("image/png");
|
||||
const link2 = document.createElement("a");
|
||||
link2.href = screenshot2;
|
||||
link2.download = `slide-${slide.slide_number}-sketch.png`;
|
||||
link2.click();
|
||||
}
|
||||
|
||||
|
||||
if (onSlideUpdate) {
|
||||
onSlideUpdate(updatedSlideData);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ export const useSlideProcessing = (
|
|||
selectedFile: File | null,
|
||||
slides: ProcessedSlide[],
|
||||
setSlides: React.Dispatch<React.SetStateAction<ProcessedSlide[]>>,
|
||||
fontsData: FontData | null,
|
||||
|
||||
setFontsData: React.Dispatch<React.SetStateAction<FontData | null>>
|
||||
) => {
|
||||
const [isProcessingPptx, setIsProcessingPptx] = useState(false);
|
||||
|
|
@ -44,7 +44,6 @@ export const useSlideProcessing = (
|
|||
);
|
||||
|
||||
console.log(`Successfully processed slide ${slide.slide_number}`);
|
||||
|
||||
// Update slide with success
|
||||
setSlides((prev) => {
|
||||
const newSlides = prev.map((s, i) =>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { SaveLayoutButton } from "./components/SaveLayoutButton";
|
|||
import { SaveLayoutModal } from "./components/SaveLayoutModal";
|
||||
import EachSlide from "./components/EachSlide/NewEachSlide";
|
||||
|
||||
|
||||
const CustomLayoutPage = () => {
|
||||
const { refetch } = useLayout();
|
||||
|
||||
|
|
@ -29,7 +30,6 @@ const CustomLayoutPage = () => {
|
|||
selectedFile,
|
||||
slides,
|
||||
setSlides,
|
||||
fontsData,
|
||||
setFontsData
|
||||
);
|
||||
const { isSavingLayout, isModalOpen, openSaveModal, closeSaveModal, saveLayout } = useLayoutSaving(
|
||||
|
|
@ -81,6 +81,7 @@ const CustomLayoutPage = () => {
|
|||
interactive HTML layouts
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
{/* File Upload Section */}
|
||||
<FileUploadSection
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ const OutlineContent: React.FC<OutlineContentProps> = ({
|
|||
)}
|
||||
|
||||
{/* Empty state */}
|
||||
{!isLoading && outlines && outlines.length === 0 && (
|
||||
{!isStreaming && !isLoading && outlines && outlines.length === 0 && (
|
||||
<div className="text-center py-12 bg-white rounded-lg border-2 border-dashed border-gray-200">
|
||||
<FileText className="w-12 h-12 text-gray-400 mx-auto mb-4" />
|
||||
<p className="text-gray-600 mb-4">No outlines available</p>
|
||||
|
|
|
|||
|
|
@ -424,4 +424,97 @@ thead {
|
|||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* code editor */
|
||||
.container_editor_area {
|
||||
tab-size: 4ch;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
|
||||
.container__content {
|
||||
width: 440px;
|
||||
max-width: 100%;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.container__content_area {
|
||||
tab-size: 4ch;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
|
||||
.container__editor {
|
||||
|
||||
font-variant-ligatures: common-ligatures;
|
||||
background-color: #fafafa;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.container__editor textarea {
|
||||
outline: 0;
|
||||
}
|
||||
/* Syntax highlighting */
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: #90a4ae;
|
||||
}
|
||||
.token.punctuation {
|
||||
color: #9e9e9e;
|
||||
}
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #e91e63;
|
||||
}
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #4caf50;
|
||||
}
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #795548;
|
||||
}
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #3f51b5;
|
||||
}
|
||||
.token.function {
|
||||
color: #f44336;
|
||||
}
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #ff9800;
|
||||
}
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
109
servers/nextjs/package-lock.json
generated
109
servers/nextjs/package-lock.json
generated
|
|
@ -45,12 +45,14 @@
|
|||
"lucide-react": "^0.447.0",
|
||||
"marked": "^15.0.11",
|
||||
"mermaid": "^11.9.0",
|
||||
"next": "15.4.3",
|
||||
"next": "15.4.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"prismjs": "^1.30.0",
|
||||
"puppeteer": "^24.13.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-simple-code-editor": "^0.14.1",
|
||||
"recharts": "^2.15.4",
|
||||
"sharp": "^0.34.3",
|
||||
"sonner": "^2.0.6",
|
||||
|
|
@ -63,6 +65,7 @@
|
|||
"devDependencies": {
|
||||
"@types/babel__standalone": "^7.1.9",
|
||||
"@types/node": "^20",
|
||||
"@types/prismjs": "^1.26.5",
|
||||
"@types/puppeteer": "^5.4.7",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
|
@ -1422,15 +1425,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.3.tgz",
|
||||
"integrity": "sha512-lKJ9KJAvaWzqurIsz6NWdQOLj96mdhuDMusLSYHw9HBe2On7BjUwU1WeRvq19x7NrEK3iOgMeSBV5qEhVH1cMw==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.5.tgz",
|
||||
"integrity": "sha512-ruM+q2SCOVCepUiERoxOmZY9ZVoecR3gcXNwCYZRvQQWRjhOiPJGmQ2fAiLR6YKWXcSAh7G79KEFxN3rwhs4LQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.4.3.tgz",
|
||||
"integrity": "sha512-YAhZWKeEYY7LHQJiQ8fe3Y6ymfcDcTn7rDC8PDu/pdeIl1Z2LHD4uyPNuQUGCEQT//MSNv6oZCeQzZfTCKZv+A==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.4.5.tgz",
|
||||
"integrity": "sha512-84dAN4fkfdC7nX6udDLz9GzQlMUwEMKD7zsseXrl7FTeIItF8vpk1lhLEnsotiiDt+QFu3O1FVWnqwcRD2U3KA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1444,9 +1447,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.4.3.tgz",
|
||||
"integrity": "sha512-ZPHRdd51xaxCMpT4viQ6h8TgYM1zPW1JIeksPY9wKlyvBVUQqrWqw8kEh1sa7/x0Ied+U7pYHkAkutrUwxbMcg==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.4.5.tgz",
|
||||
"integrity": "sha512-CL6mfGsKuFSyQjx36p2ftwMNSb8PQog8y0HO/ONLdQqDql7x3aJb/wB+LA651r4we2pp/Ck+qoRVUeZZEvSurA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1460,9 +1463,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.4.3.tgz",
|
||||
"integrity": "sha512-QUdqftCXC5vw5cowucqi9FeOPQ0vdMxoOHLY0J5jPdercwSJFjdi9CkEO4Xkq1eG4t1TB/BG81n6rmTsWoILnw==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.4.5.tgz",
|
||||
"integrity": "sha512-1hTVd9n6jpM/thnDc5kYHD1OjjWYpUJrJxY4DlEacT7L5SEOXIifIdTye6SQNNn8JDZrcN+n8AWOmeJ8u3KlvQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1476,9 +1479,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.4.3.tgz",
|
||||
"integrity": "sha512-HTL31NsmoafX+r5g91Yj3+q34nrn1xKmCWVuNA+fUWO4X0pr+n83uGzLyEOn0kUqbMZ40KmWx+4wsbMoUChkiQ==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.4.5.tgz",
|
||||
"integrity": "sha512-4W+D/nw3RpIwGrqpFi7greZ0hjrCaioGErI7XHgkcTeWdZd146NNu1s4HnaHonLeNTguKnL2Urqvj28UJj6Gqw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1492,9 +1495,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.4.3.tgz",
|
||||
"integrity": "sha512-HRQLWoeFkKXd2YCEEy9GhfwOijRm37x4w5r0MMVHxBKSA6ms3JoPUXvGhfHT6srnGRcEUWNrQ2vzkHir5ZWTSw==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.4.5.tgz",
|
||||
"integrity": "sha512-N6Mgdxe/Cn2K1yMHge6pclffkxzbSGOydXVKYOjYqQXZYjLCfN/CuFkaYDeDHY2VBwSHyM2fUjYBiQCIlxIKDA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1508,9 +1511,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.4.3.tgz",
|
||||
"integrity": "sha512-NyXUx6G7AayaRGUsVPenuwhyAoyxjQuQPaK50AXoaAHPwRuif4WmSrXUs8/Y0HJIZh8E/YXRm9H7uuGfiacpuQ==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.4.5.tgz",
|
||||
"integrity": "sha512-YZ3bNDrS8v5KiqgWE0xZQgtXgCTUacgFtnEgI4ccotAASwSvcMPDLua7BWLuTfucoRv6mPidXkITJLd8IdJplQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -1524,9 +1527,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.4.3.tgz",
|
||||
"integrity": "sha512-2CUTmpzN/7cL1a7GjdLkDFlfH3nwMwW8a6JiaAUsL9MtKmNNO3fnXqnY0Zk30fii3hVEl4dr7ztrpYt0t2CcGQ==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.4.5.tgz",
|
||||
"integrity": "sha512-9Wr4t9GkZmMNcTVvSloFtjzbH4vtT4a8+UHqDoVnxA5QyfWe6c5flTH1BIWPGNWSUlofc8dVJAE7j84FQgskvQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -1540,9 +1543,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.4.3.tgz",
|
||||
"integrity": "sha512-i54YgUhvrUQxQD84SjAbkfWhYkOdm/DNRAVekCHLWxVg3aUbyC6NFQn9TwgCkX5QAS2pXCJo3kFboSFvrsd7dA==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.4.5.tgz",
|
||||
"integrity": "sha512-voWk7XtGvlsP+w8VBz7lqp8Y+dYw/MTI4KeS0gTVtfdhdJ5QwhXLmNrndFOin/MDoCvUaLWMkYKATaCoUkt2/A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -3599,6 +3602,13 @@
|
|||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/prismjs": {
|
||||
"version": "1.26.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz",
|
||||
"integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/puppeteer": {
|
||||
"version": "5.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.7.tgz",
|
||||
|
|
@ -7133,12 +7143,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "15.4.3",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-15.4.3.tgz",
|
||||
"integrity": "sha512-uW7Qe6poVasNIE1X382nI29oxSdFJzjQzTgJFLD43MxyPfGKKxCMySllhBpvqr48f58Om+tLMivzRwBpXEytvA==",
|
||||
"version": "15.4.5",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-15.4.5.tgz",
|
||||
"integrity": "sha512-nJ4v+IO9CPmbmcvsPebIoX3Q+S7f6Fu08/dEWu0Ttfa+wVwQRh9epcmsyCPjmL2b8MxC+CkBR97jgDhUUztI3g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@next/env": "15.4.3",
|
||||
"@next/env": "15.4.5",
|
||||
"@swc/helpers": "0.5.15",
|
||||
"caniuse-lite": "^1.0.30001579",
|
||||
"postcss": "8.4.31",
|
||||
|
|
@ -7151,14 +7161,14 @@
|
|||
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "15.4.3",
|
||||
"@next/swc-darwin-x64": "15.4.3",
|
||||
"@next/swc-linux-arm64-gnu": "15.4.3",
|
||||
"@next/swc-linux-arm64-musl": "15.4.3",
|
||||
"@next/swc-linux-x64-gnu": "15.4.3",
|
||||
"@next/swc-linux-x64-musl": "15.4.3",
|
||||
"@next/swc-win32-arm64-msvc": "15.4.3",
|
||||
"@next/swc-win32-x64-msvc": "15.4.3",
|
||||
"@next/swc-darwin-arm64": "15.4.5",
|
||||
"@next/swc-darwin-x64": "15.4.5",
|
||||
"@next/swc-linux-arm64-gnu": "15.4.5",
|
||||
"@next/swc-linux-arm64-musl": "15.4.5",
|
||||
"@next/swc-linux-x64-gnu": "15.4.5",
|
||||
"@next/swc-linux-x64-musl": "15.4.5",
|
||||
"@next/swc-win32-arm64-msvc": "15.4.5",
|
||||
"@next/swc-win32-x64-msvc": "15.4.5",
|
||||
"sharp": "^0.34.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
@ -7634,6 +7644,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.30.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
|
||||
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
|
|
@ -8115,6 +8134,16 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-simple-code-editor": {
|
||||
"version": "0.14.1",
|
||||
"resolved": "https://registry.npmjs.org/react-simple-code-editor/-/react-simple-code-editor-0.14.1.tgz",
|
||||
"integrity": "sha512-BR5DtNRy+AswWJECyA17qhUDvrrCZ6zXOCfkQY5zSmb96BVUbpVAv03WpcjcwtCwiLbIANx3gebHOcXYn1EHow==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-smooth": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
|
||||
|
|
|
|||
|
|
@ -49,10 +49,12 @@
|
|||
"mermaid": "^11.9.0",
|
||||
"next": "15.4.5",
|
||||
"next-themes": "^0.4.6",
|
||||
"prismjs": "^1.30.0",
|
||||
"puppeteer": "^24.13.0",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"react-redux": "^9.1.2",
|
||||
"react-simple-code-editor": "^0.14.1",
|
||||
"recharts": "^2.15.4",
|
||||
"sharp": "^0.34.3",
|
||||
"sonner": "^2.0.6",
|
||||
|
|
@ -65,6 +67,7 @@
|
|||
"devDependencies": {
|
||||
"@types/babel__standalone": "^7.1.9",
|
||||
"@types/node": "^20",
|
||||
"@types/prismjs": "^1.26.5",
|
||||
"@types/puppeteer": "^5.4.7",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2017",
|
||||
"target": "esnext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue