diff --git a/.prettierignore b/.prettierignore index c184fdba..55d3c7c5 100644 --- a/.prettierignore +++ b/.prettierignore @@ -35,4 +35,7 @@ coverage *.swp # Ignore all files with the .DS_Store extension (macOS specific) -.DS_Store \ No newline at end of file +.DS_Store + +# Ignore all files in uploads directory +uploads \ No newline at end of file diff --git a/backend.dockerfile b/backend.dockerfile index 87cd21c6..b6ab95a6 100644 --- a/backend.dockerfile +++ b/backend.dockerfile @@ -9,6 +9,7 @@ COPY package.json /home/perplexica/ COPY yarn.lock /home/perplexica/ RUN mkdir /home/perplexica/data +RUN mkdir /home/perplexica/uploads RUN yarn install --frozen-lockfile --network-timeout 600000 RUN yarn build diff --git a/docker-compose.yaml b/docker-compose.yaml index 46d82c60..a0e1d734 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -22,6 +22,7 @@ services: - 3001:3001 volumes: - backend-dbstore:/home/perplexica/data + - uploads:/home/perplexica/uploads - ./config.toml:/home/perplexica/config.toml extra_hosts: - 'host.docker.internal:host-gateway' @@ -50,3 +51,4 @@ networks: volumes: backend-dbstore: + uploads: diff --git a/package.json b/package.json index db70194f..3a3a1ccf 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "start": "npm run db:push && node dist/app.js", "build": "tsc", - "dev": "nodemon src/app.ts", + "dev": "nodemon --ignore uploads/ src/app.ts ", "db:push": "drizzle-kit push sqlite", "format": "prettier . --check", "format:write": "prettier . --write" @@ -16,6 +16,7 @@ "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/html-to-text": "^9.0.4", + "@types/multer": "^1.4.12", "@types/pdf-parse": "^1.1.4", "@types/readable-stream": "^4.0.11", "@types/ws": "^8.5.12", @@ -41,6 +42,8 @@ "express": "^4.19.2", "html-to-text": "^9.0.5", "langchain": "^0.1.30", + "mammoth": "^1.8.0", + "multer": "^1.4.5-lts.1", "pdf-parse": "^1.1.1", "winston": "^3.13.0", "ws": "^8.17.1", diff --git a/src/agents/webSearchAgent.ts b/src/agents/webSearchAgent.ts index e2c5adc1..43037626 100644 --- a/src/agents/webSearchAgent.ts +++ b/src/agents/webSearchAgent.ts @@ -20,10 +20,12 @@ import eventEmitter from 'events'; import computeSimilarity from '../utils/computeSimilarity'; import logger from '../utils/logger'; import LineListOutputParser from '../lib/outputParsers/listLineOutputParser'; -import { getDocumentsFromLinks } from '../lib/linkDocument'; import LineOutputParser from '../lib/outputParsers/lineOutputParser'; import { IterableReadableStream } from '@langchain/core/utils/stream'; import { ChatOpenAI } from '@langchain/openai'; +import path from 'path'; +import fs from 'fs'; +import { getDocumentsFromLinks } from '../utils/documents'; const basicSearchRetrieverPrompt = ` You are an AI question rephraser. You will be given a conversation and a follow-up question, you will have to rephrase the follow up question so it is a standalone question and can be used by another LLM to search the web for information to answer it. @@ -316,6 +318,7 @@ const createBasicWebSearchAnsweringChain = ( llm: BaseChatModel, embeddings: Embeddings, optimizationMode: 'speed' | 'balanced' | 'quality', + fileIds: string[], ) => { const basicWebSearchRetrieverChain = createBasicWebSearchRetrieverChain(llm); @@ -336,8 +339,32 @@ const createBasicWebSearchAnsweringChain = ( return docs; } + const filesData = fileIds + .map((file) => { + const filePath = path.join(process.cwd(), 'uploads', file); + + const contentPath = filePath + '-extracted.json'; + const embeddingsPath = filePath + '-embeddings.json'; + + const content = JSON.parse(fs.readFileSync(contentPath, 'utf8')); + const embeddings = JSON.parse(fs.readFileSync(embeddingsPath, 'utf8')); + + const fileSimilaritySearchObject = content.contents.map( + (c: string, i) => { + return { + fileName: content.title, + content: c, + embeddings: embeddings.embeddings[i], + }; + }, + ); + + return fileSimilaritySearchObject; + }) + .flat(); + if (query.toLocaleLowerCase() === 'summarize') { - return docs.slice(0, 15) + return docs.slice(0, 15); } const docsWithContent = docs.filter( @@ -345,7 +372,43 @@ const createBasicWebSearchAnsweringChain = ( ); if (optimizationMode === 'speed') { - return docsWithContent.slice(0, 15); + if (filesData.length > 0) { + const [queryEmbedding] = await Promise.all([ + embeddings.embedQuery(query), + ]); + + const fileDocs = filesData.map((fileData) => { + return new Document({ + pageContent: fileData.content, + metadata: { + title: fileData.fileName, + url: `File`, + }, + }); + }); + + const similarity = filesData.map((fileData, i) => { + const sim = computeSimilarity(queryEmbedding, fileData.embeddings); + + return { + index: i, + similarity: sim, + }; + }); + + const sortedDocs = similarity + .filter((sim) => sim.similarity > 0.3) + .sort((a, b) => b.similarity - a.similarity) + .slice(0, 8) + .map((sim) => fileDocs[sim.index]); + + return [ + ...sortedDocs, + ...docsWithContent.slice(0, 15 - sortedDocs.length), + ]; + } else { + return docsWithContent.slice(0, 15); + } } else if (optimizationMode === 'balanced') { const [docEmbeddings, queryEmbedding] = await Promise.all([ embeddings.embedDocuments( @@ -354,6 +417,20 @@ const createBasicWebSearchAnsweringChain = ( embeddings.embedQuery(query), ]); + docsWithContent.push( + ...filesData.map((fileData) => { + return new Document({ + pageContent: fileData.content, + metadata: { + title: fileData.fileName, + url: `File`, + }, + }); + }), + ); + + docEmbeddings.push(...filesData.map((fileData) => fileData.embeddings)); + const similarity = docEmbeddings.map((docEmbedding, i) => { const sim = computeSimilarity(queryEmbedding, docEmbedding); @@ -408,6 +485,7 @@ const basicWebSearch = ( llm: BaseChatModel, embeddings: Embeddings, optimizationMode: 'speed' | 'balanced' | 'quality', + fileIds: string[], ) => { const emitter = new eventEmitter(); @@ -416,6 +494,7 @@ const basicWebSearch = ( llm, embeddings, optimizationMode, + fileIds, ); const stream = basicWebSearchAnsweringChain.streamEvents( @@ -446,6 +525,7 @@ const handleWebSearch = ( llm: BaseChatModel, embeddings: Embeddings, optimizationMode: 'speed' | 'balanced' | 'quality', + fileIds: string[], ) => { const emitter = basicWebSearch( message, @@ -453,6 +533,7 @@ const handleWebSearch = ( llm, embeddings, optimizationMode, + fileIds, ); return emitter; }; diff --git a/src/db/schema.ts b/src/db/schema.ts index 9eefa558..cee96603 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -1,3 +1,4 @@ +import { sql } from 'drizzle-orm'; import { text, integer, sqliteTable } from 'drizzle-orm/sqlite-core'; export const messages = sqliteTable('messages', { @@ -11,9 +12,17 @@ export const messages = sqliteTable('messages', { }), }); +interface File { + name: string; + fileId: string; +} + export const chats = sqliteTable('chats', { id: text('id').primaryKey(), title: text('title').notNull(), createdAt: text('createdAt').notNull(), focusMode: text('focusMode').notNull(), + files: text('files', { mode: 'json' }) + .$type() + .default(sql`'[]'`), }); diff --git a/src/lib/providers/ollama.ts b/src/lib/providers/ollama.ts index 8c36c98f..e23fb766 100644 --- a/src/lib/providers/ollama.ts +++ b/src/lib/providers/ollama.ts @@ -6,7 +6,7 @@ import { ChatOllama } from '@langchain/community/chat_models/ollama'; export const loadOllamaChatModels = async () => { const ollamaEndpoint = getOllamaApiEndpoint(); const keepAlive = getKeepAlive(); - + if (!ollamaEndpoint) return {}; try { @@ -25,7 +25,7 @@ export const loadOllamaChatModels = async () => { baseUrl: ollamaEndpoint, model: model.model, temperature: 0.7, - keepAlive: keepAlive + keepAlive: keepAlive, }), }; diff --git a/src/routes/index.ts b/src/routes/index.ts index 28c297fa..cb2c9156 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -7,6 +7,7 @@ import suggestionsRouter from './suggestions'; import chatsRouter from './chats'; import searchRouter from './search'; import discoverRouter from './discover'; +import uploadsRouter from './uploads'; const router = express.Router(); @@ -18,5 +19,6 @@ router.use('/suggestions', suggestionsRouter); router.use('/chats', chatsRouter); router.use('/search', searchRouter); router.use('/discover', discoverRouter); +router.use('/uploads', uploadsRouter); export default router; diff --git a/src/routes/uploads.ts b/src/routes/uploads.ts new file mode 100644 index 00000000..7b063fc1 --- /dev/null +++ b/src/routes/uploads.ts @@ -0,0 +1,151 @@ +import express from 'express'; +import logger from '../utils/logger'; +import multer from 'multer'; +import path from 'path'; +import crypto from 'crypto'; +import fs from 'fs'; +import { Embeddings } from '@langchain/core/embeddings'; +import { getAvailableEmbeddingModelProviders } from '../lib/providers'; +import { PDFLoader } from '@langchain/community/document_loaders/fs/pdf'; +import { DocxLoader } from '@langchain/community/document_loaders/fs/docx'; +import { RecursiveCharacterTextSplitter } from '@langchain/textsplitters'; +import { Document } from 'langchain/document'; + +const router = express.Router(); + +const splitter = new RecursiveCharacterTextSplitter({ + chunkSize: 500, + chunkOverlap: 100, +}); + +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + cb(null, path.join(process.cwd(), './uploads')); + }, + filename: (req, file, cb) => { + const splitedFileName = file.originalname.split('.'); + const fileExtension = splitedFileName[splitedFileName.length - 1]; + if (!['pdf', 'docx', 'txt'].includes(fileExtension)) { + return cb(new Error('File type is not supported'), ''); + } + cb(null, `${crypto.randomBytes(16).toString('hex')}.${fileExtension}`); + }, +}); + +const upload = multer({ storage }); + +router.post( + '/', + upload.fields([ + { name: 'files' }, + { name: 'embedding_model', maxCount: 1 }, + { name: 'embedding_model_provider', maxCount: 1 }, + ]), + async (req, res) => { + try { + const { embedding_model, embedding_model_provider } = req.body; + + if (!embedding_model || !embedding_model_provider) { + res + .status(400) + .json({ message: 'Missing embedding model or provider' }); + return; + } + + const embeddingModels = await getAvailableEmbeddingModelProviders(); + const provider = + embedding_model_provider ?? Object.keys(embeddingModels)[0]; + const embeddingModel: Embeddings = + embedding_model ?? Object.keys(embeddingModels[provider])[0]; + + let embeddingsModel: Embeddings | undefined; + + if ( + embeddingModels[provider] && + embeddingModels[provider][embeddingModel] + ) { + embeddingsModel = embeddingModels[provider][embeddingModel].model as + | Embeddings + | undefined; + } + + if (!embeddingsModel) { + res.status(400).json({ message: 'Invalid LLM model selected' }); + return; + } + + const files = req.files['files'] as Express.Multer.File[]; + if (!files || files.length === 0) { + res.status(400).json({ message: 'No files uploaded' }); + return; + } + + await Promise.all( + files.map(async (file) => { + let docs: Document[] = []; + + if (file.mimetype === 'application/pdf') { + const loader = new PDFLoader(file.path); + docs = await loader.load(); + } else if ( + file.mimetype === + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ) { + const loader = new DocxLoader(file.path); + docs = await loader.load(); + } else if (file.mimetype === 'text/plain') { + const text = fs.readFileSync(file.path, 'utf-8'); + docs = [ + new Document({ + pageContent: text, + metadata: { + title: file.originalname, + }, + }), + ]; + } + + const splitted = await splitter.splitDocuments(docs); + + const json = JSON.stringify({ + title: file.originalname, + contents: splitted.map((doc) => doc.pageContent), + }); + + const pathToSave = file.path.replace(/\.\w+$/, '-extracted.json'); + fs.writeFileSync(pathToSave, json); + + const embeddings = await embeddingsModel.embedDocuments( + splitted.map((doc) => doc.pageContent), + ); + + const embeddingsJSON = JSON.stringify({ + title: file.originalname, + embeddings: embeddings, + }); + + const pathToSaveEmbeddings = file.path.replace( + /\.\w+$/, + '-embeddings.json', + ); + fs.writeFileSync(pathToSaveEmbeddings, embeddingsJSON); + }), + ); + + res.status(200).json({ + files: files.map((file) => { + return { + fileName: file.originalname, + fileExtension: file.filename.split('.').pop(), + fileId: file.filename.replace(/\.\w+$/, ''), + }; + }), + }); + } catch (err: any) { + logger.error(`Error in uploading file results: ${err.message}`); + res.status(500).json({ message: 'An error has occurred.' }); + } + }, +); + +export default router; diff --git a/src/lib/linkDocument.ts b/src/utils/documents.ts similarity index 98% rename from src/lib/linkDocument.ts rename to src/utils/documents.ts index 5e905712..5cd03669 100644 --- a/src/lib/linkDocument.ts +++ b/src/utils/documents.ts @@ -3,7 +3,7 @@ import { htmlToText } from 'html-to-text'; import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter'; import { Document } from '@langchain/core/documents'; import pdfParse from 'pdf-parse'; -import logger from '../utils/logger'; +import logger from './logger'; export const getDocumentsFromLinks = async ({ links }: { links: string[] }) => { const splitter = new RecursiveCharacterTextSplitter(); diff --git a/src/utils/files.ts b/src/utils/files.ts new file mode 100644 index 00000000..3e7a134a --- /dev/null +++ b/src/utils/files.ts @@ -0,0 +1,16 @@ +import path from 'path'; +import fs from 'fs'; +export const getFileDetails = (fileId: string) => { + const fileLoc = path.join( + process.cwd(), + './uploads', + fileId + '-extracted.json', + ); + + const parsedFile = JSON.parse(fs.readFileSync(fileLoc, 'utf8')); + + return { + name: parsedFile.title, + fileId: fileId, + }; +}; diff --git a/src/websocket/messageHandler.ts b/src/websocket/messageHandler.ts index e915b229..d2a25186 100644 --- a/src/websocket/messageHandler.ts +++ b/src/websocket/messageHandler.ts @@ -13,6 +13,7 @@ import db from '../db'; import { chats, messages as messagesSchema } from '../db/schema'; import { eq, asc, gt } from 'drizzle-orm'; import crypto from 'crypto'; +import { getFileDetails } from '../utils/files'; type Message = { messageId: string; @@ -26,6 +27,7 @@ type WSMessage = { type: string; focusMode: string; history: Array<[string, string]>; + files: Array; }; export const searchHandlers = { @@ -141,6 +143,7 @@ export const handleMessage = async ( llm, embeddings, parsedWSMessage.optimizationMode, + parsedWSMessage.files, ); handleEmitterEvents(emitter, ws, aiMessageId, parsedMessage.chatId); @@ -157,6 +160,7 @@ export const handleMessage = async ( title: parsedMessage.content, createdAt: new Date().toString(), focusMode: parsedWSMessage.focusMode, + files: parsedWSMessage.files.map(getFileDetails), }) .execute(); } diff --git a/ui/components/Chat.tsx b/ui/components/Chat.tsx index 8c0fb804..81aa32f6 100644 --- a/ui/components/Chat.tsx +++ b/ui/components/Chat.tsx @@ -2,7 +2,7 @@ import { Fragment, useEffect, useRef, useState } from 'react'; import MessageInput from './MessageInput'; -import { Message } from './ChatWindow'; +import { File, Message } from './ChatWindow'; import MessageBox from './MessageBox'; import MessageBoxLoading from './MessageBoxLoading'; @@ -12,12 +12,20 @@ const Chat = ({ sendMessage, messageAppeared, rewrite, + fileIds, + setFileIds, + files, + setFiles, }: { messages: Message[]; sendMessage: (message: string) => void; loading: boolean; messageAppeared: boolean; rewrite: (messageId: string) => void; + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + files: File[]; + setFiles: (files: File[]) => void; }) => { const [dividerWidth, setDividerWidth] = useState(0); const dividerRef = useRef(null); @@ -78,7 +86,14 @@ const Chat = ({ className="bottom-24 lg:bottom-10 fixed z-40" style={{ width: dividerWidth }} > - + )} diff --git a/ui/components/ChatWindow.tsx b/ui/components/ChatWindow.tsx index f9bd5839..fd3d0a6a 100644 --- a/ui/components/ChatWindow.tsx +++ b/ui/components/ChatWindow.tsx @@ -21,6 +21,12 @@ export type Message = { sources?: Document[]; }; +export interface File { + fileName: string; + fileExtension: string; + fileId: string; +} + const useSocket = ( url: string, setIsWSReady: (ready: boolean) => void, @@ -217,6 +223,8 @@ const loadMessages = async ( setChatHistory: (history: [string, string][]) => void, setFocusMode: (mode: string) => void, setNotFound: (notFound: boolean) => void, + setFiles: (files: File[]) => void, + setFileIds: (fileIds: string[]) => void, ) => { const res = await fetch( `${process.env.NEXT_PUBLIC_API_URL}/chats/${chatId}`, @@ -253,6 +261,17 @@ const loadMessages = async ( document.title = messages[0].content; + const files = data.chat.files.map((file: any) => { + return { + fileName: file.name, + fileExtension: file.name.split('.').pop(), + fileId: file.fileId, + }; + }); + + setFiles(files); + setFileIds(files.map((file: File) => file.fileId)); + setChatHistory(history); setFocusMode(data.chat.focusMode); setIsMessagesLoaded(true); @@ -281,6 +300,9 @@ const ChatWindow = ({ id }: { id?: string }) => { const [chatHistory, setChatHistory] = useState<[string, string][]>([]); const [messages, setMessages] = useState([]); + const [files, setFiles] = useState([]); + const [fileIds, setFileIds] = useState([]); + const [focusMode, setFocusMode] = useState('webSearch'); const [optimizationMode, setOptimizationMode] = useState('speed'); @@ -302,6 +324,8 @@ const ChatWindow = ({ id }: { id?: string }) => { setChatHistory, setFocusMode, setNotFound, + setFiles, + setFileIds, ); } else if (!chatId) { setNewChatCreated(true); @@ -354,6 +378,7 @@ const ChatWindow = ({ id }: { id?: string }) => { chatId: chatId!, content: message, }, + files: fileIds, focusMode: focusMode, optimizationMode: optimizationMode, history: [...chatHistory, ['human', message]], @@ -511,6 +536,10 @@ const ChatWindow = ({ id }: { id?: string }) => { sendMessage={sendMessage} messageAppeared={messageAppeared} rewrite={rewrite} + fileIds={fileIds} + setFileIds={setFileIds} + files={files} + setFiles={setFiles} /> ) : ( @@ -520,6 +549,10 @@ const ChatWindow = ({ id }: { id?: string }) => { setFocusMode={setFocusMode} optimizationMode={optimizationMode} setOptimizationMode={setOptimizationMode} + fileIds={fileIds} + setFileIds={setFileIds} + files={files} + setFiles={setFiles} /> )} diff --git a/ui/components/EmptyChat.tsx b/ui/components/EmptyChat.tsx index 6b2412b3..c47c3013 100644 --- a/ui/components/EmptyChat.tsx +++ b/ui/components/EmptyChat.tsx @@ -2,6 +2,7 @@ import { Settings } from 'lucide-react'; import EmptyChatMessageInput from './EmptyChatMessageInput'; import SettingsDialog from './SettingsDialog'; import { useState } from 'react'; +import { File } from './ChatWindow'; const EmptyChat = ({ sendMessage, @@ -9,12 +10,20 @@ const EmptyChat = ({ setFocusMode, optimizationMode, setOptimizationMode, + fileIds, + setFileIds, + files, + setFiles, }: { sendMessage: (message: string) => void; focusMode: string; setFocusMode: (mode: string) => void; optimizationMode: string; setOptimizationMode: (mode: string) => void; + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + files: File[]; + setFiles: (files: File[]) => void; }) => { const [isSettingsOpen, setIsSettingsOpen] = useState(false); @@ -37,6 +46,10 @@ const EmptyChat = ({ setFocusMode={setFocusMode} optimizationMode={optimizationMode} setOptimizationMode={setOptimizationMode} + fileIds={fileIds} + setFileIds={setFileIds} + files={files} + setFiles={setFiles} /> diff --git a/ui/components/EmptyChatMessageInput.tsx b/ui/components/EmptyChatMessageInput.tsx index 42ad9170..43d1e28a 100644 --- a/ui/components/EmptyChatMessageInput.tsx +++ b/ui/components/EmptyChatMessageInput.tsx @@ -4,6 +4,8 @@ import TextareaAutosize from 'react-textarea-autosize'; import CopilotToggle from './MessageInputActions/Copilot'; import Focus from './MessageInputActions/Focus'; import Optimization from './MessageInputActions/Optimization'; +import Attach from './MessageInputActions/Attach'; +import { File } from './ChatWindow'; const EmptyChatMessageInput = ({ sendMessage, @@ -11,12 +13,20 @@ const EmptyChatMessageInput = ({ setFocusMode, optimizationMode, setOptimizationMode, + fileIds, + setFileIds, + files, + setFiles, }: { sendMessage: (message: string) => void; focusMode: string; setFocusMode: (mode: string) => void; optimizationMode: string; setOptimizationMode: (mode: string) => void; + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + files: File[]; + setFiles: (files: File[]) => void; }) => { const [copilotEnabled, setCopilotEnabled] = useState(false); const [message, setMessage] = useState(''); @@ -73,8 +83,15 @@ const EmptyChatMessageInput = ({ placeholder="Ask anything..." />
-
+
+
void; loading: boolean; + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + files: File[]; + setFiles: (files: File[]) => void; }) => { const [copilotEnabled, setCopilotEnabled] = useState(false); const [message, setMessage] = useState(''); @@ -69,7 +79,14 @@ const MessageInput = ({ mode === 'multi' ? 'flex-col rounded-lg' : 'flex-row rounded-full', )} > - {mode === 'single' && } + {mode === 'single' && ( + + )} - +
{ - return ( +const Attach = ({ + fileIds, + setFileIds, + showText, + files, + setFiles, +}: { + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + showText?: boolean; + files: FileType[]; + setFiles: (files: FileType[]) => void; +}) => { + const [loading, setLoading] = useState(false); + const fileInputRef = useRef(); + + const handleChange = async (e: React.ChangeEvent) => { + setLoading(true); + const data = new FormData(); + + for (let i = 0; i < e.target.files!.length; i++) { + data.append('files', e.target.files![i]); + } + + const embeddingModelProvider = localStorage.getItem( + 'embeddingModelProvider', + ); + const embeddingModel = localStorage.getItem('embeddingModel'); + + data.append('embedding_model_provider', embeddingModelProvider!); + data.append('embedding_model', embeddingModel!); + + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/uploads`, { + method: 'POST', + body: data, + }); + + const resData = await res.json(); + + setFiles([...files, ...resData.files]); + setFileIds([...fileIds, ...resData.files.map((file: any) => file.fileId)]); + setLoading(false); + }; + + return loading ? ( +
+ +

+ Uploading.. +

+
+ ) : files.length > 0 ? ( + + 0 ? '-ml-2 lg:-ml-3' : '', + )} + > + {files.length > 1 && ( + <> + +

+ {files.length} files +

+ + )} + + {files.length === 1 && ( + <> + +

+ {files[0].fileName.length > 10 + ? files[0].fileName.replace(/\.\w+$/, '').substring(0, 3) + + '...' + + files[0].fileExtension + : files[0].fileName} +

+ + )} +
+ + +
+
+

+ Attached files +

+
+ + +
+
+
+
+ {files.map((file, i) => ( +
+
+ +
+

+ {file.fileName.length > 25 + ? file.fileName.replace(/\.\w+$/, '').substring(0, 25) + + '...' + + file.fileExtension + : file.fileName} +

+
+ ))} +
+
+ + + + ) : ( ); }; diff --git a/ui/components/MessageInputActions/AttachSmall.tsx b/ui/components/MessageInputActions/AttachSmall.tsx new file mode 100644 index 00000000..3514a585 --- /dev/null +++ b/ui/components/MessageInputActions/AttachSmall.tsx @@ -0,0 +1,153 @@ +import { cn } from '@/lib/utils'; +import { + Popover, + PopoverButton, + PopoverPanel, + Transition, +} from '@headlessui/react'; +import { CopyPlus, File, LoaderCircle, Plus, Trash } from 'lucide-react'; +import { Fragment, useRef, useState } from 'react'; +import { File as FileType } from '../ChatWindow'; + +const AttachSmall = ({ + fileIds, + setFileIds, + files, + setFiles, +}: { + fileIds: string[]; + setFileIds: (fileIds: string[]) => void; + files: FileType[]; + setFiles: (files: FileType[]) => void; +}) => { + const [loading, setLoading] = useState(false); + const fileInputRef = useRef(); + + const handleChange = async (e: React.ChangeEvent) => { + setLoading(true); + const data = new FormData(); + + for (let i = 0; i < e.target.files!.length; i++) { + data.append('files', e.target.files![i]); + } + + const embeddingModelProvider = localStorage.getItem( + 'embeddingModelProvider', + ); + const embeddingModel = localStorage.getItem('embeddingModel'); + + data.append('embedding_model_provider', embeddingModelProvider!); + data.append('embedding_model', embeddingModel!); + + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/uploads`, { + method: 'POST', + body: data, + }); + + const resData = await res.json(); + + setFiles([...files, ...resData.files]); + setFileIds([...fileIds, ...resData.files.map((file: any) => file.fileId)]); + setLoading(false); + }; + + return loading ? ( +
+ +
+ ) : files.length > 0 ? ( + + + + + + +
+
+

+ Attached files +

+
+ + +
+
+
+
+ {files.map((file, i) => ( +
+
+ +
+

+ {file.fileName.length > 25 + ? file.fileName.replace(/\.\w+$/, '').substring(0, 25) + + '...' + + file.fileExtension + : file.fileName} +

+
+ ))} +
+
+ + + + ) : ( + + ); +}; + +export default AttachSmall; diff --git a/ui/components/MessageInputActions/Focus.tsx b/ui/components/MessageInputActions/Focus.tsx index e4716305..c95be5ab 100644 --- a/ui/components/MessageInputActions/Focus.tsx +++ b/ui/components/MessageInputActions/Focus.tsx @@ -75,7 +75,7 @@ const Focus = ({ setFocusMode: (mode: string) => void; }) => { return ( - + {focusModes.find((mode) => mode.key === focusMode)?.title}

- +
) : ( - +
+ +

Focus

+
)} { @@ -36,13 +37,19 @@ const MessageSources = ({ sources }: { sources: Document[] }) => {

- favicon + {source.metadata.url === 'File' ? ( +
+ +
+ ) : ( + favicon + )}

{source.metadata.url.replace(/.+\/\/|www.|\..+/g, '')}

@@ -60,16 +67,21 @@ const MessageSources = ({ sources }: { sources: Document[] }) => { className="bg-light-100 hover:bg-light-200 dark:bg-dark-100 dark:hover:bg-dark-200 transition duration-200 rounded-lg p-3 flex flex-col space-y-2 font-medium" >
- {sources.slice(3, 6).map((source, i) => ( - favicon - ))} + {sources.slice(3, 6).map((source, i) => { + return source.metadata.url === 'File' ? ( +
+ +
+ ) : ( + favicon + ); + })}

View {sources.length - 3} more @@ -106,13 +118,19 @@ const MessageSources = ({ sources }: { sources: Document[] }) => {

- favicon + {source.metadata.url === 'File' ? ( +
+ +
+ ) : ( + favicon + )}

{source.metadata.url.replace( /.+\/\/|www.|\..+/g, diff --git a/ui/package.json b/ui/package.json index 4d630273..445b9a34 100644 --- a/ui/package.json +++ b/ui/package.json @@ -11,7 +11,7 @@ "format:write": "prettier . --write" }, "dependencies": { - "@headlessui/react": "^2.1.9", + "@headlessui/react": "^2.2.0", "@icons-pack/react-simple-icons": "^9.4.0", "@langchain/openai": "^0.0.25", "@tailwindcss/typography": "^0.5.12", diff --git a/ui/yarn.lock b/ui/yarn.lock index 550a20c1..0798ca9a 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -74,9 +74,9 @@ "@floating-ui/utils" "^0.2.8" "@floating-ui/dom@^1.0.0": - version "1.6.11" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723" - integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ== + version "1.6.12" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.12.tgz#6333dcb5a8ead3b2bf82f33d6bc410e95f54e556" + integrity sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w== dependencies: "@floating-ui/core" "^1.6.0" "@floating-ui/utils" "^0.2.8" @@ -89,9 +89,9 @@ "@floating-ui/dom" "^1.0.0" "@floating-ui/react@^0.26.16": - version "0.26.24" - resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.24.tgz#072b9dfeca4e79ef4e3000ef1c28e0ffc86f4ed4" - integrity sha512-2ly0pCkZIGEQUq5H8bBK0XJmc1xIK/RM3tvVzY3GBER7IOD1UgmC2Y2tjj4AuS+TC+vTE1KJv2053290jua0Sw== + version "0.26.28" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.28.tgz#93f44ebaeb02409312e9df9507e83aab4a8c0dc7" + integrity sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw== dependencies: "@floating-ui/react-dom" "^2.1.2" "@floating-ui/utils" "^0.2.8" @@ -102,10 +102,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== -"@headlessui/react@^2.1.9": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-2.1.9.tgz#d8d3ff64255177a87706cc4f24f42aeac65b1695" - integrity sha512-ckWw7vlKtnoa1fL2X0fx1a3t/Li9MIKDVXn3SgG65YlxvDAsNrY39PPCxVM7sQRA7go2fJsuHSSauKFNaJHH7A== +"@headlessui/react@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-2.2.0.tgz#a8e32f0899862849a1ce1615fa280e7891431ab7" + integrity sha512-RzCEg+LXsuI7mHiSomsu/gBJSjpupm6A1qIZ5sWjd7JhARNlMiSA4kKfJpCKwU9tE+zMRterhhrP74PvfJrpXQ== dependencies: "@floating-ui/react" "^0.26.16" "@react-aria/focus" "^3.17.1" @@ -317,20 +317,20 @@ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@react-aria/focus@^3.17.1": - version "3.18.3" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.18.3.tgz#4fe32de1e7530beab8da2e7b89f0f17d22a47e5e" - integrity sha512-WKUElg+5zS0D3xlVn8MntNnkzJql2J6MuzAMP8Sv5WTgFDse/XGR842dsxPTIyKKdrWVCRegCuwa4m3n/GzgJw== + version "3.18.4" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.18.4.tgz#a6e95896bc8680d1b5bcd855e983fc2c195a1a55" + integrity sha512-91J35077w9UNaMK1cpMUEFRkNNz0uZjnSwiyBCFuRdaVuivO53wNC9XtWSDNDdcO5cGy87vfJRVAiyoCn/mjqA== dependencies: - "@react-aria/interactions" "^3.22.3" + "@react-aria/interactions" "^3.22.4" "@react-aria/utils" "^3.25.3" "@react-types/shared" "^3.25.0" "@swc/helpers" "^0.5.0" clsx "^2.0.0" -"@react-aria/interactions@^3.21.3", "@react-aria/interactions@^3.22.3": - version "3.22.3" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.22.3.tgz#3ba50db12f6ed443ae061eed79e41509eaa3d8e6" - integrity sha512-RRUb/aG+P0IKTIWikY/SylB6bIbLZeztnZY2vbe7RAG5MgVaCgn5HQ45SI15GlTmhsFG8CnF6slJsUFJiNHpbQ== +"@react-aria/interactions@^3.21.3", "@react-aria/interactions@^3.22.4": + version "3.22.4" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.22.4.tgz#88ed61ab6a485f869bc1f65ae6688d48ca96064b" + integrity sha512-E0vsgtpItmknq/MJELqYJwib+YN18Qag8nroqwjk1qOnBa9ROIkUhWJerLi1qs5diXq9LHKehZDXRlwPvdEFww== dependencies: "@react-aria/ssr" "^3.9.6" "@react-aria/utils" "^3.25.3" @@ -380,11 +380,11 @@ tslib "^2.4.0" "@swc/helpers@^0.5.0": - version "0.5.13" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.13.tgz#33e63ff3cd0cade557672bd7888a39ce7d115a8c" - integrity sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w== + version "0.5.15" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" + integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== dependencies: - tslib "^2.4.0" + tslib "^2.8.0" "@tailwindcss/typography@^0.5.12": version "0.5.12" @@ -397,16 +397,16 @@ postcss-selector-parser "6.0.10" "@tanstack/react-virtual@^3.8.1": - version "3.10.8" - resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz#bf4b06f157ed298644a96ab7efc1a2b01ab36e3c" - integrity sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA== + version "3.10.9" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.9.tgz#40606b6dd8aba8e977f576d8f7df07f69ca63eea" + integrity sha512-OXO2uBjFqA4Ibr2O3y0YMnkrRWGVNqcvHQXmGvMu6IK8chZl3PrDxFXdGZ2iZkSrKh3/qUYoFqYe+Rx23RoU0g== dependencies: - "@tanstack/virtual-core" "3.10.8" + "@tanstack/virtual-core" "3.10.9" -"@tanstack/virtual-core@3.10.8": - version "3.10.8" - resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.8.tgz#975446a667755222f62884c19e5c3c66d959b8b4" - integrity sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA== +"@tanstack/virtual-core@3.10.9": + version "3.10.9" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz#55710c92b311fdaa8d8c66682a0dbdd684bc77c4" + integrity sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw== "@types/json5@^0.0.29": version "0.0.29" @@ -3192,10 +3192,10 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.4.0, tslib@^2.8.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" diff --git a/uploads/.gitignore b/uploads/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/uploads/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/yarn.lock b/yarn.lock index deb35eaf..0ea5916f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -576,6 +576,26 @@ "@types/range-parser" "*" "@types/send" "*" +"@types/express-serve-static-core@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz#3c9997ae9d00bc236e45c6374e84f2596458d9db" + integrity sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.0.tgz#13a7d1f75295e90d19ed6e74cab3678488eaa96c" + integrity sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^5.0.0" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/express@^4.17.21": version "4.17.21" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" @@ -606,6 +626,13 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== +"@types/multer@^1.4.12": + version "1.4.12" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.12.tgz#da67bd0c809f3a63fe097c458c0d4af1fea50ab7" + integrity sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg== + dependencies: + "@types/express" "*" + "@types/node-fetch@^2.6.4": version "2.6.11" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" @@ -708,6 +735,11 @@ optionalDependencies: onnxruntime-node "1.14.0" +"@xmldom/xmldom@^0.8.6": + version "0.8.10" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" + integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -758,6 +790,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -768,6 +805,13 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +argparse@~1.0.3: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -879,6 +923,11 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" +bluebird@~3.4.0: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== + body-parser@1.20.2: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" @@ -925,6 +974,13 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +busboy@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -1070,6 +1126,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -1092,6 +1158,11 @@ cookie@0.6.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@^2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -1202,6 +1273,11 @@ digest-fetch@^1.3.0: base-64 "^0.1.0" md5 "^2.3.0" +dingbat-to-unicode@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz#5091dd673241453e6b5865e26e5a4452cdef5c83" + integrity sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w== + dom-serializer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" @@ -1251,6 +1327,13 @@ drizzle-orm@^0.31.2: resolved "https://registry.yarnpkg.com/drizzle-orm/-/drizzle-orm-0.31.2.tgz#221a257dd487bab49ddb88a17bd82388600cf655" integrity sha512-QnenevbnnAzmbNzQwbhklvIYrDE8YER8K7kSrAWQSV1YvFCdSQPzj+jzqRdTSsV2cDqSpQ0NXGyL1G9I43LDLg== +duck@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/duck/-/duck-0.1.12.tgz#de7adf758421230b6d7aee799ce42670586b9efa" + integrity sha512-wkctla1O6VfP89gQ+J/yDesM0S7B7XLXjKGzXxMDVFg7uEn706niAtyYovKbyq1oT9YwDcly721/iUWoc8MVRg== + dependencies: + underscore "^1.13.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -1657,7 +1740,12 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4: +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + +inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1716,6 +1804,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + js-tiktoken@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/js-tiktoken/-/js-tiktoken-1.0.12.tgz#af0f5cf58e5e7318240d050c8413234019424211" @@ -1742,6 +1835,16 @@ jsonpointer@^5.0.1: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== +jszip@^3.7.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + kuler@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" @@ -1825,6 +1928,13 @@ leac@^0.6.0: resolved "https://registry.yarnpkg.com/leac/-/leac-0.6.0.tgz#dcf136e382e666bd2475f44a1096061b70dc0912" integrity sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg== +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -1847,6 +1957,15 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +lop@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/lop/-/lop-0.4.2.tgz#c9c2f958a39b9da1c2f36ca9ad66891a9fe84640" + integrity sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw== + dependencies: + duck "^0.1.12" + option "~0.2.1" + underscore "^1.13.1" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1859,6 +1978,22 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +mammoth@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/mammoth/-/mammoth-1.8.0.tgz#d8f1b0d3a0355fda129270346e9dc853f223028f" + integrity sha512-pJNfxSk9IEGVpau+tsZFz22ofjUsl2mnA5eT8PjPs2n0BP+rhVte4Nez6FdgEuxv3IGI3afiV46ImKqTGDVlbA== + dependencies: + "@xmldom/xmldom" "^0.8.6" + argparse "~1.0.3" + base64-js "^1.5.1" + bluebird "~3.4.0" + dingbat-to-unicode "^1.0.1" + jszip "^3.7.1" + lop "^0.4.1" + path-is-absolute "^1.0.0" + underscore "^1.13.1" + xmlbuilder "^10.0.0" + md5@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f" @@ -1912,7 +2047,7 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -1922,6 +2057,13 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + ml-array-mean@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56" @@ -1973,6 +2115,19 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multer@^1.4.5-lts.1: + version "1.4.5-lts.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.5-lts.1.tgz#803e24ad1984f58edffbc79f56e305aec5cfd1ac" + integrity sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ== + dependencies: + append-field "^1.0.0" + busboy "^1.0.0" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + type-is "^1.6.4" + xtend "^4.0.0" + mustache@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" @@ -2050,7 +2205,7 @@ num-sort@^2.0.0: resolved "https://registry.yarnpkg.com/num-sort/-/num-sort-2.1.0.tgz#1cbb37aed071329fdf41151258bc011898577a9b" integrity sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg== -object-assign@^4: +object-assign@^4, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -2146,6 +2301,11 @@ openapi-types@^12.1.3: resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-12.1.3.tgz#471995eb26c4b97b7bd356aacf7b91b73e777dd3" integrity sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw== +option@~0.2.1: + version "0.2.4" + resolved "https://registry.yarnpkg.com/option/-/option-0.2.4.tgz#fd475cdf98dcabb3cb397a3ba5284feb45edbfe4" + integrity sha512-pkEqbDyl8ou5cpq+VsnQbe/WlEy5qS7xPzMS1U55OCG9KPvwFD46zDbxQIj3egJSFc3D+XhYOPUzz49zQAVy7A== + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -2174,6 +2334,11 @@ p-timeout@^3.2.0: dependencies: p-finally "^1.0.0" +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + parseley@^0.12.0: version "0.12.1" resolved "https://registry.yarnpkg.com/parseley/-/parseley-0.12.1.tgz#4afd561d50215ebe259e3e7a853e62f600683aef" @@ -2187,6 +2352,11 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" @@ -2238,6 +2408,11 @@ prettier@^3.2.5: resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + protobufjs@^6.8.8: version "6.11.4" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" @@ -2320,6 +2495,19 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +readable-stream@^2.2.2, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" @@ -2351,7 +2539,7 @@ safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.1: +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -2421,6 +2609,11 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -2491,6 +2684,11 @@ source-map@^0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -2501,6 +2699,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + streamx@^2.15.0, streamx@^2.16.1: version "2.16.1" resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.16.1.tgz#2b311bd34832f08aa6bb4d6a80297c9caef89614" @@ -2518,6 +2721,13 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -2636,7 +2846,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -type-is@~1.6.18: +type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -2644,6 +2854,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + typescript@^5.4.3: version "5.4.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" @@ -2654,6 +2869,11 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== +underscore@^1.13.1: + version "1.13.7" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.7.tgz#970e33963af9a7dda228f17ebe8399e5fbe63a10" + integrity sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g== + undici-types@~5.26.4: version "5.26.5" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" @@ -2664,7 +2884,7 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -util-deprecate@^1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -2763,6 +2983,16 @@ ws@^8.17.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== +xmlbuilder@^10.0.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0" + integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"