diff --git a/backend/src/upload/upload.service.ts b/backend/src/upload/upload.service.ts index b78e89b7..6bdc1678 100644 --- a/backend/src/upload/upload.service.ts +++ b/backend/src/upload/upload.service.ts @@ -99,7 +99,7 @@ export class UploadService { // Get the appropriate URL for the uploaded file const bucketUrl = this.getBucketUrl(); - return { url: `${bucketUrl}/${key}`, key }; + return { url: path.join(bucketUrl, key), key }; } else { // Upload to local storage from buffer const directory = path.join(this.mediaDir, subdirectory); @@ -135,8 +135,7 @@ export class UploadService { // Get the appropriate URL for the uploaded file const bucketUrl = this.getBucketUrl(); - - return { url: `${bucketUrl}/${key}`, key }; + return { url: path.join(bucketUrl, key), key }; } else { // Upload to local storage using stream const directory = path.join(this.mediaDir, subdirectory); diff --git a/frontend/package.json b/frontend/package.json index ffb7364b..23aa05fe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -51,6 +51,7 @@ "motion": "^12.4.7", "next": "^14.2.13", "next-themes": "^0.3.0", + "puppeteer": "^24.3.1", "react": "^18.3.1", "react-activity-calendar": "^2.7.8", "react-code-blocks": "^0.1.6", diff --git a/frontend/src/app/api/runProject/route.ts b/frontend/src/app/api/runProject/route.ts index cb7269b1..70ad7b3f 100644 --- a/frontend/src/app/api/runProject/route.ts +++ b/frontend/src/app/api/runProject/route.ts @@ -3,6 +3,10 @@ import { exec } from 'child_process'; import * as path from 'path'; import * as net from 'net'; import { getProjectPath } from 'codefox-common'; +import puppetter from 'puppeteer'; +import { useMutation } from '@apollo/client/react/hooks/useMutation'; +import { toast } from 'sonner'; +import { UPDATE_PROJECT_PHOTO_URL } from '@/graphql/request'; const runningContainers = new Map< string, @@ -294,6 +298,7 @@ export async function GET(req: Request) { try { const { domain, containerId } = await buildAndRunDocker(projectPath); + return NextResponse.json({ message: 'Docker container started', domain, diff --git a/frontend/src/app/api/screenshot/route.ts b/frontend/src/app/api/screenshot/route.ts new file mode 100644 index 00000000..ed7a6441 --- /dev/null +++ b/frontend/src/app/api/screenshot/route.ts @@ -0,0 +1,56 @@ +import { randomUUID } from 'crypto'; +import { NextResponse } from 'next/server'; +import puppeteer from 'puppeteer'; + +export async function GET(req: Request) { + const { searchParams } = new URL(req.url); + const url = searchParams.get('url'); + + if (!url) { + return NextResponse.json( + { error: 'URL parameter is required' }, + { status: 400 } + ); + } + + try { + const browser = await puppeteer.launch({ + headless: true, + }); + const page = await browser.newPage(); + + // Set viewport to a reasonable size + await page.setViewport({ + width: 1280, + height: 720, + }); + + await page.goto(url, { + waitUntil: 'networkidle0', + timeout: 30000, + }); + + // Take screenshot + const screenshot = await page.screenshot({ + path: `dsadas.png`, + type: 'png', + fullPage: true, + }); + + await browser.close(); + + // Return the screenshot as a PNG image + return new Response(screenshot, { + headers: { + 'Content-Type': 'image/png', + 'Cache-Control': 's-maxage=3600', + }, + }); + } catch (error: any) { + console.error('Screenshot error:', error); + return NextResponse.json( + { error: error.message || 'Failed to capture screenshot' }, + { status: 500 } + ); + } +} diff --git a/frontend/src/components/chat/code-engine/project-context.tsx b/frontend/src/components/chat/code-engine/project-context.tsx index 0aa394e3..b689a3fb 100644 --- a/frontend/src/components/chat/code-engine/project-context.tsx +++ b/frontend/src/components/chat/code-engine/project-context.tsx @@ -14,6 +14,7 @@ import { GET_CHAT_DETAILS, GET_USER_PROJECTS, UPDATE_PROJECT_PUBLIC_STATUS, + UPDATE_PROJECT_PHOTO_URL, } from '@/graphql/request'; import { Project } from '../project-modal'; import { useRouter } from 'next/navigation'; @@ -40,12 +41,31 @@ export interface ProjectContextType { ) => Promise; pollChatProject: (chatId: string) => Promise; isLoading: boolean; + getWebUrl: ( + projectPath: string + ) => Promise<{ domain: string; containerId: string }>; + takeProjectScreenshot: (projectId: string, url: string) => Promise; } export const ProjectContext = createContext( undefined ); - +const checkUrlStatus = async (url: string) => { + let status = 0; + while (status !== 200) { + try { + const res = await fetch(url, { method: 'HEAD' }); + status = res.status; + if (status !== 200) { + console.log(`URL status: ${status}. Retrying...`); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + } catch (err) { + console.error('Error checking URL status:', err); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + } +}; export function ProjectProvider({ children }: { children: ReactNode }) { const router = useRouter(); @@ -173,6 +193,106 @@ export function ProjectProvider({ children }: { children: ReactNode }) { } ); + const [updateProjectPhotoMutation] = useMutation(UPDATE_PROJECT_PHOTO_URL, { + onCompleted: (data) => { + // Update projects list + setProjects((prev) => + prev.map((project) => + project.id === data.updateProjectPhoto.id + ? { + ...project, + photoUrl: data.updateProjectPhoto.photoUrl, + } + : project + ) + ); + + // Update current project if it's the one being modified + if (curProject?.id === data.updateProjectPhoto.id) { + setCurProject((prev) => + prev + ? { + ...prev, + photoUrl: data.updateProjectPhoto.photoUrl, + } + : prev + ); + } + }, + onError: (error) => { + toast.error(`Failed to update project photo: ${error.message}`); + }, + }); + + const takeProjectScreenshot = useCallback( + async (projectId: string, url: string) => { + try { + await checkUrlStatus(url); + + const screenshotResponse = await fetch( + `/api/screenshot?url=${encodeURIComponent(url)}` + ); + + if (!screenshotResponse.ok) { + throw new Error('Failed to capture screenshot'); + } + + const arrayBuffer = await screenshotResponse.arrayBuffer(); + const blob = new Blob([arrayBuffer], { type: 'image/png' }); + + const file = new File([blob], 'screenshot.png', { type: 'image/png' }); + + await updateProjectPhotoMutation({ + variables: { + input: { + projectId, + file, + }, + }, + }); + } catch (error) { + console.error('Error:', error); + } + }, + [updateProjectPhotoMutation] + ); + + const getWebUrl = useCallback( + async (projectPath: string) => { + try { + const response = await fetch( + `/api/runProject?projectPath=${encodeURIComponent(projectPath)}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + } + ); + + if (!response.ok) { + throw new Error('Failed to get web URL'); + } + + const data = await response.json(); + const baseUrl = `http://${data.domain}`; + const project = projects.find((p) => p.projectPath === projectPath); + if (project) { + await takeProjectScreenshot(project.id, baseUrl); + } + + return { + domain: data.domain, + containerId: data.containerId, + }; + } catch (error) { + console.error('Error getting web URL:', error); + throw error; + } + }, + [projects, updateProjectPhotoMutation] + ); + const [getChatDetail] = useLazyQuery(GET_CHAT_DETAILS, { fetchPolicy: 'network-only', }); @@ -300,8 +420,31 @@ export function ProjectProvider({ children }: { children: ReactNode }) { const { data } = await getChatDetail({ variables: { chatId } }); if (data?.getChatDetails?.project) { - chatProjectCache.current.set(chatId, data.getChatDetails.project); - return data.getChatDetails.project; + const project = data.getChatDetails.project; + chatProjectCache.current.set(chatId, project); + + try { + // Get web URL and wait for it to be ready + const response = await fetch( + `/api/runProject?projectPath=${encodeURIComponent(project.projectPath)}`, + { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + } + ); + + if (response.ok) { + const data = await response.json(); + const baseUrl = `http://${data.domain}`; + await takeProjectScreenshot(project.id, baseUrl); + } + } catch (error) { + console.error('Error capturing project screenshot:', error); + } + + return project; } } catch (error) { console.error('Error polling chat:', error); @@ -314,7 +457,7 @@ export function ProjectProvider({ children }: { children: ReactNode }) { chatProjectCache.current.set(chatId, null); return null; }, - [getChatDetail] + [getChatDetail, updateProjectPhotoMutation] ); const contextValue = useMemo( @@ -331,6 +474,8 @@ export function ProjectProvider({ children }: { children: ReactNode }) { setProjectPublicStatus, pollChatProject, isLoading, + getWebUrl, + takeProjectScreenshot, }), [ projects, @@ -342,6 +487,7 @@ export function ProjectProvider({ children }: { children: ReactNode }) { setProjectPublicStatus, pollChatProject, isLoading, + getWebUrl, ] ); diff --git a/frontend/src/components/chat/code-engine/web-view.tsx b/frontend/src/components/chat/code-engine/web-view.tsx index 86d3d890..5476551b 100644 --- a/frontend/src/components/chat/code-engine/web-view.tsx +++ b/frontend/src/components/chat/code-engine/web-view.tsx @@ -11,9 +11,13 @@ import { ZoomIn, ZoomOut, } from 'lucide-react'; +import puppeteer from 'puppeteer'; export default function WebPreview() { - const { curProject } = useContext(ProjectContext); + const { curProject, getWebUrl } = useContext(ProjectContext); + if (!curProject || !getWebUrl) { + throw new Error('ProjectContext not properly initialized'); + } const [baseUrl, setBaseUrl] = useState(''); const [displayPath, setDisplayPath] = useState('/'); const [history, setHistory] = useState(['/']); @@ -26,7 +30,7 @@ export default function WebPreview() { const lastProjectPathRef = useRef(null); useEffect(() => { - const getWebUrl = async () => { + const initWebUrl = async () => { if (!curProject) return; const projectPath = curProject.projectPath; @@ -42,53 +46,23 @@ export default function WebPreview() { } try { - const response = await fetch( - `/api/runProject?projectPath=${encodeURIComponent(projectPath)}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - } - ); - const json = await response.json(); - - await new Promise((resolve) => setTimeout(resolve, 100)); - + const { domain } = await getWebUrl(projectPath); containerRef.current = { projectPath, - domain: json.domain, + domain, }; - const checkUrlStatus = async (url: string) => { - let status = 0; - while (status !== 200) { - try { - const res = await fetch(url, { method: 'HEAD' }); - status = res.status; - if (status !== 200) { - console.log(`URL status: ${status}. Retrying...`); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - } catch (err) { - console.error('Error checking URL status:', err); - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - } - }; - - const baseUrl = `http://${json.domain}`; - await checkUrlStatus(baseUrl); - + const baseUrl = `http://${domain}`; + console.log('baseUrl:', baseUrl); setBaseUrl(baseUrl); setDisplayPath('/'); } catch (error) { - console.error('fetching url error:', error); + console.error('Error getting web URL:', error); } }; - getWebUrl(); - }, [curProject]); + initWebUrl(); + }, [curProject, getWebUrl]); useEffect(() => { if (iframeRef.current && baseUrl) { diff --git a/frontend/src/components/root/expand-card.tsx b/frontend/src/components/root/expand-card.tsx index 1095aacc..edb66ffe 100644 --- a/frontend/src/components/root/expand-card.tsx +++ b/frontend/src/components/root/expand-card.tsx @@ -1,13 +1,16 @@ 'use client'; import Image from 'next/image'; -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { AnimatePresence, motion } from 'framer-motion'; import { X } from 'lucide-react'; +import { ProjectContext } from '../chat/code-engine/project-context'; export function ExpandableCard({ projects }) { const [active, setActive] = useState(null); const [iframeUrl, setIframeUrl] = useState(''); const ref = useRef(null); + const { getWebUrl, takeProjectScreenshot } = useContext(ProjectContext); + const cachedUrls = useRef(new Map()); useEffect(() => { function onKeyDown(event: KeyboardEvent) { @@ -15,7 +18,6 @@ export function ExpandableCard({ projects }) { setActive(null); } } - if (active && typeof active === 'object') { document.body.style.overflow = 'hidden'; } else { @@ -25,31 +27,23 @@ export function ExpandableCard({ projects }) { window.addEventListener('keydown', onKeyDown); return () => window.removeEventListener('keydown', onKeyDown); }, [active]); - - const getWebUrl = async (project) => { - if (!project) return; - console.log('project:', project); - const projectPath = project.path; + const handleCardClick = async (project) => { + setActive(project); + setIframeUrl(''); + if (cachedUrls.current.has(project.id)) { + setIframeUrl(cachedUrls.current.get(project.id)); + return; + } try { - const response = await fetch( - `/api/runProject?projectPath=${encodeURIComponent(projectPath)}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - } - ); - const json = await response.json(); - const baseUrl = `http://${json.domain}`; - setIframeUrl(baseUrl); - setActive(project); + const data = await getWebUrl(project.path); + const url = `http://${data.domain}`; + cachedUrls.current.set(project.id, url); + setIframeUrl(url); } catch (error) { - console.error('fetching url error:', error); + console.error('Error fetching project URL:', error); } }; - return ( <> @@ -122,7 +116,15 @@ export function ExpandableCard({ projects }) { getWebUrl(project)} + onClick={async () => { + const data = await getWebUrl(project.path); + + console.log(project.image); + const url = `http://${data.domain}`; + setIframeUrl(url); + handleCardClick(project); + setActive(project); + }} className="group cursor-pointer" > - {project.name}; }; +export type EmailConfirmationResponse = { + __typename: 'EmailConfirmationResponse'; + message: Scalars['String']['output']; + success?: Maybe; +}; + export type FetchPublicProjectsInputs = { size: Scalars['Float']['input']; strategy: Scalars['String']['input']; @@ -144,6 +150,7 @@ export type Message = { export type Mutation = { __typename: 'Mutation'; clearChatHistory: Scalars['Boolean']['output']; + confirmEmail: EmailConfirmationResponse; createChat: Chat; createProject: Chat; deleteChat: Scalars['Boolean']['output']; @@ -153,6 +160,7 @@ export type Mutation = { refreshToken: RefreshTokenResponse; regenerateDescription: Scalars['String']['output']; registerUser: User; + resendConfirmationEmail: EmailConfirmationResponse; subscribeToProject: Project; triggerChatStream: Scalars['Boolean']['output']; updateChatTitle?: Maybe; @@ -164,6 +172,10 @@ export type MutationClearChatHistoryArgs = { chatId: Scalars['String']['input']; }; +export type MutationConfirmEmailArgs = { + token: Scalars['String']['input']; +}; + export type MutationCreateChatArgs = { newChatInput: NewChatInput; }; @@ -200,6 +212,10 @@ export type MutationRegisterUserArgs = { input: RegisterUserInput; }; +export type MutationResendConfirmationEmailArgs = { + input: ResendEmailInput; +}; + export type MutationSubscribeToProjectArgs = { projectId: Scalars['ID']['input']; }; @@ -275,6 +291,7 @@ export type Query = { getChatHistory: Array; getHello: Scalars['String']['output']; getProject: Project; + getRemainingProjectLimit: Scalars['Int']['output']; getSubscribedProjects: Array; getUserChats?: Maybe>; getUserProjects: Array; @@ -319,6 +336,10 @@ export type RegisterUserInput = { username: Scalars['String']['input']; }; +export type ResendEmailInput = { + email: Scalars['String']['input']; +}; + export type Role = 'Assistant' | 'System' | 'User'; export type StreamStatus = 'DONE' | 'STREAMING'; @@ -350,6 +371,8 @@ export type User = { id: Scalars['ID']['output']; isActive: Scalars['Boolean']['output']; isDeleted: Scalars['Boolean']['output']; + isEmailConfirmed: Scalars['Boolean']['output']; + lastEmailSendTime: Scalars['Date']['output']; projects: Array; /** @deprecated Use projects with forkedFromId instead */ subscribedProjects?: Maybe>; @@ -476,9 +499,11 @@ export type ResolversTypes = ResolversObject<{ CheckTokenInput: CheckTokenInput; CreateProjectInput: CreateProjectInput; Date: ResolverTypeWrapper; + EmailConfirmationResponse: ResolverTypeWrapper; FetchPublicProjectsInputs: FetchPublicProjectsInputs; Float: ResolverTypeWrapper; ID: ResolverTypeWrapper; + Int: ResolverTypeWrapper; IsValidProjectInput: IsValidProjectInput; LoginResponse: ResolverTypeWrapper; LoginUserInput: LoginUserInput; @@ -492,6 +517,7 @@ export type ResolversTypes = ResolversObject<{ Query: ResolverTypeWrapper<{}>; RefreshTokenResponse: ResolverTypeWrapper; RegisterUserInput: RegisterUserInput; + ResendEmailInput: ResendEmailInput; Role: Role; StreamStatus: StreamStatus; String: ResolverTypeWrapper; @@ -513,9 +539,11 @@ export type ResolversParentTypes = ResolversObject<{ CheckTokenInput: CheckTokenInput; CreateProjectInput: CreateProjectInput; Date: Scalars['Date']['output']; + EmailConfirmationResponse: EmailConfirmationResponse; FetchPublicProjectsInputs: FetchPublicProjectsInputs; Float: Scalars['Float']['output']; ID: Scalars['ID']['output']; + Int: Scalars['Int']['output']; IsValidProjectInput: IsValidProjectInput; LoginResponse: LoginResponse; LoginUserInput: LoginUserInput; @@ -529,6 +557,7 @@ export type ResolversParentTypes = ResolversObject<{ Query: {}; RefreshTokenResponse: RefreshTokenResponse; RegisterUserInput: RegisterUserInput; + ResendEmailInput: ResendEmailInput; String: Scalars['String']['output']; Subscription: {}; UpdateChatTitleInput: UpdateChatTitleInput; @@ -615,6 +644,16 @@ export interface DateScalarConfig name: 'Date'; } +export type EmailConfirmationResponseResolvers< + ContextType = any, + ParentType extends + ResolversParentTypes['EmailConfirmationResponse'] = ResolversParentTypes['EmailConfirmationResponse'], +> = ResolversObject<{ + message?: Resolver; + success?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}>; + export type LoginResponseResolvers< ContextType = any, ParentType extends @@ -668,6 +707,12 @@ export type MutationResolvers< ContextType, RequireFields >; + confirmEmail?: Resolver< + ResolversTypes['EmailConfirmationResponse'], + ParentType, + ContextType, + RequireFields + >; createChat?: Resolver< ResolversTypes['Chat'], ParentType, @@ -722,6 +767,12 @@ export type MutationResolvers< ContextType, RequireFields >; + resendConfirmationEmail?: Resolver< + ResolversTypes['EmailConfirmationResponse'], + ParentType, + ContextType, + RequireFields + >; subscribeToProject?: Resolver< ResolversTypes['Project'], ParentType, @@ -861,6 +912,11 @@ export type QueryResolvers< ContextType, RequireFields >; + getRemainingProjectLimit?: Resolver< + ResolversTypes['Int'], + ParentType, + ContextType + >; getSubscribedProjects?: Resolver< Array, ParentType, @@ -926,6 +982,12 @@ export type UserResolvers< id?: Resolver; isActive?: Resolver; isDeleted?: Resolver; + isEmailConfirmed?: Resolver< + ResolversTypes['Boolean'], + ParentType, + ContextType + >; + lastEmailSendTime?: Resolver; projects?: Resolver< Array, ParentType, @@ -947,6 +1009,7 @@ export type Resolvers = ResolversObject<{ ChatCompletionChunkType?: ChatCompletionChunkTypeResolvers; ChatCompletionDeltaType?: ChatCompletionDeltaTypeResolvers; Date?: GraphQLScalarType; + EmailConfirmationResponse?: EmailConfirmationResponseResolvers; LoginResponse?: LoginResponseResolvers; Menu?: MenuResolvers; Message?: MessageResolvers; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2b20fb9e..57973d51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -342,7 +342,7 @@ importers: version: 3.10.0(react-hook-form@7.54.2) '@langchain/community': specifier: ^0.3.1 - version: 0.3.34(@browserbasehq/stagehand@1.13.1)(@ibm-cloud/watsonx-ai@1.5.1)(@langchain/core@0.3.42)(axios@1.7.9)(ibm-cloud-sdk-core@5.1.3)(openai@4.86.1)(ws@8.18.1) + version: 0.3.34(@browserbasehq/stagehand@1.13.1)(@ibm-cloud/watsonx-ai@1.5.1)(@langchain/core@0.3.42)(axios@1.7.9)(ibm-cloud-sdk-core@5.1.3)(openai@4.86.1)(puppeteer@24.3.1)(ws@8.18.1) '@langchain/core': specifier: ^0.3.3 version: 0.3.42(openai@4.86.1) @@ -433,6 +433,9 @@ importers: next-themes: specifier: ^0.3.0 version: 0.3.0(react-dom@18.3.1)(react@18.3.1) + puppeteer: + specifier: ^24.3.1 + version: 24.3.1(typescript@5.6.3) react: specifier: ^18.3.1 version: 18.3.1 @@ -6539,7 +6542,7 @@ packages: resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} dev: false - /@langchain/community@0.3.34(@browserbasehq/stagehand@1.13.1)(@ibm-cloud/watsonx-ai@1.5.1)(@langchain/core@0.3.42)(axios@1.7.9)(ibm-cloud-sdk-core@5.1.3)(openai@4.86.1)(ws@8.18.1): + /@langchain/community@0.3.34(@browserbasehq/stagehand@1.13.1)(@ibm-cloud/watsonx-ai@1.5.1)(@langchain/core@0.3.42)(axios@1.7.9)(ibm-cloud-sdk-core@5.1.3)(openai@4.86.1)(puppeteer@24.3.1)(ws@8.18.1): resolution: {integrity: sha512-s0KVulgVIPd90s3m6XZtWrCRGQPWsY93uY62seFMmNhzcyF+I65kKnN04Nbiouthrn/YJ9HB4hW8MJAFuX6RRg==} engines: {node: '>=18'} peerDependencies: @@ -6925,6 +6928,7 @@ packages: langchain: 0.3.19(@langchain/core@0.3.42)(axios@1.7.9)(openai@4.86.1)(ws@8.18.1) langsmith: 0.3.12(openai@4.86.1) openai: 4.86.1(ws@8.18.1)(zod@3.24.2) + puppeteer: 24.3.1(typescript@5.6.3) uuid: 10.0.0 ws: 8.18.1 zod: 3.24.2 @@ -8124,6 +8128,23 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false + /@puppeteer/browsers@2.7.1: + resolution: {integrity: sha512-MK7rtm8JjaxPN7Mf1JdZIZKPD2Z+W7osvrC1vjpvfOX1K0awDIHYbNi89f7eotp7eMUn2shWnt03HwVbriXtKQ==} + engines: {node: '>=18'} + hasBin: true + dependencies: + debug: 4.4.0(supports-color@5.5.0) + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.5.0 + semver: 7.7.1 + tar-fs: 3.0.8 + yargs: 17.7.2 + transitivePeerDependencies: + - bare-buffer + - supports-color + dev: false + /@radix-ui/number@1.1.0: resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} dev: false @@ -9759,6 +9780,10 @@ packages: engines: {node: '>= 10'} dev: true + /@tootallnate/quickjs-emscripten@0.23.0: + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + dev: false + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -10283,6 +10308,14 @@ packages: dependencies: '@types/yargs-parser': 21.0.3 + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + requiresBuild: true + dependencies: + '@types/node': 22.13.9 + dev: false + optional: true + /@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0)(eslint@8.57.1)(typescript@5.6.3): resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} engines: {node: ^16.0.0 || >=18.0.0} @@ -10898,7 +10931,6 @@ packages: /agent-base@7.1.3: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} - dev: true /agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} @@ -11282,6 +11314,13 @@ packages: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} dev: true + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.8.1 + dev: false + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -11375,6 +11414,10 @@ packages: engines: {node: '>= 0.4'} dev: true + /b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + dev: false + /babel-jest@29.7.0(@babel/core@7.26.9): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -11577,9 +11620,65 @@ packages: /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + /bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + requiresBuild: true + dev: false + optional: true + + /bare-fs@4.0.1: + resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==} + engines: {bare: '>=1.7.0'} + requiresBuild: true + dependencies: + bare-events: 2.5.4 + bare-path: 3.0.0 + bare-stream: 2.6.5(bare-events@2.5.4) + transitivePeerDependencies: + - bare-buffer + dev: false + optional: true + + /bare-os@3.5.1: + resolution: {integrity: sha512-LvfVNDcWLw2AnIw5f2mWUgumW3I3N/WYGiWeimhQC1Ybt71n2FjlS9GJKeCnFeg1MKZHxzIFmpFnBXDI+sBeFg==} + engines: {bare: '>=1.14.0'} + requiresBuild: true + dev: false + optional: true + + /bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + requiresBuild: true + dependencies: + bare-os: 3.5.1 + dev: false + optional: true + + /bare-stream@2.6.5(bare-events@2.5.4): + resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} + requiresBuild: true + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + dependencies: + bare-events: 2.5.4 + streamx: 2.22.0 + dev: false + optional: true + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + /basic-ftp@5.0.5: + resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + engines: {node: '>=10.0.0'} + dev: false + /batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} dev: false @@ -11727,6 +11826,10 @@ packages: node-int64: 0.4.0 dev: true + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: false + /buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} dev: false @@ -12067,6 +12170,16 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} + /chromium-bidi@2.1.2(devtools-protocol@0.0.1402036): + resolution: {integrity: sha512-vtRWBK2uImo5/W2oG6/cDkkHSm+2t6VHgnj+Rcwhb0pP74OoUb4GipyRX/T/y39gYQPhioP0DPShn+A7P6CHNw==} + peerDependencies: + devtools-protocol: '*' + dependencies: + devtools-protocol: 0.0.1402036 + mitt: 3.0.1 + zod: 3.24.2 + dev: false + /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -12568,6 +12681,22 @@ packages: typescript: 5.7.2 dev: true + /cosmiconfig@9.0.0(typescript@5.6.3): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.6.3 + dev: false + /create-jest@29.7.0(@types/node@16.18.126): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -12955,6 +13084,11 @@ packages: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} + /data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + dev: false + /data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -13119,6 +13253,15 @@ packages: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + /degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + dev: false + /del@6.1.1: resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} engines: {node: '>=10'} @@ -13217,6 +13360,10 @@ packages: dependencies: dequal: 2.0.3 + /devtools-protocol@0.0.1402036: + resolution: {integrity: sha512-JwAYQgEvm3yD45CHB+RmF5kMbWtXBaOGwuxa87sZogHcLCv8c/IqnThaoQ1y60d7pXWjSKWQphPEc+1rAScVdg==} + dev: false + /dezalgo@1.0.4: resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} dependencies: @@ -13519,9 +13666,7 @@ packages: /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - requiresBuild: true dev: false - optional: true /env-var@7.5.0: resolution: {integrity: sha512-mKZOzLRN0ETzau2W2QXefbFjo5EF4yWq28OyKb9ICdeNhHJlOE/pHHnz4hdYJ9cNZXcJHo5xN4OT4pzuSHSNvA==} @@ -13768,7 +13913,6 @@ packages: esutils: 2.0.3 optionalDependencies: source-map: 0.6.1 - dev: true /eslint-config-next@14.2.13(eslint@8.57.1)(typescript@5.6.3): resolution: {integrity: sha512-aro1EKAoyYchnO/3Tlo91hnNBO7QO7qnv/79MAFC+4Jq8TdUVKQlht5d2F+YjrePjdpOvfL+mV9JPfyYNwkk1g==} @@ -14345,6 +14489,20 @@ packages: is-plain-obj: 4.1.0 dev: false + /extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.4.0(supports-color@5.5.0) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + dev: false + /fast-content-type-parse@2.0.1: resolution: {integrity: sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==} dev: false @@ -14356,6 +14514,10 @@ packages: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} dev: true + /fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + dev: false + /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -14457,6 +14619,12 @@ packages: - encoding dev: true + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: false + /fdir@6.4.3(picomatch@4.0.2): resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} peerDependencies: @@ -14995,6 +15163,13 @@ packages: dev: false optional: true + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.2 + dev: false + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -15014,6 +15189,17 @@ packages: resolve-pkg-maps: 1.0.0 dev: true + /get-uri@6.0.4: + resolution: {integrity: sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==} + engines: {node: '>= 14'} + dependencies: + basic-ftp: 5.0.5 + data-uri-to-buffer: 6.0.2 + debug: 4.4.0(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + dev: false + /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} dev: false @@ -15773,7 +15959,6 @@ packages: debug: 4.4.0(supports-color@5.5.0) transitivePeerDependencies: - supports-color - dev: true /http-proxy-middleware@2.0.7(@types/express@4.17.21): resolution: {integrity: sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==} @@ -15830,7 +16015,6 @@ packages: debug: 4.4.0(supports-color@5.5.0) transitivePeerDependencies: - supports-color - dev: true /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} @@ -16056,12 +16240,10 @@ packages: /ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} - requiresBuild: true dependencies: jsbn: 1.1.0 sprintf-js: 1.1.3 dev: false - optional: true /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} @@ -17412,9 +17594,7 @@ packages: /jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - requiresBuild: true dev: false - optional: true /jsdom@20.0.3: resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} @@ -18993,6 +19173,10 @@ packages: rimraf: 5.0.10 dev: false + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: false + /mjml-accordion@4.15.3: resolution: {integrity: sha512-LPNVSj1LyUVYT9G1gWwSw3GSuDzDsQCu0tPB2uDsq4VesYNnU6v3iLCQidMiR6azmIt13OEozG700ygAUuA6Ng==} requiresBuild: true @@ -19567,6 +19751,11 @@ packages: /neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: false + /next-themes@0.3.0(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} peerDependencies: @@ -20329,6 +20518,30 @@ packages: dev: false optional: true + /pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.3 + debug: 4.4.0(supports-color@5.5.0) + get-uri: 6.0.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + dev: false + + /pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + dev: false + /package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -20540,6 +20753,10 @@ packages: engines: {node: '>=8'} dev: false + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: false + /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} dev: false @@ -21665,6 +21882,22 @@ packages: forwarded: 0.2.0 ipaddr.js: 1.9.1 + /proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@5.5.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 7.18.3 + pac-proxy-agent: 7.2.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + dev: false + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -21817,6 +22050,43 @@ packages: escape-goat: 4.0.0 dev: false + /puppeteer-core@24.3.1: + resolution: {integrity: sha512-585ccfcTav4KmlSmYbwwOSeC8VdutQHn2Fuk0id/y/9OoeO7Gg5PK1aUGdZjEmos0TAq+pCpChqFurFbpNd3wA==} + engines: {node: '>=18'} + dependencies: + '@puppeteer/browsers': 2.7.1 + chromium-bidi: 2.1.2(devtools-protocol@0.0.1402036) + debug: 4.4.0(supports-color@5.5.0) + devtools-protocol: 0.0.1402036 + typed-query-selector: 2.12.0 + ws: 8.18.1 + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - utf-8-validate + dev: false + + /puppeteer@24.3.1(typescript@5.6.3): + resolution: {integrity: sha512-k0OJ7itRwkr06owp0CP3f/PsRD7Pdw4DjoCUZvjGr+aNgS1z6n/61VajIp0uBjl+V5XAQO1v/3k9bzeZLWs9OQ==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true + dependencies: + '@puppeteer/browsers': 2.7.1 + chromium-bidi: 2.1.2(devtools-protocol@0.0.1402036) + cosmiconfig: 9.0.0(typescript@5.6.3) + devtools-protocol: 0.0.1402036 + puppeteer-core: 24.3.1 + typed-query-selector: 2.12.0 + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - typescript + - utf-8-validate + dev: false + /pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} dev: true @@ -23270,9 +23540,7 @@ packages: /smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - requiresBuild: true dev: false - optional: true /snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -23301,15 +23569,24 @@ packages: dev: false optional: true + /socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@5.5.0) + socks: 2.8.4 + transitivePeerDependencies: + - supports-color + dev: false + /socks@2.8.4: resolution: {integrity: sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - requiresBuild: true dependencies: ip-address: 9.0.5 smart-buffer: 4.2.0 dev: false - optional: true /sonner@1.7.4(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==} @@ -23395,9 +23672,7 @@ packages: /sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - requiresBuild: true dev: false - optional: true /sql-highlight@6.0.0: resolution: {integrity: sha512-+fLpbAbWkQ+d0JEchJT/NrRRXbYRNbG15gFpANx73EwxQB1PRjj+k/OI0GTU0J63g8ikGkJECQp9z8XEJZvPRw==} @@ -23485,6 +23760,15 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + /streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + dev: false + /string-env-interpolation@1.0.1: resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} dev: true @@ -23941,6 +24225,18 @@ packages: tar-stream: 2.2.0 dev: false + /tar-fs@3.0.8: + resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} + dependencies: + pump: 3.0.2 + tar-stream: 3.1.7 + optionalDependencies: + bare-fs: 4.0.1 + bare-path: 3.0.0 + transitivePeerDependencies: + - bare-buffer + dev: false + /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} @@ -23952,6 +24248,14 @@ packages: readable-stream: 3.6.2 dev: false + /tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.0 + dev: false + /tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -24042,6 +24346,12 @@ packages: minimatch: 3.1.2 dev: true + /text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + dependencies: + b4a: 1.6.7 + dev: false + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -24560,6 +24870,10 @@ packages: reflect.getprototypeof: 1.0.10 dev: true + /typed-query-selector@2.12.0: + resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==} + dev: false + /typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: @@ -25771,6 +26085,13 @@ packages: y18n: 5.0.8 yargs-parser: 21.1.1 + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: false + /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'}